Posts for blargg

Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
Yes, a superhuman could alter the temperature and other things that contribute to the initial state of the console. We could approximate it by turning it of and on until its state is what we want, then save viewers the bore of that by skipping all the unsuccessful power ons. Note that all this only applies to a TAS where one wants a particular initial state (sort of like manipulating luck); if one is fine with however the console powers on for one's TAS, then it really is just turning it on and pressing things on the controller.
Post subject: Defense of initial console state for TAS playback
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
There was some criticism of TAS on the nesdev forum over it requiring a known initial state on the NES, thus eliminating the possibility of playing back on a stock NES. Below is my defense of TAS that it in fact is done on the equivalent of a stock NES powered on, and thus is just a lack of thinking through what TAS is. Apologies if this kind of defense has already been elaborated elsewhere. TAS is about something that could be done in real-time if one were superhuman. We could put the game in, power up a NES, then play it in an unbelievable way, all through the controller. Since we aren't superhuman, we use tools to give us those powers as far as the NES and game are concerned. Our tools essentially allow time travel. We can stop time and think about the next buttons to press/release. We can also let time go forward, see what would happen, then go back and use that information in choosing what to press. We can also of course go back and redo something that we realize was an error. So, to make a TAS, we put the game in, power up the NES, freeze time, make a note of the entire state of the NES, then construct our controller states while we run the NES forward and backward. When we're finally done, we rewind time back to the initial power-up state and play our TAS movie in real-time while everyone enjoys it. If someone wants to see it again, they can go back in time to this NES in its same initial state and replay the TAS. Since this requires an actual time machine, we can approximate stopping time by stopping the NES clock or something similar, and approximate going back in time by restoring the same initial state to the NES before replaying the TAS. Rather than leave the NES on while we make the TAS, we might turn it off and then restore the state when we want to play it back for the first time. This, like the TAS tools, is for overcoming our own limitations, not altering the essential TAS process. Thus, I don't see the initial NES state issue as being a violation of TAS at all. It's still turning on a NES and feeding it just a series of button presses, created with the assistance of tools, that result in an unbelievable play.
Post subject: Analogy for TAS: musicians and sequencers
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
I think the presentation/explanation of TAS could be improved by making a strong analogy to modern music sequencing versus playing live, and referring back to it often. The FAQ mentions movies, but I think the music analogy is a richer source of proper notions about TAS runs. With movies, there was always a non-live aspect and ability to edit things together, but music can be done completely live, like video game playing. For example: Musicians who use sequencers don't claim their music is being played live. Some people might prefer it to live music, but that's partly because sequenced music can do things live can't. The musician wants to make sounds that are satisfying to listen to, and sequencers opened new possibilities. Where before a musician's physical skill was a limitation, with a sequencer he is limited only by his mind. This doesn't mean that making satisfying music is easy for anyone to make if they have a sequencer, so it's still an enjoyable challenge for the musician. On the other hand, people probably have more respect for live music, since sequenced music highlights its unique aspects better. Probably when music sequencers were first introduced, musicians using them were accused of cheating; at the time, it was probably reasonable to wonder whether sequencing would hurt music.
Post subject: Re: FCEU Question
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
Bisqwit wrote:
Also, the thread topic should be more descriptive.
Really. Using the question mark properly, the thread topic is basically "FCEU?" And since it's in the FCEU forum now, it really amounts to "?" which is about 1 bit of information (the other possibility would be a thread giving some information, rather than requesting it). And this thread seems to be half-filled with what looks like private correspondence. That's what private messages are for.
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
I think the biggest impact of this is that these times can't be achieved on NES hardware, and that should be the main reason to note this difference somewhere. Changing the movie rate to a hair more than 60 FPS might not be easy, and might cause other problems, so the simplest solution would be to post a conversion factor and perhaps show the "hardware" time in parenthesis. Too bad NES clock crystals don't vary a lot, then you could just claim to be emulating one with a slightly slow crystal. So there's no way around this difference, and it doesn't vary depending on any random variables either. BTW, some games use the "screen off" timing all the time, like Battletoads, because they disable the PPU during the beginning of the screen refresh.
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
For stepping backwards one frame at a time, consider an emulator that makes an automatic save state every second, for the last two minutes (120 states), and keeps track of controller input for every frame of those two minutes. - At any point, you can immediately rewind to any of those previous seconds and then play back everything to present. - To jump to a particular frame in those two minutes, restore the state for that second, then replay 0 to 59 frames. - To step backwards one frame, jump to the previous frame using the above technique. This will get slower the closer you get to the next second, as it will involve up to 59 emulated frames for every step. - To quickly step backwards one frame a time for several frames, restore the most recent save state, then emulate up to the current time and SAVE THE IMAGES for each frame into a buffer. So if you were currently at frame 50 since the last save state and stepped back one frame, you'd build up 49 images for the previous frames. Then stepping back would be immediate, just display the next earlier frame from the buffer. To reduce delay for the first backwards frame step, you could perhaps always save the last 60 graphic images or something. - To eliminate the delay for the image buffer technique when the buffer is exhausted, you can be refilling the buffer for the previous second while the user is stepping through the next. Say the user starts at the 60th frame in the buffer, then steps backwards one frame. Display the 59th and restore the save state for the previous second and generate the first frame in place of the 60th. Then when the user steps back to the 58th frame, run the emulator forwards one frame and put that where the 59th was. Once the user steps back to the first frame in the buffer, you've got it full with the previous 60 frames, no delay. This can be extended to allow rewinding back to the beginning of the movie by having a second level of save states every 30 seconds or so. Then when rewinding before the two-minute set of save states, you'd go back to the closest 30-second state and run until the desired point, making the one-second save states along the way. The main two issues are the speed of the emulator and how big save states are. For example, if an emulator can run at 2x realtime, then the first backwards step could take half a second worst-case (any after that would be instant). This could be reduced by saving states more often; for example saving states every half second would reduce this to 1/4 second. QuickNES (for Windows) implements this technique, though the emulator is insanely fast (about 21x real-time on a 400 MHz machine).
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
Heh, just noticed this thread. Hope its revival isn't a problem. - If volume level was the main issue, it shouldn't be hard to increase FCEU's volume. - Back when I was doing more APU research, Xodnizel was implementing my findings too, and implemented the non-linear mixing, which I still don't do in any code I've released. It's minor, but in this respect, it's more accurate. Not sure about its accuracy in other areas. - FCEU uses band-limited synthesis too, as far as I know (if it's anything like Festalon, which was my first inspiration for getting into emulation coding), so there shouldn't be any noticeable difference. I didn't hear much difference in the sound samples (besides volume). Of course the compression artifacts of a ~50 kbps mp3 stream mask anything subtle anyway. On the other hand, FCEU used a quite slow synthesis algorithm, so maybe the speed increase is worth it. - NES sound does NOT have any aliasing. It's generated at effectively a 1.79 MHz clock rate. Yes, while your sound card only runs at 48000 Hz or so, the NES runs at 1789773 Hz. Any aliasing is due to poor emulation, and not accurate. This includes the noise being too loud. If you prefer aliasing, then you have not had enough exposure to the real thing, and obviously didn't record and listen to the game music on tape as a kid all the time :). My code and FCEU both convert this 1.79 MHz signal down to 48000 Hz (or whatever rate you set) the same way it would be converted if you hooked a NES up to the line input of a PC sound card and digitized it. NES noise does get softer at at higher rates, because more of the signal goes above audible (and above the Nyquist limit around 20 kHz) and is thus filtered out. No guessing is involved. The error diagram on my band-limited synthesis page is showing the error that linear interpolation introduces, as compared to proper band-limited interpolation. Linear interpolation simply doesn't filter out the frequencies above Nyquist, so they fold over (alias) and become audible scratchyness or worse.
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
moozooh wrote:
One more question, though: what is the cause of such a great variation in average mem/disk space consuming?
The amount of additional memory in the cartridge itself is the main contributor. The NES has 2KB of internal CPU RAM + 2KB screen memory, and many cartridges add another 8KB of CPU RAM and some 8KB of CHR RAM (for graphics). This increases each save state by quite a bit. The increase is lessened due to the compressor finding common data between separate save states, since the games don't usually rewrite every byte that often. Another cause is that some games simply have a more compressible set of bytes in memory at most times. Visual Boy Advance save states are so much larger because the GBA itself has a lot of on-board RAM which must be saved each time. Wikipedia claims the GBA has 128KB of internal RAM (32K CPU + 96K VRAM), so you can only fit 8 uncompressed save states per megabyte of RAM.
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
Right, as you're playing, QuickNES saves state every second to a cache of the most recent two minutes (120 save states), and also saves state to the ongoing movie every 30 seconds. These are both adjustable in the code. As for movie size on disk and in memory, here are some data for complete movies, keyframes every 30 seconds (on disk they are gzipped and in memory compressed using a custom algorithm):
Time  Disk  Average    Mem    Average   Game
--------------------------------------------------------------
0:30   46K  1.5K/min   126K   4.2K/min  A Boy and His Blob
0:20   54K  2.7K/min   145K   7.3K/min  Batman
0:52  370K  7.1K/min   662K  12.7K/min  Bionic Commando
1:00  150K  2.5K/min   423K   7.1K/min  Blaster Master
0:23   84K  3.7K/min   232K  10.1K/min  Castlevania
0:43  182K  4.2K/min   420K   9.8K/min  Deadly Towers
0:57  222K  3.9K/min   621K  10.9K/min  Duck Tales 2
2:21  430K  3.0K/min  1165K   8.3K/min  Esper Dream 2
0:36   60K  1.7K/min   172K   4.8K/min  Fester's Quest
0:20   46K  2.3K/min   113K   5.7K/min  Gimmick!
0:51  138K  2.7K/min   459K   9.0K/min  Metroid
0:20   34K  1.7K/min   113K   5.7K/min  Mighty Bomb Jack
0:49   94K  1.9K/min   239K   4.9K/min  Ninja Gaiden
0:34  178K  5.2K/min   405K  11.9K/min  Rygar
0:43  118K  2.7K/min   355K   8.3K/min  Section-Z
0:52   98K  1.9K/min   282K   5.4K/min  Solomon's Key
0:59  180K  3.1K/min   518K   8.8K/min  Wizards & Warriors
0:19   42K  2.2K/min   116K   6.1K/min  Yume Penguin Monogatari
As mentioned on the linked Wiki page, the keyframe rate is entirely adjustable, allowing reduction in file size (you could save a movie with keyframes every 5 minutes, even if you recorded it with them every 30 seconds, for example). The in-memory compression is a custom algorithm I wrote to be extremely fast; using minilzo results in about 35% less memory usage (I imagine even zlib would perform decently, reducing memory usage further). The most recently accessed snapshots are kept uncompressed (and un-modified ones aren't re-compressed, similar to virtual memory), so compression doesn't affect performance much. Implementation is very straight forward; the emulator core exposes functions to emulate one frame, and save/load to/from a memory-based state snapshot. The movie functions are then implemented using these functions. The only reason this scheme might not work for a particular emulator is if it's relatively slow. On a 1.8 GHz Pentium 4 M laptop, my NES emulator runs about 3180 frames per second (5700 with sound and image disabled, as is done when skipping frames during seeking), so speed is not at all an issue in my case. EDIT: I see you were asking about memory usage, so I added that to the above table.
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
JXQ wrote:
Here's a neat idea. How about the ability to take a movie that you are currently working on, select a frame range, and export a movie that plays from a savestate at the beginning of that range? This way, you can show certain parts of your run if that's all you want to do, or you can update WIPs and people won't ask for savestates, all the while working from your master file.
If you have a Mac, take a look at QuickNES (download link). All game play is recorded into a movie, which supports rewind and fast-forward to any point (including single frame stepping), and re-recording at any time. You can trim a movie down to a short segment and save that. You can even watch a movie backwards from end to beginning.
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
My emulator QuickNES runs decently on older machines and has nice movie support with re-recording: http://forums.emuscene.com/viewtopic.php?t=2579 The latest posted version is 1.1b1: QuickNES-1.1b1.sit
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
A month ago I built a NES movie replayer that connects to the controller port and replays data. I got it working both playing live on the NES through it, and replaying a movie recorded with my experimental emulator. I was able to get several-minute Mega Man and Metroid movies to replay consistently. No modification was required to the cartridge, just the replay device that connects to the controller port. There's more about it at the Nesdev thread "PC to NES Transfer Cable".
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
The algorithm summarized: - Make a save state every second, record controller input, and keep the last 60 save states. This allows immediate seeking to any second in the last minute. - To play one second in reverse, restore previous second of save state, generate all frames into an image/sound buffer that has 60 slots, then display the frames in reverse order. - To play continuously in reverse, fill the frame buffer with one second of material. Then, as you display each frame, be filling the buffer with the previous second. Once all 60 frames have been displayed, the buffer is now filled with the previous second. Do the same for each previous second. Note that after setup, CPU usage is not much more than for forward emulation. - A further optimization is to keep the buffer filled at all times with the most recent 60 frames, so that switching to reverse doesn't require immediate generation of 60 frames. When using the example code, set aside however many save states you want to use. Also make a buffer of frames (60 in this example, i.e. one second) and call re_init( 60 ). Implement the emu_ functions in your emulator. Then use re_next_frame() and re_prev_frame() to go forward/backward, using the return value as an index into your buffer of frames to choose which one to display/play the audio of. In most cases, each requested frame results in emulation of only one frame. Currently the code doesn't have a way to specify how far back the save states go; the indicies passed to the save state functions go from 0 to however many seconds (assuming re_init( 60 )) you've emulated since initializing. You could just take the modulo of the save state index, i.e. save_states [n % 60] (note that this 60 isn't the same one as used for re_init() and the number of frames in the buffer). Sorry for the lack of clear writing; I've been up too long.
Post subject: Real-time reverse replay feature
Emulator Coder, Experienced Forum User
Joined: 6/8/2005
Posts: 14
There has been recent discussion and development over at Nesdev of an algorithm for immediate backwards replay at any point, without using much more processing than for normal forwards emulation. In my very experimental NES emulator I made it so if you hit the reverse key, video and audio slow down to a crawl, then smoothly speed up in reverse, similar to the opening scene in The Matrix. Then as it plays backwards, at any point you can pick up playing (or hit the reverse key and replay back to the point where you reversed). It's quite cool. I'm posting this so that any programmers who want to open-source emulators might add this feature, and so that anyone interested can request this in their favorite emulator. I've refined the core algorithm and written a commented C implementation, with callbacks to the emulator, so it shouldn't be hard to integrate (it's only a hundred or so lines long). I'll also provide any assistance with understanding or implementing it. I posted an mp3 from my emulator (I don't have any easy way to make a video, sorry) to the nesdev thread mentioned above and I'd appreciate someone mirroring it and posting the URL here.