This is totally awesome! I've been trying to explain to people without emulator knowledge how TASs work without the technical jargon and I always said that if you could spit that input into an actual NES it would play the game on an actual console, now I have a demonstration.
I watched this video and my mind was blown, and yet somehow in this blown state I managed to think of something that if possible could blow one's mind so far beyond belief it would be crazy. Imagine if this very concept could be applied to the latest 0 star Mario 64 run.
I've followed all the various runs for Mario 64 and to me it seems possible, but I'm not expert and wouldn't know if there is any of the previously mentioned issues that would keep it from being possible.
As Is:
SMB (04:57.31), SM64 (05:02.25), SMB2 (07:41.16), SMB2:LL (08:05.28), SMW (09:57.82), SMB3 (10:25.6)
Some Day:
SM64, SMB, SMB2, SMB2:LL, SMW, SMB3
I haven't acquainted myself with the N64 hardware, but I fear that the more modern the console, the more difficult, if not outright impossible, running pre-recorded playing on it would be. For example, if the console happens to have a battery-backed-up clock and the game initializes its random number generator from it, you can absolutely forget about it. There are also many other things that make it extremely difficult to run things deterministically from controller input only.
Well, we can now add Marble Madness to that list. I got it to work last night. I'll get a video up of it as soon as I can.
I ran into an issue though getting it to run. The movie started fine, but around 3 seconds into the first course the ball started spinning too early and ran itself off. I tried my new code based off Derakon's example, and I noticed even when the emulator said the frame was not a lag frame, sometimes the game wasn't actually looking for buttons. With the new code the resulting file was a few frames shorter, and ran perfectly. Is that a bug with FCEUX, or do I not understand it's definition of a lag frame?
As for my other games:
I tried SMB2, it desynced when toad entered the alternate world for the first time.
SMB3 gave me the same random failures I talked about before.
Adventures of Lolo desynced in the second puzzle room after pushing the block towards the other creature. He didn't walk far enough south to get around the block.
Zelda 1 stopped working soon after starting the game. It may have been a problem with my bot, since it seems the game polls multiple times in a frame and my bot doesn't handle that well yet (it's too fast for it). Link would randomly stop and start walking. Also if I'm not mistaken that movie uses the second controller to restart the game, which I have no way of dealing with right now. Maybe in the future.
Zelda 2: both videos are .fcm files, do those work in recent emulators? I haven't tried it yet. I'll need to run my lua script along side it, so if it runs in an emulator with that support there may be a chance.
I'm waiting on Tetris, Excitebike, and Gradius to come in the mail. I'll start messing with them once they arrive. I also bought more components to build an SNES bot and maybe another one of these.
Also, if I started selling these for around $100-150, would anyone be interested? That price includes design, parts (a board and the components) and construction (I'll put it together for you and make sure it works).
"A lag frame" is simply when an NMI occurs before the actual game program has finished doing whatever it planned doing before the next NMI, such as run AI, spawn/delete actors, mogrify actors, set up instructions for the NMI routine to execute while the PPU is having a lunchbreak, etc.
What it can do depends on the number of CPU cycles elapsed in each instructions and on the number of CPU cycles that are the interval for NMIs to occur.
NMI is, as you all know, the signal sent by the PPU to the CPU telling "I'm gone to lunchbreak, you take advantage of it *now* and don't break anything", upon which the CPU stops everything it was doing and goes to execute the NMI routine (also provided by the game), after which it resumes what it was doing before. It happens about 60 times per second.
Thus, differences between the real hardware and the emulator with respect to lag frames are simply caused by the emulator counting a different number of cycles at some point or other than the real hardware. It is difficult to emulate properly, because the exact timings are not precisely known, and the timing of a single instruction can depend on multiple factors.
There's a function built into FCEUX to convert .fcm to .fm2 it should work for pretty much any published movie I think. (There was some really early builds of FCEU that weren't compatible.)
I would debate purchasing one. The thing is they don't really serve any practical use beyond seeing what is possible on console, which you are already doing.
Also with your current boards, they could theoretically support SMB3 if software agreements could be sorted out, right? (Does the circuit need to be modified to open up possibilities of games like SMB3 to work, or just the software?)
If I have understood correctly, what the circuit does is it just plays back a stream of "when the console asks for the next set of buttons-pressed-down-bitmask, here's what to reply". The console (or in fact, the game) provides all the timing; the circuit does not have any timers whatsoever. It's just like a faucet, except instead of flowing continuously, it flows a drop at time upon request. Mupen64 movie files are built upon this principle (of recording input only whenever the game requests for it).
I think DarkKobold's suggestion for dumping the movies only upon game's requests would work. If not (due to lua's limitations), perhaps modifying the emulator itself to accomplish the same thing. I don't know if that is already being done here.
SMB3 will not work until FCEUX implements the PCM bug. Essentially, from what Acmlm taught me/what I've read, the PCM writes to $4015, and the controller writes to $4016. So, therefore, FCEUX needs to catch those overflows, and write a press right to the input stream.
That said, this would totally desync with the current TAS, because it would change where lag frames are - i.e. more read operations per frame when the PCM glitch happens.
I think he meant me.
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Hmm. I wonder if the parallel port of a PC can be connected directly to the joypad socket (with some pin adaptation of course). Or a serial port. If I had a TV (with which I could try to use my NTDec, a Famicom clone), I would try this. No need for a special Arduino board if a PC can be used...
Would it help at all if the Arduino program had an idea of time, instead of blindly presenting the next input on the card whenever the NES asked for it? I'm thinking something along the lines of:
main() {
wait for first input request
present first input
initialize timer to 0
wait forever
}
InputRequestInterruptRoutine() {
if(timer value > 15ms) // 16ms is about 1/60 sec
{
present next input
reset timer to 0
}
else present last input
}
This shouldn't be affected too badly by any inaccuracies in the Arduino's timing relative to the NES, since the timer is reset every frame, and it should be possible to handle lag frames as well (i.e. without pre-stripping them) if you're clever about it. (Say the NES has definitely lagged if the timer hits 18ms without a poll. In that case, add an interrupt routine for timer=18ms that resets the timer to 2ms and skips a frame of input.)
Or, in modern times, a NES controller - USB adaptor. This would indeed be more versatile than a separate board because it would allow programming and running the logic directly from your PC (as long as you can interface with the USB, or paralle, port from your favorite programming language).
That was a great movie there, and from the replies calling for bullshit, it's definately sure that they don't know what they are dealing with.
Of course, they cannot comprehend what they just witnessed. I loved every minute of it myself. I'd love to see more of these. Good work, and I will put my vote forward if I can remember to do it when this happens for you.
As I've said a few times, I was working on doing something like this with a PIC MCU. Obviously it didn't get finished and this did =) But I do understand not everyone has access to one of these and a means to program it. Some people may have "legacy" x86 computers and want to just use a parallel port or something to do this on their own. It should be possible and fairly easy.
Thanks for the clarification Bisqwit. I'll stick to my new method of getting input data, since it seems to generally work better.
Yes, the board is basically an arduino microcontroller connected to the shift register, with a few buttons and LEDs for input from the user and status. It also has a microSD slot to store the data. If the software can be worked out, SMB3 should work fine.
I did mean you, my apologizes! My new code based off your sample is working much better.
That's the idea I've had in mind that I'm going to try next. It gets a little more complicated because timing (delays, etc) doesn't work in an interrupt routine, but I'll try some other methods and see if I can get it to work.
As I mentioned before, I got Marble Madness to work. I shot a video of it today: http://www.youtube.com/watch?v=VjB6-2iH1oY. Sorry for it being low quality, I don't have access to the tv I used last time. I also tried turning down the brightness of this TV in an attempt to get the colors to not run together, with not much luck. I hope its reasonably watchable. If not, I'll re-shoot it in a couple days.
I also got Gradius in the mail yesterday. The TAS for it also worked perfectly on the console. I have a video of it too, but that'll take a while to upload.
Recent projects: SMB warpless TAS (2018), SMB warpless walkathon (2019), SMB something never done before (2019), Extra Mario Bros. (best ending) (2020).
Hey, I can see the future! I'm applying to the JREF $1 million right now.
Here's a compilation of quotes:
All this "evidence" of fakery reminds me a lot of all those conspiracy theories and their "evidence" of fakery.
Joined: 5/1/2004
Posts: 4096
Location: Rio, Brazil
"Since when does an NES system start up that quickly. . ."
That's my favorite because it shows how the NES is so good.
I don't see where I can vote... Yes, I am logged in, but it's a new account.
Thanks for trying! I forgot voting closed last night (I thought it went on until the 19th). It's not a big deal though, I'm a finalist in the competition! So thanks to anyone who did get a vote in!
I'm uploading my video of SMB1 warpless on the console. I'll add a link here when it's finished.
Edit: NESBot: SMB1 Warpless
Try using the hardware timers (Timer0, Timer1, Timer2) that are part of the microcontroller; I'd be stunned if they stop on an interrupt. Once you've set one up, it should increment itself automatically (at an interval you choose) no matter what's going on elsewhere in the processor, and you can check and change its value whenever you like.