1 2 3
7 8
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
Trying to read and write a joypad to "hook" buttons.
	joy			= joypad.read(1);
	if joy["select"] then 
		joy["select"]	= nil;
		joypad.set(1, joy);
	end;
This sometimes works. It's like the game thinks that the select button is constantly being pressed ala turbofire... so I can't get it to work at all. Any help is greatly appreciated; the manual isn't helpful either in that it uses "joypad.write" (when it's joypad.set)
Perma-banned
Player (120)
Joined: 2/11/2007
Posts: 1522
Xkeeper wrote:
Trying to read and write a joypad to "hook" buttons.
	joy			= joypad.read(1);
	if joy["select"] then 
		joy["select"]	= nil;
		joypad.set(1, joy);
	end;
This sometimes works. It's like the game thinks that the select button is constantly being pressed ala turbofire... so I can't get it to work at all. Any help is greatly appreciated; the manual isn't helpful either in that it uses "joypad.write" (when it's joypad.set)
I believe joypad.set sets the input for the next frame and joypad.read only works on buttons that have already been sent to the emulator... so it has to register you actually pressing select for a frame, which eliminates select for the next frame (and also eliminates any different player input for the next frame... for example you press select and A, the next frame you press just B but it will show just A) Since that next frame doesn't have select, it reads from the keyboard again. I would suggest reading select (or another button) on the second joypad. There might be a way to do what you are attempting but the second joypad will probably be easier :)
I make a comic with no image files and you should read it. While there is a lower class, I am in it, and while there is a criminal element I am of it, and while there is a soul in prison, I am not free. -Eugene Debs
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
D'oh. Well, even in that case, wouldn't it stop accepting any input at all? (I moved the joypad.set out of the if loop later.) If it was based on the next frame, it would read this frame's input, then write it for the next frame infinitely. But that isn't the observed action; Select acts on a one-frame turbo. Using the 2P select won't work as well, since the intended feature is to replace the in-game Select operation with something else. Now if there was a way to have, say, a function called in Lua before the frame was beginning to be emulated, then that would be nice. e.g., run preframe(), then execute the frame, then return to the main Lua loop. That way input could be intercepted before the game got ahold of it, allowing better interception of player input.
Perma-banned
Player (120)
Joined: 2/11/2007
Posts: 1522
Yes, if it's out of the if block it basically would not take input. Except for changing the implementation to do as you suggest (have a brief period where Lua could see what you were trying to push and change it before the emulator sees it), using the second controller is really the only option. You just need to warn people to set Select on the second controller and use that (you could even rebind your keys temporarily). In a perfect world, I'd love to see input from the full keyboard instead of just from controllers :)
I make a comic with no image files and you should read it. While there is a lower class, I am in it, and while there is a criminal element I am of it, and while there is a soul in prison, I am not free. -Eugene Debs
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
Yes, if it's out of the if block it basically would not take input.
I'm not sure what you mean here -- if the code is being run once every frame, then wouldn't it stop any input at all from going though (infinite write/read loop?) The thing is, that isn't waht I'm observing with joypad.set(); it does take input, though it "flickers" in a turbo-state. Hopefully there can be a way to register a Lua function to occur any time something happens... it might be possible to intercept the actual writing of the joypad byte in memory if the register function works as I think it does (and runs when it is written, not at the end of a frame).
Perma-banned
Player (120)
Joined: 2/11/2007
Posts: 1522
If it's set in the if block, then it only sets every other frame, because the next frame will not have select and will not go into the if block. Don't know if that's any clearer.
I make a comic with no image files and you should read it. While there is a lower class, I am in it, and while there is a criminal element I am of it, and while there is a soul in prison, I am not free. -Eugene Debs
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
alden wrote:
If it's set in the if block, then it only sets every other frame, because the next frame will not have select and will not go into the if block.
Yeah, that makes more sense. The problem is that it exibited that behavior after I moved it out of the block, so it would've been writing every frame. (Should've made that clearer, as well.) Edit: Strange. After simply making a test case:
	joy			= joypad.read(1);
	if joy["select"] then 
		gui.popup("Select button pushed");
	end;

	joy["select"]	= nil;
	joypad.set(1, joy);
...the behavior is no longer aparrent. It simply ceases accepting input, as expected (though not desired). Seems to have been a phantom bug.
Perma-banned
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
Hm; well, this works for Valkyrie no Bouken, so feel free to test it:
function stuff()
	gui.text(8, 8, string.format("%02X", memory.readbyte(0x0026)));
	memory.writebyte(0x0026, AND(memory.readbyte(0x0026), 0xFB));
end;

memory.register(0x0026, stuff);

while (true) do
	FCEU.frameadvance();
end;
This will intercept writes to the controller address and change them on its own, to remove "Select". This can be tested easily (the cursor won't move on the title screen). As for it being "slow", it might be a better idea to figure out how breakpoints in the debugger work, and then using that system for Lua. (In fact, you could even have a "Lua registers" list, that could be changed/disabled on the fly via it!) ... This solution should work on any game, and allows much easier interception of the controller... the only problem is that you can't "set" keys unless the player themselves is actually doing something, since it won't fire otherwise.
Perma-banned
Post subject: "Real" Rewinding
Player (120)
Joined: 2/11/2007
Posts: 1522
Nice! A good solution. The downside is having to find the memory address for each game, though that's not terribly hard. You and part of Braid inspired me to try to make a true rewind -- one that plays each frame going back and at the same FPS, rather than jumping back a second or two each time you press rewind. http://lua.pastey.net/96030-1tab It's pretty fun. Holding Select on the second controller rewinds. I have it set to hold a minute of gameplay, but you can change it to hold more or less by altering the second line. More means it needs more RAM though obviously. It also seems to stutter a bit once in a while... So if somebody can help optimize the idea a bit I would appreciate it :)
I make a comic with no image files and you should read it. While there is a lower class, I am in it, and while there is a criminal element I am of it, and while there is a soul in prison, I am not free. -Eugene Debs
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
Neat; I'll have to play with it later, definitely. I can't see anything that could immediately use fixing, though... Lua as a whole just kind of randomly stutters for me, unfortunately :( For now, I made this: Somewhat improved version of my Lua script; I have a lot of other ideas for it that will come soon, though, like making a better character create screen and some other things, as well as cleaning up the script and removing debug output.
Perma-banned
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
Well, using my knowledge of how the Gens lag counter worked, I perverted the idea slightly. First, it checks is "Select" is pushed. It writes "Select" every frame. (In this game, it has no use.) The result is that, on frames where the game takes input, Select will not be pushed. This can be expanded into a lag counter. And, needless to say, this game has an awful lot of it. (For your information, the lag counter often sits at 2-3, when nothing else except Bugs is active. It's very, very poorly coded...)
Perma-banned
Player (120)
Joined: 2/11/2007
Posts: 1522
Or you can assign a key to FCEUX's built in lag detector :) (I only stumbled upon that recently -- this emulator keeps surprising me!)
I make a comic with no image files and you should read it. While there is a lower class, I am in it, and while there is a criminal element I am of it, and while there is a soul in prison, I am not free. -Eugene Debs
Joined: 4/25/2004
Posts: 615
Location: The Netherlands
The way I do it is by putting my input into a key table and at the very end write it to the joypad table. That way I can poll key to see what buttons I will actually press. And in case this wasn't cleared up yet... FCEU will use the user input when lua has not written anything to the joypad. FCUE will (ONLY) use Lua input when lua writes something to a joypad. You will ALWAYS get the original userinput (keyboard) when doing joypad.read(x), never Lua. (ok nevermind...) Finally, I don't remember for sure, but I believe this was player independent. So setting input for player 1 in Lua still makes it possible to directly input player 2 (this you'd have to test though).
qfox.nl
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
alden wrote:
Or you can assign a key to FCEUX's built in lag detector :) (I only stumbled upon that recently -- this emulator keeps surprising me!)
Yeah, except every time I check it, it doesn't work -- it stays unchecked.
You will ALWAYS get the original userinput (keyboard) when doing joypad.read(x), never Lua.
No, that's incorrect. Try using
while (true) do

	joypad.set(1, joypad.read(1)); 
	FCEU.frameadvance();

end;
That will put it into an endless loop. Buttons you push will have no effect whatsoever.
Perma-banned
Player (120)
Joined: 2/11/2007
Posts: 1522
A question about Lua... when I load an "anonymous" savestate it says something like "State snlua100 loaded" Is there a file associated with this "snlua100"?
I make a comic with no image files and you should read it. While there is a lower class, I am in it, and while there is a criminal element I am of it, and while there is a soul in prison, I am not free. -Eugene Debs
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
A good test would be to make an anonymous save state, pause the emulator, and then do a sort-by-date in directories to see which one has the newest timestamp. If it's right when it was made, it has a file; if not, it's probably saved in memory. Alternatively, you can always open up your process list viewer of choice, have it slowly take 100 anonymous savestates, and see if the memory usage grows a lot :)
Perma-banned
Joined: 4/25/2004
Posts: 615
Location: The Netherlands
As I recall the savestate was placed in your userdirectory. However, Zero talked about not using files for anonymous savestates to speed things up and I don't know whether and when he did so. Last I checked I had 32000 savestates and no problem, so 100 savestates isn't going to show up significantly ;)
qfox.nl
Post subject: Item finder luck manipulation / memory monitor script
Moderator, Senior Ambassador, Experienced player (898)
Joined: 9/14/2008
Posts: 1007
I spent a fair amount of time working on an item finder script (specifically for the NES game High Speed). This script can be adapted fairly easily to work on other games by changing the memory location watch variable and the desired value variable list. You will also want to edit the script file to indicate how many frames you want to attempt random input on before trying again. I've tried to add copious comments so things somewhat make sense, but this is only my second Lua script and I'm absolutely certain this script could be significantly improved. Here's the link: http://lua.pastey.net/97140-44vx Please have a look and let me know what you think. Thanks to everyone who helped me sort through the implementation details (DeHackEd and Alden in particular). Enjoy, A.C. ******
I was laid off in May 2023 and could use support via Patreon or onetime donations as I work on TASBot Re: and TASBot HD. I'm dwangoAC, part of the senior staff of TASVideos as the Senior Ambassador and BDFL of the TASBot community; I post TAS content on YouTube.com/dwangoAC based on livestreams from Twitch.tv/dwangoAC.
Joined: 4/25/2004
Posts: 615
Location: The Netherlands
Oh lol, read too fast. Just started the game (didn't know it was pinball!) and loaded the script but it kept tilting. I figured it was due to something going so fast I couldn't see it :p But after a while, nothing happened still so I read again :p -- Actually, it'd be nice to write a pinballbot (for pinbot! ;)) and just watch it play, something for you Xkeeper? :p
qfox.nl
Player (120)
Joined: 2/11/2007
Posts: 1522
Bot for Pinball (the original) from back in the day. Should be pretty easy to adapt to Lua...
FCEU.speedmode("normal")

-- 0x7 is x of ball, 0x9 is y, 0x125 is amount launcher is pulled back

while true do
    --check if it needs to be launched
    if memory.readbyte(0x7)==225 and memory.readbyte(0x9)==154 and memory.readbyte(0x125)~=4 then
        joypad.set(1,{"B"=true})
    end
   --check right flipper
   if memory.readbyte(0x7) > 145 and memory.readbyte(0x7) < 175 and memory.readbyte(0x9) > 189 and memory.readbyte(0x9) < 226 then
         joypad.set(1,{"A"=true})
    end
    --check left flipper
    if memory.readbyte(0x7) > 110 and memory.readbyte(0x7) < 138 and memory.readbyte(0x9) > 189 and memory.readbyte(0x9) < 226 then
         joypad.set(1,{"up"=true})
    end
end
Don't have the emulator with me so it might have bugs :D
I make a comic with no image files and you should read it. While there is a lower class, I am in it, and while there is a criminal element I am of it, and while there is a soul in prison, I am not free. -Eugene Debs
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
Yeah, it's got a ton of bugs.
-- 0x7 is x of ball, 0x9 is y, 0x125 is amount launcher is pulled back 

while (true) do 


    --check if it needs to be launched 
    if memory.readbyte(0x7)==225 and memory.readbyte(0x9)==154 and memory.readbyte(0x125)~=4 then 
        joypad.set(1,{B=true}) 
    end 
   --check right flipper 
   if memory.readbyte(0x7) > 145 and memory.readbyte(0x7) < 175 and memory.readbyte(0x9) > 189 and memory.readbyte(0x9) < 226 then 
         joypad.set(1,{A=true}) 
    end 
    --check left flipper 
    if memory.readbyte(0x7) > 110 and memory.readbyte(0x7) < 138 and memory.readbyte(0x9) > 189 and memory.readbyte(0x9) < 226 then 
         joypad.set(1,{up=true}) 
    end 

	FCEU.frameadvance();
end
This actually runs without crashing the emulator :P For your refrence, it scored 97,730, then 75,360, then 18,880. (Avg.63,990 but very random) I'm going to try correcting some obvious (to me) flaws with this and see how it works out...
qFox wrote:
Actually, it'd be nice to write a pinballbot (for pinbot! ;)) and just watch it play, something for you Xkeeper? :p
I can't do bots. :( Now if you wanted some statistical output on your screen, then you call me :P
Perma-banned
Moderator, Senior Ambassador, Experienced player (898)
Joined: 9/14/2008
Posts: 1007
qFox wrote:
Actually, it'd be nice to write a pinballbot (for pinbot! ;)) and just watch it play, something for you Xkeeper? :p
Hmmm... Well, if you get the game to a state where there's a ball in play (or even more preferably get it so multiball is in progress), you can see some fairly interesting results by changing the buttonmask to only left and A (remove the override on A as well). You'll probably want to set the maxframes to something like 3000 and perhaps change what memory it's watching to something that stays at 255 (although you can always say "no" if it asks you to accept a solution). I set it up like this and it actually played long enough to grab a third safe drop and launch two of the three balls into the safe. It's entertaining, anyway. :) This could definitely be extended into an actual bot which watched collision memory addresses, etc. to do even more complex things which I may do at some point once I get the mess of variable names I created for myself cleaned up. Bisqwit posted a bot function at http://tasvideos.org/Bisqwit/LuaFunctions.html which looked interesting, but I could never quite work out how it did what it did... Maybe if all of the code was in a single file I'd be able to piece it together better. His page has a cool input simplification function among other things that I'd like to comprehend at some point. Thanks for the reply qFox - I'll be sure to post updates as I refine this. A.C. ******
I was laid off in May 2023 and could use support via Patreon or onetime donations as I work on TASBot Re: and TASBot HD. I'm dwangoAC, part of the senior staff of TASVideos as the Senior Ambassador and BDFL of the TASBot community; I post TAS content on YouTube.com/dwangoAC based on livestreams from Twitch.tv/dwangoAC.
Player (120)
Joined: 2/11/2007
Posts: 1522
LOL Xkeeper, thanks... stupid frameadvance. I'm sure it could be improved vastly; the original was written with BasicBot so crammed all that functionality into 3 lines :) Would be interested to see what could be done with it... and the only difference between statistics and bots is pushing buttons based on the statistics :D Hey qFox, snes9x+Lua has a timeout function where if it runs for a certain amount of time without advancing a frame it will warn the user and allow you to kill it... would that be hard to implement in the future?
I make a comic with no image files and you should read it. While there is a lower class, I am in it, and while there is a criminal element I am of it, and while there is a soul in prison, I am not free. -Eugene Debs
Joined: 4/25/2004
Posts: 615
Location: The Netherlands
That actually got ripped from fceux. I believe it had to do with iup, but there was a good reason for it. Just don't forget yer FA ;) A bot isn't that hard, is it? Just shoot the ball back when you detect the flipper can hit it, and go on from there :D Also, Alden, get in IRC, get with the program! :p
qfox.nl
Post subject: Input from Lua is not recorded by FCEUX
Moderator, Senior Ambassador, Experienced player (898)
Joined: 9/14/2008
Posts: 1007
I need some help. I'm working with a slightly tweaked version of the Item Finder script I wrote which I've posted to: http://lua.pastey.net/97648 The script is designed to try random inputs until Something Good (TM) happens and a memory address matches a target value at which point the user can stop the script and continue playing from there. The problem I'm running into is that FCEUX truncates the movie at whatever point the Lua script was executed. Here are the steps I'm taking: 1. Start the game game (High Speed in this case) and load a movie in read-only mode 2. Play the movie and pause on the last frame 3. Save the current state, switch to read-write mode, and load the savestate to trigger record mode 4. Optionally add additional input until it's at a point where the item finder script should be run and save the state again 5. Run the Lua script and let it loop until it finds a set of inputs that meet the desired result 6. Accept the script's input and exit the script; this saves in a different slot At that point everything still looks normal - FCEUX still reports that recording is taking place and manual input can be made and saved. However, closing and reopening the movie shows that the framecount is truncated to the frame at which the Lua script was executed for the first time - all additional input including manual input is entirely missing. Am I doing something incorrect here? Should the Lua script be manually manipulating the movie somehow? I always assumed that anything sent to joypad.set would be treated by FCEUX as if it were input from a human... Thanks in advance to any help or advice on fixing this as I'd really like to move forward with my High Speed TAS run and this item finder script would help greatly. A.C. ******
I was laid off in May 2023 and could use support via Patreon or onetime donations as I work on TASBot Re: and TASBot HD. I'm dwangoAC, part of the senior staff of TASVideos as the Senior Ambassador and BDFL of the TASBot community; I post TAS content on YouTube.com/dwangoAC based on livestreams from Twitch.tv/dwangoAC.
1 2 3
7 8