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

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
Here it is:
Code:
System.currentDirectory("/CTGP-7/")
Graphics.init()
function getcontrol()
    GC_key = Controls.read()
    GC_x,GC_y = Controls.readCirclePad()
    GC_outkey = ""
    if (Controls.check(GC_key,KEY_A)) and not(Controls.check(GC_oldkey,KEY_A)) then
        GC_outkey = "A"
    elseif (Controls.check(GC_key,KEY_B)) and not(Controls.check(GC_oldkey,KEY_B)) then
        GC_outkey = "B"
    end
    if (Timer.getTime(ctrl_timer) >= 500) then
        Timer.reset(ctrl_timer)
        GC_oldkey = KEY_X
        GC_oldx = 0
        GC_oldy = 0
    end
    if (((Controls.check(GC_key,KEY_DLEFT)) and not(Controls.check(GC_oldkey,KEY_DLEFT))) or ((GC_x < -128) and not (GC_oldx < -128))) then
        GC_outkey = "Left"
        Timer.reset(ctrl_timer)
    elseif (((Controls.check(GC_key,KEY_DRIGHT)) and not(Controls.check(GC_oldkey,KEY_DRIGHT))) or ((GC_x > 128) and not (GC_oldx > 128))) then
        GC_outkey = "Right"
        Timer.reset(ctrl_timer)
    elseif (((Controls.check(GC_key,KEY_DUP)) and not(Controls.check(GC_oldkey,KEY_DUP))) or ((GC_y > 128) and not (GC_oldy > 128))) then
        GC_outkey = "Up"
        Timer.reset(ctrl_timer)
    elseif (((Controls.check(GC_key,KEY_DDOWN)) and not(Controls.check(GC_oldkey,KEY_DDOWN))) or ((GC_y < -128) and not (GC_oldy < -128))) then
        GC_outkey = "Down"
        Timer.reset(ctrl_timer)
    end
    GC_oldkey = GC_key
    GC_oldx = GC_x
    GC_oldy = GC_y
    return GC_outkey
end
function listDirectory(dir)
    dir = System.listDirectory(dir)
    files_table = {}
    for i,file in pairs(dir) do
        if not file.directory then
            table.insert(files_table,file)
        end
    end
    table.sort(files_table, function (a, b) return (a.name:lower() < b.name:lower() ) end)
    return files_table
end
function getconfig()
    filenames = {}
    filenames = listDirectory(System.currentDirectory().."gamefs/Course/")
    trackn = #filenames
    tracke = {}
    local i
    local z = ""
    tracks = {}
    for i = 1, trackn, 1 do
        z = filenames[i].name
        z = string.sub(z,1,-5)
        if (string.sub(z,1,1) == "_") then
            tracke[i] = false
            tracks[i] = string.sub(z,2,-1)
        else
            tracke[i] = true
            tracks[i] = z
        end
    end
    dofile(System.currentDirectory().."config/names.lua")
    if not (#cts == trackn) then
        System.exit()
    end
    return true
end
function applyconfig()
    local z
    for z = 1, trackn, 1 do
        if (System.doesFileExist(System.currentDirectory().."gamefs/Course/"..tracks[z]..".szs")) then
            if not (tracke[z]) then
                System.renameFile(System.currentDirectory().."gamefs/Course/"..tracks[z]..".szs", System.currentDirectory().."gamefs/Course/_"..tracks[z]..".szs")
            end
        elseif (System.doesFileExist(System.currentDirectory().."gamefs/Course/_"..tracks[z]..".szs")) then
            if (tracke[z]) then
                System.renameFile(System.currentDirectory().."gamefs/Course/_"..tracks[z]..".szs", System.currentDirectory().."gamefs/Course/"..tracks[z]..".szs")
            end
        end
    end
    return true
end
function checkntr()
    local cias = System.listCIA()
    local v
    local installed
    local count = 0
    for _ in pairs(cias) do count = count + 1 end
    for v = 1, count, 1 do
        if (cias[v].unique_id == 0x00b00000) then
            installed = true
            break
        else
            installed = false
        end
    end
    return installed
end
-- Load files
topimgl = Screen.loadImage(System.currentDirectory().."resources/top_l.bmp")
submen0 = Graphics.loadImage(System.currentDirectory().."resources/submen0.png")
submen1 = Screen.loadImage(System.currentDirectory().."resources/submen1.bmp")
submen2 = Screen.loadImage(System.currentDirectory().."resources/submen2.bmp")
submen3 = Screen.loadImage(System.currentDirectory().."resources/submen3.bmp")
btn_u = Graphics.loadImage(System.currentDirectory().."resources/btn_u.png")
btn_s = Graphics.loadImage(System.currentDirectory().."resources/btn_s.png")
btn_en = Graphics.loadImage(System.currentDirectory().."resources/btn_en.png")
btn_dis = Graphics.loadImage(System.currentDirectory().."resources/btn_dis.png")
btn_sl = Graphics.loadImage(System.currentDirectory().."resources/btn_sl.png")
bgm = Sound.openOgg(System.currentDirectory().."resources/bgm.ogg", true)
beep = Sound.openOgg(System.currentDirectory().."resources/beep.ogg", false)
beep1 = Sound.openOgg(System.currentDirectory().."resources/beep1.ogg", false)
font = Font.load(System.currentDirectory().."resources/font.ttf")
-- End load files
mus0 = false
installntr = false
men = 0
men1 = 0
men3 = 1
disp1 = men3 + 1
disp2 = men3 - 1
submen = 0
oldpad = Controls.read
topscreen = topimgl
bottomscreen = submen3
ntrinstalled = checkntr()
getconfig()
ctrl_timer = Timer.new()
Sound.init()
Sound.play(bgm,LOOP)
while true do
Sound.updateStream()
    checkbutton = true
    pad = getcontrol()
    Screen.waitVblankStart()
    Screen.refresh()
    Screen.clear(BOTTOM_SCREEN)

    Screen.drawImage(0,0,topscreen,TOP_SCREEN)
    if (installntr) then
        System.installCIA(System.currentDirectory().."ntr/ntr.cia")
        submen = 0
        men = 0
        men1 = 0
        installntr = false
        checkbutton = false
        ntrinstalled = checkntr()
    end
    if not (ntrinstalled) then
        submen = 255
        Screen.debugPrint(0, 0, "NTR must be installed,", Color.new(255,255,255), BOTTOM_SCREEN)
        Screen.debugPrint(0, 10, "do you want to install it?", Color.new(255,255,255), BOTTOM_SCREEN)
        Screen.debugPrint(0, 30, "A = Just do it!!", Color.new(255,255,255), BOTTOM_SCREEN)
        Screen.debugPrint(0, 40, "B = NO!!", Color.new(255,255,255), BOTTOM_SCREEN)
        if (pad == "A") then
            Screen.debugPrint(0, 60, "Installing...", Color.new(255,255,255), BOTTOM_SCREEN)
            installntr = true
            checkbutton = false
        elseif (pad == "B") then
            Sound.pause(bgm)
            Sound.close(bgm)
            Sound.pause(beep)
            Sound.close(beep)
            Sound.pause(beep1)
            Sound.close(beep1)
            Sound.term()
            System.exit()
        end
    end
    if (launchntr) then
        System.launchCIA(0x00b00000,SDMC)
        System.exit()
    end
    if (submen == 0) then -- main menu
        Font.setPixelSizes(font, 32)
        if (pad == "Down") then
            men = men + 1
            Sound.play(beep, NO_LOOP)
        elseif (pad == "Up") then
            men = men - 1
            Sound.play(beep, NO_LOOP)
        end
        if (men > 2) then
            men = 0
        elseif (men < 0) then
            men = 2
        end
        if (men == 0) then
            Graphics.initBlend(BOTTOM_SCREEN)
            Graphics.drawImage(0, 0, submen0)
            Graphics.drawImage(5, 15, btn_s)
            Graphics.drawImage(5, 90, btn_u)
            Graphics.drawImage(5, 165, btn_u)
            Graphics.termBlend()
            Font.print(font, 25, 30, "Launch CTGP-7", Color.new(0,0,255), BOTTOM_SCREEN)
            Font.print(font, 25, 105, "Course Manager", Color.new(255,255,255), BOTTOM_SCREEN)
            Font.print(font, 25, 180, "Exit", Color.new(255,255,255), BOTTOM_SCREEN)
            if (pad == "A") and (checkbutton) then
                launchntr = true
            end
        elseif (men == 1) then
            Graphics.initBlend(BOTTOM_SCREEN)
            Graphics.drawImage(0, 0, submen0)
            Graphics.drawImage(5, 15, btn_u)
            Graphics.drawImage(5, 90, btn_s)
            Graphics.drawImage(5, 165, btn_u)
            Graphics.termBlend()
            Font.print(font, 25, 30, "Launch CTGP-7", Color.new(255,255,255), BOTTOM_SCREEN)
            Font.print(font, 25, 105, "Course Manager", Color.new(0,0,255), BOTTOM_SCREEN)
            Font.print(font, 25, 180, "Exit", Color.new(255,255,255), BOTTOM_SCREEN)
            if (pad == "A") and (checkbutton) then
                Sound.play(beep, NO_LOOP)
                submen = 1
                men = 0
                men1 = 0
                checkbutton = false
            end
        elseif (men == 2) then
            Graphics.initBlend(BOTTOM_SCREEN)
            Graphics.drawImage(0, 0, submen0)
            Graphics.drawImage(5, 15, btn_u)
            Graphics.drawImage(5, 90, btn_u)
            Graphics.drawImage(5, 165, btn_s)
            Graphics.termBlend()
            Font.print(font, 25, 30, "Launch CTGP-7", Color.new(255,255,255), BOTTOM_SCREEN)
            Font.print(font, 25, 105, "Course Manager", Color.new(255,255,255), BOTTOM_SCREEN)
            Font.print(font, 25, 180, "Exit", Color.new(0,0,255), BOTTOM_SCREEN)
            if (pad == "A") and (checkbutton) then
                Sound.pause(bgm)
                Sound.close(bgm)
                Sound.pause(beep)
                Sound.close(beep)
                Sound.pause(beep1)
                Sound.close(beep1)
                Sound.term()
                System.exit()
            end
        end
    end
    if (submen == 1) then -- Course manager

        Font.setPixelSizes(font, 25)
        if (pad == "Down") then
            men3 = men3 - 1
            Sound.play(beep1, NO_LOOP)
        elseif (pad == "Up") then
            men3 = men3 + 1
            Sound.play(beep1, NO_LOOP)
        end
        if (men3 >= trackn + 1) then
            men3 = 1
        elseif (men3 <= 0) then
            men3 = trackn
        end
        disp1 = men3 + 1
        disp2 = men3 - 1
        if (disp1 >= trackn + 1) then
            disp1 = 1
        elseif (disp1 <= 0) then
            disp1 = trackn
        end
        if (disp2 >= trackn + 1) then
            disp2 = 1
        elseif (disp2 <= 0) then
            disp2 = trackn
        end
        if ((pad == "Right") or (pad == "Left") or (pad == "A")) and (checkbutton) then
            tracke[men3] = not tracke[men3]
            Sound.play(beep, NO_LOOP)
        end
        if (pad == "B") and (checkbutton) then
            Sound.play(beep1, NO_LOOP)
            submen = 0
            men = 1
            checkbutton = false
            applyconfig()
        end
        color_ed = {}
        if (tracke[men3]) then
            btn_enadisa = btn_en
            color_ed[3] = Color.new(0,255,0)
        else
            btn_enadisa = btn_dis
            color_ed[3] = Color.new(255,0,0)
        end
        Graphics.initBlend(BOTTOM_SCREEN)
        Graphics.drawImage(0, 0, submen0)
        Graphics.drawImage(4, 73, btn_sl)
        Graphics.drawImage(8, 151, btn_enadisa)
        Graphics.termBlend()
        if (tracke[disp1]) then
            color_ed[1] = Color.new(0,153,0)
        else
            color_ed[1] = Color.new(153,0,0)
        end
        if (tracke[disp2]) then
            color_ed[2] = Color.new(0,153,0)
        else
            color_ed[2] = Color.new(153,0,0)
        end
        Font.print(font, 8, 0,men3.." / "..trackn, Color.new(255,255,255), BOTTOM_SCREEN)
        Font.print(font, 8, 203,"Press B to exit", Color.new(255,255,255), BOTTOM_SCREEN)
        Font.print(font, 8, 50,cts[disp1], color_ed[1], BOTTOM_SCREEN)
        Font.print(font, 12, 75,cts[men3], color_ed[3], BOTTOM_SCREEN)
        Font.print(font, 8, 100,cts[disp2], color_ed[2], BOTTOM_SCREEN)
    end
    oldpad = pad
    Screen.flip()
end

Pretty strange it crashes. Try to use Sound.getService and print the result.
If it says csnd:SND, place a dsp firmware in /3ds (dspfirm.cdc) and retry.
 

GalladeGuy

Cool and Epic
Member
Joined
Oct 28, 2015
Messages
2,686
Trophies
1
XP
3,115
Country
United States
tscreen = TOP_SCREEN
white = Color.new(255,255,255)

For some reason String.find doesn't work properly on strings downloaded via Network.requestString. It will return nil no matter what. Either that or I'm just stupid. Here's an example:
Code:
function insidestring(startst,endst,st,stoffset)
    st1start, st1end = string.find(st,startst,stoffset)
    st2start, st2end = string.find(st,endst,stoffset)
    stringstloc = st1end + 1
    stringendloc = st2start - 1
    retstring = string.sub(st,stringstloc,stringendloc)
    return retstring
end

while true do
    Screen.waitVblankStart()
    Screen.refresh()
    pad = Controls.read()
    if (Controls.check(pad, KEY_Y) and pad ~= oldpad) then
        st = Network.requestString("http://galladeguy.x10host.com/3DS/test.txt")
        Screen.debugPrint(0,0,insidestring("[MY_NAME]","[/MY_NAME]",st,1),white,tscreen)
    end
    Screen.flip()
    oldpad = pad
end

It should print GalladeGuy because that's what's in between [MY_NAME] and [/MY_NAME] in the downloaded string, but it returns nil instead and doesn't print anything. Is there something wrong with my code? Or is String.find just not working properly? I know Network.requestString is working properly because I tried printing the string and it was exactly what it should be. Sorry for asking such a long question but I really need help.
 
Last edited by GalladeGuy,

ihaveahax

Well-Known Member
Member
Joined
Apr 20, 2015
Messages
6,070
Trophies
2
XP
7,854
Country
United States
For some reason String.find doesn't work properly on strings downloaded via Network.requestString. It will return nil no matter what. Either that or I'm just stupid. Here's an example:
Code:
function insidestring(startst,endst,st,stoffset)
    st1start, st1end = string.find(st,startst,stoffset)
    st2start, st2end = string.find(st,endst,stoffset)
    stringstloc = st1end + 1
    stringendloc = st2start - 1
    retstring = string.sub(st,stringstloc,stringendloc)
    return retstring
end

while True do
    if (Controls.check(pad, KEY_Y) and pad ~= oldpad) then
        st = Network.requestString("http://galladeguy.x10host.com/3DS/test.txt")
        Screen.debugPrint(0,0,insidestring("[MY_NAME]","[/MY_NAME]",st,1),white,tscreen)
    end
end

It should print GalladeGuy because that's what's in between [MY_NAME] and [/MY_NAME] in the downloaded string, but it returns nil instead and doesn't print anything. Is there something wrong with my code? Or is String.find just not working properly? I know Network.requestString is working properly because I tried printing the string and it was exactly what it should be. Sorry for asking such a long question but I really need help.
I made a reply on GitHub for the issue you made: https://github.com/Rinnegatamante/lpp-3ds/issues/15#issuecomment-176225314

the capital True might be messing with it. change it to true and see how it goes. I think Lua is thinking "True" is a variable which wasn't set.

by the way, this line shouldn't be in the while loop:
Code:
st = Network.requestString("http://galladeguy.x10host.com/3DS/test.txt")
 

GalladeGuy

Cool and Epic
Member
Joined
Oct 28, 2015
Messages
2,686
Trophies
1
XP
3,115
Country
United States
I made a reply on GitHub for the issue you made: https://github.com/Rinnegatamante/lpp-3ds/issues/15#issuecomment-176225314

the capital True might be messing with it. change it to true and see how it goes. I think Lua is thinking "True" is a variable which wasn't set.

by the way, this line shouldn't be in the while loop:
Code:
st = Network.requestString("http://galladeguy.x10host.com/3DS/test.txt")
The capital true was just a typo I made when writing the example code. What's wrong with having that line in the while loop though? In my main program, it needs to be able to change every time it loads a txt file. And it would only be activated when you press Y.
 

ihaveahax

Well-Known Member
Member
Joined
Apr 20, 2015
Messages
6,070
Trophies
2
XP
7,854
Country
United States
The capital true was just a typo I made when writing the example code. What's wrong with having that line in the while loop though? In my main program, it needs to be able to change every time it loads a txt file. And it would only be activated when you press Y.
while you're holding Y, it would keep requesting "http://galladeguy.x10host.com/3DS/test.txt" each time it loops. unless you intend for it to change each time it happens you should probably call it once.

other than that it shouldn't have problems...? I managed to run it on a computer when I made it print to the console. I should go try this on a 3DS if that doesn't work...
 

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
For some reason String.find doesn't work properly on strings downloaded via Network.requestString. It will return nil no matter what. Either that or I'm just stupid. Here's an example:
Code:
function insidestring(startst,endst,st,stoffset)
    st1start, st1end = string.find(st,startst,stoffset)
    st2start, st2end = string.find(st,endst,stoffset)
    stringstloc = st1end + 1
    stringendloc = st2start - 1
    retstring = string.sub(st,stringstloc,stringendloc)
    return retstring
end

while True do
    if (Controls.check(pad, KEY_Y) and pad ~= oldpad) then
        st = Network.requestString("http://galladeguy.x10host.com/3DS/test.txt")
        Screen.debugPrint(0,0,insidestring("[MY_NAME]","[/MY_NAME]",st,1),white,tscreen)
    end
end

It should print GalladeGuy because that's what's in between [MY_NAME] and [/MY_NAME] in the downloaded string, but it returns nil instead and doesn't print anything. Is there something wrong with my code? Or is String.find just not working properly? I know Network.requestString is working properly because I tried printing the string and it was exactly what it should be. Sorry for asking such a long question but I really need help.

Are you sure requestString is returning the correct string? (Maybe it failed download).
 

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
Try with this:

Code:
function insidestring(tag_in, tag_out, str, offset)
   offs_st = string.find(str, tag_in, offset) + string.len(tag_in)
   offs_end = string.find(str, tag_out, offset)
   return string.sub(str, offs_st, offs_end)
end
 

PabloMK7

Red Yoshi! ^ω^
Developer
Joined
Feb 21, 2014
Messages
2,616
Trophies
2
Age
24
Location
Yoshi's Island
XP
5,173
Country
Spain
I've added this to my main loop:
Code:
    Graphics.initBlend(TOP_SCREEN,LEFT_EYE)
    Graphics.drawImage(0, 0, topimgl)
    Graphics.termBlend()
    Graphics.initBlend(TOP_SCREEN,RIGHT_EYE)
    Graphics.drawImage(0, 0, topimgr)
    Graphics.termBlend()
However, it is only drawing in 2D. Also, after I Graphics.term() and System.exit() the program crashes and the 3DS restarts
 

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've added this to my main loop:
Code:
    Graphics.initBlend(TOP_SCREEN,LEFT_EYE)
    Graphics.drawImage(0, 0, topimgl)
    Graphics.termBlend()
    Graphics.initBlend(TOP_SCREEN,RIGHT_EYE)
    Graphics.drawImage(0, 0, topimgr)
    Graphics.termBlend()
However, it is only drawing in 2D. Also, after I Graphics.term() and System.exit() the program crashes and the 3DS restarts

You should enable 3D with Screen.enable3D().
For the crash, are you sure are you cleaning everything you're using?

Still doesn't work.

It's pretty impossible that this function returns nil. Are you really sure requestString returns the correct string? If so, it should work.
 

GalladeGuy

Cool and Epic
Member
Joined
Oct 28, 2015
Messages
2,686
Trophies
1
XP
3,115
Country
United States
Even if they're wrong values (don't know why but anyway) string.sub shouldn't fail. I'm going to have some tests on Citra3DS about this.
I actually got it to work last night. So I set it up to get some values off a txt file like I originally planned. The only problem is, it would return value 1, value 2, the first 4 letters of value 3, and then wouldn't show value 4 at all. Very strange.
 

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 actually got it to work last night. So I set it up to get some values off a txt file like I originally planned. The only problem is, it would return value 1, value 2, the first 4 letters of value 3, and then wouldn't show value 4 at all. Very strange.

I posted a corrected version of the function in your GitHub issue.
 
  • Like
Reactions: GalladeGuy

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
Hi, I'm getting an error when I try to run my code. Could you help me? The error is:
Code:
Error:[String "?"]:2: JPGV module unavailable with dsp::DSP service.

The code I'm trying to run is the jpgv.lua with the lyrics part of the code removed.

http://pastebin.com/aP92wpLc

As said in release post, you should use the advanced audio descriptor to use JPGV module cause it needs csnd:SND service.
 

Ev1l0rd

(⌐◥▶◀◤) girl - noirscape
Member
Joined
Oct 26, 2015
Messages
2,004
Trophies
1
Location
Site 19
Website
catgirlsin.space
XP
3,441
Country
Netherlands
As said in release post, you should use the advanced audio descriptor to use JPGV module cause it needs csnd:SND service.
I put that in the appropriate xml file. Now I get the message: error opening file. My JPGV was made with JPGVthon if that is important. It is named output.jpgv and is placed in the same folder as lpp-3ds.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    D @ diamondsofmayhem: G'night!