Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
The microcontroller runs at 80MHz which turned out to be just enough time to handle the pulse lengths of the protocol. The microcontroller also has no interrupts, so it is just constantly listening for data. I believe I used a sort of "wait for pin to go low/high" function to pause until that state happens.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
That's a fun glitch! I would love to know if that is possible using normal means, but unfortunately it probably is not useful for completing the game quicker. The prize world code you enter at the beginning of the game is processed in a number of steps, and the steps are in a certain order based on the order of the maps you go through as well as a few special events. The processing is designed such that as long as you complete the game as intended (no skipping screens, etc) the processing will work out correctly and the prize world will load. However if you skip certain screens/events the processing will do the wrong thing and the prize world will not load.
I discovered this first hand when I found a way to skip the car scene in world 2. I went on to finish the rest of the levels, but the carnival world never loaded. I've recently confirmed this theory by discovering that both entering the car, and leaving the car map are events that trigger processing, and if they are skipped the processing is invalid when it comes time to load the carnival world.
As for world 4, certain maps, including the middle screen when you go over the waterfall in the barrel, trigger processing, so I don't think skipping them would result in the prize world loading. However, something I've been wondering about is if it is possible to skip steps of the processing with a different prize code. The code would have to work out correctly after all the steps of processing the game not including the ones you skip. I think there is a change this is possible but it seems unlikely to me. Plus the only way to find such a code would be to bruteforce it which would take a long time and isn't guaranteed to work.
That is an idea I'd like to explore later, but right now I am gearing up to try to find that second prize world code. I've made a lot of progress, but it still seems that I will need to bruteforce it. I'll make another post soon with more details of my progress and how the community can help out.
Thanks for sharing!
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
While at AGDQ 2014 I was able to borrow Weatherton's Everdrive, and we gave #3555: SwordlessLink's N64 Wildwaters: Extreme Kayak in 01:30.93 a try. The results were interesting:
Link to video
I had to set the bot to activate the game from the Everdrive menu, but besides that I had little trouble getting it to play back. I ran it a few times, and each time the in-game time was significantly longer than the TAS length. It does seem like all the actions from the TAS played back correctly, just slower than the emulator. Someone who knows the game better than I can confirm or deny this. I'm not sure if this is emulator inaccuracy, if the Everdrive played a part in this, or if it was something else.
I'm inclined to call this a console verification, but I'd like to hear some input from other people before we call it that.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
To get a better idea of what kind of impact this would have, I decided to look at a number of NES games and see which access uninitialized RAM.
I modified Bizhawk slightly to monitor the RAM usage. If the game read from a RAM address before it has written to it, I recorded that. I also recorded what addresses were written to.
I took a list of NES games that the site has movies for, ran them for 600 frames each in that modified Bizhawk, and then outputted the data collected. I then turned the data into images to make it easier to digest the information.
Here is the image set (warning: large/long images)
Each 8x8 pixel block represents a RAM address, starting at 0x0000 at the top left, and ending at 0x07FF at the bottom right. The colors mean the following:
Black - RAM was not read from or written to (still uninitialized)
Green - RAM was written to first
Red - RAM was read from before it was initialized, and still hasn't been written to (still uninitialized)
Orange - RAM was read from before it was initialized, but has since been written to
Keep in mind that this data is from only 600 frames of the game, and with no input. The results may change if input is given or the analysis is run for longer.
You can tell from the images that a large number of games access uninitialized memory, but I'm not sure what they are doing with it. As other people have said, some games start up in a different way depending on the initial state of the RAM. Being able to control this initial state might be beneficial to movie authors, but I'll leave that up to other users who know more about each game to determine. This data was simply to get an idea of how many games might be impacted by this new policy.
Also, if anyone is interested in seeing my changes to Bizhawk or the raw data I made the pictures from I'll be happy to post it.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
I actually hacked my way into (what I'm pretty sure is) the second prize world a while back, but it was horribly broken (music was the same as the first world, enemies were weird, no important items like keys or anything were available) I did make a map, and the level looks pretty cool. I'm looking forward to playing it at some point!
From what I've heard, the second prize code was for a second contest (that I guess never happened). The contest would be very similar to the one that did run in that the code would be released on a certain day, so I'll have to play the whole game again to get to it.
I'm doubtful that changes could be hexed it, but I suppose its worth a shot. I'll try it when I get back to the TAS. Right now though I'm focusing all my efforts on finding this second prize code.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
Has it really been over a year since I last posted here? Wow...
Anyway, I've made a major breakthrough in understanding how the prize code is processed. I've know for a while now that the 24 characters you enter on the screen are translated into 15 bytes of data, which then have some operations done to them, including two checksums, and a basic check. If any of these checks fail, the code is denied.
Tonight I discovered that only 8 of those bytes actually matter. The other 7 are ignored after passing the checks and are overwritten with new values. This got me to thinking, could I fill those 7 bytes with different values, enough that it passes the checks, and still activate the prize world?
The answer? Yes.
I traced those 8 bytes back to their characters representations, then filled the rest with new values, accounting for the checks.
The known prize code is:
3HDJL9DNQV2WYTV4S91RXR86
and my new code is
3D0001DNQV2WYTV4S91Q0H85
I've tried entering my new code and playing through the game, and it correctly activated the carnival prize world.
The code can be manipulated even more, but to keep it simple I didn't change it too dramatically. You'll notice the middle ~13 characters match. This is the actual payload of the prize code that activates the carnival world. The "8" at the end is a part of a checksum, and just happened to match again. The "3" at the beginning changes how the second checksum works. I believe I could have changed it, but it made testing easier to not change it. I filled the rest with "0"s. There are clearly a large number of codes that will activate the carnival world.
So what does this mean? For TASing, I can likely save a little time on the code entry if I choose a different code. I can generate all valid codes for the carnival world and figure out which would take the least amount of time to enter.
I also mentioned previously that there is a second prize world. I am still working on finding a way into it, and knowing now there are only 8 important bytes greatly reduces the number of codes to try if I end up using a brute force method. I am in the process of figuring out how the final check of the working code works, and if I make any breakthroughs with that I'll post about them.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
The shift register used is the 4021, a parallel to serial shift register. I'm sure there are plenty of descriptions of this kind of shift register available, but basically the chip takes 8 bits and outputs them over one pin. A game toggles the latch pin which causes the chip to read the bits and remember them. Then the game toggles the clock pin 8 times. The shift register outputs one bit at a time, and changes which bit it is giving each clock. For an SNES game, the game would toggle 12 times, and the two chips combined would supply 12 different bits.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
I have plans to build a SNEBot, I just haven't gotten to it yet. The biggest thing holding me back right now is my lack of a workspace, but that should be changing soon.
The hardware to build a SNESBot would be a simple expansion of the NESBot.
The SNES controller is an NES controller with 4 more buttons. The shift register they used only supports 8 bits, so they tacked on a second one to support the extra buttons. The interface is the same (power, ground, clock, latch, and data). SNES games then just poll the controller for 12 bits, while NES games only poll for 8 bits. Don't quote me on this, but I'll bet if you swapped out the plug on a SNES controller for an NES plug, it would work fine and the extra buttons would just be ignored.
I hadn't tried building the bot back when I was more active with the NESBot because I believe I ran out of pins on the Arduino. Since then I have pursued other microcontrollers and have a new design in mind.
As for getting movies to sync, that is a totally different problem. As Ilari described, consoles are hard to emulate perfectly accurately. Things like initial state and lag can ruin games chances of syncing. When I first started playing with the NESBot I used SMB1, a game that is easier to emulate correctly. I'd suggest picking a game that is easier to emulate on the SNES to have the best chance of a movie syncing. I'm not actually sure what that is, but I'm sure someone else here has some suggestions.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
I did some work on the Atari core last night that fixed Enduro, Pleiades, and Activision Boxing (and probably others), but Frostbite and Megamania are unfortunately still broken. I'm going to look into them more this weekend.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
The SNES controller is pretty much just an NES controller with more buttons. The electronics are almost identical (except there is an additional chip to account for the 4 extra buttons). I just never spent time on getting a SNES bot working since at the time we didn't have a very accurate SNES, but now with lsnes and Bizhawk this is definitely something worth looking into. I should hopefully have a workspace set up again soon where I can play with these bots, probably in a few weeks.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
Console Verified, for now
Link to video
The oscilloscope is showing the button data from my bot. But since it didn't fit all on screen it is showing just the last ~half, which is the joystick data.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
Using a bot of my own design, I managed to get the "0 star" M64 run to sync on the console.
Link to video
I haven't tested any other games or runs yet (I only just got this working last night).
I eliminated the controller circuit board all together and instead faked a controller with my bot. Since it's hard to see in the video, I shoved wires into the controller port (I'm waiting for a controller I ordered to steal the cable from). Any time the console asked for new buttons, I sent it new buttons.
I had to modify the .m64 file to match what the bot wanted. I cut out all the metadata, and then swapped the endianness of the controller data to make my bot code happy. Beyond that I didn't modify it at all. I didn't even have to add any frames to the beginning or anything.
I used the parallax propeller chip which is pretty inexpensive, meaning others could duplicate this on a low budget. Slightly off topic, but the NESBot runs great on this chip as well, so I can definitely see an NES/SNES/N64 combo-bot in the future. I'll get my code up in the google code project soon so you guys can look it over.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
Unfortunately I haven't made any progress. I've been busy with other projects and school, but I do plan on finishing this as soon as I have the time again, which should hopefully be soon.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
I'd love to see the zero star run on the console as well, but I have to agree that Mupen is not nearly accurate enough to make that possible. It may be possible however to record someone playing the actual console, and later play those button presses back. That's on my list of things to try, whenever I can find some free time.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
When I'm doing these checks I try to test each movie a few times before giving up and moving on. I usually try to make sure the game fails in the same way each time to make sure it wasn't one of a few other problems that could come up.
One game that was especially bad at that was SMB3. With earlier versions of my code that game would desync completely randomly. I've since learned that is due to the PCM bug, and I've more or less worked around it. Other problems include power button bounce. If you press the power button too slowly, the console can flicker on and off for a short period of time before actually staying on. If the game polls for input in that time my bot will react, but just continue to increment the frame count instead of resetting with the console. That could cause the input to be a few frames too soon, usually meaning the game doesn't start (that one is fairly obvious). I've also had problems with other electrical devices causing interference, like my dorm fridge. When that thing kicks on, movies almost instantly desync.
When I built the NESBot I had the intention of making a bot that plugged in as a controller and did not modify the console at all, since that was theoretically how TASes work anyway. The NES does have a vsync pin, but it is also internal to the console. I need a little free time, but I plan to try using that, even if just to see if it works as I'd like. It'll break up the clean plug-in design of the bot if it does, but if more runs work as we'd like then I'm fine with that. Maybe I'll end up with a completely hacked TAS playing console when I'm all done.
I have the parts in the mail (somewhere, silly international shipping) to make an SNES version. I've heard from multiple people that it's less likely to work due to the SNES emulators being less accurate than FCEUX is, but I figure its worth a shot considering that the electronics required are almost identical to what I currently have. I will need to borrow games for that testing though, since I only have LoZ LTTP. I don't personally have a genesis, but I'd love to mess with one if I could get my hands on one. I have looked into doing this for an N64, and it doesn't seem overly complicated, but it is very doubtful that any runs we currently have will sync. But who knows, maybe mupen64 is better than we think!
This page lists all movies that have been verified on the console: Wiki: ConsoleVerifiedMovies. And as zidanax mentioned, there is a check mark next to the title of the run which indicates it has been shown to run on the console.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
Even better! I guess it was you that I contacted a few months ago about trying to do a run.
Anyway, I found all the checkpoints for Coventry Cove!
In the town, before the left fork (with the jump over water)
Before the barn, on the right there's a tree immediately behind the fence. In that area.
A few car lengths back from the u-turn sign near the castle jump
After doing 3 laps, there's one where the road turns into dirt for the finish area(pre finish line)
The finish line
From the start of the race, you need to hit the town, barn, castle checkpoints, then hit the town again to increase the lap count. Barn, castle, town to make it the third lap. Go to the barn, pre finish line, and finish line, and the race ends.
Using MHS and those known checkpoints, I managed to set a fairly impressive course record.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
If that gets implemented it would be a nice addition to a script I'm working on. I'm hoping to collect some metadata on games, things like if they use PCM, if they do sub-frame polling and how many polls it typically does or at least the max and min number, does it start from initialized memory, etc. Info like this may make getting runs to sync easier in the future.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
And after a few months of delay, here's an update:
Updated, but not guaranteed to be the final revision of level 3
I changed around the harm in this version. After getting the first machine part I stop before the last screw (in my last video I got hurt by it), leaving me with 2 bars of health instead of 1. I used both on the screws at the bottom of the level. After getting the key I killed myself on a screw, and luckily do not death warp back at all. The timing was right on the next screw to let me walk right under it, and I pause for the next screw to keep all my health. Overall the video is 101 frames longer, but that may not be a bad thing.
So health is getting trickier and trickier. If I stick with this video (which I may not, I'm not sure yet) I'll have 3 bars of health to work with (no lives left after this). Those 3 can really come in handy in level 5 when I'm doing all the bullet dodging. I may also like some points to work with in level 6, but I get an extra life there. However there is an extra life in level 4 that would take little time to grab, and it might be possible to make up for that in taking hits. I'm really not sure what to do yet.
I'm pretty sure the ducking works on an x position cycle. It seems on a 4 pixel barrier he stands up for a frame when I'm trying to duck walk. If get under the piston at the right spot I can move at most 3 more pixels, since one more movement would kill me. I don't have much control over where I get under the piston though. I pretty much just keep moving as much as I can without dying.
Emulator Coder, Experienced Forum User, Published Author, Player
(68)
Joined: 10/4/2005
Posts: 197
I've been using Glide 64 'Napalm WX' release 1 for my video plugin with good luck. Some things are still kind of glitchy (like trees), but the game is still very much playable. I've also been trying out the anti-desync mupen. I still have desyncs, but if I reload the movie and reload a savestate I can usually get them to go away.
I wrote a few scripts in MHS that allows me to fly around a map, and I managed to "beat" coventry cove in ~1:40 just by roughly following the level. I was planning to find those invisible checkpoints using this.
And for the sunset sands skip, is this the one you're talking about?
Similar to that one, this jump may be useful if done correctly and the checkpoints don't cause a problem.