Skip to content

Commit

Permalink
Updated files to v1.5
Browse files Browse the repository at this point in the history
Added fade and offline mode
  • Loading branch information
EK720 committed Oct 6, 2024
1 parent dff9bff commit e0e346a
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 38 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#compiled vpk
*.vpk
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# MikuVU
A homebrew app for the PS Vita that displays mostly SFW images of Hatsune Miku, sourced from Gelbooru.
# MikuVU
A homebrew app for the PS Vita that displays mostly SFW images of Hatsune Miku, sourced from Gelbooru.
Binary file added deps/font/ShinGo-Trimmed.ttf
Binary file not shown.
Binary file removed deps/font/ShinGo.ttf
Binary file not shown.
186 changes: 150 additions & 36 deletions index.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@ pcall(Network.term)
-- Initialize network
Network.init()

-- Seed random number generator
local rh,rm,rs = System.getTime()
math.randomseed(rh .. rm .. rs)
-- Load JSON parser
local json = dofile("app0:/deps/lua/json.lua")
-- Load font and set font size
local fnt0 = Font.load("app0:/deps/font/ShinGo.ttf")
local fnt0 = Font.load("app0:/deps/font/ShinGo-Trimmed.ttf")
Font.setPixelSizes(fnt0, 25)
-- Define colors
local white, translucentBlack = Color.new(255,255,255), Color.new(0,0,0,160)
-- Init constants
local dataFolder = "ux0:/data/MikuVU"
local saveFolder = dataFolder .. "/SAVED"
-- Init values
local currentId = nil -- ID of the currently loaded image, used when saving images
local autoNext = 0 -- Auto next variable
local seconds = 5 -- Delay in seconds
local rating = 1 -- max rating allowed (0=general, 1=sensitive, 2=questionable, 3=explicit)
local ratingURL="-rating:questionable+-rating:explicit" -- URL additive related to the rating var above
local fadeImages = false -- Fade in and out images?
local response = nil -- Response of function ID (used in main loop)
local message = "" -- Callback Message (used in main loop)
local status = nil -- Callback Status (used in main loop)
Expand All @@ -26,10 +33,30 @@ local tmr2 = Timer.new() -- Set timer for delays in main loop
Timer.pause(tmr2) -- Pause timer at 0
local buttonDown = false -- Ensures no input lag and no unpredicted calls to functions every loop
local menu = false -- If menu is open
local jsonValid = true -- Valid JSON Response (Default True)
local jsonValid = true -- Valid JSON Response (Default true)
local drawMode = false -- The space in between Graphics.initBlend and Graphics.termBlend where anything can happen.
local imageDrawn = false -- Is the image fully shown?
local imgData = {} -- Arguments for the last rendered image
local offlineMode = false -- If the user has no internet, just show a slideshow of saved images
local offlineImgIndex = 0 -- Currently displayed image # in folder
local offlineImgList = {} -- List of all saved images for offline use

-- Functions

-- Sets bool when drawMode is active
local old_init = Graphics.initBlend
local old_term = Graphics.termBlend

function Graphics.initBlend()
drawMode = true
old_init()
end

function Graphics.termBlend()
drawMode = false
old_term()
end

-- Increases auto next delay
function timerIncrease()
local id = 1
Expand Down Expand Up @@ -72,16 +99,19 @@ end
-- Saves image with the ID as name
function saveImage()
local id = 4
if System.doesFileExist("ux0:/data/MikuVU/SAVED/" .. currentId .. ".jpg") then
if offlineMode then
return id, "Error | Offline", 2
end
if System.doesFileExist(saveFolder .. "/" .. currentId .. ".jpg") then
return id, "Image Already Saved", 0
elseif img ~= nil then
if fullRes then
local new = System.openFile("ux0:/data/MikuVU/SAVED/" .. currentId .. ".jpg", FCREATE)
local new = System.openFile(saveFolder .. "/" .. currentId .. ".jpg", FCREATE)
System.writeFile(new, image, size2) -- Image data and Size Loaded in getmiku()
System.closeFile(new)
else
local fullExt = string.lower(string.match(fullUrl,"%.[%a%d]+$"))
Network.downloadFile(fullUrl, "ux0:/data/MikuVU/SAVED/" .. currentId .. fullExt)
Network.downloadFile(fullUrl, saveFolder .. "/" .. currentId .. fullExt)
end
return id, "Saved | " .. currentId .. ".jpg", 1
else
Expand All @@ -106,26 +136,67 @@ function changeFilter()
return id, "Explicit"
end
end

function toggleFade()
local id = 6
fadeImages = not(fadeImages)

if fadeImages then
return id, "Fade | On"
else
return id, "Fade | Off"
end
end

-- Fades in an image at the specified scale in a certain amount of time.
-- 4x fadeSpeed is approximately 1 second on my Vita.
function fadeInImageScale(x, y, img, x_scale, y_scale, fadeSpeed)
local prevDrawMode = drawMode

if drawMode then
Graphics.termBlend()
Screen.flip()
Screen.waitVblankStart()
end

for i=1,255,fadeSpeed do
Graphics.initBlend()
--Screen.clear()
Graphics.fillRect(0,960,0,544,Color.new(0,0,0,tonumber(i/4)))
Graphics.drawScaleImage(x, y, img, x_scale, y_scale, Color.new(255,255,255,i))
Graphics.termBlend()
Screen.flip()
Screen.waitVblankStart()
end

if prevDrawMode then
Graphics.initBlend()
end
end

-- Gets and loads pictures from decoded JSON
function getmiku()
::getmiku::
-- Clear last loaded image from memory
if img ~= nil then
Graphics.freeImage(img)
img = nil
end

if Network.isWifiEnabled() then
Network.downloadFile("https://gelbooru.com/index.php?limit=1&page=dapi&s=post&q=index&json=1&tags=hatsune_miku+-furry+-animal_ears+sort:random+highres+"..ratingURL, "ux0:/data/MikuVU/post.json")
local file1 = System.openFile("ux0:/data/MikuVU/post.json", FREAD)
Network.downloadFile("https://gelbooru.com/index.php?limit=1&page=dapi&s=post&q=index&json=1&tags=hatsune_miku+-furry+-animal_ears+sort:random+highres+"..ratingURL, dataFolder.."/post.json")
local file1 = System.openFile(dataFolder.."/post.json", FREAD)
local size1 = System.sizeFile(file1)
local jsonEncoded = System.readFile(file1, size1) -- Encoded JSON file data
local pcallStat, jsonDecoded = pcall(json.decode, jsonEncoded) -- Decoded JSON to table
System.closeFile(file1)
System.deleteFile("ux0:/data/MikuVU/post.json")
System.deleteFile(dataFolder.."/post.json")
if not pcallStat then
jsonValid = pcallStat
return
end
jsonValid = pcallStat
if img ~= nil then
Graphics.freeImage(img)
img = nil
end

-- if sample (smaller) image doesn't exist, display full-size image instead
url = jsonDecoded["post"][1]["sample_url"]
fullUrl = jsonDecoded["post"][1]["file_url"]
Expand All @@ -141,36 +212,65 @@ function getmiku()
end

currentId = jsonDecoded["post"][1]["id"]
Network.downloadFile(url, "ux0:/data/MikuVU/MikuVU.jpg")
local file2 = System.openFile("ux0:/data/MikuVU/MikuVU.jpg", FREAD)
Network.downloadFile(url, dataFolder.."/MikuVU.jpg")
local file2 = System.openFile(dataFolder.."/MikuVU.jpg", FREAD)
size2 = System.sizeFile(file2)
if size2 == 0 then
System.closeFile(file2)
goto getmiku
end
image = System.readFile(file2, size2)
System.closeFile(file2)
img = Graphics.loadImage("ux0:/data/MikuVU/MikuVU.jpg")
System.deleteFile("ux0:/data/MikuVU/MikuVU.jpg")
img = Graphics.loadImage(dataFolder.."/MikuVU.jpg")
System.deleteFile(dataFolder.."/MikuVU.jpg")
else
-- if no internet, load images in /saved/
if System.doesDirExist(saveFolder) and not(offlineMode) then
local savedFiles = System.listDirectory(saveFolder)
local fullExt = ""
for _, image in ipairs(savedFiles) do
fullExt = string.lower(string.match(image["name"],"%.[%a%d]+$"))
if fullExt == ".jpg" or fullExt == ".jpeg" or fullExt == ".png" or fullExt == ".bmp" then
offlineImgList[#offlineImgList+1] = image["name"]
end
end
offlineMode = true
end

-- if images already loaded, display the next one
if #offlineImgList > 0 then
local lastIndex = offlineImgIndex
::randomize::
offlineImgIndex = math.random(1,#offlineImgList-1)
if offlineImgIndex == lastIndex then goto randomize end

img = Graphics.loadImage(saveFolder.."/"..offlineImgList[offlineImgIndex])
end
end

-- if no wifi and no images, then something is wrong and image should NOT be loaded
if #offlineImgList == 0 and not(Network.isWifiEnabled()) then
img = nil
else
width = Graphics.getImageWidth(img)
height = Graphics.getImageHeight(img)
drawWidth = 480 - (width * 544 / height / 2)
drawHeight = 272 - (height * 960 / width / 2)
if (autoNext == 1) then
Timer.setTime(tmr, seconds * 1000) -- Set time in seconds
end
else
img = nil
imageDrawn = false
end
end


-- Check if ux0:/data/MikuVU exists
if not System.doesDirExist("ux0:/data/MikuVU") then
System.createDirectory("ux0:/data/MikuVU")
if not System.doesDirExist(dataFolder) then
System.createDirectory(dataFolder)
end
-- Check if SAVED folder exists
if not System.doesDirExist("ux0:/data/MikuVU/SAVED") then
System.createDirectory("ux0:/data/MikuVU/SAVED")
if not System.doesDirExist(saveFolder) then
System.createDirectory(saveFolder)
end

getmiku()
Expand All @@ -185,7 +285,7 @@ while true do
local delaySec = 4000 -- Value used for the delay timer

-- Controls
if jsonValid and Network.isWifiEnabled() and img ~= nil then
if jsonValid and img ~= nil then
if Controls.check(pad, SCE_CTRL_CROSS) or Controls.check(pad, SCE_CTRL_DOWN) or (autoNext == 1 and time > 0) then
getmiku()
elseif Controls.check(pad, SCE_CTRL_CIRCLE) or Controls.check(pad, SCE_CTRL_RIGHT) then
Expand Down Expand Up @@ -213,6 +313,11 @@ while true do
response, message = changeFilter()
end
buttonDown = true
elseif (Controls.check(pad, SCE_CTRL_START)) then
if not buttonDown then
response, message = toggleFade()
end
buttonDown = true
else
buttonDown = false
end
Expand All @@ -233,28 +338,33 @@ while true do

-- Start drawing
Graphics.initBlend()
Screen.clear()
if not Network.isWifiEnabled() then
Graphics.debugPrint(5, 220, "Error | Check Network Connection", Color.new(255,255,255))
elseif not jsonValid then
if not jsonValid then
Graphics.debugPrint(5, 220, "Error | Check Network Connection", Color.new(255,255,255))
elseif img == nil then
Graphics.debugPrint(5, 220, "Error | Check Network Connection", Color.new(255,255,255))
else
if height > width then
Graphics.drawScaleImage(drawWidth, 0, img, 544 / height, 544 / height)
if height >= width then
imgData = {drawWidth, 0, img, 544 / height, 544 / height, 4}
elseif width > height then
Graphics.drawScaleImage(0, drawHeight, img, 960 / width, 960 / width)
imgData = {0, drawHeight, img, 960 / width, 960 / width, 4}
end

if fadeImages and not(imageDrawn) then
fadeInImageScale(imgData[1], imgData[2], imgData[3], imgData[4], imgData[5], imgData[6])
imageDrawn = true
end

Screen.clear()
Graphics.drawScaleImage(imgData[1], imgData[2], imgData[3], imgData[4], imgData[5])
end

-- "Menu"
if delay < 0 then -- Informational display delay dimer is set, print info by function ID
menu = true -- Set menu visibility to false
if response == 1 or response == 2 then -- timerIncrease()/timerDecrease()
if delay < 0 then -- Informational display delay timer is set, print info by function ID
menu = true -- Set menu visibility to true
if response == 1 or response == 2 then -- timerIncrease()/timerDecrease()
Graphics.fillRect(15, 250, 30, 80, translucentBlack)
Font.print(fnt0, 20, 30, string.format("Delay | %02ds", seconds), white)
elseif response == 3 then -- toggleAutoNext()
elseif response == 3 then -- toggleAutoNext()
Graphics.fillRect(15, 250, 30, 80, translucentBlack)
if Timer.isPlaying(tmr) then
Font.print(fnt0, 20, 30, string.format("Timer | %02ds", timeSec), white)
Expand All @@ -272,8 +382,11 @@ while true do
end
Font.print(fnt0, 20, 30, message, white)
elseif response == 5 then
Graphics.fillRect(15, 350, 30, 80, translucentBlack)
Font.print(fnt0, 20, 30, string.format("Max rating: %s",message), white)
Graphics.fillRect(15, 375, 30, 80, translucentBlack)
Font.print(fnt0, 20, 30, string.format("Max Rating | %s",message), white)
elseif response == 6 then
Graphics.fillRect(15, 250, 30, 80, translucentBlack)
Font.print(fnt0, 20, 30, message, white)
else
menu = false
Graphics.fillRect(15, 325, 30, 80, translucentBlack)
Expand All @@ -282,6 +395,7 @@ while true do
else
menu = false -- Set menu visibility to false
end

-- Finish drawing
Graphics.termBlend()
Screen.flip()
Expand Down
Binary file modified sce_sys/manual/001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e0e346a

Please sign in to comment.