2017-05-01 16:13:55 +03:00
|
|
|
-- Creating dirs in case they do not exist
|
|
|
|
System.createDirectory("ux0:/data/TrackPlug")
|
|
|
|
System.createDirectory("ux0:/data/TrackPlugArchive")
|
|
|
|
|
2016-10-17 23:27:03 +03:00
|
|
|
-- Scanning TrackPlug folder
|
|
|
|
local tbl = System.listDirectory("ux0:/data/TrackPlug")
|
2020-03-14 14:54:22 +03:00
|
|
|
-- Removing apps with no region, may also add livetweet, crunchyroll etc.
|
2020-03-14 14:27:44 +03:00
|
|
|
for i, file in pairs(tbl) do
|
|
|
|
local regcod = string.sub(file.name,1,4)
|
2020-03-15 03:22:00 +03:00
|
|
|
local titleid = string.sub(file.name,1,-5)
|
|
|
|
-- DOA 5 Plus breaks the tracker
|
|
|
|
if titleid == "PCSE00235" then
|
|
|
|
System.deleteFile("ux0:/data/TrackPlug/"..file.name)
|
|
|
|
elseif regcod ~= "PCSA" and regcod ~= "PCSE" and regcod ~= "PCSB" and regcod ~= "PCSF" and regcod ~= "PCSG" and regcod ~= "PCSH" then
|
2020-03-14 14:27:44 +03:00
|
|
|
System.deleteFile("ux0:/data/TrackPlug/"..file.name)
|
|
|
|
end
|
|
|
|
end
|
2020-03-14 14:54:22 +03:00
|
|
|
-- Reset the table
|
2020-03-14 14:27:44 +03:00
|
|
|
tbl = System.listDirectory("ux0:/data/TrackPlug")
|
|
|
|
|
2016-10-19 19:29:18 +03:00
|
|
|
if tbl == nil then
|
|
|
|
tbl = {}
|
|
|
|
end
|
2016-10-17 23:27:03 +03:00
|
|
|
|
2020-03-14 14:54:22 +03:00
|
|
|
-- Convert a 32 bit binary string to an integer
|
2016-10-17 23:27:03 +03:00
|
|
|
function bin2int(str)
|
|
|
|
local b1, b2, b3, b4 = string.byte(str, 1, 4)
|
|
|
|
return (b4 << 24) + (b3 << 16) + (b2 << 8) + b1
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Format raw time data
|
|
|
|
function FormatTime(val)
|
|
|
|
local minutes = math.floor(val/60)
|
|
|
|
local seconds = val%60
|
|
|
|
local hours = math.floor(minutes/60)
|
|
|
|
local minutes = minutes%60
|
|
|
|
local res = ""
|
|
|
|
if hours > 0 then
|
|
|
|
res = hours .. "h "
|
|
|
|
end
|
|
|
|
if minutes > 0 then
|
|
|
|
res = res .. minutes .. "m "
|
|
|
|
end
|
2017-05-01 16:13:55 +03:00
|
|
|
res = res .. seconds .. "s "
|
2016-10-17 23:27:03 +03:00
|
|
|
return res
|
|
|
|
end
|
|
|
|
|
2017-05-01 16:13:55 +03:00
|
|
|
-- Recover title from homebrew database
|
|
|
|
function recoverTitle(tid)
|
|
|
|
local file = System.openFile("ux0:/data/TrackPlugArchive/" .. tid .. ".txt", FREAD)
|
|
|
|
fsize = System.sizeFile(file)
|
|
|
|
local title = System.readFile(file, fsize)
|
|
|
|
System.closeFile(file)
|
|
|
|
return title
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Extracts title name from an SFO file
|
|
|
|
function extractTitle(file, tid)
|
|
|
|
local data = System.extractSFO(file)
|
|
|
|
if System.doesFileExist("ux0:/data/TrackPlugArchive/" .. tid .. ".txt") then
|
|
|
|
System.deleteFile("ux0:/data/TrackPlugArchive/" .. tid .. ".txt")
|
|
|
|
end
|
|
|
|
local file = System.openFile("ux0:/data/TrackPlugArchive/" .. tid .. ".txt", FCREATE)
|
|
|
|
System.writeFile(file, data.title, string.len(data.title))
|
|
|
|
System.closeFile(file)
|
|
|
|
return data.title
|
2016-10-17 23:27:03 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Loading unknown icon
|
|
|
|
local unk = Graphics.loadImage("app0:/unk.png")
|
|
|
|
|
2017-05-01 16:13:55 +03:00
|
|
|
-- Getting region, playtime, icon and title name for any game
|
|
|
|
for i, file in pairs(tbl) do
|
|
|
|
if file.name == "config.lua" then
|
|
|
|
dofile("ux0:/data/TrackPlug/"..file.name)
|
|
|
|
cfg_idx = i
|
|
|
|
else
|
|
|
|
local titleid = string.sub(file.name,1,-5)
|
|
|
|
local regioncode = string.sub(file.name,1,4)
|
|
|
|
if regioncode == "PCSA" or regioncode == "PCSE" then
|
|
|
|
file.region = "USA"
|
|
|
|
elseif regioncode == "PCSB" then
|
|
|
|
file.region = "EUR"
|
|
|
|
elseif regioncode == "PCSF" then
|
|
|
|
file.region = "AUS"
|
|
|
|
elseif regioncode == "PCSG" then
|
|
|
|
file.region = "JPN"
|
|
|
|
elseif regioncode == "PCSH" then
|
|
|
|
file.region = "ASN"
|
|
|
|
else
|
|
|
|
file.region = "UNK"
|
2016-10-19 20:29:17 +03:00
|
|
|
end
|
2017-05-01 16:13:55 +03:00
|
|
|
if System.doesFileExist("ur0:/appmeta/" .. titleid .. "/icon0.png") then
|
|
|
|
file.icon = Graphics.loadImage("ur0:/appmeta/" .. titleid .. "/icon0.png")
|
|
|
|
else
|
|
|
|
file.icon = unk
|
2016-10-17 23:27:03 +03:00
|
|
|
end
|
2017-05-01 16:13:55 +03:00
|
|
|
if System.doesFileExist("ux0:/data/TrackPlugArchive/" .. titleid .. ".txt") then
|
|
|
|
file.title = recoverTitle(titleid)
|
|
|
|
elseif System.doesFileExist("ux0:/app/" .. titleid .. "/sce_sys/param.sfo") then
|
|
|
|
file.title = extractTitle("ux0:/app/" .. titleid .. "/sce_sys/param.sfo", titleid)
|
|
|
|
else
|
2020-03-14 14:27:44 +03:00
|
|
|
file.title = "Unknown Title"
|
2017-05-01 16:13:55 +03:00
|
|
|
end
|
|
|
|
file.id = titleid
|
|
|
|
fd = System.openFile("ux0:/data/TrackPlug/" .. file.name, FREAD)
|
|
|
|
file.rtime = bin2int(System.readFile(fd, 4))
|
|
|
|
file.ptime = FormatTime(file.rtime)
|
|
|
|
System.closeFile(fd)
|
2016-10-17 23:27:03 +03:00
|
|
|
end
|
|
|
|
end
|
2017-05-01 16:13:55 +03:00
|
|
|
if cfg_idx ~= nil then
|
|
|
|
table.remove(tbl, cfg_idx)
|
|
|
|
end
|
2016-10-17 23:27:03 +03:00
|
|
|
|
2016-10-19 19:29:18 +03:00
|
|
|
-- Background wave effect
|
|
|
|
local colors = {
|
2020-03-14 14:27:44 +03:00
|
|
|
{Color.new(72,72,72), Color.new(30,20,25), Color.new(200,180,180)} -- Black'N'Rose
|
2016-10-19 19:29:18 +03:00
|
|
|
}
|
2016-10-19 20:29:17 +03:00
|
|
|
if col_idx == nil then
|
2020-03-14 14:27:44 +03:00
|
|
|
col_idx = 0
|
2016-10-19 20:29:17 +03:00
|
|
|
end
|
2020-03-14 14:27:44 +03:00
|
|
|
|
2020-03-14 14:54:22 +03:00
|
|
|
local function LoadWave(height,dim,f,x_dim)
|
2020-03-15 03:22:00 +03:00
|
|
|
f=f or 0.1
|
|
|
|
local onda={pi=math.pi,Frec=f,Long_onda=dim,Amplitud=height}
|
|
|
|
function onda:color(a,b,c) self.a=a self.b=b self.c=c end
|
|
|
|
function onda:init(desfase)
|
|
|
|
desfase=desfase or 0
|
|
|
|
if not self.contador then
|
|
|
|
self.contador=Timer.new()
|
2020-03-14 14:27:44 +03:00
|
|
|
end
|
2020-03-15 03:22:00 +03:00
|
|
|
if not self.a or not self.b or not self.c then
|
|
|
|
self.a = 255
|
|
|
|
self.b = 200
|
|
|
|
self.c = 220
|
2020-03-14 14:54:22 +03:00
|
|
|
end
|
2020-03-15 03:22:00 +03:00
|
|
|
local t,x,y,i
|
|
|
|
t = Timer.getTime(self.contador)/1000+desfase
|
|
|
|
for x = 0,x_dim,8 do
|
|
|
|
y = 404+self.Amplitud*math.sin(2*self.pi*(t*self.Frec-x/self.Long_onda))
|
|
|
|
i = self.Amplitud*(self.pi/self.Long_onda)*math.cos(2*self.pi*(t*self.Frec-x/self.Long_onda))
|
|
|
|
k = self.Amplitud*(1*self.pi/self.Long_onda)*math.sin(-1*self.pi*(t*self.Frec-x/self.Long_onda))
|
|
|
|
Graphics.drawLine(x-30,x+30,y-i*30,y+i*30,Color.new(self.a,self.b,self.c,math.floor(x/65)))
|
|
|
|
Graphics.drawLine(x-150,x+150,y-k*150,y+k*150,Color.new(self.a-60,self.b-80,self.a-70,math.floor(x/20)))
|
|
|
|
end
|
2020-03-14 14:54:22 +03:00
|
|
|
end
|
2020-03-15 03:22:00 +03:00
|
|
|
function onda:destroy()
|
|
|
|
Timer.destroy(self.contador)
|
|
|
|
end
|
|
|
|
return onda
|
2016-10-19 19:29:18 +03:00
|
|
|
end
|
2020-03-14 14:27:44 +03:00
|
|
|
|
2020-03-14 14:54:22 +03:00
|
|
|
wav = LoadWave(100,1160, 0.1, 1160)
|
2016-10-19 19:29:18 +03:00
|
|
|
|
2016-10-17 23:27:03 +03:00
|
|
|
-- Internal stuffs
|
|
|
|
local list_idx = 1
|
|
|
|
local order_idx = 1
|
|
|
|
local orders = {"Name", "Playtime"}
|
|
|
|
|
|
|
|
-- Ordering titles
|
|
|
|
table.sort(tbl, function (a, b) return (a.title:lower() < b.title:lower() ) end)
|
|
|
|
function resortList(o_type, m_idx)
|
|
|
|
local old_id = tbl[m_idx].id
|
2020-03-14 14:54:22 +03:00
|
|
|
table.sort(tbl, function (a, b) return (a.rtime > b.rtime ) end)
|
2016-10-17 23:27:03 +03:00
|
|
|
for i, title in pairs(tbl) do
|
|
|
|
if title.id == old_id then
|
|
|
|
return i
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Internal stuffs
|
|
|
|
local white = Color.new(255, 255, 255)
|
|
|
|
local yellow = Color.new(255, 255, 0)
|
|
|
|
local grey = Color.new(40, 40, 40)
|
|
|
|
|
|
|
|
-- Shows an alarm with selection on screen
|
|
|
|
local alarm_val = 128
|
|
|
|
local alarm_decrease = true
|
|
|
|
function showAlarm(title, select_idx)
|
|
|
|
if alarm_decrease then
|
|
|
|
alarm_val = alarm_val - 4
|
|
|
|
if alarm_val == 40 then
|
|
|
|
alarm_decrease = false
|
|
|
|
end
|
|
|
|
else
|
|
|
|
alarm_val = alarm_val + 4
|
|
|
|
if alarm_val == 128 then
|
|
|
|
alarm_decrease = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local sclr = Color.new(alarm_val, alarm_val, alarm_val)
|
|
|
|
Graphics.fillRect(200, 760, 200, 280, grey)
|
|
|
|
Graphics.debugPrint(205, 205, title, yellow)
|
|
|
|
Graphics.fillRect(200, 760, 215 + select_idx * 20, 235 + select_idx * 20, sclr)
|
|
|
|
Graphics.debugPrint(205, 235, "Yes", white)
|
|
|
|
Graphics.debugPrint(205, 255, "No", white)
|
|
|
|
end
|
|
|
|
-- Scroll-list Renderer
|
|
|
|
local sel_val = 128
|
|
|
|
local decrease = true
|
|
|
|
local freeze = false
|
2018-10-11 12:40:41 +03:00
|
|
|
local mov_y = 0
|
|
|
|
local mov_step = 0
|
|
|
|
local new_list_idx = nil
|
|
|
|
local real_i = 1
|
|
|
|
local big_tbl = {}
|
2016-10-17 23:27:03 +03:00
|
|
|
function RenderList()
|
2018-10-11 12:40:41 +03:00
|
|
|
local r_max = 0
|
|
|
|
local r = 0
|
|
|
|
if #tbl < 4 then
|
|
|
|
r_max = 8
|
|
|
|
else
|
|
|
|
r_max = 2
|
|
|
|
end
|
|
|
|
while r < r_max do
|
|
|
|
for k, v in pairs(tbl) do
|
|
|
|
table.insert(big_tbl, v)
|
|
|
|
end
|
|
|
|
r = r + 1
|
|
|
|
end
|
|
|
|
local y = -124
|
|
|
|
local i = list_idx - 1
|
2016-10-17 23:27:03 +03:00
|
|
|
if not freeze then
|
|
|
|
if decrease then
|
|
|
|
sel_val = sel_val - 4
|
|
|
|
if sel_val == 0 then
|
|
|
|
decrease = false
|
|
|
|
end
|
|
|
|
else
|
|
|
|
sel_val = sel_val + 4
|
|
|
|
if sel_val == 128 then
|
|
|
|
decrease = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-10-11 12:40:41 +03:00
|
|
|
if mov_y ~= 0 then
|
2020-03-15 03:22:00 +03:00
|
|
|
mov_y = math.floor(mov_y*1.2)
|
2018-10-11 12:40:41 +03:00
|
|
|
if math.abs(mov_y) >= 132 then
|
|
|
|
mov_y = 0
|
|
|
|
list_idx = new_list_idx
|
|
|
|
i = new_list_idx - 1
|
2016-10-17 23:27:03 +03:00
|
|
|
end
|
2018-10-11 12:40:41 +03:00
|
|
|
end
|
|
|
|
while i <= list_idx + 4 do
|
|
|
|
if i < 1 then
|
|
|
|
real_i = i
|
|
|
|
i = #big_tbl - math.abs(i)
|
|
|
|
end
|
2020-03-15 03:22:00 +03:00
|
|
|
Graphics.fillRect(5, 955, y+mov_y, y+mov_y-4, Color.new(255, 255, 255, 60))
|
|
|
|
if i ~= list_idx + 5 then
|
2018-10-11 12:40:41 +03:00
|
|
|
Graphics.drawImage(5, y + mov_y, big_tbl[i].icon)
|
|
|
|
end
|
2020-03-15 03:22:00 +03:00
|
|
|
Graphics.debugPrint(150, y + 35 + mov_y, big_tbl[i].title, Color.new(230,140,175))
|
|
|
|
--Graphics.debugPrint(150, y + 45 + mov_y, "Title ID: " .. big_tbl[i].id, white)
|
|
|
|
--Graphics.debugPrint(150, y + 65 + mov_y, "Region: " .. big_tbl[i].region, white)
|
|
|
|
Graphics.debugPrint(150, y + 65 + mov_y, "Playtime: " .. big_tbl[i].ptime, white)
|
2018-10-11 12:40:41 +03:00
|
|
|
local r_idx = i % #tbl
|
|
|
|
if r_idx == 0 then
|
|
|
|
r_idx = #tbl
|
|
|
|
end
|
2020-03-15 03:22:00 +03:00
|
|
|
Graphics.debugPrint(920, y + 100 + mov_y, "#" .. r_idx, white)
|
2016-10-17 23:27:03 +03:00
|
|
|
y = y + 132
|
2018-10-11 12:40:41 +03:00
|
|
|
if real_i <= 0 then
|
|
|
|
i = real_i
|
|
|
|
real_i = 1
|
|
|
|
end
|
2016-10-17 23:27:03 +03:00
|
|
|
i = i + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Main loop
|
|
|
|
local f_idx = 1
|
|
|
|
local oldpad = Controls.read()
|
|
|
|
while #tbl > 0 do
|
|
|
|
Graphics.initBlend()
|
2020-03-14 14:27:44 +03:00
|
|
|
Graphics.fillRect(0,960,0,544,Color.new(10,5,15))
|
2016-10-19 19:29:18 +03:00
|
|
|
wav:init()
|
2016-10-17 23:27:03 +03:00
|
|
|
RenderList()
|
2020-03-15 03:22:00 +03:00
|
|
|
if freeze then
|
|
|
|
showAlarm("Do you want to delete this record permanently?", f_idx)
|
|
|
|
end
|
2016-10-17 23:27:03 +03:00
|
|
|
Graphics.termBlend()
|
|
|
|
Screen.flip()
|
|
|
|
Screen.waitVblankStart()
|
|
|
|
local pad = Controls.read()
|
2018-10-11 12:40:41 +03:00
|
|
|
if Controls.check(pad, SCE_CTRL_UP) and mov_y == 0 then
|
2016-10-17 23:27:03 +03:00
|
|
|
if freeze then
|
|
|
|
f_idx = 1
|
|
|
|
else
|
2018-10-11 12:40:41 +03:00
|
|
|
new_list_idx = list_idx - 1
|
|
|
|
if new_list_idx == 0 then
|
|
|
|
new_list_idx = #tbl
|
2016-10-17 23:27:03 +03:00
|
|
|
end
|
2020-03-15 03:22:00 +03:00
|
|
|
mov_y = 5
|
2016-10-17 23:27:03 +03:00
|
|
|
end
|
2018-10-11 12:40:41 +03:00
|
|
|
elseif Controls.check(pad, SCE_CTRL_DOWN) and mov_y == 0 then
|
2016-10-17 23:27:03 +03:00
|
|
|
if freeze then
|
|
|
|
f_idx = 2
|
|
|
|
else
|
2018-10-11 12:40:41 +03:00
|
|
|
new_list_idx = list_idx + 1
|
|
|
|
if new_list_idx > #tbl then
|
|
|
|
new_list_idx = 1
|
2016-10-17 23:27:03 +03:00
|
|
|
end
|
2020-03-15 03:22:00 +03:00
|
|
|
mov_y = -5
|
|
|
|
end
|
|
|
|
elseif Controls.check(pad, SCE_CTRL_TRIANGLE) and not Controls.check(oldpad, SCE_CTRL_TRIANGLE) and not freeze then
|
|
|
|
freeze = true
|
|
|
|
f_idx = 1
|
|
|
|
elseif Controls.check(pad, SCE_CTRL_CROSS) and not Controls.check(oldpad, SCE_CTRL_CROSS) and freeze then
|
|
|
|
freeze = false
|
|
|
|
if f_idx == 1 then -- Delete
|
|
|
|
System.deleteFile("ux0:/data/TrackPlug/" .. tbl[list_idx].name)
|
|
|
|
table.remove(tbl, list_idx)
|
|
|
|
big_tbl = {}
|
|
|
|
list_idx = list_idx - 1
|
2016-10-17 23:27:03 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
oldpad = pad
|
|
|
|
end
|
|
|
|
|
|
|
|
-- No games played yet apparently
|
|
|
|
while true do
|
|
|
|
Graphics.initBlend()
|
|
|
|
Screen.clear()
|
|
|
|
Graphics.debugPrint(5, 5, "No games tracked yet.", white)
|
|
|
|
Graphics.termBlend()
|
|
|
|
Screen.flip()
|
|
|
|
Screen.waitVblankStart()
|
2020-03-14 14:27:44 +03:00
|
|
|
end
|