Homebrew [Release] Lua Player Plus 3DS (lpp-3ds) - LUA interpreter for 3DS

D

Deleted User

Guest
When will LPP-3DS be able to support sleep mode? And, out of curiosity, why won't sleep mode work, even on CFW and NH 2.5?
 

Rinnegatamante

Well-Known Member
OP
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
29
Location
Bologna
Website
rinnegatamante.it
XP
4,857
Country
Italy
Really? How would one go about this?

What do you mean for sleep mode? If you mean pressin Home to return temporary to home menu, yes lpp-3ds already support it with some glitches. (Basically there are some glitches with GPU state restoring that need to be solved).
 
  • Like
Reactions: Deleted User
D

Deleted User

Guest
What do you mean for sleep mode? If you mean pressin Home to return temporary to home menu, yes lpp-3ds already support it with some glitches. (Basically there are some glitches with GPU state restoring that need to be solved).

What I mean is the ability for the program to continue running as usual when the 3DS is closed and opened again (to continue running out of sleep mode, so to speak).

From all the LPP-3DS programs I've used so far, once you close the 3DS and reopen it, the program crashes and you're stuck with a black screen, forcing you to restart the 3DS.
 
  • Like
Reactions: PabloMK7

PabloMK7

Red Yoshi! ^ω^
Developer
Joined
Feb 21, 2014
Messages
2,604
Trophies
2
Age
24
Location
Yoshi's Island
XP
5,025
Country
Spain
Could someone post a sample of how to recieve a file with sockets from https://example.com/file.zip ? I can't figure it out -_-.

This is what I've done so far to HTTP server, but I get an empty string: (Used a sample I found somewhere else)

I'm printing the string correctly, that's not the problem.
EDIT2: Second try.

Code:
function testsocket()
    Socket.init()
    checksckt = Socket.connect("133.130.123.204", 80, false) -- (Also tried with the domain name ctgp.dshack.org, still doesn't work)
    Socket.send(checksckt, "GET /check.txt HTTP/1.1\nHost: ctgp.dshack.org\n\n")
    checkscktdata = Socket.receive(checksckt, 1024)
    Socket.term()
end
Printing checkscktdata returns an empty string ("")
 
Last edited by PabloMK7,
  • Like
Reactions: Deleted User

Rinnegatamante

Well-Known Member
OP
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
29
Location
Bologna
Website
rinnegatamante.it
XP
4,857
Country
Italy
Could someone post a sample of how to recieve a file with sockets from https://example.com/file.zip ? I can't figure it out -_-.

This is what I've done so far to HTTP server, but I get an empty string: (Used a sample I found somewhere else)

I'm printing the string correctly, that's not the problem.
EDIT2: Second try.

Code:
function testsocket()
    Socket.init()
    checksckt = Socket.connect("133.130.123.204", 80, false) -- (Also tried with the domain name ctgp.dshack.org, still doesn't work)
    Socket.send(checksckt, "GET /check.txt HTTP/1.1\nHost: ctgp.dshack.org\n\n")
    checkscktdata = Socket.receive(checksckt, 1024)
    Socket.term()
end
Printing checkscktdata returns an empty string ("")

If you're using latest nightly build, you can use Network module to download via SSL or you can use Socket.connect with third argument set as true (as stated in the documentation: http://rinnegatamante.it/lpp-3ds_doc.html )
 

PabloMK7

Red Yoshi! ^ω^
Developer
Joined
Feb 21, 2014
Messages
2,604
Trophies
2
Age
24
Location
Yoshi's Island
XP
5,025
Country
Spain
If you're using latest nightly build, you can use Network module to download via SSL or you can use Socket.connect with third argument set as true (as stated in the documentation: http://rinnegatamante.it/lpp-3ds_doc.html )
The server I'm trying to connect is not SSL (trying to connect with SSL returns "Failed to create SSL connection"), the http request or read is what isn't working. (I don't want to use Network.DownloadFile because I can't make a progress bar with it.)
 
Last edited by PabloMK7,

Rinnegatamante

Well-Known Member
OP
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
29
Location
Bologna
Website
rinnegatamante.it
XP
4,857
Country
Italy
  • Like
Reactions: PabloMK7

PabloMK7

Red Yoshi! ^ω^
Developer
Joined
Feb 21, 2014
Messages
2,604
Trophies
2
Age
24
Location
Yoshi's Island
XP
5,025
Country
Spain
I got it working, here is a function to download string using sockets if you want to use it :P

Code:
function socket_string(string_host, number_port, bool_usessl, string_path, number_stringmaxsize, number_checkfrequency, number_checktimeout)
    checksckt = Socket.connect(string_host, number_port, bool_usessl)
    sockettmr = Timer.new()
    globalsockettmr = Timer.new()
    Socket.send(checksckt, "GET "..string_path.." HTTP/1.0\r\nHost: "..string_host.."\r\n\r\n")
    local checkscktdata = ""
    while (string.len(checkscktdata) == 0) do
        if (Timer.getTime(sockettmr)>=number_checkfrequency) then
            Timer.reset(sockettmr)
            checkscktdata = Socket.receive(checksckt, number_stringmaxsize)
            if (Timer.getTime(globalsockettmr) > number_checktimeout) then
                return "Timed out!"
            end
        end
    end
    Timer.destroy(sockettmr)
    Timer.destroy(globalsockettmr)
    local _,bytesoffset = string.find(checkscktdata, "Length: ")
    checkscktdata = string.sub(checkscktdata, bytesoffset + 1)
    local contentsize = string.match(checkscktdata, '%d+')
    checkscktdata = string.sub(checkscktdata, (string.len(checkscktdata) - contentsize))
    return checkscktdata
end

Example:
Code:
socket_string("ctgp.dshack.org", 80, false, "/check.txt", 4096, 100, 5000)
(Time is in msec)

Download file:

Code:
function socket_downloadfile(string_host, number_port, bool_usessl, string_path, number_chunksize, number_writeeach, number_checktimeout, string_savepath, bool_showinfo)
    if System.doesFileExist(string_savepath) then
        System.deleteFile(string_savepath)
    end
    if bool_showinfo then
        Font.setPixelSizes(font, 18)
    end
    checksckt = Socket.connect(string_host, number_port)
    sockettimeout = Timer.new()
    Socket.send(checksckt, "GET "..string_path.." HTTP/1.0\r\nHost: "..string_host.."\r\n\r\n")
    checkscktdata = ""
    while (string.len(checkscktdata) == 0) do
        checkscktdata = Socket.receive(checksckt, 512)
        if (Timer.getTime(sockettimeout) > number_checktimeout) then
            return "Timed out!"
        end
    end
    _,bytesoffset = string.find(checkscktdata, "Length: ") -- Search for the Content-Length data
    checkscktdata = string.sub(checkscktdata, bytesoffset) -- Ignore everything until Content-Length
    contentsize = tonumber(string.match(checkscktdata, '%d+')) -- Get the value (number of bytes)
    fileStream = io.open(string_savepath,FCREATE)
    _,contentoffset = string.find(checkscktdata, "\r\n\r\n") -- Find the 2 newlines (start of the content)
    checkscktdata = string.sub(checkscktdata, contentoffset + 1) -- Ignore everything but the actual content.
    io.write(fileStream,0,checkscktdata, string.len(checkscktdata)) -- Write first chunk to file.
    Timer.reset(sockettimeout)
    writetofile = ""
    total_size = 0
    if bool_showinfo then
        speedtmr = Timer.new()
        oldsize = 0
        progress = ""
    end
    while true do -- Socket closes after data transfering, so I create this to check when the socket closes.
        if ((total_size + number_chunksize) >= contentsize) then
            number_chunksize = number_chunksize - ((total_size + number_chunksize) - contentsize)
        end
        scktdata = Socket.receive(checksckt, number_chunksize) -- Receive next chunk of data
        if (string.len(scktdata)>0) then
            writetofile = writetofile..scktdata
        end
        file_size = io.size(fileStream)
        string_size = string.len(writetofile)
        total_size = file_size + string_size
        if not bool_showinfo then
            if (total_size  == contentsize) then
                io.write(fileStream, file_size, writetofile, string_size)
                writetofile = ""
                io.close(fileStream)
                Timer.destroy(sockettimeout)
                Socket.close(checksckt)
                return true
            end
            if (string_size >= number_writeeach) then
                io.write(fileStream, file_size, writetofile, string_size) -- Write data to the end of the file.
                writetofile = ""
            end
            Timer.reset(sockettimeout)
        elseif bool_showinfo then
            if (total_size == contentsize) then
                io.write(fileStream, file_size, writetofile, string_size)
                writetofile = ""
                io.close(fileStream)
                Timer.destroy(sockettimeout)
                Timer.destroy(speedtmr)
                Socket.close(checksckt)
                return true
            end
            if (string_size >= number_writeeach) then
                io.write(fileStream, file_size, writetofile, string_size) -- Write data to the end of the file.
                writetofile = ""
            end
            if (Timer.getTime(speedtmr) >= 1000) then
                progress = (total_size - oldsize)
                oldsize = total_size
-- Print your info here, example:
                Screen.waitVblankStart()
                Screen.refresh()
                Screen.clear(TOP_SCREEN)
                Screen.clear(BOTTOM_SCREEN)
                Graphics.initBlend(TOP_SCREEN)
                Graphics.fillEmptyRect(80, 320, 120, 150, Color.new(255,255,255))
                Graphics.fillRect(80, 80 + math.ceil(( total_size / contentsize ) * 240), 120, 150,Color.new(255,255,255))
                Graphics.termBlend()
                Font.print(font,80,150,round((contentsize / 1048576),2).." MB, "..round((progress / 1024),2).." KB/sec, "..SecondsToClock((contentsize - total_size) / (progress + 0.01)),Color.new(255,255,255), TOP_SCREEN)
                Screen.flip()
-- End printing your info here.
                Timer.reset(speedtmr)
            end
            Timer.reset(sockettimeout)
        elseif (Timer.getTime(sockettimeout) > number_checktimeout) then
            io.close(fileStream)
            System.deleteFile(string_savepath)
            Timer.destroy(sockettimeout)
            if bool_showinfo then
                Timer.destroy(speedtmr)
            end
            return false
        end
    end
    return true
end
Example:
Code:
socket_downloadfile("www.dshack.org", 80, false, "/assets/store/164/0.7update.zip", 4096, 1048576, 10000, "/file.zip", true)

The example downloads a file from dshack.org, in chunks of 4096 bytes, writes to file each MB, and has a 10sec timeout. It downloads at 120KB/sec. (4096 and 1048576 should not be changed to something bigger to prevent file corruption.)
 
Last edited by PabloMK7,
  • Like
Reactions: gnmmarechal

Rinnegatamante

Well-Known Member
OP
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
29
Location
Bologna
Website
rinnegatamante.it
XP
4,857
Country
Italy
I got it working, here is a function to download string using sockets if you want to use it :P

Code:
function socket_string(string_host, number_port, bool_usessl, string_path, number_stringmaxsize, number_checkfrequency, number_checktimeout)
    checksckt = Socket.connect(string_host, number_port, bool_usessl)
    sockettmr = Timer.new()
    globalsockettmr = Timer.new()
    Socket.send(checksckt, "GET "..string_path.." HTTP/1.0\r\nHost: "..string_host.."\r\n\r\n")
    local checkscktdata = ""
    while (string.len(checkscktdata) == 0) do
        if (Timer.getTime(sockettmr)>=number_checkfrequency) then
            Timer.reset(sockettmr)
            checkscktdata = Socket.receive(checksckt, number_stringmaxsize)
            if (Timer.getTime(globalsockettmr) > number_checktimeout) then
                return "Timed out!"
            end
        end
    end
    Timer.destroy(sockettmr)
    Timer.destroy(globalsockettmr)
    local _,bytesoffset = string.find(checkscktdata, "Length: ")
    checkscktdata = string.sub(checkscktdata, bytesoffset + 1)
    local contentsize = string.match(checkscktdata, '%d+')
    checkscktdata = string.sub(checkscktdata, (string.len(checkscktdata) - contentsize))
    return checkscktdata
end

Example:
Code:
socket_string("ctgp.dshack.org", 80, false, "/check.txt", 4096, 100, 5000)
(Time is in msec)

Download file:

Code:
function socket_downloadfile(string_host, number_port, bool_usessl, string_path, number_chunksize, number_writeeach, number_checktimeout, string_savepath, bool_showinfo)
    if System.doesFileExist(string_savepath) then
        System.deleteFile(string_savepath)
    end
    if bool_showinfo then
        Font.setPixelSizes(font, 18)
    end
    checksckt = Socket.connect(string_host, number_port)
    sockettimeout = Timer.new()
    Socket.send(checksckt, "GET "..string_path.." HTTP/1.0\r\nHost: "..string_host.."\r\n\r\n")
    checkscktdata = ""
    while (string.len(checkscktdata) == 0) do
        checkscktdata = Socket.receive(checksckt, 512)
        if (Timer.getTime(sockettimeout) > number_checktimeout) then
            return "Timed out!"
        end
    end
    _,bytesoffset = string.find(checkscktdata, "Length: ") -- Search for the Content-Length data
    checkscktdata = string.sub(checkscktdata, bytesoffset) -- Ignore everything until Content-Length
    contentsize = tonumber(string.match(checkscktdata, '%d+')) -- Get the value (number of bytes)
    fileStream = io.open(string_savepath,FCREATE)
    _,contentoffset = string.find(checkscktdata, "\r\n\r\n") -- Find the 2 newlines (start of the content)
    checkscktdata = string.sub(checkscktdata, contentoffset + 1) -- Ignore everything but the actual content.
    io.write(fileStream,0,checkscktdata, string.len(checkscktdata)) -- Write first chunk to file.
    Timer.reset(sockettimeout)
    writetofile = ""
    total_size = 0
    if bool_showinfo then
        speedtmr = Timer.new()
        oldsize = 0
        progress = ""
    end
    while true do -- Socket closes after data transfering, so I create this to check when the socket closes.
        if ((total_size + number_chunksize) >= contentsize) then
            number_chunksize = number_chunksize - ((total_size + number_chunksize) - contentsize)
        end
        scktdata = Socket.receive(checksckt, number_chunksize) -- Receive next chunk of data
        if (string.len(scktdata)>0) then
            writetofile = writetofile..scktdata
        end
        file_size = io.size(fileStream)
        string_size = string.len(writetofile)
        total_size = file_size + string_size
        if not bool_showinfo then
            if (total_size  == contentsize) then
                io.write(fileStream, file_size, writetofile, string_size)
                writetofile = ""
                io.close(fileStream)
                Timer.destroy(sockettimeout)
                Socket.close(checksckt)
                return true
            end
            if (string_size >= number_writeeach) then
                io.write(fileStream, file_size, writetofile, string_size) -- Write data to the end of the file.
                writetofile = ""
            end
            Timer.reset(sockettimeout)
        elseif bool_showinfo then
            if (total_size == contentsize) then
                io.write(fileStream, file_size, writetofile, string_size)
                writetofile = ""
                io.close(fileStream)
                Timer.destroy(sockettimeout)
                Timer.destroy(speedtmr)
                Socket.close(checksckt)
                return true
            end
            if (string_size >= number_writeeach) then
                io.write(fileStream, file_size, writetofile, string_size) -- Write data to the end of the file.
                writetofile = ""
            end
            if (Timer.getTime(speedtmr) >= 1000) then
                progress = (total_size - oldsize)
                oldsize = total_size
-- Print your info here, example:
                Screen.waitVblankStart()
                Screen.refresh()
                Screen.clear(TOP_SCREEN)
                Screen.clear(BOTTOM_SCREEN)
                Graphics.initBlend(TOP_SCREEN)
                Graphics.fillEmptyRect(80, 320, 120, 150, Color.new(255,255,255))
                Graphics.fillRect(80, 80 + math.ceil(( total_size / contentsize ) * 240), 120, 150,Color.new(255,255,255))
                Graphics.termBlend()
                Font.print(font,80,150,round((contentsize / 1048576),2).." MB, "..round((progress / 1024),2).." KB/sec, "..SecondsToClock((contentsize - total_size) / (progress + 0.01)),Color.new(255,255,255), TOP_SCREEN)
                Screen.flip()
-- End printing your info here.
                Timer.reset(speedtmr)
            end
            Timer.reset(sockettimeout)
        elseif (Timer.getTime(sockettimeout) > number_checktimeout) then
            io.close(fileStream)
            System.deleteFile(string_savepath)
            Timer.destroy(sockettimeout)
            if bool_showinfo then
                Timer.destroy(speedtmr)
            end
            return false
        end
    end
    return true
end
Example:
Code:
socket_downloadfile("www.dshack.org", 80, false, "/assets/store/164/0.7update.zip", 4096, 1048576, 10000, "/file.zip", true)

The example downloads a file from dshack.org, in chunks of 4096 bytes, writes to file each MB, and has a 10sec timeout. It downloads at 120KB/sec. (4096 and 1048576 should not be changed to something bigger to prevent file corruption.)

If you're using latest nightly build, you can use up to 32768 bytes as receive size without getting lost bytes issues. (That should also make download process faster since I/O is pretty slow on 3DS and the less you call io.write, the better it will be. (You should consider for example to save something like 15 MB on a temp var and then call a single write every time 15 MB is reached to increase download speed).
 

PabloMK7

Red Yoshi! ^ω^
Developer
Joined
Feb 21, 2014
Messages
2,604
Trophies
2
Age
24
Location
Yoshi's Island
XP
5,025
Country
Spain
If you're using latest nightly build, you can use up to 32768 bytes as receive size without getting lost bytes issues. (That should also make download process faster since I/O is pretty slow on 3DS and the less you call io.write, the better it will be. (You should consider for example to save something like 15 MB on a temp var and then call a single write every time 15 MB is reached to increase download speed).
Tried to set to 15MB, but at 5MB I get not enough memory :S
 

The_Marcster

Well-Known Member
Newcomer
Joined
Aug 18, 2015
Messages
98
Trophies
0
Age
24
XP
86
Country
Gambia, The
I have a problem when trying to render more than one circle, one the first one shows up. This doesn't happen when I'm drawing something else like rectangles. Here is an example:

Code:
-- Init GPU
Graphics.init()

-- Main Loop
while true do
   
    -- Start printing on top screen
    Screen.refresh()
    Graphics.initBlend(TOP_SCREEN)
   
    -- Draw something on screen
    Graphics.drawCircle(200, 120, 10, Color.new(0, 255, 0))
    Graphics.drawCircle(300, 120, 10, Color.new(255, 0, 0))
   
    -- Terminate printing phase
    Graphics.termBlend()
   
    -- Flip screens
    Screen.flip()
    Screen.waitVblankStart()
   
    -- Exit sample
    if Controls.check(Controls.read(), KEY_SELECT) then
        Graphics.term()
        System.exit()
    end
   
end

Note that this is the GPU example just with circle drawing functions.

Any help would be greatly appreciated :)
 

Rinnegatamante

Well-Known Member
OP
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
29
Location
Bologna
Website
rinnegatamante.it
XP
4,857
Country
Italy
Tried to connect to https://dshack.org using ssl sockets with: Socket.connect(www.dshack.org, 443, true). However I'm getting: "Error:[string"?"]:56: SSL connection failed." @Rinnegatamante (Also tried with port 80)

Thanks to @ksanislo improvements, this should be now solved.

I have a problem when trying to render more than one circle, one the first one shows up. This doesn't happen when I'm drawing something else like rectangles. Here is an example:

Code:
-- Init GPU
Graphics.init()

-- Main Loop
while true do
  
    -- Start printing on top screen
    Screen.refresh()
    Graphics.initBlend(TOP_SCREEN)
  
    -- Draw something on screen
    Graphics.drawCircle(200, 120, 10, Color.new(0, 255, 0))
    Graphics.drawCircle(300, 120, 10, Color.new(255, 0, 0))
  
    -- Terminate printing phase
    Graphics.termBlend()
  
    -- Flip screens
    Screen.flip()
    Screen.waitVblankStart()
  
    -- Exit sample
    if Controls.check(Controls.read(), KEY_SELECT) then
        Graphics.term()
        System.exit()
    end
  
end

Note that this is the GPU example just with circle drawing functions.

Any help would be greatly appreciated :)

Unfortunately this is a well known bug in sf2dlib that still needs to be solved. ( https://github.com/xerpi/sf2dlib/issues/9 )
 

Rinnegatamante

Well-Known Member
OP
Member
Joined
Nov 24, 2014
Messages
3,162
Trophies
2
Age
29
Location
Bologna
Website
rinnegatamante.it
XP
4,857
Country
Italy
Is there nothing you can do about this? The author says this and this commit from December 2015 fixed the issue

lpp-3ds uses very latest version of sf2dlib. This is not the only project with such issue. Anyway soon sf2dlib will receive a major update migrating the whole backend API to citro3d. In the next weeks, i'll update the whole Graphics module so maybe this change will fix such bug too.
 

The_Marcster

Well-Known Member
Newcomer
Joined
Aug 18, 2015
Messages
98
Trophies
0
Age
24
XP
86
Country
Gambia, The
lpp-3ds uses very latest version of sf2dlib. This is not the only project with such issue. Anyway soon sf2dlib will receive a major update migrating the whole backend API to citro3d. In the next weeks, i'll update the whole Graphics module so maybe this change will fix such bug too.

Oh, thanks for the info. Really looking forward to that then :)
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Veho @ Veho: The cybertruck is a death trap.