Яндекс

Saturday, May 26, 2018

HLE implementation of microcodes for "Indiana Jones" and "Battle for Naboo" completed.

Hello!

The long-awaited implementation of Factor5 microcodes for "Indiana Jones & the Infernal Machine" and "Star Wars Episode I - Battle for Naboo" completed. It was a long road. We started that work last December and finished it only now. It was incredibly hard task. Until December the hardest task we completed was our previous work, microcode for Star Wars - Rogue Squadron. We worked several months on Rogue Squadron. It is very large and very complex microcode. Resulted source code has circa 1300 lines, much larger than implementation of any other microcode. Microcodes for Indiana and Naboo are almost as large as the one for Rogue Squadron, and much more harder to decipher. Factor5 programmers really pushed RSP chip to its limits. We spent six months on decoding and implementation. The microcode has very tangled code flow. Debugging was very long and painful process. Many times I wished to stop that work and never return to it. It was huge relief when we finally squashed the last bug and completed reverse engineering stage. The result is circa 2300 (sic!) lines of source code after all cleanups. Hardest part of work - microcode deciphering - done entirely by olivieryuyu. He wrote tons of excel sheets with explanations how things work. I wrote the code.

I recommend to read interviews with Factor5 developers on IGN for technical details: Bringing Indy to N64 and Battling the Naboo. Cite: "Our new microcode allows almost unlimited real-time lights and a much higher polygon count than the original". It is true. Real time lighting system is amazing. Particles system, which can output thousands particles per frame is very impressive. Microcode for Indiana is true masterpiece. Microcode for Naboo is an extension of the one for Indiana. It extends original microcode with command for explosions (very similar to the one for Rogue Squadron) and with commands for terrain polygons. Landscape generation code has almost nothing in common with landscape code in Rogue Squadron. The result is very impressive. Open air levels have very large draw distance with no need to hide horizon in fog.

I recorded few videos during that long work. You may watch them to see how the project progressed:





Links to test builds can be found on GitHub: https://github.com/gonetz/GLideN64/issues/1259

To help the project:

Sunday, May 6, 2018

Overscan

I have many request from users to "remove these darn annoying black boarders". They refer to black boarder around image, which many N64 games add to compensate overscan. Games for old consoles designed to have black boarders and since GLideN64 does its best to produce as accurate picture as possible, it shows black boarders too.
Black boarders, which can be cropped.
However, GLideN64 does its best to be user-friendly. Thus, Public Release 2.0 introduced Crop feature designed to crop black boarders from the image. Crop efficiently eliminates black boarders, presented in rendered frame buffer.
Crop. Black line at the bottom added by VI.
 However, it does not fix the problem entirely. Many games render image without boarders, but when Video Interface put that image on TV screen, it can do it with offsets from edges of visible area, thus adding black boarders to output by itself. Crop feature can't do anything with such cases. Besides, Video Interface almost always skips one-two scan-lines on top and bottom. These black lines are visible even with Crop enabled. Especially sad story is with PAL games. NTSC standard uses 480 scan-lines. Games programmed to look crisp on TV with 480 scan-lines. PAL uses 576 scan-lines. When NTSC game ported to PAL, it becomes the problem. Game needs larger rendering buffer to utilize 576 scan-lines without loss in quality. These requires massive changes in program code with debugging and testing. Thus, most often porting done in lazy way: ignore extra scan-lines and just center our 640x480 image on PAL TV screen with Video Interface. Result is very large vertical boarders on top and bottom, which GLideN64 of course emulated:
PAL version. Crop can't do anything with black horizontal boarders.
I understand that users are not happy about it, but accuracy first.

I was remembering about that not-critical but annoying problem. Crop of rendered buffer was quite easy and fast to implement. Removal of black boarders added by VI is harder. Recently I got one spare day and decided to make ultimate solution for that problem. The idea has direct analogue in real life. If whole TV picture looks like this:


TV could be tuned to enlarge the picture and move its edges out of visible area:


I made Overscan feature, which, when enabled, redirects output of Video Interface from screen to auxiliary render buffer. Part of that buffer then mapped to screen. In fact, it is Crop, but moved to the final stage of image processing. Offsets from each edge are user defined:
As for Crop, Overscan defines offsets in native resolution. Thus, the same settings work for any user resolution. Our PAL example looks like this with Overscan enabled:

Of course, Overscan is compatible with widescreen hack:
PAL game in FullHD + Overscan
Offsets also can be negative. In that case image becomes shrunk instead of enlarged and we get even bigger black boarders:

Why do that? I don't know. Just an option.

The only problem I see with Overscan feature is that I don't know how to make it automatically pick necessary offsets. User have to do it manually. Overscan settings can be added to ini file with custom game settings. That is, user may pick offsets for a game, save them as custom game settings and never return to that procedure. Custom settings use internal rom name, which is usually the same for PAL and NTSC versions. Since PAL and NTSC versions usually need different Overscan offsets, Overscan has two set of settings.

File with custom settings has plain text format. It can be modified in any text editor and until now it was the only way to update the custom settings file. I implemented save of current settings to custom ini from GUI to simplify that task for end users. If option "Use per-game settings" is enabled, GUI will suggest user to save current settings to custom section. Settings with non-default values will be added to custom section. Run a game, enable Overscan, pick offsets and when everything is Ok save settings to custom ini.

Since image is cropped and then mapped to screen, I recommend to use "Multiple of native resolution" option and set large multiple to get image in high resolution. That way you will avoid quality loss with Overscan. And the last note: proportions of rendered objects are changed when Overscan is used.

To help the project: