4 ms·
Wow, so, ok. Former N64 programmer here, so my take is certainly biased but here goes. This guys has clearly done a lot of work, building on top of the existi
by midnightclubbed 5y ago
Wow, so, ok. Former N64 programmer here, so my take is certainly biased but here goes.
This guys has clearly done a lot of work, building on top of the existing reverse disassembly of the Mario 64 codebase and has a great understanding of the heavily dissected 25 year old hardware. And that's where my paise stops.
The level of snark here is outstanding. Maybe its a cultural thing, maybe he's trying to hype up his Patreon, but he comes across to me as a complete egotistical a-hole. Does he really think the Nintendo programmers were 'smelling the grass' rather working 24/7 to get a ground-breaking game shipped. He does his best to call the team who made several of the most influential and important video games of all time incompetent.
Breaking down his snark:
- The RSP/RDP co-processor had microcode that the game programmers interacted with (you generated a rendering command list on the CPU and called a library function to start the RSP processing that scene). So any criticisms of things the Mario team could have moved to the RSP (ie billboard calculations) are short-comings of the microcode made available by the NCL driver/hardware team - post launch there were regular revisions to the microcode and optimizations made available.
- A lot of the matrix operations were provided in library form to game teams and you were encouraged (forced) to use them rather than rolling your own - there was probably a concern that an overly aggressive optimization would send bad data to the RSP/RDP and cause issues on current or future hardware revisions. The divide by zero checks were likely there for similar reasons - the RSP microcode could run in a mode that skipped near-plain clipping of triangles, which was faster but would blow up spectacularly (huge jaggie triangles all over the screen) if you had triangles that did indeed clip into the near plain.
- I have not seen the Mario 64 source but I imagine some of the lowest level code was written in mips assembly but has been decompiled into C. I may be wrong here, but if that is the case there were likely branch-delay-slot optimizations and cycle counted operations that have been trampled by the reverse engineering. I may be off-base here so would love to know if that is the case?
- Yes the gameplay code has unused variables, duplicated code, etc. But this was a brand new genre of game, there would have been a lot of experimentation, tuning, things would have been in flux until shipping and there certainly was no time to refactor and run the risk of breaking something.
- I suspect the debug flags in gameplay code were to avoid compiler bugs. The mips compiler would sometimes emit some back-back floating point operations that caused the N64 mips cpu to hang (but was fine for all other mips processors). That may have affected the gameplay code with optimizations enabled. Later there was a command-line tool you had to run on your game elf that would look for this bad combination of instructions (and you would then change the offending code until the compiler did not emit the 'bad' instruction combination). Gcc was not allowed by Nintendo until much later, and had its own issues.
- Older floating point units were less predicable with numerical accuracy, rounding errors etc. If early testing showed differences in game control/feel between the debug and optimized builds then I can see why the team would be more comfortable shipping with debug code rather than risking a bug that was not picked up until after you manufactured a million or two cartridges.
- The memory bank conflicts were well documented and games worked around/with that knowledge. Mario 64 was likely well under development before that information was known. As others have pointed out, using the memory expansion module is cheating - that gives you a whole bunch of un-conflicted memory banks to use. 2x the memory also gives a lot of optimization oppertunities.
- I don't see a 6x speedup. I see ~10% gains in most systems and a best case frame time improvement from 29 fps to 41 fps. Which is pointless. An NTSC tv runs at 60Hz, you either hit 60fps or 30fps, anything in-between results in horrible tearing of the screen or your frames bounce between 60 and 30 and movement feels horrific. The game was optimized to hit targets and to ship.
- His split screen optimization is crap! Reducing load on the RDP (rasterizer) by killing rendering area (big black bars on the screen) is lazier than most everything he snarked on. The slightly better approach would be to ab-use the TV output timing registers so that the screen buffer can be less than 320x240 but still fill the screen. You trade black bars for smeary sludge but on the target NTSC TV that was generally the way to go if you didn't want your game rejected by Nintendo QA. Or actually re-write the renderer and reduce the amount of pixel fill.
- And a minor nit pick, the sound processing was not done on the CPU (as he claimed). The cpu built audio command lists that the RCP then used to generate the output waveforms.
- holmium 5y ago> The level of snark here is outstanding. [...] 'smelling the grass' I thought his snark wasn't too off the charts in this video. I'd bet it's more a cultural thing. If you were working on the N64, you're probably like two decades above Kaze's target audience for his youtube videos haha. Like, he said that you can either be a weirdo who spends all day optimizing nearly 30 year old source code, or someone who "touches grass"[1]. He, of course, was referencing his own lack of life, not Nintendo's programmers. But, you'd have to pretty familiar with current online memes and insults to get his joke. > I have not seen the Mario 64 source but I imagine some of the lowest level code was written in mips assembly but has been decompiled into C. No, we only decompiled C code back into C code. The decompilation matches 1 to 1 with the released ROM images.[2] iirc, the only, non-libultra ASM code was the decompressor[3]. The C code was pretty obvious due to "wonders" of IDO -O0 optimization. We were forced to get surprisingly close to what Nintendo wrote. We were stuck with an `f32 [3]` 3-vec instead of a `struct`... > I suspect the debug flags in gameplay code were to avoid compiler bugs. As far as we could tell, this wasn't an issue. IDO 5.3 had no issues that we could find when compiling at -O2, but then again it was decompiled code. I personally subscribe to the '-O2 -g' IDO meme, but Giles Goddard thought it was out of fear of the unknown. So, I'd trust him. We had the `mulmul` patch for IDO. I don't know the chronology for the release of that patch to devs, though. We also haven't been able to find any N64s that have the mulmul issue. > An NTSC tv runs at 60Hz, you either hit 60fps or 30fps, anything in-between results in horrible tearing of the screen or your frames bounce between 60 and 30 and movement feels horrific. I wonder what Kaze is doing. I know that there was work on a variable framerate mod/revamp for SM64. I'd guess it'd be outputting at the N64's 60 fps mode with duplicated frames, but you'd have much better luck asking one of the modders/coders who were working on that a couple years ago. ---------- [1] which is Twitter's insult du jour: https://knowyourmeme.com/memes/touch-grass https://knowyourmeme.com/memes/touch-grass [2] https://github.com/n64decomp/sm64 https://github.com/n64decomp/sm64 [3] https://github.com/n64decomp/sm64/blob/master/asm/decompress.s https://github.com/n64decomp/sm64/blob/master/asm/decompress...
- midnightclubbed 5y agoThanks for filling in the details on the disassembly, I'm surprised the matrix functions weren't in asm but I believe you. If I remember correctly NOA did the CPU/lib side and NCL did the RSP code (definitely in asm) and hardware side. The back to back multiplies definitely could cause hangs on real hardware (actually I'll back up and say it certainly could hang a dev-board and I think the hardware was the same as production). I don't know if there were particular registers or data that caused the hang but I remember QA picked up hangs with builds that had them in there. Adding extra frame buffers lets you output at 60Hz without tearing but you'll bounce between duplicated frames and single frames. You technically get 40fps (or whatever) but smooth camera movements feel 'off'. That extra frame eats pretty badly into the remaining space in the 2Mb base memory (at 640x480 you could have just one frame buffer and render interlaced, so long as your frame rate always hit 60Hz).