Joined: 1/26/2009
Posts: 558
Location: Canada - Québec
I give your script a try with FCEUX, while playing back a movie... but nothing seem to happen when I press "enter" or any key. Maybe I'm doing something wrong?
Editor, Skilled player (1202)
Joined: 9/27/2008
Posts: 1085
BadPotato wrote:
I give your script a try with FCEUX, while playing back a movie... but nothing seem to happen when I press "enter" or any key. Maybe I'm doing something wrong?
After starting the script, at least one frame needs to play in FCEUX for anything to appear. Beyond that, the default controls should let control+LeftClick create a new script-based subtitle. FCEUX has its own built-in subtitles, but this script does not work with that in particular. If you mean another script (I believe it's subtitler.lua as part of the FCEUX package), let me know if it's that instead.
Joined: 1/26/2009
Posts: 558
Location: Canada - Québec
Ok, I managed to get FCEUX working with the lastest version. Some feedback: As you said, it pretty much became an emu/editor with basic feature and this look great! I think your script deserve more attention. I tried the script with some other emulator and it's works almost perfectly with pcsxrr and the "RunWhilePaused" mode (in fact, it just add some unnecessary space as you write text but the pause is working pretty good). FBArr and gens(thought gens doesn't support the pause feature) are a bit offtrack to follow up the cursor and Psxjin has issue for drawing the box and cursor. Note: For making those emulator I just switch the "elseif FCEU", by the emulator name of the script above. Despite that I guess that more feature like a "delete" hotkey to get along with backspace or maybe somekind of basic hud interface would be awesome. Also, for the emulator without the pause feature support, I think that the DarkKolbold popup idea could be good. There's probably some other lua extension module that could do it. As for the rendering output(to match with your filename.lua), sometime the gui.text() font feel a bit crappy. I've been wondering how hard it would be to write a library that could load some font and draw the text, but this seem a bit off lua limit. Anyway, I know that currently it became a bit an old project of your, but do you plan to keep improving it ?
Editor, Skilled player (1202)
Joined: 9/27/2008
Posts: 1085
BadPotato wrote:
Ok, I managed to get FCEUX working with the lastest version.
Great! Nice to know this script is capable.
BadPotato wrote:
Some feedback: As you said, it pretty much became an emu/editor with basic feature and this look great! I think your script deserve more attention.
It is good to know I'm getting feedback, even if I only get it long after I've released this script to the public in this thread. It's quite a capable text editor, indeed.
BadPotato wrote:
I tried the script with some other emulator and it's works almost perfectly with pcsxrr and the "RunWhilePaused" mode (in fact, it just add some unnecessary space as you write text but the pause is working pretty good). FBArr and gens(thought gens doesn't support the pause feature) are a bit offtrack to follow up the cursor and Psxjin has issue for drawing the box and cursor.
I'm surprised on how many emulators it works in. I only have tried a small handful, yet I produced a script that works decently in others. I intended for it to be general-purpose, and I'm glad it reaches beyond what I can test myself. As for the cursor/box wandering where the text isn't displayed, as though the offsets weren't set correctly, there's no way I could possibly guess the text width properly. If the emulators use fixed-width text, then find the WID near the top of the script and adjust that little number you see there. If they use variable-width text, it is impossible for me to have the display match up with the emulator's text. Not without knowing the specific width of each character. In that particular case, I would be rather encouraged to abuse other graphical functions (say, pixels and lines) in order to create my own custom text from the lua side.
BadPotato wrote:
Note: For making those emulator I just switch the "elseif FCEU", by the emulator name of the script above.
Not sure where in particular you mean.
BadPotato wrote:
Despite that I guess that more feature like a "delete" hotkey to get along with backspace or maybe somekind of basic hud interface would be awesome. Also, for the emulator without the pause feature support, I think that the DarkKolbold popup idea could be good. There's probably some other lua extension module that could do it.
Any ideas in mind for the interface? Some thoughts that do come to mind would be to display things like start or end frames of current subtitle. Which I miraculously fail to implement. As it stands, one can drag subtitles around, select them, and edit them. Though some of it feels unintuitive when I finally cracked open this script.
BadPotato wrote:
As for the rendering output(to match with your filename.lua), sometime the gui.text() font feel a bit crappy. I've been wondering how hard it would be to write a library that could load some font and draw the text, but this seem a bit off lua limit.
I'm sure it's possible. Even if it means a dozen calls to gui.pixel per character, I see no reason why it can't work. If the emulator has some capacity of putting an image on the window, like gui.gdoverlay, I could create a table of strings that represent every character. The construction would probably be pretty slow, but once everything's loaded, it would have my own images efficiently painted on. I hope.
BadPotato wrote:
Anyway, I know that currently it became a bit an old project of your, but do you plan to keep improving it ?
I had no plans before this day, mainly due to the fact I forgot it existed. Your posts may have revived some of my interests in this old script, but still no solid plans, I must say.
Editor, Skilled player (1202)
Joined: 9/27/2008
Posts: 1085
Made a new subtitle script. Feel free to download. This is an auxiliary script. I recommend making a new lua file that includes a dofile("SubtitleDisplayer.lua") somewhere near the beginning. This way, all the subtitling you want is in one file and the actual code that does the work doesn't clutter your subtitle file. It now allows out-of-order subtitling. That is, you don't need to worry about keeping all the start frames of the subtitles in ascending order in your subtitles file. Download SubtitleDisplayer.lua
Language: lua

--Aids in displaying lua-based subtitles --FatRatKnight --S(start,end,left,top,line1, line2, ..., lineN) --Subtitle. Displays text --B(start,end,left,top,right,bottom,FillColor,BorderColor) --Box. Paints a colored box at selected area. --R1U(start,end,left,top,text,address) --ReadAddress. Displays one line of text and displays value at address. --Full list of related functions: R1U, R2U, R4U, R1S, R2S, R4S --A(start,end,left,top,FillColor,BorderColor, line1, line2, ..., lineN) --Auto Box&Subtitle. Displays text and a text-fitting box around it. --Additionally, I provide a lowercase letter version of each function. --The end parameter for lowercase is relative to start, so inserting 300 there --means that the subtitle will last 300 frames. Additionally, lowercase also --makes the box routine ask for width and height instead of right-side and --bottom-side. --The R#U and R#S functions need to be fully lowercase. r1U will fail. --But r1u will work just fine. local Subbies= {} local WID= 6 -- Width of each character. DeSmuME uses 6. local HGT= 9 -- Height. I'm arbitrarily using 9 here. if stylus then --DeSmuME. Platform: DS WID= 6; HGT= 9 elseif snes9x then --Snes9x. Platform: SNES WID= 4; HGT= 8 elseif vba then --VisualBoy Advance. Platforms: GBA, GB, GBC, SGB WID= 4; HGT= 8 elseif FCEU then --FCE Ultra / FCEUX. Platform: NES. WID= 2; HGT= 9 end -- Array based functions. --############################################################################# --***************************************************************************** local function DispMsg(T) --***************************************************************************** for i= 1, #T do gui.text(T.x,T.y+HGT*(i-1),T[i],T.c1,T.c2) end end --***************************************************************************** local function DispAddr(T) --***************************************************************************** gui.text(T.x,T.y, string.format(T.txt, T.rv(T.v)) , T.c1,T.c2) end --***************************************************************************** local function DispBox(T) --***************************************************************************** gui.box(T.x,T.y,T.x2,T.y2 , T.c1,T.c2) end --############################################################################# local CurrentIndex= 1 local ActiveSubs= {} --***************************************************************************** local function HandleArray() --***************************************************************************** -- I'll leave the intelligence of add/removal here. --Add while Subbies[CurrentIndex] and (Subbies[CurrentIndex].t <= movie.framecount()) do table.insert(ActiveSubs,Subbies[CurrentIndex]) CurrentIndex= CurrentIndex+1 end --Execute/remove local i= 1 while ActiveSubs[i] do if ActiveSubs[i].e >= movie.framecount() then ActiveSubs[i]:fn() i= i+1 else table.remove(ActiveSubs,i) end end end --***************************************************************************** local function ResetArray() --***************************************************************************** CurrentIndex= 1 ActiveSubs= {} end --***************************************************************************** local function AddToSubbies(T) --***************************************************************************** for i= #Subbies, 1, -1 do if T.t >= Subbies[i].t then table.insert(Subbies,i+1,T) return -- Escape, as we have inserted it! end end table.insert(Subbies,1,T) -- If we go here, the loop failed to insert. end --############################################################################# --############################################################################# -- [S]ubtitle -- Can take an arbitrary number of lines -- Its name is one letter long to save bytes. Lots of them. --***************************************************************************** function S(start,End , left,top , ...) --***************************************************************************** -- This is a CAPITAL S. Use absolutes. if arg.n <= 0 then return end -- Sanity; Must have text! local NewSub= { fn= DispMsg, t= start, e= End, x= left, y= top } for i= 1, arg.n do NewSub[i]= arg[i] end AddToSubbies(NewSub) end --***************************************************************************** function s(start,length , left,top , ...) --***************************************************************************** -- Lowercase s. Use relatives where it makes sense (frame end is it). if arg.n <= 0 then return end -- Sanity; Must have text! local NewSub= { fn= DispMsg, t= start, e= start+length, x= left, y= top } for i= 1, arg.n do NewSub[i]= arg[i] end AddToSubbies(NewSub) end --***************************************************************************** local function ReadMem(start,End , left,top , str,addr , NewFn) --***************************************************************************** -- Not for end-user; Call the R#U/S series instead! -- The usual start,end,left,top applies AddToSubbies{ fn= DispAddr, t= start, e= End, x= left, y= top, txt= str, v= addr, rv= NewFn } end --============================================================================= function R1U(start,End , x1,y1 , str,addr) ReadMem(start,End , x1,y1 , str,addr , memory.readbyteunsigned) end function R2U(start,End , x1,y1 , str,addr) ReadMem(start,End , x1,y1 , str,addr , memory.readwordunsigned) end function R4U(start,End , x1,y1 , str,addr) ReadMem(start,End , x1,y1 , str,addr , memory.readdwordunsigned) end function R1S(start,End , x1,y1 , str,addr) ReadMem(start,End , x1,y1 , str,addr , memory.readbytesigned) end function R2S(start,End , x1,y1 , str,addr) ReadMem(start,End , x1,y1 , str,addr , memory.readwordsigned) end function R4S(start,End , x1,y1 , str,addr) ReadMem(start,End , x1,y1 , str,addr , memory.readdwordsigned) end function r1u(start,length , x1,y1 , str,addr) ReadMem(start,start+length , x1,y1 , str,addr , memory.readbyteunsigned) end function r2u(start,length , x1,y1 , str,addr) ReadMem(start,start+length , x1,y1 , str,addr , memory.readwordunsigned) end function r4u(start,length , x1,y1 , str,addr) ReadMem(start,start+length , x1,y1 , str,addr , memory.readdwordunsigned) end function r1s(start,length , x1,y1 , str,addr) ReadMem(start,start+length , x1,y1 , str,addr , memory.readbytesigned) end function r2s(start,length , x1,y1 , str,addr) ReadMem(start,start+length , x1,y1 , str,addr , memory.readwordsigned) end function r4s(start,length , x1,y1 , str,addr) ReadMem(start,start+length , x1,y1 , str,addr , memory.readdwordsigned) end --============================================================================= -- [B]ox --***************************************************************************** function B(start,End , left,top , right,bottom , cf,cb) --***************************************************************************** AddToSubbies{ fn= DispBox, t= start, e= End, x= left, y= top, x2= right, y2= bottom, c1= cf, c2= cb } end --***************************************************************************** function b(start,length , left,top , width,height , cf,cb) --***************************************************************************** AddToSubbies{ fn= DispBox, t= start, e= start+length, x= left, y= top, x2= left+width, y2= top+height, c1= cf, c2= cb } end -- [A]uto -- Boxes and subtitles, wrapped in one. -- Calculates the box size for you! --***************************************************************************** function A(start,End , left,top , cf,cb , ...) --***************************************************************************** if arg.n <= 0 then return end -- Sanity local NewSub= { fn= DispMsg, t= start, e= End, x= left, y= top } local len= 0 for i= 1, arg.n do NewSub[i]= arg[i] len= math.max(len, string.len(arg[i])) end B(start,End , left-1,top-1 , left+len*WID,top+arg.n*HGT, cf,cb) AddToSubbies(NewSub) end --***************************************************************************** function a(start,length , left,top , cf,cb , ...) --***************************************************************************** if arg.n <= 0 then return end -- Sanity local NewSub= { fn= DispMsg, t= start, e= start+length, x= left, y= top } local len= 0 for i= 1, arg.n do NewSub[i]= arg[i] len= math.max(len, string.len(arg[i])) end B(start,start+length , left-1,top-1 , left+len*WID,top+arg.n*HGT, cf,cb) AddToSubbies(NewSub) end --############################################################################# --############################################################################# local LastFC= 0 --***************************************************************************** local function FrameCountSanity() --***************************************************************************** local FC= movie.framecount() if FC < LastFC then ResetArray() end LastFC= FC end --***************************************************************************** local function HandleSubs() --***************************************************************************** FrameCountSanity() HandleArray() end gui.register(HandleSubs)