13 Commits

Author SHA1 Message Date
SweetSea
1c6857bca9 Fix longlasting wrong icon key 2024-11-24 15:40:16 +07:00
SweetSea
0e8d3ceacc Merge https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile 2024-10-27 05:58:03 +07:00
SweetSea
b73c82c765 Fix scene stack and bump ver 2024-10-27 05:56:40 +07:00
SweetSea-ButImNotSweet
d7d9f77127 Fix buttons in replay scene broken
Signed-off-by: SweetSea-ButImNotSweet <sweetsea-butimnotsweet@noreply.gitea.com>
2024-10-06 12:17:44 +00:00
Nguyễn Quốc Hưng
c0089fc4a5 Multiple changes
- Fix softlock in Name entry
- Wrong page count in Replay scene
- Last key can't be ignored by other controllers
- Small B.T.S changes
2024-10-06 16:57:49 +07:00
Nguyễn Quốc Hưng
1f5a21fec4 Cleaning stuffs 2024-08-17 16:11:42 +07:00
Nguyễn Quốc Hưng
628cf22110 Add user management scene 2024-08-17 16:10:52 +07:00
Nguyễn Quốc Hưng
0647babc90 Fix player's info is not updated correctly when changing name 2024-08-16 09:06:43 +07:00
Nguyễn Quốc Hưng
c29b97cece Fix wrong saving bind place 2024-08-11 10:12:57 +07:00
Nguyễn Quốc Hưng
78501f368c Update both key and stick configuration scenes 2024-08-10 17:13:43 +07:00
Nguyễn Quốc Hưng
e6388c79bc Attempt to fix, one again 2024-08-10 16:53:49 +07:00
Nguyễn Quốc Hưng
e4e43ec61e Fix dumb error 2024-08-10 14:45:22 +07:00
Nguyễn Quốc Hưng
0eb274436e Attempt to fix broken button 2024-08-10 14:34:08 +07:00
14 changed files with 378 additions and 204 deletions

View File

@@ -41,7 +41,7 @@ local virtual_quad=setmetatable((function()
empty_quad=gc_newQuad(0,0,1,1,5*w,2*w) empty_quad=gc_newQuad(0,0,1,1,5*w,2*w)
for i,name in next,{ for i,name in next,{
'left','right','up','down','restart', 'left','right','up','down','restart',
'rotate_right','rotate_left','rotate_right2','rotate_left2' 'rotate_left','rotate_right','rotate_left2','rotate_right2'
} do if #name>0 then t[name]=gc_newQuad((i-1)%5*w,math.floor((i-1)/5)*w,w,w,5*w,2*w) end end } do if #name>0 then t[name]=gc_newQuad((i-1)%5*w,math.floor((i-1)/5)*w,w,w,5*w,2*w) end end
return t return t
end)(),{ end)(),{
@@ -108,7 +108,7 @@ function control_type.button:draw(forceAlpha)
if self.shape=='circle' then if self.shape=='circle' then
love.graphics.setColor(0,0,0,alpha) love.graphics.setColor(0,0,0,alpha)
love.graphics.circle('fill',self.x,self.y,self.r-4) love.graphics.circle('fill',self.x,self.y,self.r-4)
love.graphics.setColor(1,1,1,self.pressed and .5 or 0) love.graphics.setColor(1,1,1,self.pressed and .5 or 0)
love.graphics.circle('fill',self.x,self.y,self.r-4) love.graphics.circle('fill',self.x,self.y,self.r-4)
@@ -117,7 +117,7 @@ function control_type.button:draw(forceAlpha)
elseif self.shape=='square' then elseif self.shape=='square' then
love.graphics.setColor(0,0,0,alpha) love.graphics.setColor(0,0,0,alpha)
love.graphics.rectangle('fill',self.x-self.r-4,self.y-self.r-4,self.r*2+8,self.r*2+8) love.graphics.rectangle('fill',self.x-self.r-4,self.y-self.r-4,self.r*2+8,self.r*2+8)
love.graphics.setColor(1,1,1,self.pressed and .5 or 0) love.graphics.setColor(1,1,1,self.pressed and .5 or 0)
love.graphics.rectangle('fill',self.x-self.r-4,self.y-self.r-4,self.r*2+8,self.r*2+8) love.graphics.rectangle('fill',self.x-self.r-4,self.y-self.r-4,self.r*2+8,self.r*2+8)
@@ -182,7 +182,7 @@ function VCTRL.clearAll()
local toggle = global_toggle local toggle = global_toggle
VCTRL.toggle(false) VCTRL.toggle(false)
global_toggle = toggle global_toggle = toggle
for i=#VCTRL,1,-1 do VCTRL[i] = nil end for i=#VCTRL,1,-1 do VCTRL[i] = nil end
collectgarbage() collectgarbage()
end end

View File

@@ -40,6 +40,7 @@ function love.load()
require "game.vctrl" -- VCTRL require "game.vctrl" -- VCTRL
SCENE = LoadingScene() SCENE = LoadingScene()
sceneStack = {SCENE}
VCTRL.new(SETTINGS.input.virtual) VCTRL.new(SETTINGS.input.virtual)
end end
@@ -124,7 +125,6 @@ function love.keypressed(key, scancode)
love.resize(love.graphics.getDimensions()) love.resize(love.graphics.getDimensions())
elseif scancode == "f2" and SCENE.title ~= "Input Config" and SCENE.title ~= "Game" then elseif scancode == "f2" and SCENE.title ~= "Input Config" and SCENE.title ~= "Game" then
SCENE = InputConfigScene() SCENE = InputConfigScene()
elseif scancode == "f3" then SCENE = UserManagementScene()
elseif scancode == "f12" then LLDEBUGGER.requestBreak() elseif scancode == "f12" then LLDEBUGGER.requestBreak()
-- elseif scancode == "f11" then SETTINGS.firstTime = true -- elseif scancode == "f11" then SETTINGS.firstTime = true
-- function keys are reserved -- function keys are reserved
@@ -309,6 +309,7 @@ function love.run()
end end
end end
if SCENE and SCENE.update and love.timer then if SCENE and SCENE.update and love.timer then
SCENE:update() SCENE:update()
@@ -413,7 +414,7 @@ function love.errorhandler(msg)
love.graphics.setColor(1, 1, 1) love.graphics.setColor(1, 1, 1)
love.graphics.draw(screenshot_canva, 0, 0, 0, screenshot_canva_scale) love.graphics.draw(screenshot_canva, 0, 0, 0, screenshot_canva_scale)
if not showScreenshot then if not showScreenshot then
love.graphics.setColor(0, 0, 0, 0.75) love.graphics.setColor(0, 0, 0, 0.75)
love.graphics.rectangle("fill", 0, 0, 640, 480) love.graphics.rectangle("fill", 0, 0, 640, 480)
@@ -569,6 +570,5 @@ function MainBackground()
while main_bg_cur_color == main_bg_last_color do main_bg_cur_color = minos[love.math.random(1,7)] end while main_bg_cur_color == main_bg_last_color do main_bg_cur_color = minos[love.math.random(1,7)] end
main_bg_cur_mino = 1 main_bg_cur_mino = 1
end end
main_bg_placed = false
main_bg_draw_frame = main_bg_draw_frame + 1 main_bg_draw_frame = main_bg_draw_frame + 1
end end

View File

@@ -1,55 +0,0 @@
local Object = require "libs.classic"
SCENE = Object:extend()
function SCENE:new() end
function SCENE:update() end
function SCENE:render() end
-- You can use the class SCENE_onInput to show suggestions for `e` table
---@class SCENE_onInput
---@field type "key"|"joystick"|"virtual"|"touch"|"mouse"|"wheel"
---
---@field input? string # Action triggered<br>Only visible via keyboard and gamepad
---@field key? love.KeyConstant Key pressed? Only visible via keyboard and gamepad
---@field scancode? love.Scancode Key pressed but on the US layout? Only visible via keyboard and gamepad
---
---@field x? number Only visible via touch and mouse
---@field y? number Only visible via touch and mouse
---@field dx? number # Delta X<br> Only visible via touch, mouse and wheel
---@field dy? number # Delta Y<br> Only visible via touch, mouse and wheel
---@field id? lightuserdata # Only visible via touch
---@field presses? number # Only visible via mouse
-- e in 4 below functions will contain different things based on it's type:
-- key - input, key, scancode
-- joystick - input, button, name
-- virtual - input
-- touch - x, y, dx, dy, id
-- mouse - x, y, dx, dy, presses
-- wheel - dx, dy
function SCENE:onInputMove(e) end
function SCENE:onInputPress(e) end
function SCENE:onInputRelease(e) end
GameScene = require "scene.game"
TrainingScene = require "scene.training"
NameEntryScene = require "scene.name_entry"
KeyConfigScene = require "scene.key_config"
StickConfigScene = require "scene.stick_config"
TouchConfigScene = require "scene.touch_config"
TouchConfigPreviewScene = require "scene.touch_config_preview"
InputConfigScene = require "scene.input_config"
ReplaySelectScene = require "scene.replay"
ReplayTestScene = require"scene.replay_test"
FullscreenScene = require "scene.fullscreen"
MusicToggleScene = require "scene.music_toggle"
LinesToggleScene = require "scene.lines_toggle"
ExitScene = require "scene.exit"
TitleScene = require "scene.title"

View File

@@ -76,6 +76,7 @@ SettingsScene = require "scene.settings"
EraseHighScoresScene = require "scene.data.erase_high_scores" EraseHighScoresScene = require "scene.data.erase_high_scores"
ResetAllScene = require "scene.data.reset_all" ResetAllScene = require "scene.data.reset_all"
DataManagementScene = require "scene.data_management" DataManagementScene = require "scene.data_management"
UserManagementScene = require "scene.user_management"
ReplaySelectScene = require "scene.replay" ReplaySelectScene = require "scene.replay"
ReplayTestScene = require"scene.replay_test" ReplayTestScene = require"scene.replay_test"

View File

@@ -26,7 +26,7 @@ local data_explaination = {
local NULL = function() end local NULL = function() end
local settings_func = { local settings_func = {
function() love.system.openURL(love.filesystem.getSaveDirectory()) end, function() love.system.openURL(love.filesystem.getSaveDirectory()) end,
NULL, function() return UserManagementScene() end,
function() return EraseHighScoresScene() end, function() return EraseHighScoresScene() end,
function() return ResetAllScene() end, function() return ResetAllScene() end,
function() return TitleScene() end, function() return TitleScene() end,

View File

@@ -71,7 +71,7 @@ function ConfigScene:new(first_time)
secret_code_used = false secret_code_used = false
secret_code_input = {} -- When it matches 88663366 then we will automatically set the special keybind secret_code_input = {} -- When it matches 88663366 then we will automatically set the special keybind
self.menu_state = 1 self.menu_state = 1
if first_time then if first_time then
self.first_time = true self.first_time = true
@@ -84,15 +84,18 @@ function ConfigScene:update() end
function ConfigScene:render() function ConfigScene:render()
MainBackground() MainBackground()
love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 0, 0, 640, 480)
if secret_code_used then if secret_code_used then
if SETTINGS.tvMode then if SETTINGS.tvMode then
drawText("TV mode is ON now! Check keybind below", 80, 40, 1000) drawText("TV mode is ON now! Check keybind below", 80, 40, 1000)
drawText("Which controls do you want to configure?", 80, 70, 1000) drawText("Which controls do you want to configure?", 80, 70, 1000)
drawText( drawText(
"2 - Up 1 - Rotate left 5 - Confirm selection\n".. "2 - Up 1 - Rotate left 5 - Confirm selection\n"..
"8 - Right 3 - Rotate right 0 - Back\n".. "8 - Down 3 - Rotate right 0 - Back\n"..
"4 - Left 7 - Rotate left 2\n".. "4 - Left 7 - Rotate left 2\n"..
"6 - Down 9 - Rotate right 2", 80, 350, 1000 "6 - Right 9 - Rotate right 2", 80, 350, 1000
) )
else else
drawText("TV mode is OFF now!", 80, 40, 1000) drawText("TV mode is OFF now!", 80, 40, 1000)
@@ -132,7 +135,7 @@ local function checkSecretCodeInput(key)
if secret_code_used then return end if secret_code_used then return end
if key:sub(1, 2) == "kp" then if key:sub(1, 2) == "kp" then
table.insert(secret_code_input, key:sub(3,3)) table.insert(secret_code_input, key:sub(3,3))
elseif key:find("[0-9.]") == 1 then elseif key:find("[0-9]") == 1 then
table.insert(secret_code_input, key) table.insert(secret_code_input, key)
else else
secret_code_input = {} -- Reset secret_code_input = {} -- Reset
@@ -146,14 +149,14 @@ local function checkSecretCodeInput(key)
if current_code == "88663366" then --TVMODEON if current_code == "88663366" then --TVMODEON
-- Set keybind -- Set keybind
SETTINGS.input.keys = { SETTINGS.input.keys = {
["2"] = "up", ["kp2"] = "up", ["2"] = "up", ["kp8"] = "up",
["8"] = "down", ["kp8"] = "down", ["8"] = "down", ["kp2"] = "down",
["4"] = "left", ["kp4"] = "left", ["4"] = "left", ["kp4"] = "left",
["6"] = "right", ["kp6"] = "right", ["6"] = "right", ["kp6"] = "right",
["1"] = "rotate_left", ["kp1"] = "rotate_left", ["1"] = "rotate_left", ["kp7"] = "rotate_left",
["3"] = "rotate_right", ["kp3"] = "rotate_right", ["3"] = "rotate_right", ["kp9"] = "rotate_right",
["7"] = "rotate_left2", ["kp7"] = "rotate_left2", ["7"] = "rotate_left2", ["kp1"] = "rotate_left2",
["9"] = "rotate_right2", ["kp9"] = "rotate_right2", ["9"] = "rotate_right2", ["kp3"] = "rotate_right2",
["5"] = "menu_decide", ["kp5"] = "menu_decide", ["5"] = "menu_decide", ["kp5"] = "menu_decide",
["0"] = "menu_back", ["kp0"] = "menu_back", ["0"] = "menu_back", ["kp0"] = "menu_back",
} }
@@ -161,7 +164,7 @@ local function checkSecretCodeInput(key)
SETTINGS.tvMode = true SETTINGS.tvMode = true
secret_code_used = true secret_code_used = true
updateButtonList(SCENE) updateButtonList(SCENE)
elseif current_code == "........" then elseif current_code == "11111111" then
SETTINGS.input.keys = {} SETTINGS.input.keys = {}
SETTINGS.tvMode = false SETTINGS.tvMode = false
secret_code_used = true secret_code_used = true

View File

@@ -27,7 +27,6 @@ local input_names = {
rotate_right2='Rotate Clockwise (2)' rotate_right2='Rotate Clockwise (2)'
} }
local function newSetInputs() local function newSetInputs()
local set_inputs = {} local set_inputs = {}
for i, input in ipairs(configurable_inputs) do for i, input in ipairs(configurable_inputs) do
@@ -40,47 +39,40 @@ function KeyConfigScene:new()
self.input_state = 1 self.input_state = 1
self.set_inputs = newSetInputs() self.set_inputs = newSetInputs()
self.new_input = {} self.new_input = {}
self.axis_timer = 0
BUTTON.reset(buttonList) BUTTON.reset(buttonList)
buttonList = { -- Configuring buttonList = { -- Configuring
BUTTON.new{ BUTTON.new{
text = CHAR.icon.fastForward.." SKIP", text = CHAR.key.tab.."\nTab",
x = 40, y = 300, w = 100, h = 30, x = 40, y = 300, w = 100, h = 50,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "tab"} end codeWhenReleased = function() self:onInputPress{type = "key", scancode = "tab"} end
}, },
BUTTON.new{ BUTTON.new{
text = CHAR.icon.cross_thick.." Cancel", text = CHAR.key.enter_or_return.."\nEnter/Return",
x = 150, y = 300, w = 100, h = 30, x = 150, y = 300, w = 100, h = 50,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "return"} end
},
BUTTON.new{
text = CHAR.key.del.."\nDelete",
x = 260, y = 300, w = 100, h = 50,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "delete"} end
},
BUTTON.new{
text = CHAR.key.esc.."\nEscape",
x = 370, y = 300, w = 100, h = 50,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "escape"} end codeWhenReleased = function() self:onInputPress{type = "key", scancode = "escape"} end
}, },
} }
end end
function KeyConfigScene:update() function KeyConfigScene:update()
if self.input_state > #configurable_inputs then
BUTTON.reset(buttonList)
buttonList = { -- Confirming
BUTTON.new{
text = CHAR.icon.checkMark.." CONFIRM",
x = 40, y = 300, w = 100, h = 30,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "return"} end
},
BUTTON.new{
text = CHAR.icon.retry_spin.." Restart",
x = 150, y = 300, w = 100, h = 30,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "delete"} end
},
BUTTON.new{
text = CHAR.icon.cross_thick.." Cancel",
x = 260, y = 300, w = 100, h = 30,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "escape"} end
}
}
end
end end
function KeyConfigScene:render() function KeyConfigScene:render()
MainBackground() MainBackground()
love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 0, 0, 640, 480)
BUTTON.draw(buttonList) BUTTON.draw(buttonList)
for i, input in ipairs(configurable_inputs) do for i, input in ipairs(configurable_inputs) do
@@ -90,10 +82,10 @@ function KeyConfigScene:render()
end end
end end
if self.input_state > #configurable_inputs then if self.input_state > #configurable_inputs then
drawText("Press Enter/Confirm Selection to confirm, delete/backspace to retry" .. (SETTINGS.input.keys and ", esc/Go Back to cancel" or ""),0,0,1000) drawText("Press Enter/Confirm Selection to confirm, Delete/Backspace to retry" .. (SETTINGS.input.keys and ", Esc/Go Back to cancel" or ""), 0, 0, 1000)
else else
drawText("Press key input for " .. input_names[configurable_inputs[self.input_state]] .. ", escape to cancel\nPress tab on keyboard, or any key from other inputs, to skip",0,0,1000) drawText("Press key input for " .. input_names[configurable_inputs[self.input_state]] .. ", escape to cancel\nPress tab on keyboard, or any key from other inputs, to skip",0,0,1000)
drawText("Function keys (F1, F2, etc.), escape, and tab can't be changed", 0, 35,1000) drawText("Function keys (F1, F2, etc.), Escape, and Tab can't be changed", 0, 35,1000)
end end
end end
@@ -121,7 +113,7 @@ function KeyConfigScene:onInputPress(e)
self.new_input[e.scancode] = configurable_inputs[self.input_state] self.new_input[e.scancode] = configurable_inputs[self.input_state]
self.input_state = self.input_state + 1 self.input_state = self.input_state + 1
end end
elseif self.input_state < #configurable_inputs then elseif self.input_state <= #configurable_inputs then
self.set_inputs[configurable_inputs[self.input_state]] = "skipped" self.set_inputs[configurable_inputs[self.input_state]] = "skipped"
self.input_state = self.input_state + 1 self.input_state = self.input_state + 1
end end

View File

@@ -37,7 +37,7 @@ local Grid = require 'game.grid'
function NameEntryScene:new() function NameEntryScene:new()
VCTRL.toggle(false) VCTRL.toggle(false)
self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890." self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890."
self.char_pos = 1 self.char_pos = 1
self.name_entry = {'A','A','A'} self.name_entry = {'A','A','A'}
@@ -79,7 +79,7 @@ end
function NameEntryScene:render() function NameEntryScene:render()
MainBackground() MainBackground()
BUTTON.draw(buttonList) BUTTON.draw(buttonList)
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.line(216,80,216,80+(16*self.grid.height)) love.graphics.line(216,80,216,80+(16*self.grid.height))
love.graphics.line(216+(16*self.grid.width),80,216+(16*self.grid.width),80+(16*self.grid.height)) love.graphics.line(216+(16*self.grid.width),80,216+(16*self.grid.width),80+(16*self.grid.height))
@@ -153,17 +153,6 @@ function NameEntryScene:onInputPress(e)
local name = string.lower(table.concat(self.name_entry, '', 1, 3)) local name = string.lower(table.concat(self.name_entry, '', 1, 3))
if e.type == "mouse" or e.type == "touch" then if e.type == "mouse" or e.type == "touch" then
BUTTON.press(buttonList, e.x, e.y, e.id) BUTTON.press(buttonList, e.x, e.y, e.id)
elseif e.key and #e.key == 1 then
local pos = string.find(self.chars, string.upper(e.key), 1, true)
if pos then
if self.entry_pos <= 3 then
self.char_pos = pos
self.name_entry[self.entry_pos] = string.upper(e.key)
self.name_entry[self.entry_pos + 1] = string.upper(e.key)
end
if self.entry_pos == 3 then self:getPlayInfo(name) end
self.entry_pos = math.min(self.entry_pos + 1, 4)
end
elseif e.input == "menu_decide" or e.input == "rotate_left" or e.scancode == "return" then elseif e.input == "menu_decide" or e.input == "rotate_left" or e.scancode == "return" then
if self.entry_pos == 4 then if self.entry_pos == 4 then
BUTTON.release(buttonList, e.x, e.y, e.id) BUTTON.release(buttonList, e.x, e.y, e.id)
@@ -190,6 +179,17 @@ function NameEntryScene:onInputPress(e)
self.entry_pos = self.entry_pos - 1 self.entry_pos = self.entry_pos - 1
self.grade = 0 self.grade = 0
end end
elseif e.key and #e.key == 1 then
local pos = string.find(self.chars, string.upper(e.key), 1, true)
if pos then
if self.entry_pos <= 3 then
self.char_pos = pos
self.name_entry[self.entry_pos] = string.upper(e.key)
self.name_entry[self.entry_pos + 1] = string.upper(e.key)
end
self.entry_pos = math.min(self.entry_pos + 1, 4)
if self.entry_pos == 4 then self:getPlayInfo(string.lower(table.concat(self.name_entry, '', 1, 3))) end
end
end end
end end

View File

@@ -1,67 +1,52 @@
local ReplaySelectScene = SCENE:extend() local ReplaySelectScene = SCENE:extend()
ReplaySelectScene.title = "Replay" ReplaySelectScene.title = "Replay"
local scene_self
local replay_list local replay_list
local buttonList = { local buttonList = {
BUTTON.new{ BUTTON.new{
x = 325, y = 385, w = 100, h = 30, x = 325, y = 375, w = 100, h = 30,
text = CHAR.key.up.." Page up", text = CHAR.key.up.." Page up",
codeWhenReleased = function() codeWhenReleased = function() SCENE:onInputPress{input = "left"} end
if scene_self.page == 1 then
scene_self.page = 1 + math.floor(#scene_self.replays / scene_self.page_flip)
else
scene_self.page = scene_self.page - 1
end
scene_self.replay_select = 1;
end
}, },
BUTTON.new{ BUTTON.new{
x = 435, y = 385, w = 100, h = 30, x = 435, y = 375, w = 100, h = 30,
text = CHAR.key.down.." Page down", text = CHAR.key.down.." Page down",
codeWhenReleased = function() codeWhenReleased = function() SCENE:onInputPress{input = "right"} end
if scene_self.page < 1 + math.floor(#scene_self.replays / scene_self.page_flip) then
scene_self.page = scene_self.page + 1
else
scene_self.page = 1
end
scene_self.replay_select = 1;
end
}, },
BUTTON.new{ BUTTON.new{
x = 105, y = 385, w = 100, h = 30, x = 105, y = 375, w = 100, h = 30,
text = CHAR.icon.play.." Play", text = CHAR.icon.play.." Play",
codeWhenPressed = function() scene_self:onInputPress {input = "menu_decide"} end, codeWhenPressed = function() SCENE:onInputPress {input = "menu_decide"} end,
codeWhenReleased = function() scene_self:onInputRelease{input = "menu_decide"} end codeWhenReleased = function() SCENE:onInputRelease{input = "menu_decide"} end
}, },
BUTTON.new{ BUTTON.new{
x = 105, y = 425, w = 100, h = 30, x = 105, y = 415, w = 100, h = 45,
text = CHAR.icon.home.." Home", text = CHAR.icon.home.." Home",
codeWhenPressed = function() scene_self:onInputPress {input = "menu_back"} end, codeWhenPressed = function() SCENE:onInputPress {input = "menu_back"} end,
codeWhenReleased = function() scene_self:onInputRelease{input = "menu_back"} end codeWhenReleased = function() SCENE:onInputRelease{input = "menu_back"} end
}, },
BUTTON.new{ BUTTON.new{
x = 215, y = 425, w = 100, h = 30, x = 215, y = 415, w = 100, h = 45,
text = CHAR.icon.save.." Converter", text = CHAR.icon.save.." Converter",
codeWhenReleased = function() love.system.openURL("https://sweetsea-butimnotsweet.github.io/tromi_replay_converter/") end codeWhenReleased = function() love.system.openURL("https://sweetsea-butimnotsweet.github.io/tromi_replay_converter/") end
}, },
BUTTON.new{ BUTTON.new{
x = 325, y = 425, w = 100, h = 30, x = 325, y = 415, w = 100, h = 45,
text = CHAR.icon.export.." Export", text = CHAR.icon.export.." Export\n(R.Left)",
codeWhenPressed = function() scene_self:onInputPress {input = "rotate_left"} end, codeWhenPressed = function() SCENE:onInputPress {input = "rotate_left"} end,
codeWhenReleased = function() scene_self:onInputRelease{input = "rotate_left"} end codeWhenReleased = function() SCENE:onInputRelease{input = "rotate_left"} end
}, },
BUTTON.new{ BUTTON.new{
x = 435, y = 425, w = 100, h = 30, x = 435, y = 415, w = 100, h = 45,
text = CHAR.icon.import.." Import", text = CHAR.icon.import.." Import\n(R.Right)",
codeWhenPressed = function() scene_self:onInputPress {input = "rotate_right"} end, codeWhenPressed = function() SCENE:onInputPress {input = "rotate_right"} end,
codeWhenReleased = function() scene_self:onInputRelease{input = "rotate_right"} end codeWhenReleased = function() SCENE:onInputRelease{input = "rotate_right"} end
}, },
} }
function ReplaySelectScene:new() function ReplaySelectScene:new()
self:initList() self:initList()
scene_self = self SCENE = self
BUTTON.reset(buttonList) BUTTON.reset(buttonList)
PENTO_MODE = false PENTO_MODE = false
end end
@@ -103,29 +88,30 @@ function ReplaySelectScene:render()
love.graphics.setColor(0, 0, 0, 0.7) love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 0, 0, 640, 480) love.graphics.rectangle("fill", 0, 0, 640, 480)
love.graphics.setColor(0.4, 1, 1, 0.5)
love.graphics.rectangle("fill", 0, 15 + 30 * self.replay_select, 640, 27)
BUTTON.draw(buttonList) if #self.replays > 0 then
love.graphics.setColor(0.4, 1, 1, 0.5)
love.graphics.rectangle("fill", 0, 15 + 30 * self.replay_select, 640, 27)
drawText('Name - Grade - Score', 40, 20, 1000, "left") drawText('Name - Grade - Score', 40, 20, 1000, "left")
drawText(string.format('Page %s/%s', self.page, math.floor(#self.replays / self.page_flip) + 1), 215, 390, 100, "center") drawText(string.format('Page %s/%s', self.page, 1 + math.floor((#self.replays - 1) / self.page_flip)), 215, 380, 100, "center")
local i, j = 1, 1 local i, j = 1, 1
while i <= #self.replay_text do while i <= #self.replay_text do
if j > self.page_flip then j = 1 if j > self.page_flip then j = 1
elseif j < 1 then j = self.page_flip elseif j < 1 then j = self.page_flip
end
if i > (self.page-1) * self.page_flip and i <= self.page * self.page_flip then
drawText(self.replay_text[i], 40, 20 + 30 * j, 1000, "left")
end
j = j + 1
i = i + 1
end end
if i > (self.page-1) * self.page_flip and i <= self.page * self.page_flip then else
drawText(self.replay_text[i], 40, 20 + 30 * j, 1000, "left")
end
j = j + 1
i = i + 1
end
if self.replays[1] == nil then
drawText('No replays yet!', 40, 40, 1000, "left") drawText('No replays yet!', 40, 40, 1000, "left")
end end
BUTTON.draw(buttonList)
end end
function ReplaySelectScene:update() function ReplaySelectScene:update()
@@ -167,7 +153,11 @@ function ReplaySelectScene:onInputPress(e)
local selected_replay = self.replays[self.replay_select + ((self.page-1) * self.page_flip)] local selected_replay = self.replays[self.replay_select + ((self.page-1) * self.page_flip)]
local selected_replay_text = self.replay_text[self.replay_select + ((self.page-1) * self.page_flip)] local selected_replay_text = self.replay_text[self.replay_select + ((self.page-1) * self.page_flip)]
if (e.type == "touch" or e.type == "mouse") and not BUTTON.press(buttonList, e.x, e.y, e.id) then if (
(e.type == "touch" or e.type == "mouse") and
not BUTTON.press(buttonList, e.x, e.y, e.id) and
#self.replays > 0
) then
local selection = math.floor((e.y - 15) / 30) local selection = math.floor((e.y - 15) / 30)
if ( if (
selection >= 1 and selection >= 1 and
@@ -212,6 +202,22 @@ function ReplaySelectScene:onInputPress(e)
elseif e.input == "down" or e.scancode == "down" then elseif e.input == "down" or e.scancode == "down" then
if self.replays[1] == nil then SCENE = TitleScene(); return end if self.replays[1] == nil then SCENE = TitleScene(); return end
self.direction = 'down' self.direction = 'down'
elseif e.input == "left" or e.scancode == "left" then
if self.replays[1] == nil then SCENE = TitleScene(); return end
if self.page == 1 then
self.page = math.floor((#self.replays - 1) / self.page_flip)
else
self.page = self.page - 1
end
self.replay_select = 1;
elseif e.input == "right" or e.scancode == "right" then
if self.replays[1] == nil then SCENE = TitleScene(); return end
if self.page < 1 + math.floor((#self.replays - 1) / self.page_flip) then
self.page = self.page + 1
else
self.page = 1
end
self.replay_select = 1;
elseif e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete" then elseif e.input == "menu_back" or e.scancode == "backspace" or e.scancode == "delete" then
SCENE = TitleScene() SCENE = TitleScene()
end end

View File

@@ -5,7 +5,6 @@ local error_message
local valid_data local valid_data
local prev_scene local prev_scene
function ReplayTestScene:new(input_file) function ReplayTestScene:new(input_file)
prev_scene = SCENE prev_scene = SCENE
@@ -36,7 +35,7 @@ function ReplayTestScene:render()
if valid_data then if valid_data then
if error_message then if error_message then
drawText("Replay test failed! Data corrupted!", 80, 40, 1000) drawText("Replay test failed!", 80, 40, 1000)
drawText("Press any key to go back. Anyway here is the error info:", 80, 70, 1000) drawText("Press any key to go back. Anyway here is the error info:", 80, 70, 1000)
drawText(error_message, 80, 100, 560) drawText(error_message, 80, 100, 560)
else else

View File

@@ -12,7 +12,7 @@ local settings_explaination = {
"Enable music?\nThis does not apply to sound effects.", "Enable music?\nThis does not apply to sound effects.",
"Show level and lines counter?\nThis setting is ignored when replaying.", "Show level and lines counter?\nThis setting is ignored when replaying.",
"Enter or leave fullscreen\nYou can press F4 key at any screen to do this quick.", "Enter or leave fullscreen\nYou can press F4 key at any screen to do this quick.",
"This is where you can re-configure your keybinds.\nYou can press F2 on the keyboard to open this quick\n\nTip for TV:\n\t88663366: enable TV mode.\n\t........: disable TV mode", "This is where you can re-configure your keybinds.\nYou can press F2 on the keyboard to open this quick\n\nTip for TV:\n\t88663366: enable TV mode.\n\t11111111 disable TV mode",
"Back to main menu" "Back to main menu"
} }

View File

@@ -44,43 +44,35 @@ function StickConfigScene:new()
BUTTON.reset(buttonList) BUTTON.reset(buttonList)
buttonList = { -- Configuring buttonList = { -- Configuring
BUTTON.new{ BUTTON.new{
text = CHAR.icon.fastForward.." SKIP", text = CHAR.key.tab.."\nTab",
x = 40, y = 300, w = 100, h = 30, x = 40, y = 300, w = 100, h = 50,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "tab"} end codeWhenReleased = function() self:onInputPress{type = "key", scancode = "tab"} end
}, },
BUTTON.new{ BUTTON.new{
text = CHAR.icon.cross_thick.." Cancel", text = CHAR.key.enter_or_return.."\nEnter/Return",
x = 150, y = 300, w = 100, h = 30, x = 150, y = 300, w = 100, h = 50,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "return"} end
},
BUTTON.new{
text = CHAR.key.del.."\nDelete",
x = 260, y = 300, w = 100, h = 50,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "delete"} end
},
BUTTON.new{
text = CHAR.key.esc.."\nEscape",
x = 370, y = 300, w = 100, h = 50,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "escape"} end codeWhenReleased = function() self:onInputPress{type = "key", scancode = "escape"} end
}, },
} }
end end
function StickConfigScene:update() function StickConfigScene:update()
if self.input_state > #configurable_inputs then
BUTTON.reset(buttonList)
buttonList = { -- Confirming
BUTTON.new{
text = CHAR.icon.checkMark.." CONFIRM",
x = 40, y = 300, w = 100, h = 30,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "return"} end
},
BUTTON.new{
text = CHAR.icon.retry_spin.." Restart",
x = 150, y = 300, w = 100, h = 30,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "delete"} end
},
BUTTON.new{
text = CHAR.icon.cross_thick.." Cancel",
x = 260, y = 300, w = 100, h = 30,
codeWhenReleased = function() self:onInputPress{type = "key", scancode = "escape"} end
}
}
end
end end
function StickConfigScene:render() function StickConfigScene:render()
MainBackground() MainBackground()
love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 0, 0, 640, 480)
BUTTON.draw(buttonList) BUTTON.draw(buttonList)
for i, input in ipairs(configurable_inputs) do for i, input in ipairs(configurable_inputs) do
@@ -90,7 +82,7 @@ function StickConfigScene:render()
end end
end end
if self.input_state > #configurable_inputs then if self.input_state > #configurable_inputs then
drawText("Press enter/Confirm Selection to confirm, delete/backspace to retry" .. (SETTINGS.input.joysticks and ", esc/Go Back to cancel" or ""), 0, 0, 1000) drawText("Press Enter/Confirm Selection to confirm, Delete/Backspace to retry" .. (SETTINGS.input.joysticks and ", Esc/Go Back to cancel" or ""), 0, 0, 1000)
else else
drawText("Press joystick input for " .. input_names[configurable_inputs[self.input_state]] .. ", tab to skip, escape to cancel", 0, 0, 1000) drawText("Press joystick input for " .. input_names[configurable_inputs[self.input_state]] .. ", tab to skip, escape to cancel", 0, 0, 1000)
end end
@@ -104,7 +96,6 @@ local function addJoystick(input, name)
end end
end end
---@param e SCENE_onInput
function StickConfigScene:onInputPress(e) function StickConfigScene:onInputPress(e)
if e.type == "mouse" or e.type == "touch" then if e.type == "mouse" or e.type == "touch" then
BUTTON.press(buttonList, e.x, e.y, e.id) BUTTON.press(buttonList, e.x, e.y, e.id)
@@ -114,7 +105,7 @@ function StickConfigScene:onInputPress(e)
SCENE = InputConfigScene(SETTINGS.firstTime) SCENE = InputConfigScene(SETTINGS.firstTime)
elseif self.input_state > #configurable_inputs then elseif self.input_state > #configurable_inputs then
if e.scancode == "return" or e.input == "menu_decide" then if e.scancode == "return" or e.input == "menu_decide" then
SETTINGS.input.keys = self.new_input SETTINGS.input.joysticks = self.new_input
SCENE = SETTINGS.firstTime and TitleScene() or InputConfigScene() SCENE = SETTINGS.firstTime and TitleScene() or InputConfigScene()
SETTINGS.firstTime = false SETTINGS.firstTime = false
elseif e.scancode == "delete" or e.scancode == "backspace" then elseif e.scancode == "delete" or e.scancode == "backspace" then

View File

@@ -25,7 +25,7 @@ local main_menu_scenes = {
DataManagementScene, DataManagementScene,
function() love.system.openURL("https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile") end, function() love.system.openURL("https://gitea.com/SweetSea-ButImNotSweet/tromi_mobile") end,
AboutScene, AboutScene,
TrainingScene, TrainingScene,
function() love.system.openURL("https://mycophobia.org/forums/viewtopic.php?t=29") end, function() love.system.openURL("https://mycophobia.org/forums/viewtopic.php?t=29") end,
SettingsScene, SettingsScene,
@@ -39,7 +39,7 @@ local main_menu_icons = {
CHAR.icon.export, CHAR.icon.export,
CHAR.icon.home, CHAR.icon.home,
CHAR.icon.info, CHAR.icon.info,
CHAR.icon.toDown, CHAR.icon.toDown,
CHAR.icon.globe, CHAR.icon.globe,
CHAR.icon.settings, CHAR.icon.settings,
@@ -63,13 +63,13 @@ end
function Title2Scene:render() function Title2Scene:render()
MainBackground() MainBackground()
love.graphics.setColor(0, 0, 0, 0.7) love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 30, 60, 580, 85, 10, 10) -- Tromi love.graphics.rectangle("fill", 30, 60, 580, 85, 10, 10) -- Tromi
love.graphics.rectangle("fill", 30, 165, 580, 225, 10, 10) -- Menu love.graphics.rectangle("fill", 30, 165, 580, 225, 10, 10) -- Menu
drawBigText("Tromi", 40, 65, 100, "left") drawBigText("Tromi", 40, 65, 100, "left")
drawText("Mobile 1.1 - PC 2.3", 150, 78, 200, "left") drawText("Mobile 1.4 - PC 2.3", 150, 78, 200, "left")
drawText("https://mycophobia.org\nhttps://github.com/SweetSea-ButImNotSweet/", 40, 100, 300, "left") drawText("https://mycophobia.org\nhttps://github.com/SweetSea-ButImNotSweet/", 40, 100, 300, "left")
if PENTO_MODE then if PENTO_MODE then
@@ -109,7 +109,7 @@ local function checkCode(c)
if ( if (
code_string == "-1,-1,-1,-1,1,1,1,1" or code_string == "-1,-1,-1,-1,1,1,1,1" or
code_string == "2,2,2,2,2,2,2,2" code_string == "2,2,2,2,2,2,2,2"
) then ) then
PENTO_MODE = true PENTO_MODE = true
end end
end end

237
scene/user_management.lua Normal file
View File

@@ -0,0 +1,237 @@
local UserManagementScene = SCENE:extend()
local max_items_per_page = 10
local gradeNames = {
"19k", "18k", "17k", "16k", "15k", "14k", "13k", "12k", "11k",
"10k", " 9k", " 8k", " 7k", " 6k", " 5k", " 4k", " 3k", " 2k", " 1k",
" 1D", " 2D", " 3D", " 4D", " 5D", " 6D", " 7D", " 8D", " 9D"
}
local user_list
local buttonList = {
BUTTON.new{
text = CHAR.icon.home.." Home\nEsc/Go back",
x = 510, y = 45, w = 120, h = 55,
codeWhenPressed = function() SCENE = TitleScene() end
},
BUTTON.new{
text = CHAR.icon.trash.." Delete\nDel/Rotate right",
x = 510, y = 105, w = 120, h = 55,
codeWhenPressed = function() SCENE:onInputPress{key = "delete"} end
},
BUTTON.new{
text = CHAR.key.up.." Page up\nLeft",
x = 510, y = 165, w = 120, h = 55,
},
BUTTON.new{
text = CHAR.key.down.." Page down\nRight",
x = 510, y = 225, w = 120, h = 55,
}
}
function UserManagementScene:new()
user_list = {}
self.current_page = 1
self.direction = nil
self.selecting = 1
self.repeat_counter = max_items_per_page - 1
for _, f in pairs(love.filesystem.getDirectoryItems(SAVE_DIR)) do
local file = SAVE_DIR .. f
local info = love.filesystem.getInfo(file)
if info and info.type == "file" and string.sub(f, 4, -1) == "_grade_history.sav" then
local name = string.sub(f, 1, 3)
table.insert(user_list, {
name = name,
valid = false, -- Data is not broken?
grade = 1, -- Player's grade
promo = 2, -- Promotion Meter
games = 0, -- Games played
})
local okay, _ = pcall(function()
local data = FILE.read(file)
if not data then error() end
user_list[#user_list].grade = data[1]
user_list[#user_list].promo = data[2]
user_list[#user_list].games = data[4]
end)
if okay then
user_list[#user_list].valid = true
end
end
end
end
local function getPromotionText(grade, promotion)
local points_text
if grade == 1 then
points_text = ({
[2] = " |..",
[3] = " .|.",
[4] = " ..|",
})[promotion]
else
points_text = ({
[0] = "|....",
[1] = ".|...",
[2] = "..|..",
[3] = "...|.",
[4] = "....|",
})[promotion]
end
return (grade > 1 and "-" or " ")..points_text..(grade < 29 and "+" or "")
end
function UserManagementScene:changeOption(rel)
local len = #user_list
self.selecting = self.selecting + rel
if self.selecting + ((self.current_page-1) * max_items_per_page) > len then
self.current_page = 1
self.selecting = 1
elseif self.selecting < 1 and self.current_page == 1 then
self.current_page = 1 + (math.floor(len / max_items_per_page))
self.selecting = len - ((self.current_page - 1) * max_items_per_page)
end
if self.selecting > max_items_per_page then
self.current_page = self.current_page + 1
self.selecting = 1
elseif self.selecting < 1 then
self.current_page = self.current_page - 1
self.selecting = max_items_per_page
end
end
function UserManagementScene:deleteCurrentReplay()
local name = user_list[max_items_per_page * (self.current_page - 1) + self.selecting].name
if love.window.showMessageBox(
"Delete the selected profile?",
"Are you sure you want to delete " .. string.upper(name) .. "'s profile?",
{
"Delete", ">>>CANCEL<<<",
escapebutton = 2
},
"warning"
) == 1 then
if love.window.showMessageBox(
"Are you really sure???",
"You really want to erase " .. string.upper(name) .. "'s profile?????\nYou may REGRET your action. This is NOT INVERSIBLE!",
{
">>>CANCEL<<<", "Delete",
escapebutton = 1
},
"warning"
) == 2 then
love.filesystem.remove(SAVE_DIR .. name .. "_grade_history.sav")
self:new()
end
end
end
function UserManagementScene:render()
MainBackground()
love.graphics.setColor(0, 0, 0, 0.7)
love.graphics.rectangle("fill", 0, 0, 640, 480)
love.graphics.setColor(0.4, 1, 1, 0.5)
love.graphics.rectangle("fill", 0, 15 + 30 * self.selecting, 500, 27)
BUTTON.draw(buttonList)
drawText('Name - Grade - Pro.Meter - Games', 40, 20, 1000, "left")
-- SEA 19k -..|..+ 12345
for i = (self.current_page - 1) * max_items_per_page + 1, math.min((self.current_page) * max_items_per_page, #user_list) do
if user_list[i].valid then
local name = user_list[i].name
local games = string.format("%5d", user_list[i].games)
local grade = gradeNames[user_list[i].grade]
local promo = getPromotionText(user_list[i].grade, user_list[i].promo)
drawText(
" " ..
name .. " " ..
grade .. " " ..
promo .. " " ..
games,
40, 20 + 30 * (i - (self.current_page - 1) * max_items_per_page), 1000, "left"
)
else
drawText(
" " .. user_list[i].name.." ??? -?????+ ?????",
40, 20 + 30 * (i - (self.current_page - 1) * max_items_per_page), 1000, "left"
)
end
end
drawText(string.format('Page %s/%s', self.current_page, math.floor(#user_list / max_items_per_page) + 1), 15, 440, 100,
"center")
end
function UserManagementScene:update()
if self.direction == "up" then
if self.repeat_counter >= max_items_per_page then
self:changeOption(-1)
self.repeat_counter = 0
end
self.repeat_counter = self.repeat_counter + 1
elseif self.direction == "down" then
if self.repeat_counter >= max_items_per_page then
self:changeOption(1)
self.repeat_counter = 0
end
self.repeat_counter = self.repeat_counter + 1
end
end
---@param e SCENE_onInput
function UserManagementScene:onInputPress(e)
if e.type == "mouse" or e.type == "touch" then
if not BUTTON.press(buttonList, e.x, e.y, e.id) then
local selection = math.floor((e.y - 45) / 30) + 1
love.window.showMessageBox("", selection)
if (
selection >= 1 and
selection <= self.repeat_counter and
selection + ((self.current_page-1) * max_items_per_page) <= #user_list
) then
self.selecting = selection
end
end
elseif e.input == "menu_back" then SCENE = TitleScene()
elseif e.input == "up" or e.key == "up" then self.direction = "up"
elseif e.input == "down" or e.key == "down" then self.direction = "down"
elseif e.input == "left" or e.key == "left" then
if self.current_page == 1 then
self.current_page = 1 + math.floor(#user_list / max_items_per_page)
else
self.current_page = self.current_page - 1
end
self.selecting = 1
elseif e.input == "right" or e.key == "right" then
if self.current_page < 1 + math.floor(#user_list / max_items_per_page) then
self.current_page = self.current_page + 1
else
self.current_page = 1
end
self.selecting = 1
elseif e.input == "rotate_right" or e.key == "delete" then self:deleteCurrentReplay()
end
end
function UserManagementScene:onInputRelease(e)
if e.type == "mouse" or e.type == "touch" then
BUTTON.release(buttonList, e.x, e.y, e.id)
elseif e.input == "up" or e.scancode == "up" or e.input == "down" or e.scancode == "down" then
self.direction = nil
self.repeat_counter = max_items_per_page - 1
end
end
function UserManagementScene:onInputMove(e)
if e.type == "mouse" then
BUTTON.checkHovering(buttonList, e.x, e.y)
end
end
return UserManagementScene