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

The_Marcster

Well-Known Member
Newcomer
Joined
Aug 18, 2015
Messages
98
Trophies
0
Age
24
XP
86
Country
Gambia, The
This is totally working in Citra for me. Are your files/folders set up correctly? Do you have a main loop?
A sample I was testing worked fine on a 3DS but failed in Citra because I hadn't implemented a loop yet.

Also, is there something wrong with reading and writing files? When I read a file's contents and output its text, the output had weird trailing characters and would show as hex in Sublime Text. I wrote this:
Code:
-- HI SCORE IS BROKEN
-- idk why

hiscorefile = io.open("/gfx/hiscore",FCREATE)
text = io.read(hiscorefile,0,10)
hiscore = tonumber(text)
if (score > hiscore) then
    hiscore = score
    io.write(hiscorefile,0,hiscore, 21)
end

Well, when I try it, a few things work and a few don't.
 

0x0wl

Member
Newcomer
Joined
Aug 18, 2015
Messages
17
Trophies
0
Age
33
XP
66
Country
United States
This is totally working in Citra for me. Are your files/folders set up correctly? Do you have a main loop?
A sample I was testing worked fine on a 3DS but failed in Citra because I hadn't implemented a loop yet.

I finally got it working. You need to put the index.lua file in the citra/user/sdmc folder.

edit: I checked out your code.

Also, is there something wrong with reading and writing files? When I read a file's contents and output its text, the output had weird trailing characters and would show as hex in Sublime Text. I wrote this:
Code:
-- HI SCORE IS BROKEN
-- idk why

hiscorefile = io.open("/gfx/hiscore",FCREATE)
text = io.read(hiscorefile,0,10)
hiscore = tonumber(text)
if (score > hiscore) then
    hiscore = score
    io.write(hiscorefile,0,hiscore, 21)
end

There's a couple problems with it.
- FCREATE deletes existing files so you're reading in nothing when you do this. You need to check if the file exists first, and if it does, open it in FREAD mode.
- When only writing the file, open in FWRITE mode.
- The last parameter of io.write() is the size in bytes of the text you're writing. If your high score is "100" then you want a size of 3 since each character is 1 byte.

This code works for me:

Code:
   -- only do FCREATE when the file doesn't exist!
    -- FCREATE deletes contents if exists
    hiscorefile = io.open("/hiscore", FCREATE)
    io.write(hiscorefile,0,"100",string.len("100"))
 
    score = 200
 
    text = io.read(hiscorefile,0,3)
 
    hiscore = tonumber(text)
    if (score > hiscore) then
        hsString = tostring(score)
     
        io.write(hiscorefile,0,hsString,string.len(hsString))
    end
    io.close(hiscorefile)
 
Last edited by 0x0wl,

dfsa3fdvc1

Well-Known Member
Member
Joined
Jan 3, 2015
Messages
226
Trophies
0
XP
214
Country
Albania
Really awesome development tool. I started writing a VNDS (Visual Novel DS) interpreter which when done would allow people to play dozens of popular visual novels on 3DS. Attached a screen of what it looks like right now in Citra.

Anyone have a pre-compiled CIA? I own a Gateway so I'd love to have a CIA. I read this entire thread and the posts suggesting using Makerom on the included .elf but I can't found any idiot proof guides on turning a .elf into a CIA. Knowing my luck any CIA made by me would screw up my entire EmuNAND...
NVM: Got it to compile and output a .cia using this awesome tutorial : )
EDIT: Shoot, I imported it into Gateway EmuNAND but it never showed up in my System Menu. Shows up in Software Management though. Oh well, the .3DS file seems to work. Well I need to change my code cause it threw an error I'd never seen on previous version but it works. Or just stick to the R2 release.

EDIT: Link to original DS version of VNDS for anyone intersted in learning more about VNDS.
 

Attachments

  • screenshot.png
    screenshot.png
    61.9 KB · Views: 396
Last edited by dfsa3fdvc1,
  • Like
Reactions: Hawxx and ihaveahax

Hawxx

New Member
Newbie
Joined
Aug 29, 2015
Messages
1
Trophies
0
XP
51
Country
Really awesome development tool. I started writing a VNDS (Visual Novel DS) interpreter which when done would allow people to play dozens of popular visual novels on 3DS. Attached a screen of what it looks like right now in Citra.

Anyone have a pre-compiled CIA? I own a Gateway so I'd love to have a CIA. I read this entire thread and the posts suggesting using Makerom on the included .elf but I can't found any idiot proof guides on turning a .elf into a CIA. Knowing my luck any CIA made by me would screw up my entire EmuNAND...
NVM: Got it to compile and output a .cia using this awesome tutorial : )
EDIT: Shoot, I imported it into Gateway EmuNAND but it never showed up in my System Menu. Shows up in Software Management though. Oh well, the .3DS file seems to work. Well I need to change my code cause it threw an error I'd never seen on previous version but it works. Or just stick to the R2 release.

EDIT: Link to original DS version of VNDS for anyone intersted in learning more about VNDS.
Holy crap dude, I recently decided that I wanted to get into making 3DS homebrew and a VN Interpreter was one of my first ideas, I was so surprised to see one is already in the works, and it looks pretty damn awesome too. Good luck with your project man, I'll definitely keep an eye on it! Also, is Lua good for making 3DS homebrew? I was looking around here to find what language is good for making homebrew and it looks like Lua could work pretty well.
 

ihaveahax

Well-Known Member
Member
Joined
Apr 20, 2015
Messages
6,069
Trophies
2
XP
7,827
Country
United States
Holy crap dude, I recently decided that I wanted to get into making 3DS homebrew and a VN Interpreter was one of my first ideas, I was so surprised to see one is already in the works, and it looks pretty damn awesome too. Good luck with your project man, I'll definitely keep an eye on it! Also, is Lua good for making 3DS homebrew? I was looking around here to find what language is good for making homebrew and it looks like Lua could work pretty well.
For simple projects (what defines simple depends), Lua is a good place to start. Take a look at an example here that I created.
 

dfsa3fdvc1

Well-Known Member
Member
Joined
Jan 3, 2015
Messages
226
Trophies
0
XP
214
Country
Albania
Also, is Lua good for making 3DS homebrew?

I originally wasn't a fan of Lua because it looks kind of weird compared to what I'm used to but it's fairly easy at least to get something running thanks to all the useful commands by the creator for handling images, audio, and text.
I also find lua much more well documented. Right now I'm copy/pasting off this page to help handle text strings and it's working great.

The interpreter will let you know where errors occur which for a beginner like me is absolutely necesssary.

You might want to start this project as well because I rarely actually finish projects, lol

EDIT: Quick question / heads up to anyone planning to do GPU rendering.
Anyone know if the GPU rendering supports .JPGs? Kept getting errors when trying to Graphics.drawImag() a GPU Texture loaded from a JPG but loaded from a PNG it works fine.
The latest commit to my uninformed eyes makes it look like imagescaling is going to be a thing which is awesome but w/o JPG support it looks like I won't be able to use GPU rendering.
EDIT2: I see some stuff like openjpg() which return a bitmap but IDK how to get it to work. I'm on the R2 version BTW.
 
Last edited by dfsa3fdvc1,

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 originally wasn't a fan of Lua because it looks kind of weird compared to what I'm used to but it's fairly easy at least to get something running thanks to all the useful commands by the creator for handling images, audio, and text.
I also find lua much more well documented. Right now I'm copy/pasting off this page to help handle text strings and it's working great.

The interpreter will let you know where errors occur which for a beginner like me is absolutely necesssary.

You might want to start this project as well because I rarely actually finish projects, lol

EDIT: Quick question / heads up to anyone planning to do GPU rendering.
Anyone know if the GPU rendering supports .JPGs? Kept getting errors when trying to Graphics.drawImag() a GPU Texture loaded from a JPG but loaded from a PNG it works fine.
The latest commit to my uninformed eyes makes it look like imagescaling is going to be a thing which is awesome but w/o JPG support it looks like I won't be able to use GPU rendering.
EDIT2: I see some stuff like openjpg() which return a bitmap but IDK how to get it to work. I'm on the R2 version BTW.

For R2 probably there are issue with GPU rendering for 24bpp images (and JPG are decoded always as 24bpp images).
I'm updating sf2dlib support with more function for GPU rendering and then i'll push a new official revision.
 

dfsa3fdvc1

Well-Known Member
Member
Joined
Jan 3, 2015
Messages
226
Trophies
0
XP
214
Country
Albania
For R2 probably there are issue with GPU rendering for 24bpp images (and JPG are decoded always as 24bpp images).
I'm updating sf2dlib support with more function for GPU rendering and then i'll push a new official revision.

Cool so I'm going back to software for now. Not a big deal as they share most of the same feature and my "game" is very static and unintensive.

EDIT: I think I found an answer to this big long question below so yeah, NVM. Detailed the answer at the very bottom

Can anyone diagnose what is wrong with my main loop in my game? I image.lua sample included with R2 as a base but clearly I'm doing something wrong because I've always gotten flickering with CPU rendered stuff. Same thing happened with the CPU rendered text in my GPU build (only images were GPU rendered and those didn't flicker) which telling me I have a poor understanding of how to construct a main loop for CPU rendered stuff. GPU stuff was fine though so I think I understood that.

The flickering: EDIT Click on the gif to see it animated
citra.gif

Sample of my main. The main is at the bottom of the quote and handlestr() is the function that is supposed to draw everything when needed. There's a bunch more functions in the full lua (see attached zip) but this is just a sample of the 2 most relevant parts.
function handlestr (currentline) --takes in currentline of game script and acts on it.
local wordlist = makewordlist(currentline);
if (wordlist[1] == "bgload") then
Screen.clear(TOP_SCREEN);
sprite = Screen.loadImage("/background/" .. wordlist[2]);
x = 40;
y = 0;
elseif (wordlist[1] == "setimg") then
x = 0; y = 0;
sprite = Screen.loadImage("/foreground/" .. wordlist[2]);
if(#wordlist == 4) then
x = wordlist[3];
y = wordlist[4];
end;
elseif (wordlist[1] == "text") then
writelinearray(linearr, currentline:gsub("text ",""));
FillScreen(black, "BOTTOM_SCREEN");
printlinearray(linearr);
end;
end;

i = 1;
while true do
Screen.waitVblankStart()
Screen.refresh()
pad = Controls.read()
if (Controls.check(pad,KEY_A)) then
;--System.exit()
end
if (Controls.check(pad,KEY_B)) and not (Controls.check(oldpad,KEY_B)) then
if (i < #lines) then --prevent crashes by not trying to read further than table's length
handlestr (lines);
i = i + 1;
else
System.exit()
end
end
Screen.drawImage(x,y,sprite,TOP_SCREEN)
Screen.flip()
oldpad = pad
end

Basically what I'm trying to get is a totally static image on screen and update only when the user presses 'A'.
Maybe I just don't understand how screenbuffers work but I want to keep display the screenbuffer and when the user presses 'A', the game executes one of 3 commands
'bgload' screenbuffer is cleared. image (Background image) is loaded and applied to the blank screenbuffer
'setimg' image (character portrait) is loaded and applied to screenbuffer
'text' the array of strings is updated, bottom screenbuffer is cleared, the string are applied to bottom screenbuffer


User error I'm sure and hopefully an easy fix. I feel like all of the pieces are there but there just in the wrong order.

Also attached my index.lua and all revelevant assets. Confirmed working on Citra and 3DS hardware. Just extract it to the root of SD card or /sdmc/

ANSWER: So the solution for what I was trying to do is apparently to write the image twice. I've heard the word "double-buffered" before when it comes to stuff like this. IDK, at least it work. Without the "double writing" of the image sometimes I would see one of the images disappear from the screen when the other was loaded. With "doublewrite" it seems to be locked in and behaving like I want it to.

My code
oldpad = Controls.read();

function doublewrite(x, y, filename)
local tempimage = Screen.loadImage(filename);
Screen.flip();
Screen.drawImage(x,y,tempimage,TOP_SCREEN);
Screen.refresh()
Screen.drawImage(0,0,tempimage,TOP_SCREEN);
end

Screen.refresh()
while true do
Screen.waitVblankStart()
pad = Controls.read();

if (Controls.check(pad,KEY_A)) and not (Controls.check(oldpad,KEY_A)) then
doublewrite(0,0,"/foreground/fumi01.png")
elseif (Controls.check(pad,KEY_B)) and not (Controls.check(oldpad,KEY_B)) then
doublewrite(0,0,"/foreground/saya08.png")
end

oldpad = pad;
end

GIF of Latest version in action (click to animate)
citra2.gif
 

Attachments

  • vnds.zip
    1 MB · Views: 217
Last edited by dfsa3fdvc1,

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
Cool so I'm going back to software for now. Not a big deal as they share most of the same feature and my "game" is very static and unintensive.

EDIT: I think I found an answer to this big long question below so yeah, NVM. Detailed the answer at the very bottom

Can anyone diagnose what is wrong with my main loop in my game? I image.lua sample included with R2 as a base but clearly I'm doing something wrong because I've always gotten flickering with CPU rendered stuff. Same thing happened with the CPU rendered text in my GPU build (only images were GPU rendered and those didn't flicker) which telling me I have a poor understanding of how to construct a main loop for CPU rendered stuff. GPU stuff was fine though so I think I understood that.

The flickering: EDIT Click on the gif to see it animated
View attachment 24165

Sample of my main. The main is at the bottom of the quote and handlestr() is the function that is supposed to draw everything when needed. There's a bunch more functions in the full lua (see attached zip) but this is just a sample of the 2 most relevant parts.


Basically what I'm trying to get is a totally static image on screen and update only when the user presses 'A'.
Maybe I just don't understand how screenbuffers work but I want to keep display the screenbuffer and when the user presses 'A', the game executes one of 3 commands
'bgload' screenbuffer is cleared. image (Background image) is loaded and applied to the blank screenbuffer
'setimg' image (character portrait) is loaded and applied to screenbuffer
'text' the array of strings is updated, bottom screenbuffer is cleared, the string are applied to bottom screenbuffer


User error I'm sure and hopefully an easy fix. I feel like all of the pieces are there but there just in the wrong order.

Also attached my index.lua and all revelevant assets. Confirmed working on Citra and 3DS hardware. Just extract it to the root of SD card or /sdmc/

ANSWER: So the solution for what I was trying to do is apparently to write the image twice. I've heard the word "double-buffered" before when it comes to stuff like this. IDK, at least it work. Without the "double writing" of the image sometimes I would see one of the images disappear from the screen when the other was loaded. With "doublewrite" it seems to be locked in and behaving like I want it to.

My code


GIF of Latest version in action (click to animate)
View attachment 24215

As you said, you have to blit twice your image calling Screen.refresh() between the two blits cause 3DS uses Double Buffering by default.
You can find an easy function to do this in Sunshell internal functions file (OneshotPrint): https://github.com/Rinnegatamante/Sunshell/blob/master/LUA/scripts/funcs.lua
 

ihaveahax

Well-Known Member
Member
Joined
Apr 20, 2015
Messages
6,069
Trophies
2
XP
7,827
Country
United States
This might have been stated before, but I couldn't find any information. I'm using a New 3DS XL 9.9.0-26U and ironhax.

I have a feeling the network module doesn't work, at least on ninjhax 2.x/ironhax/tubehax. It can never access any domains (both online like google.com and local), despite the 3DS always being connected to the Internet. I've set up a second 3DS and verified that I never went offline in the friends list. Am I missing something, or is it the homebrew launcher/the exploit and not lpp-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
This might have been stated before, but I couldn't find any information. I'm using a New 3DS XL 9.9.0-26U and ironhax.

I have a feeling the network module doesn't work, at least on ninjhax 2.x/ironhax/tubehax. It can never access any domains (both online like google.com and local), despite the 3DS always being connected to the Internet. I've set up a second 3DS and verified that I never went offline in the friends list. Am I missing something, or is it the homebrew launcher/the exploit and not lpp-3ds?

The issue is caused by NH2 code cause it seems to have some kind of problem with httpc service.
 
  • Like
Reactions: ihaveahax

dfsa3fdvc1

Well-Known Member
Member
Joined
Jan 3, 2015
Messages
226
Trophies
0
XP
214
Country
Albania
As you said, you have to blit twice your image calling Screen.refresh() between the two blits cause 3DS uses Double Buffering by default.
You can find an easy function to do this in Sunshell internal functions file (OneshotPrint): https://github.com/Rinnegatamante/Sunshell/blob/master/LUA/scripts/funcs.lua

Awesome, so one other thing I ran across is not being able to read a file line by line

So here's some lua code that runs on my PC and works each print read the next line in the file from the last read
file = "s02.txt";
k = io.open(file,FREAD)
print( k:read("*l") );
print( k:read("*l") );


Attempting this in Citra shows this error
screen.png

Now for the time being, I've been just running through the file and storing it into a long table and this works but for 1000+ line files it can take over a minute before it's done putting everything in a the table.

function fileToTable(file, outTable)
local i = 1;
for line in io.lines(file) do
outTable = line;
i = i + 1;
end
end;

testTable = {};
file = "/script/s02.scr";
fileToTable(file,testTable);
System.exit();

So any ideas of how to go line my line like that original code that runs fine on PC?

New screenshot of my interpreter in action.
Demo.png
 
Last edited by dfsa3fdvc1,

730

Professional Shitposter
Member
Joined
Apr 2, 2015
Messages
485
Trophies
0
XP
628
Country
Argentina
Is there a way for a script to not turn off sound when "suspended" (pressing HOME then closing)? I've seen this behavior occasionally on blargSNES, though I don't know if it's a bug or a feature, and it's pretty random, sometimes it happens others it doesn't.
 
Last edited by 730,

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 a way for a script to not turn off sound when "suspended" (pressing HOME then closing)? I've seen this behavior occasionally on blargSNES, though I don't know if it's a bug or a feature, and it's pretty random, sometimes it happens others it doesn't.

Suspending 3DS cause some different bugs, probably is NH fault or some libctru missing setting.

Awesome, so one other thing I ran across is not being able to read a file line by line

So here's some lua code that runs on my PC and works each print read the next line in the file from the last read



Attempting this in Citra shows this error
View attachment 24272

Now for the time being, I've been just running through the file and storing it into a long table and this works but for 1000+ line files it can take over a minute before it's done putting everything in a the table.



So any ideas of how to go line my line like that original code that runs fine on PC?

New screenshot of my interpreter in action.
View attachment 24275

Have you tried Console module? (if you want to know how to use it, Sunshell filebrowser uses it for TXT files and SMDH infos: https://github.com/Rinnegatamante/Sunshell/blob/master/LUA/modules/fb.lua
 
  • Like
Reactions: dfsa3fdvc1

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
Started working on a complete PC IDE for lpp-3ds projects with the help of NaNNi.

Final release will have:

- Multi-script projects support
- Syntax higlighting
- Auto-completation
- Auto-tabulation
- Script debugging feature with Citra
- Script compiling option with luaC
- CIA, 3DS and SMDH creation for your projects

Don't know where it will be ready, repository if you want to help is here (it will be populated soon): https://github.com/Rinnegatamante/lpp-ide
Used language is VB2015.

ide.png
 
Last edited by Rinnegatamante,

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
Decided to add to the IDE also a Dark Theme for nocturnal devs to not stress eyes.

Anyway, slight progress with the IDE, here you are a screenshot of current stage (Compiler, Syntax Higlighting, Opening/Saving/Creating Projects is what works correctly for now):
ide2.png
 

sarkwalvein

There's hope for a Xenosaga port.
Member
Joined
Jun 29, 2007
Messages
8,508
Trophies
2
Age
41
Location
Niedersachsen
XP
11,232
Country
Germany
Decided to add to the IDE also a Dark Theme for nocturnal devs to not stress eyes.

Anyway, slight progress with the IDE, here you are a screenshot of current stage (Compiler, Syntax Higlighting, Opening/Saving/Creating Projects is what works correctly for now):
-snip-
Suggestion for the IDE: online help.
Go to a specific function or keyword specific in your code, then press F1 and automatically open the corresponding Doxygen page (as Doxygen docs are still not available, link everything to this).
Also provide in the Help menu a link to the Lua Reference Manual regarding the language, because, why not?
 
  • Like
Reactions: Rinnegatamante

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    HiradeGirl @ HiradeGirl: Have a nice day. Life. Week. Month. year.