1 2 3 4 5 6 7 8
Skilled player (1882)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
Ok, I think I got it to work, thanks alden. :)
Joined: 7/2/2007
Posts: 3960
"CSV" means "Comma-Separated Value", and it just means a standard text file where each line in the file is one row in the sheet, and each cell is separated by a comma. It's possible that Excel defaults to thinking that the tab character is the delimiter instead of the comma (tab is a better delimiter...but "comma" is in the bloody extension!); IIRC if you use the "import file" option you'll be able to set what the delimiter is. EDIT: too slow.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
Post subject: Reading CPU state & breakpoints in LUA
Active player, Editor (296)
Joined: 3/8/2004
Posts: 7468
Location: Arzareth
Many of my bots on FCEU have breakpoint handlers such that if the CPU happens to execute e.g. ROM location A56C, the value of the CPU register A can be captured into a variable, and used by the bot. This can be used to determine various things, from success in performing a glitch, to identifying an item that was just picked up. Now, how do I do that in FCEUX and LUA? (I've presented this question years ago and it was without a solution back then, but I imagine emulator technology has improved by heaps since then!) EDIT: It indeed has! Congratulations to all programmers. So, replying to myself for others' benefit:
memory.registerexec(0xC4D0, function()
    FCEU.message( "Acquired item " .. memory.getregister("A") )
  end)
Which can be rewritten as:
CPU=setmetatable({}, {__index=function(t,k) return memory.getregister(k) end })

memory.registerexec(0xC4D0, function()
    FCEU.message( "Acquired item " .. CPU.A )
  end)
Post subject: Include files in LUA?
Active player, Editor (296)
Joined: 3/8/2004
Posts: 7468
Location: Arzareth
So if I have a library of common functions, how do I #include it in LUA? Ah, that is dofile. Thanks Ilari and LUA manual :)
Post subject: Collection of bugs I found just by using fceux
Active player, Editor (296)
Joined: 3/8/2004
Posts: 7468
Location: Arzareth
This looks like a bug in sdl/input.cpp. g_config->getOption("SDL.Hotkeys.Pause", &bindStateKey); Should be: g_config->getOption("SDL.Hotkeys.BindState", &bindStateKey); ---- Here's my script.
local a=savestate.create(1)
savestate.load(a)
And here's how I start it:
fceu/fcx2 --loadlua test.lua game.nes
And fceux crashes. What am I doing wrong? Shouldn't the ensureLoad() method of LuaSaveState in lua-engine.cpp be called at some point? ---- fceulua.h defines FCEU_LuaFrameskip() yet in lua-engine.cpp it is FCEU_LuaFrameSkip(). Neither of which have any meaning -- they're never used anywhere. And hence, choosing the speedmode "maximum" has no effect!
Skilled player (1882)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
I often use lists of the form
u={[0]=1,4,5,2,4,3}
Is there a command that fetches the length of this list? In my example above, the length would be 6. I've tried commands like "length" and "size", but they don't seem to work. I looked around on google, but didn't find anything.
Joined: 10/3/2005
Posts: 1332
You might already know about the length operator:
print(#u)
In your example, #u is 5 probably because Lua begins counting from 1, and stops when it hits nil. You'll also find that this happens:
local u = {1, 2, [42]=3, 4}
print(#u) -- => 3
Index 42 exists, but is ignored because index 4 is nil. I guess it's for efficiency. You can define your own length function like so:
function getLen(tbl)
    local len = 0
    for i in pairs(u) do len = len + 1; end
    return len
end
...So that getLen(u) returns 6.
Skilled player (1882)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
I actually wasn't aware of the length operator, so thanks again Dromiceius, you're very helpful as always. :) With this information, I now present my "Pi music script" - run this script on the "NES Test cart" ROM when in the controller test mode - it will play up the decimals of pi, with each decimal corresponding to a joypad input - you can change the value of the variable "length" to vary how many frames the notes will play. Because there are 10 digits but only 8 buttons, I assigned digits 0 and 9 to controller 2. So if you have ever wondered what pi sounds like in music format, you can now find out:
pi ={[0]
=1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5,0,2,8,8,4,1,9,
7,1,6,9,3,9,9,3,7,5,1,0,5,8,2,0,9,7,4,9,4,4,5,9,2,3,0,7,8,1,6,4,0,6,2,8,6,2,0,
8,9,9,8,6,2,8,0,3,4,8,2,5,3,4,2,1,1,7,0,6,7,9,8,2,1,4,8,0,8,6,5,1,3,2,8,2,3,0,
6,6,4,7,0,9,3,8,4,4,6,0,9,5,5,0,5,8,2,2,3,1,7,2,5,3,5,9,4,0,8,1,2,8,4,8,1,1,1,
7,4,5,0,2,8,4,1,0,2,7,0,1,9,3,8,5,2,1,1,0,5,5,5,9,6,4,4,6,2,2,9,4,8,9,5,4,9,3,
0,3,8,1,9,6,4,4,2,8,8,1,0,9,7,5,6,6,5,9,3,3,4,4,6,1,2,8,4,7,5,6,4,8,2,3,3,7,8,
6,7,8,3,1,6,5,2,7,1,2,0,1,9,0,9,1,4,5,6,4,8,5,6,6,9,2,3,4,6,0,3,4,8,6,1,0,4,5,
4,3,2,6,6,4,8,2,1,3,3,9,3,6,0,7,2,6,0,2,4,9,1,4,1,2,7,3,7,2,4,5,8,7,0,0,6,6,0,
6,3,1,5,5,8,8,1,7,4,8,8,1,5,2,0,9,2,0,9,6,2,8,2,9,2,5,4,0,9,1,7,1,5,3,6,4,3,6,
7,8,9,2,5,9,0,3,6,0,0,1,1,3,3,0,5,3,0,5,4,8,8,2,0,4,6,6}

m=pi

n=0
length=12
c=length

d="3."

while n<=#m do

key1={}
key2={}

u=m[n]

if c==0 then n=n+1 c=length d= d .. u end
c=c-1

if u==1 then key1.A=1 end
if u==2 then key1.B=1 end
if u==3 then key1.start=1 end
if u==4 then key1.select=1 end
if u==5 then key1.left=1 end
if u==6 then key1.up=1 end
if u==7 then key1.right=1 end
if u==8 then key1.down=1 end
if u==9 then key2.A=1 end
if u==0 then key2.B=1 end

joypad.set(1,key1)
joypad.set(2,key2)

gui.text(10,18,"Tone length: " .. length)
gui.text(10,26,"Number: " .. d)

   FCEU.frameadvance()
end
Player (208)
Joined: 7/7/2006
Posts: 797
Location: US
I wonder if this would be a semi-effective way to memorize the digits. I'm sure I'm not the only one here who has memorized digits for no apparent reason. (I have 50 memorized, I'd bet multiple people on the site have over 100 memorized.)
Skilled player (1882)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
Hehe, nope, I once had around 200 memorized. :) Now I have around 40 or so memorized, so perhaps I should try and learn the tune that this script plays. ;)
Post subject: Re: Reading CPU state & breakpoints in LUA
Banned User
Joined: 12/23/2004
Posts: 1850
Bisqwit wrote:
Many of my bots on FCEU have breakpoint handlers such that if the CPU happens to execute e.g. ROM location A56C, the value of the CPU register A can be captured into a variable, and used by the bot. This can be used to determine various things, from success in performing a glitch, to identifying an item that was just picked up. Now, how do I do that in FCEUX and LUA? (I've presented this question years ago and it was without a solution back then, but I imagine emulator technology has improved by heaps since then!) EDIT: It indeed has! Congratulations to all programmers. So, replying to myself for others' benefit:
memory.registerexec(0xC4D0, function()
    FCEU.message( "Acquired item " .. memory.getregister("A") )
  end)
Wow, registerexec exists now? Wonderful, given that's the only way to tell what a game is doing sometimes. I need to check if some of the other functions still maim FCEUX.
Perma-banned
Post subject: Re: Collection of bugs I found just by using fceux
Emulator Coder
Joined: 8/12/2008
Posts: 42
Bisqwit wrote:
This looks like a bug in sdl/input.cpp. g_config->getOption("SDL.Hotkeys.Pause", &bindStateKey); Should be: g_config->getOption("SDL.Hotkeys.BindState", &bindStateKey); ---- Here's my script.
local a=savestate.create(1)
savestate.load(a)
And here's how I start it:
fceu/fcx2 --loadlua test.lua game.nes
And fceux crashes. What am I doing wrong? Shouldn't the ensureLoad() method of LuaSaveState in lua-engine.cpp be called at some point? ---- fceulua.h defines FCEU_LuaFrameskip() yet in lua-engine.cpp it is FCEU_LuaFrameSkip(). Neither of which have any meaning -- they're never used anywhere. And hence, choosing the speedmode "maximum" has no effect!
Could you post your test.lua script? I'm working on fleshing out some issues with SDL and lua.
** FceuX SDL Developer/Maintainer ** get the latest source http://sourceforge.net/p/fceultra/code/
Emulator Coder, Player (68)
Joined: 10/4/2005
Posts: 197
I'm trying to get used to lua scripting, and I wrote a basic script to switch to turbo speed for any lagged frames, and back to normal speed for any other frames.
while (true) do
  if (FCEU.lagged()) then
    FCEU.speedmode("turbo");
    gui.text(0, 0, "LAGGED!");
  else
    FCEU.speedmode("normal");
    gui.text(0, 0, "       ");
  end;
  FCEU.frameadvance();
end;
It does switch to turbo when a lagged frame is detected, but it doesn't switch back after the lagged frames are over. Also, "emulation speed 100%" stays on screen all the time. What am I doing wrong, and is there a better way to do that?
Banned User
Joined: 12/23/2004
Posts: 1850
Setting the speedmode to normal (regardless of previous settings) will make the message pop up. Use a variable to track what it was last set to, and only set it if it changes. As for why it doesn't change back, I can't begin to guess.
Could you post your test.lua script?
Bisqwit pretty clearly indicated that this was the script he was testing:
local a=savestate.create(1) 
savestate.load(a)
Perma-banned
Joined: 10/3/2005
Posts: 1332
I have one guess as to why the else clause never executes: FCEU.lagged() returns false instead of nil on a lag frame. Try "if FCEU.lagged ~= false then" ...maybe?
Banned User
Joined: 12/23/2004
Posts: 1850
False and nil are the same in Lua.
Perma-banned
adelikat
He/Him
Emulator Coder, Expert player, Site Developer, Site Owner (3581)
Joined: 11/3/2004
Posts: 4736
Location: Tennessee
Go with what Dromecious, Nil and false are indeed different values in lua.
It's hard to look this good. My TAS projects
Joined: 10/3/2005
Posts: 1332
Actually, I'm pretty sure I was wrong. False and nil are not equal, but both will evaluate not-true in an if statement. I got confused because I remembered having trouble with false being treated as true in some capacity... possibly joypad.set rather than anything in Lua proper.
Emulator Coder, Player (68)
Joined: 10/4/2005
Posts: 197
Dromiceius wrote:
I have one guess as to why the else clause never executes: FCEU.lagged() returns false instead of nil on a lag frame. Try "if FCEU.lagged ~= false then" ...maybe?
The weird thing is, the else clause does execute, but only the gui.text line. I did however try messing with different combinations of false and nil, and == vs ~=, with no luck. Does this run correctly for anyone?
Joined: 9/8/2006
Posts: 19
It appears that it is running the else clause in its entirety. This is why it says "emulation speed 100%" every frame. The reason it seems like it's not working is that it's also setting it to turbo every frame for some reason. I noticed while messing around with the script that the pitch of the audio got even higher when I commented out the normal speedmode function. EDIT: The problem is all in the turbo, it seems. Change it to "nothrottle", which according to the documentation is the same as turbo, and it works fine. That's all.
Banned User
Joined: 12/23/2004
Posts: 1850
adelikat wrote:
Go with what Dromecious, Nil and false are indeed different values in lua.
As he said, for the purposes of if (value), false and nil are equivalent (return false), which was what I meant.
Perma-banned
Emulator Coder
Joined: 8/12/2008
Posts: 42
Has anyone managed to get the iup lua libraries to work in linux? LUA works fine in linux but the iups are hell to install/configure. I can't even get them to work. And i'm the fceuX-SDL dev xfd
** FceuX SDL Developer/Maintainer ** get the latest source http://sourceforge.net/p/fceultra/code/
Post subject: Well, that doesn't sound too difficult.
Joined: 10/3/2005
Posts: 1332
Tried running the example script "MemoryWatch.lua", packaged with the emulator. First it told me it couldn't find "auxlib", but it was looking in a relative path where it couldn't possibly find it. Had to move it to /usr/local/share/lua/5.1, but then it worked. Next: "module 'libiuplua51' not found". Sure enough, I need to install that. Grepped the docs for an appropriate version, but no info found. Googled for "lua iup". Grabbed source. All the files have their executable flag set. Always a good sign, that. Build is quite broken, missing, among other things, "cdiup.h". It looks like someone's going to have to submit patches to bring the Linux build up to speed, since finding a quick workaround seems like a stupid idea, if it's even possible. I didn't fare any better using the Linux binaries than I did with the source. I "installed" the SOs and other IUP files until FCEUX stopped complaining about missing files, but then it complained about undefined symbols. I tried one of IUP's example scripts to more or less the same result.
Editor, Skilled player (1158)
Joined: 9/27/2008
Posts: 1084
I saw this topic and thought, since FCEUX has a gui.register that can run while the emulation is paused, why not have a function that can act like input.registerhotkey?
local hotkeys= {}
local keys= input.get()  --Should have an initial value
local lastkeys= keys
--*****************************************************************************
local function luahotkey(hotkey,func)
--*****************************************************************************
-- To act in place of input.registerhotkey where gui.register can run while
-- emulation is paused.
-- Returns whatever function that once occupied the specified hotkey.

    local dumpedfunction= hotkeys[hotkey]
    hotkeys[hotkey]= func
    return dumpedfunction
end



--*****************************************************************************
local function scanhotkeys()
--*****************************************************************************
-- The actual function to process each registered key.
-- Use gui.register(scanhotkey) or something similar to let it work its magic.

    lastkeys= keys
    keys= input.get()
    for key, junk in pairs(keys) do
        if (hotkeys[key]) and (not lastkeys[key]) then
            hotkeys[key]()
        end
    end
end
gui.register(scanhotkeys)



-- Junk code. Just to test the hotkey formula.

luahotkey("space",function()   gui.text(1,1,"Space, the final frontier") end)
luahotkey("Z",    function()   gui.text(1,4,"That's a Z button.") end)

while true do
    gui.pixel(0,0,"clear")
    emu.frameadvance()
end
Run it. Pause emulation. Hit one of the two buttons I keyed up. Observe. It might help organize some of my scripts to something easier to read when I can package my hotkeys separate from my main gui.register code.
Skilled player (1882)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
I'm wondering, is it possible write a lua script that only performs some commands when a movie is playing? I mean something like this:
while (movie is playing)
(commands)
end
And while we're at it, is there a way to get the length of a movie? I know movie.framecount() gives the frame that is currently playing, but I don't know how to fetch the actual length of the movie that is playing.
1 2 3 4 5 6 7 8