Hi everyone! Recently I've been working on a PC game tentatively titled Steel Assault, which aims to emulate a late NES graphic style (inspired by games such as Shatterhand and Batman where heavy dithering and details in negative space are used to create a dark atmosphere within system limitations). The game isn't adhering strictly to limitations (two of my assumptions are infinite cartridge space and expanded sprite limits lol), but I'd like for most of it to be plausible on the NES in some limited form or another. Anyway, one of my ideas for the game is to have a short (60 seconds or so) FMV intro at the start, detailing the game's scenario and background. Searching these forums, it seems like not many people have tackled the problem of FMV on the NES (aside from the Bad Apple demo, which is super cool), so I decided to try my hand at it this past week, and also learn more about NES coding (I have a bit of homebrew experience on 16-bit consoles, but this was my first major foray into 8-bit). My approach was inspired by this post by tokumaru, though I haven't implemented all of the ideas he suggested yet.
Well, it works! It's kind of stuttery at times, though (especially when there are large changes from frame to frame), and the pixelation/lack of double buffering isn't helping (more on this later). Here are some screenshots:
The videos are clips from 500 Days of Summer, Goodfellas, and Blade Runner respectively. The .nes files are attached; they look best in Nintendulator, but work on FCEUX and Nestopia as well. (My favorite is the Goodfellas clip, which plays part of the movie's famous Copacabana tracking shot.) Here are some statistics on the clips used:
Note that the ROMs crash after the clip ends lol, because I haven't bothered putting in video length values yet. Also, there isn't any music, and I doubt there's currently enough rendering time left to play any (but I haven't tried yet).
The main bottleneck seems to be that the compressed video format is bit-aligned rather than byte-aligned.* I've implemented various techniques to mitigate the effect of this, but I still can't get it fast enough to consistently render all (15FPS video) frames in under 4 NES frames; in fact, some take as many as 6 to 8. In addition, given the approach I'm taking, double buffering wastes another frame or more when turned on (as it has to copy 2048 bytes from one RAM bank to another), so video is only single buffered. I'm going to try and come up with a byte-aligned format for interframes later and see if I can get better speed while still maintaining a decent compression ratio (right now it's about 25-30%, compared to an uncompressed video which uses 2KB for each frame).
But yeah, I hope you enjoy the demos! And if anyone's interested, I can post more about the compression format and how rendering works later. (Or, you can try and find out yourself... :D)
Sri
* This decision was partially because, until I actually implemented decompression on the NES itself, I was using Huffman encoding on the delta values and naively thought I would be able to decode them in realtime.
Well, it works! It's kind of stuttery at times, though (especially when there are large changes from frame to frame), and the pixelation/lack of double buffering isn't helping (more on this later). Here are some screenshots:
The videos are clips from 500 Days of Summer, Goodfellas, and Blade Runner respectively. The .nes files are attached; they look best in Nintendulator, but work on FCEUX and Nestopia as well. (My favorite is the Goodfellas clip, which plays part of the movie's famous Copacabana tracking shot.) Here are some statistics on the clips used:
- goodfellas - 51 seconds; 441,086 bytes of video
- 500ds - 74 seconds; 482,548 bytes of video
- bladeRunner - 48 seconds; 452,686 bytes of video
Note that the ROMs crash after the clip ends lol, because I haven't bothered putting in video length values yet. Also, there isn't any music, and I doubt there's currently enough rendering time left to play any (but I haven't tried yet).
The main bottleneck seems to be that the compressed video format is bit-aligned rather than byte-aligned.* I've implemented various techniques to mitigate the effect of this, but I still can't get it fast enough to consistently render all (15FPS video) frames in under 4 NES frames; in fact, some take as many as 6 to 8. In addition, given the approach I'm taking, double buffering wastes another frame or more when turned on (as it has to copy 2048 bytes from one RAM bank to another), so video is only single buffered. I'm going to try and come up with a byte-aligned format for interframes later and see if I can get better speed while still maintaining a decent compression ratio (right now it's about 25-30%, compared to an uncompressed video which uses 2KB for each frame).
But yeah, I hope you enjoy the demos! And if anyone's interested, I can post more about the compression format and how rendering works later. (Or, you can try and find out yourself... :D)
Sri
* This decision was partially because, until I actually implemented decompression on the NES itself, I was using Huffman encoding on the delta values and naively thought I would be able to decode them in realtime.