In Contra, just to have an example, the game slows down when there's a lot of action happening. What if invisible sprites (or whatever) were added in whenever a lot of action isn't happening in order to keep the game constantly running at "slowdown" speed, and then the overall speed of the game was just "turned up"? By that, I mean like each moving object in the game is modified to move faster. As in, every single velocity (or is it just speed?) setting is recalculated. Also, the music would be resequenced to play at a faster tempo. Okay, this may not be feasible, but is this at least possible? Or am I missing something?
What you describe is slowing the entire game to less than 60 fps. A few games did this, such as anything developed by Micronics, Bugs Bunny Birthday Blowout, every Super FX game that isn't Yoshi's Island, and almost all PlayStation and Nintendo 64 games. Some Game Boy games ran at a low frame rate to compensate for the original Game Boy's slow LCD, such as Balloon Kid (and its NES port Hello Kitty World).
Other games update only half the objects each frame, such as enemies in Mega Man or explosions and smoke particles in Thwaite. Or they will run certain tasks only every few frames, such as the 21-frame IntervalTimerControl cycle of Super Mario Bros. or the 6-frame tenths cycle of Thwaite.
You don't need to go through all that to make more slowdown.
Just count frames. If you want the game to run at 30FPS, and the game has finished all its calculations within 1 frame, wait another frame before running the game logic.
And you should never need to sabotage the music. You have interrupts, music code can always be run every frame with no problems, if you do it correctly. If a game slows down the music during heavy action, it isn't programmed correctly. If the music pauses while the game switches screens (I'm looking at you, Bases Loaded), it's also programmed incorrectly.
Also, Wizards and Warriors 3 ran at half speed, but interpolated all the motion so you couldn't tell that it wasn't full speed.
Ignoring the possible sound issues, you could overclock the system to eliminate slowdown. The main games I remember having alot of slowdown at times were TMNT1 and Kirby's Adventure when using certain powers. It was annoying in TMNT1, but in Kirby not so much.
If you're emulating, or if you can engineer some sound solution, you could offload the entire sound driver to free up CPU time. Instead of having the NES CPU handling all of that it could just write sound commands to a register that would play the appropriate effects or musical arrangements.
Finally, you could investigate what exactly is happening when the game slows down and see if there isn't something that could by optimized somehow. When many games were programmed they didn't have time to truly optimize performance. And the #1 priority was that the game works, slowdowns were acceptable. Glitches not so much.
30 fps in 2D scrolling games looks pretty bad, actually. It is better to design the game and optimize the ccode in a way that will prevent any slowdowns.
Shiru wrote:
30 fps in 2D scrolling games looks pretty bad, actually.
I agree, the scrolling makes it really noticeable. One option would be to slowdown other things but not the scrolling itself. I don't think it would be too annoying if only the enemies (which are often the biggest cause of slowdowns) slowed down.
30fps generated by showing a frame twice isn't merely more choppy than 60fps; since it involves each image being shown for two frames, it greatly increases sample-and-hold motion blur when your eyes follow moving objects. That is, if the flicker weren't so awful, it would actually look smoother if the game put up a black screen every other frame in order to achieve 30 fps. Note that this all applies to a CRT or other display that only displays the image for a tiny fraction of the frame duration.
Any YouTube video of an NES game will show you what it would look like at 30hz. I love the smoothness of 60hz, but I don't think it looks unacceptable to run at 30hz. Outside of the car racing genre, most modern 3D console games target 30hz to give the renderer more time.
Anyhow, for some games you can probably eliminate slowdown just by having the emulator overclock the CPU. Make sure that the PPU, IRQs, and the APU still run at the regular speed, and just have the CPU execute twice as fast maybe.
There are many games that rely heavily on CPU timing that this won't work at all for (e.g. Battletoads or Rad Racer would require code hacks to compensate for the timing difference) though these games might not have slowdown at all, since timing is critical in these situations they may have been careful not to let it happen. A lot of games will rely on a little bit of CPU timing, especially where split-scrolling is involved, and these may be made slightly-to-very buggy by overclocking.
I guess a rule of thumb is if you can run an NTSC game in PAL mode or vice versa without problems, overclocking the CPU will likely be okay for the game.
Another thing you might try is only overclocking when not inside NMI, if you find a game where the NMI code's timing is critical (e.g. rendering, status bar), but the non-critical update (e.g. characters/gameplay) is outside the NMI.
My emulator has an overclocking feature that just adjusts the ratio of PPU clocks to CPU clocks. Most games work just fine, but it depends obviously how other components in your emulator work. TMNT1 gets a very nice improvement.
Another way to reduce slowdown that has been mentioned in emulation is to add fake lines. After the last rendered line before NMI you could run the CPU for many extra scanlines worth of time to allow game logic to finish up this frame's processing. Although for TMNT1, you'd want extra scanlines of processing to be available towards the beginning of drawing and not the end since it needs to complete processing before the status bar at the bottom is to be rendered. Other games obviously that would be bad like Zelda or SMB1 would waste all that extra time waiting for sprite zero.
I guess one thing you could do that might be fairly compatible would be at line 120 stop rendering or updating sound and just run the CPU for some extra lines worth of time. If you added around 38 dummy scanlines at 120 it would be something like having the CPU running at a bit over 2mhz. Maybe your emulator could let the user adjust how many dummy scanlines to give the CPU, and at what scanline position.
Overclocking?
I just reused Dendy Mode, and set the frame rate to 60FPS. Only issue is that the APU frame counter runs a little faster than normal, so sweeps and envelopes are too fast.
You can "overclock" emulators by adding a bunch of scanlines (maybe 240, 480 or even more) between the end of the display and the start of VBlank. Most timed effects use the start of VBlank or the start of the visible frame as reference, so this modification will give more time for the game engines without breaking timed code in most cases. It will probably still break some games that rely on the time between frames, but I imagine those are very few.
Say you have developed a game for NES emulators, and it turns out to be overclock-dependent and won't run well on the NES. If you don't want to take it down to 30 fps, there's always the option to port it to the Super NES, which gives you several ways to speed up the game engine. You get a 70% faster CPU (on average, assuming fast ROM and slow RAM), 16-bit adds for faster game physics calculations, a bunch of RAM to decompress entire maps instead of having to unpack a row or column at a time, a sane map format instead of bit-packed attributes in a separate part of the nametable, sound engine offloading, a second layer for the status bar so that you don't have to spin on sprite 0, and even the equivalent of Blast Processing to fill the CHR RAM quickly and to push nametable rows and columns into VRAM more quickly.
Tokumaru: That's what Dendy does. To make 60 Hz games run on a 50 Hz console, it inserts 50 extra post-render lines before NMI.
If you still want to do the "always in 30fps slowdown mode" method, you don't need to display extra sprites. You can cause slowdown by adding a "waste time" routine, like this:
lda #$ff
waste_time:
dec
bne waste_time
psycopathicteen wrote:
lda #$ff
waste_time:
dec
bne waste_time
Just like I said in
another thread earlier today: why guess arbitrary delays when the system gives you all the information you need? Think about it: you have a dummy loop that wastes 10,000 cycles hoping that this will make frames with few enemies take longer, but what happens on busy frames? You'll most likely get 3 repeated frames, instead of 2. Not so "always in 30fps slowdown mode" now is it?
The PPU tells you when each frame is rendered, so just count the freaking VBlanks. Every other VBlank you update the PPU so it can draw a new frame, otherwise just return from the interrupt and let the game logic continue. This will get you a steady 30fps (unless things get insanely busy to the point where 2 frames aren't enough to process a single game frame).
tokumaru wrote:
You can "overclock" emulators by adding a bunch of scanlines (maybe 240, 480 or even more) between the end of the display and the start of VBlank. Most timed effects use the start of VBlank or the start of the visible frame as reference, so this modification will give more time for the game engines without breaking timed code in most cases. It will probably still break some games that rely on the time between frames, but I imagine those are very few.
Indeed, for emulators it would seem extending the rendering peroid by some crazy amount of scanlines would be the most compatible way of reducing slowdown. Most timed raster effects would not be impacted and you would be far more likely to never miss a frame update. I don't think 480 extra lines are needed in most cases. Something like 394 total scanlines (132 extra) would be close to SNES SlowROM speed. If you added 480 extra lines that would be similar to having the NES CPU running at over 5mhz I believe.