diff --git a/main.lua b/main.lua index 92d967d..40be34d 100644 --- a/main.lua +++ b/main.lua @@ -39,7 +39,7 @@ function love.load() end if not config.input then - scene = InputConfigScene() + scene = KeyConfigScene() else if config.current_mode then current_mode = config.current_mode end if config.current_ruleset then current_ruleset = config.current_ruleset end diff --git a/scene.lua b/scene.lua index a2e4c74..aaa81b8 100644 --- a/scene.lua +++ b/scene.lua @@ -11,6 +11,8 @@ function Scene:onInputRelease() end ExitScene = require "scene.exit" GameScene = require "scene.game" ModeSelectScene = require "scene.mode_select" +KeyConfigScene = require "scene.key_config" +StickConfigScene = require "scene.stick_config" InputConfigScene = require "scene.input_config" GameConfigScene = require "scene.game_config" TuningScene = require "scene.tuning" diff --git a/scene/input_config.lua b/scene/input_config.lua index ebd6bd3..f61d942 100644 --- a/scene/input_config.lua +++ b/scene/input_config.lua @@ -2,179 +2,63 @@ local ConfigScene = Scene:extend() ConfigScene.title = "Input Config" -require 'load.save' - -local configurable_inputs = { - "menu_decide", - "menu_back", - "left", - "right", - "up", - "down", - "rotate_left", - "rotate_left2", - "rotate_right", - "rotate_right2", - "rotate_180", - "hold", - "retry", - "pause", +local menu_screens = { + KeyConfigScene, + StickConfigScene } -local function newSetInputs() - local set_inputs = {} - for i, input in ipairs(configurable_inputs) do - set_inputs[input] = false - end - return set_inputs -end - function ConfigScene:new() - self.input_state = 1 - self.key = 1 - self.set_inputs = newSetInputs() - self.new_input = {} - self.axis_timer = 0 - - DiscordRPC:update({ - details = "In menus", - state = "Changing input config", - }) + self.menu_state = 1 + DiscordRPC:update({ + details = "In menus", + state = "Changing input config", + }) end -function ConfigScene:update() -end +function ConfigScene:update() end function ConfigScene:render() - love.graphics.setColor(1, 1, 1, 1) - love.graphics.draw( + love.graphics.setColor(1, 1, 1, 1) + love.graphics.draw( backgrounds["input_config"], 0, 0, 0, 0.5, 0.5 - ) + ) - love.graphics.setFont(font_3x5_2) - for i, input in ipairs(configurable_inputs) do - love.graphics.printf(input, 40, 50 + i * 20, 200, "left") - if self.set_inputs[input] then - love.graphics.printf(self.set_inputs[input], 210, 50 + i * 20, 400, "left") - end - end - if self.input_state > table.getn(configurable_inputs) then - love.graphics.print("press enter to confirm, delete/backspace to retry" .. (config.input and ", escape to cancel" or "")) - else - love.graphics.print("press " .. (self.key == 2 and "joystick" or "key") .. " input for " .. configurable_inputs[self.input_state] .. ", tab to skip" .. (config.input and ", escape to cancel" or ""), 0, 0) - love.graphics.print("function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20) - end + love.graphics.setFont(font_3x5_4) + love.graphics.print("INPUT CONFIG", 80, 40) - self.axis_timer = self.axis_timer + 1 + love.graphics.setFont(font_3x5_2) + love.graphics.print("Which controls do you want to change?", 80, 90) + + love.graphics.setColor(1, 1, 1, 0.5) + love.graphics.rectangle("fill", 75, 118 + 50 * self.menu_state, 200, 33) + + love.graphics.setFont(font_3x5_3) + love.graphics.setColor(1, 1, 1, 1) + for i, screen in pairs(menu_screens) do + love.graphics.printf(screen.title, 80, 120 + 50 * i, 200, "left") + end end -local function addJoystick(input, name) - if not input.joysticks then - input.joysticks = {} - end - if not input.joysticks[name] then - input.joysticks[name] = {} - end +function ConfigScene:changeOption(rel) + local len = table.getn(menu_screens) + self.menu_state = (self.menu_state + len + rel - 1) % len + 1 end function ConfigScene:onInputPress(e) - if e.type == "key" then - -- function keys, escape, and tab are reserved and can't be remapped - if e.scancode == "escape" and config.input then - -- cancel only if there was an input config already - scene = SettingsScene() - elseif self.input_state > table.getn(configurable_inputs) then - if e.scancode == "return" then - -- save new input, then load next scene - config.input = self.new_input - saveConfig() - scene = TitleScene() - elseif e.scancode == "delete" or e.scancode == "backspace" then - -- retry - self.input_state = 1 - self.set_inputs = newSetInputs() - self.new_input = {} - end - elseif e.scancode == "tab" then - self.set_inputs[configurable_inputs[self.input_state]] = - ( - self.set_inputs[configurable_inputs[self.input_state]] == false - and "" or self.set_inputs[configurable_inputs[self.input_state]] - ) .. - (self.key == 2 and " / " or "") .. "skipped" - if self.key == 2 then - self.input_state = self.input_state + 1 - self.key = 1 - else - self.key = 2 - end - elseif e.scancode ~= "escape" and self.key == 1 then - -- all other keys can be configured - if not self.new_input.keys then - self.new_input.keys = {} - end - self.set_inputs[configurable_inputs[self.input_state]] = "key " .. love.keyboard.getKeyFromScancode(e.scancode) .. " (" .. e.scancode .. ")" - self.new_input.keys[e.scancode] = configurable_inputs[self.input_state] - self.key = 2 - end - elseif string.sub(e.type, 1, 3) == "joy" and self.key == 2 then - if self.input_state <= table.getn(configurable_inputs) then - if e.type == "joybutton" then - addJoystick(self.new_input, e.name) - if not self.new_input.joysticks[e.name].buttons then - self.new_input.joysticks[e.name].buttons = {} - end - self.set_inputs[configurable_inputs[self.input_state]] = - self.set_inputs[configurable_inputs[self.input_state]] .. - " / jbtn " .. - e.button .. - " " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "") - self.new_input.joysticks[e.name].buttons[e.button] = configurable_inputs[self.input_state] - self.input_state = self.input_state + 1 - self.key = 1 - elseif e.type == "joyaxis" then - if (e.axis ~= self.last_axis or self.axis_timer > 30) and e.value >= 1 then - addJoystick(self.new_input, e.name) - if not self.new_input.joysticks[e.name].axes then - self.new_input.joysticks[e.name].axes = {} - end - if not self.new_input.joysticks[e.name].axes[e.axis] then - self.new_input.joysticks[e.name].axes[e.axis] = {} - end - self.set_inputs[configurable_inputs[self.input_state]] = - self.set_inputs[configurable_inputs[self.input_state]] .. - " / jaxis " .. - e.axis .. - " " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "") - self.new_input.joysticks[e.name].axes[e.axis][e.value >= 1 and "positive" or "negative"] = configurable_inputs[self.input_state] - self.input_state = self.input_state + 1 - self.key = 1 - self.last_axis = e.axis - self.axis_timer = 0 - end - elseif e.type == "joyhat" then - if e.direction ~= "c" then - addJoystick(self.new_input, e.name) - if not self.new_input.joysticks[e.name].hats then - self.new_input.joysticks[e.name].hats = {} - end - if not self.new_input.joysticks[e.name].hats[e.hat] then - self.new_input.joysticks[e.name].hats[e.hat] = {} - end - self.set_inputs[configurable_inputs[self.input_state]] = - self.set_inputs[configurable_inputs[self.input_state]] .. - " / jhat " .. - e.hat .. " " .. e.direction .. - " " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "") - self.new_input.joysticks[e.name].hats[e.hat][e.direction] = configurable_inputs[self.input_state] - self.input_state = self.input_state + 1 - self.key = 1 - end - end - end + if e.input == "menu_decide" or e.scancode == "return" then + playSE("main_decide") + scene = menu_screens[self.menu_state]() + elseif e.input == "up" or e.scancode == "up" then + self:changeOption(-1) + playSE("cursor") + elseif e.input == "down" or e.scancode == "down" then + self:changeOption(1) + playSE("cursor") + elseif e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete" then + scene = SettingsScene() end end -return ConfigScene +return ConfigScene \ No newline at end of file diff --git a/scene/input_config_old.lua b/scene/input_config_old.lua new file mode 100644 index 0000000..ebd6bd3 --- /dev/null +++ b/scene/input_config_old.lua @@ -0,0 +1,180 @@ +local ConfigScene = Scene:extend() + +ConfigScene.title = "Input Config" + +require 'load.save' + +local configurable_inputs = { + "menu_decide", + "menu_back", + "left", + "right", + "up", + "down", + "rotate_left", + "rotate_left2", + "rotate_right", + "rotate_right2", + "rotate_180", + "hold", + "retry", + "pause", +} + +local function newSetInputs() + local set_inputs = {} + for i, input in ipairs(configurable_inputs) do + set_inputs[input] = false + end + return set_inputs +end + +function ConfigScene:new() + self.input_state = 1 + self.key = 1 + self.set_inputs = newSetInputs() + self.new_input = {} + self.axis_timer = 0 + + DiscordRPC:update({ + details = "In menus", + state = "Changing input config", + }) +end + +function ConfigScene:update() +end + +function ConfigScene:render() + love.graphics.setColor(1, 1, 1, 1) + love.graphics.draw( + backgrounds["input_config"], + 0, 0, 0, + 0.5, 0.5 + ) + + love.graphics.setFont(font_3x5_2) + for i, input in ipairs(configurable_inputs) do + love.graphics.printf(input, 40, 50 + i * 20, 200, "left") + if self.set_inputs[input] then + love.graphics.printf(self.set_inputs[input], 210, 50 + i * 20, 400, "left") + end + end + if self.input_state > table.getn(configurable_inputs) then + love.graphics.print("press enter to confirm, delete/backspace to retry" .. (config.input and ", escape to cancel" or "")) + else + love.graphics.print("press " .. (self.key == 2 and "joystick" or "key") .. " input for " .. configurable_inputs[self.input_state] .. ", tab to skip" .. (config.input and ", escape to cancel" or ""), 0, 0) + love.graphics.print("function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20) + end + + self.axis_timer = self.axis_timer + 1 +end + +local function addJoystick(input, name) + if not input.joysticks then + input.joysticks = {} + end + if not input.joysticks[name] then + input.joysticks[name] = {} + end +end + +function ConfigScene:onInputPress(e) + if e.type == "key" then + -- function keys, escape, and tab are reserved and can't be remapped + if e.scancode == "escape" and config.input then + -- cancel only if there was an input config already + scene = SettingsScene() + elseif self.input_state > table.getn(configurable_inputs) then + if e.scancode == "return" then + -- save new input, then load next scene + config.input = self.new_input + saveConfig() + scene = TitleScene() + elseif e.scancode == "delete" or e.scancode == "backspace" then + -- retry + self.input_state = 1 + self.set_inputs = newSetInputs() + self.new_input = {} + end + elseif e.scancode == "tab" then + self.set_inputs[configurable_inputs[self.input_state]] = + ( + self.set_inputs[configurable_inputs[self.input_state]] == false + and "" or self.set_inputs[configurable_inputs[self.input_state]] + ) .. + (self.key == 2 and " / " or "") .. "skipped" + if self.key == 2 then + self.input_state = self.input_state + 1 + self.key = 1 + else + self.key = 2 + end + elseif e.scancode ~= "escape" and self.key == 1 then + -- all other keys can be configured + if not self.new_input.keys then + self.new_input.keys = {} + end + self.set_inputs[configurable_inputs[self.input_state]] = "key " .. love.keyboard.getKeyFromScancode(e.scancode) .. " (" .. e.scancode .. ")" + self.new_input.keys[e.scancode] = configurable_inputs[self.input_state] + self.key = 2 + end + elseif string.sub(e.type, 1, 3) == "joy" and self.key == 2 then + if self.input_state <= table.getn(configurable_inputs) then + if e.type == "joybutton" then + addJoystick(self.new_input, e.name) + if not self.new_input.joysticks[e.name].buttons then + self.new_input.joysticks[e.name].buttons = {} + end + self.set_inputs[configurable_inputs[self.input_state]] = + self.set_inputs[configurable_inputs[self.input_state]] .. + " / jbtn " .. + e.button .. + " " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "") + self.new_input.joysticks[e.name].buttons[e.button] = configurable_inputs[self.input_state] + self.input_state = self.input_state + 1 + self.key = 1 + elseif e.type == "joyaxis" then + if (e.axis ~= self.last_axis or self.axis_timer > 30) and e.value >= 1 then + addJoystick(self.new_input, e.name) + if not self.new_input.joysticks[e.name].axes then + self.new_input.joysticks[e.name].axes = {} + end + if not self.new_input.joysticks[e.name].axes[e.axis] then + self.new_input.joysticks[e.name].axes[e.axis] = {} + end + self.set_inputs[configurable_inputs[self.input_state]] = + self.set_inputs[configurable_inputs[self.input_state]] .. + " / jaxis " .. + e.axis .. + " " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "") + self.new_input.joysticks[e.name].axes[e.axis][e.value >= 1 and "positive" or "negative"] = configurable_inputs[self.input_state] + self.input_state = self.input_state + 1 + self.key = 1 + self.last_axis = e.axis + self.axis_timer = 0 + end + elseif e.type == "joyhat" then + if e.direction ~= "c" then + addJoystick(self.new_input, e.name) + if not self.new_input.joysticks[e.name].hats then + self.new_input.joysticks[e.name].hats = {} + end + if not self.new_input.joysticks[e.name].hats[e.hat] then + self.new_input.joysticks[e.name].hats[e.hat] = {} + end + self.set_inputs[configurable_inputs[self.input_state]] = + self.set_inputs[configurable_inputs[self.input_state]] .. + " / jhat " .. + e.hat .. " " .. e.direction .. + " " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "") + self.new_input.joysticks[e.name].hats[e.hat][e.direction] = configurable_inputs[self.input_state] + self.input_state = self.input_state + 1 + self.key = 1 + end + end + end + end +end + +return ConfigScene diff --git a/scene/key_config.lua b/scene/key_config.lua new file mode 100644 index 0000000..adc74f9 --- /dev/null +++ b/scene/key_config.lua @@ -0,0 +1,101 @@ +local KeyConfigScene = Scene:extend() + +KeyConfigScene.title = "Key Config" + +require 'load.save' + +local configurable_inputs = { + "menu_decide", + "menu_back", + "left", + "right", + "up", + "down", + "rotate_left", + "rotate_left2", + "rotate_right", + "rotate_right2", + "rotate_180", + "hold", + "retry", + "pause", +} + +local function newSetInputs() + local set_inputs = {} + for i, input in ipairs(configurable_inputs) do + set_inputs[input] = false + end + return set_inputs +end + +function KeyConfigScene:new() + self.input_state = 1 + self.set_inputs = newSetInputs() + self.new_input = {} + + DiscordRPC:update({ + details = "In menus", + state = "Changing key config", + }) +end + +function KeyConfigScene:update() +end + +function KeyConfigScene:render() + love.graphics.setColor(1, 1, 1, 1) + love.graphics.draw( + backgrounds["input_config"], + 0, 0, 0, + 0.5, 0.5 + ) + + love.graphics.setFont(font_3x5_2) + for i, input in ipairs(configurable_inputs) do + love.graphics.printf(input, 40, 50 + i * 20, 200, "left") + if self.set_inputs[input] then + love.graphics.printf(self.set_inputs[input], 240, 50 + i * 20, 300, "left") + end + end + if self.input_state > table.getn(configurable_inputs) then + love.graphics.print("press enter to confirm, delete/backspace to retry" .. (config.input and ", escape to cancel" or "")) + else + love.graphics.print("press key input for " .. configurable_inputs[self.input_state] .. ", tab to skip" .. (config.input and ", escape to cancel" or ""), 0, 0) + love.graphics.print("function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 20) + end +end + +function KeyConfigScene:onInputPress(e) + if e.type == "key" then + -- function keys, escape, and tab are reserved and can't be remapped + if e.scancode == "escape" and config.input then + -- cancel only if there was an input config already + scene = InputConfigScene() + elseif self.input_state > table.getn(configurable_inputs) then + if e.scancode == "return" then + -- save new input, then load next scene + local had_config = config.input ~= nil + if not config.input then config.input = {} end + config.input.keys = self.new_input + saveConfig() + scene = had_config and InputConfigScene() or TitleScene() + elseif e.scancode == "delete" or e.scancode == "backspace" then + -- retry + self.input_state = 1 + self.set_inputs = newSetInputs() + self.new_input = {} + end + elseif e.scancode == "tab" then + self.set_inputs[configurable_inputs[self.input_state]] = "skipped" + self.input_state = self.input_state + 1 + elseif e.scancode ~= "escape" then + -- all other keys can be configured + self.set_inputs[configurable_inputs[self.input_state]] = "key " .. love.keyboard.getKeyFromScancode(e.scancode) .. " (" .. e.scancode .. ")" + self.new_input[e.scancode] = configurable_inputs[self.input_state] + self.input_state = self.input_state + 1 + end + end +end + +return KeyConfigScene diff --git a/scene/stick_config.lua b/scene/stick_config.lua new file mode 100644 index 0000000..7f36314 --- /dev/null +++ b/scene/stick_config.lua @@ -0,0 +1,150 @@ +local StickConfigScene = Scene:extend() + +StickConfigScene.title = "Joystick Config" + +require 'load.save' + +local configurable_inputs = { + "menu_decide", + "menu_back", + "left", + "right", + "up", + "down", + "rotate_left", + "rotate_left2", + "rotate_right", + "rotate_right2", + "rotate_180", + "hold", + "retry", + "pause", +} + +local function newSetInputs() + local set_inputs = {} + for i, input in ipairs(configurable_inputs) do + set_inputs[input] = false + end + return set_inputs +end + +function StickConfigScene:new() + self.input_state = 1 + self.set_inputs = newSetInputs() + self.new_input = {} + self.axis_timer = 0 + + DiscordRPC:update({ + details = "In menus", + state = "Changing joystick config", + }) +end + +function StickConfigScene:update() +end + +function StickConfigScene:render() + love.graphics.setColor(1, 1, 1, 1) + love.graphics.draw( + backgrounds["input_config"], + 0, 0, 0, + 0.5, 0.5 + ) + + love.graphics.setFont(font_3x5_2) + for i, input in ipairs(configurable_inputs) do + love.graphics.printf(input, 40, 50 + i * 20, 200, "left") + if self.set_inputs[input] then + love.graphics.printf(self.set_inputs[input], 240, 50 + i * 20, 300, "left") + end + end + if self.input_state > table.getn(configurable_inputs) then + love.graphics.print("press enter to confirm, delete/backspace to retry" .. (config.input and ", escape to cancel" or "")) + else + love.graphics.print("press joystick input for " .. configurable_inputs[self.input_state] .. ", tab to skip" .. (config.input and ", escape to cancel" or ""), 0, 0) + end + + self.axis_timer = self.axis_timer + 1 +end + +local function addJoystick(input, name) + if not input[name] then + input[name] = {} + end +end + +function StickConfigScene:onInputPress(e) + if e.type == "key" then + -- function keys, escape, and tab are reserved and can't be remapped + if e.scancode == "escape" then + scene = InputConfigScene() + elseif self.input_state > table.getn(configurable_inputs) then + if e.scancode == "return" then + -- save new input, then load next scene + config.input.joysticks = self.new_input + saveConfig() + scene = InputConfigScene() + elseif e.scancode == "delete" or e.scancode == "backspace" then + -- retry + self.input_state = 1 + self.set_inputs = newSetInputs() + self.new_input = {} + end + elseif e.scancode == "tab" then + self.set_inputs[configurable_inputs[self.input_state]] = "skipped" + self.input_state = self.input_state + 1 + end + elseif string.sub(e.type, 1, 3) == "joy" then + if self.input_state <= table.getn(configurable_inputs) then + if e.type == "joybutton" then + addJoystick(self.new_input, e.name) + if not self.new_input[e.name].buttons then + self.new_input[e.name].buttons = {} + end + self.set_inputs[configurable_inputs[self.input_state]] = + "jbtn " .. + e.button .. + " " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "") + self.new_input[e.name].buttons[e.button] = configurable_inputs[self.input_state] + self.input_state = self.input_state + 1 + elseif e.type == "joyaxis" then + if (e.axis ~= self.last_axis or self.axis_timer > 30) and e.value >= 1 then + addJoystick(self.new_input, e.name) + if not self.new_input[e.name].axes then + self.new_input[e.name].axes = {} + end + if not self.new_input[e.name].axes[e.axis] then + self.new_input[e.name].axes[e.axis] = {} + end + self.set_inputs[configurable_inputs[self.input_state]] = + "jaxis " .. + e.axis .. + " " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "") + self.new_input[e.name].axes[e.axis]["positive"] = configurable_inputs[self.input_state] + self.input_state = self.input_state + 1 + self.last_axis = e.axis + self.axis_timer = 0 + end + elseif e.type == "joyhat" then + if e.direction ~= "c" then + addJoystick(self.new_input, e.name) + if not self.new_input[e.name].hats then + self.new_input[e.name].hats = {} + end + if not self.new_input[e.name].hats[e.hat] then + self.new_input[e.name].hats[e.hat] = {} + end + self.set_inputs[configurable_inputs[self.input_state]] = + "jhat " .. + e.hat .. " " .. e.direction .. + " " .. string.sub(e.name, 1, 10) .. (string.len(e.name) > 10 and "..." or "") + self.new_input[e.name].hats[e.hat][e.direction] = configurable_inputs[self.input_state] + self.input_state = self.input_state + 1 + end + end + end + end +end + +return StickConfigScene diff --git a/tetris/rulesets/ruleset.lua b/tetris/rulesets/ruleset.lua index 1f3cbaa..d36882c 100644 --- a/tetris/rulesets/ruleset.lua +++ b/tetris/rulesets/ruleset.lua @@ -254,8 +254,8 @@ function Ruleset:initializePiece( local spawn_x if (grid.width ~= 10) then local percent = spawn_positions[data.shape].x / 10 - for i = 0, grid.width - 1 do - if i / grid.width >= percent then + for i = grid.width - 1, 0, -1 do + if i / grid.width <= percent then spawn_x = i break end