I wish I had the time to do this, but it looks like it would be relatively simple to modify render_rasterize.cpp [0] to do perspective-correct texture mapping [1]. I also wonder if going for a scanline approach [2] would be faster than iterating over the whole screen calculating barycentric coordinates?
I used some of your pages for my thesis so thanks for that :)! It is likely that a scanline rasterizer is more performant, but some of the triangles are really small on a 120x120px display, so just the sorting of up to 1500 triangles for each scanline may have its own drawbacks if many are tiny.
One of the other reasons (aside from needed implementation time) for the current approach is also the hope that future microcontrollers might simply have more cores to throw at the problem so rendering could be parallized a lot faster simply by splitting rendering areas.
Definitely plenty of room for improvement everywhere but time is sadly always a factor, hence why I hope others may be able to help ^^.
What do you mean by "sorting 1500 triangles"? You mean sorting their vertices? I believe you already do that in a couple of places; since you're using a depth buffer, I don't think you need to sort them back-to-front, so I'm not sure what you mean.
True that a 120x120 display is tiny, but that also means that you can get away with two static arrays of 120 elements for the left and right sides of the triangle, no need to do any allocation or use tons of memory.
By scanline rasterizer I assumed a system similar to the original Quake scene rasterizer best described in Michael Abrash's Graphics Programming Black Book.
The method allows saving substantially on any overdraw since fillrate is really the primary bottleneck here.
I did a quick check on your page and it seems the implementation describes a per triangle setup vs the more complicated solution by Carmack and his team? Could still work well for larger triangles, maybe with a check on triangle size to avoid really small ones.
Quake did after all utilize 3 different rasterizers to optimize performance depending on use case.
There's also RP2040 Doom which managed to get doom running on the RP2040, complete with sound, music and networking over I2C. The VGA signal is generated by a PIO state machine on the RP2040.
IIRC, the ARM7 one was essentially identical to the ARM7 used in the GBA, and was used for the GBA backwards compatibility mode on the original DS/lite.
As an aside, if you haven’t yet found this wonderful if tiny retro gaming experience, the InfoNES emulator project ported to PicoSystem is definitely worth hitting up:
I wonder what's with safety of such enclosures made of pcbs? For instance is it going to have unpleasant chemicals transferring on the fingers and then to the body when someone touches eyes or mouth?
As a user can confirm siblings comment. The way it's designed your fingers don't really come into contacting the faceplate, and even then it's not raw but painted. Certainly, I have not felt anything coming off of it and I've used it rather a lot.
Intended use of PCBs is to provide a rigid platform supporting electronic components and so would you not agree that regulation is written with that in mind, as the bar for chemical safety would be set higher if the product was intended to be touched (even accidentally), rather than being hidden inside an enclosure away from direct contact?
Use of PCB as a human user interface started in hobbyist world, because it was cheap and easy to create sturdy front panels and was good enough for creating prototypes, but it was never meant for mainstream commercial use in this way - as PCBs even if they meet RoHS, still can contain dangerous chemicals - like flame retardants.
From personal experience I know a 266 MHz (single core) PC from c. 1997 can run 3D games with somewhat comparable graphics just fine (MechWarrior 2, the PC version of FF7) at low SVGA resolutions (640x480 - 800x600).
The Pico3D is 1/2 the performance (133 MHz if you use only one core for rendering), but 1/8 as many pixels (240x240 display).
Definitely a cool project, but based on specs it's actually not that surprising this is possible.
One key relevant difference between the Picosystem/RP2040 and a '97 PC is available RAM and video RAM, the RP2040 has only 264KB of any fast RAM (excluding external flash which has DMA and XiP but is still comparably slow).
Whereas a '97 PC would be in the many tens of MB or possibly hundreds, and at least a few MB dedicated VRAM on a video card. So not an equivalent comparison really, this is a much more constrained environment.
I seem to recall running Windows 95 on a 200mhz - 300mhz processor with 64mb ram.
It wasnt top of the line but I don't think windows 95 was top of the line either. My ex corporate windows 2000 pc upgrade had 128mb ram. Neither had fancy graphics cards.
Mechwarrior as I recall ran on my 486 with 8mb ram. I'd guess that's in the same ball park of 256k for ram with xip flash. With a lot of hand waving of course. It could certainly run doom.
Floating point doesn't really matter much here. Even at the time, you'd typically use integer fixed point math unless you were micro optimizing for the different execution ports of the CPUs you were targeting and didn't want the float pipes to sit idle.
It describes a lot of previous commercial game devices, but doesn't really discuss current alternatives to the PicoSystem. I wonder if there are more capable open-firmware devices at around the same price?
Nothing I'm aware of has nailed the form-factor/ergonomics and quality of the controls. It's a solid unit and has the feel of a finished product. Alternatives are typically bare circuit boards or lack quality input.
It seems like Pimoroni spent time to get those aspects right, and so while there aren't that many games (yet?) - the good quality ones are a joy to play feel-wise, eg Square Bros (which comes installed on a new unit).
The SDK is well thought-out and simple, and has a unified API - micropython or c/c++.
They are apparently working on a successor that plugs into a TV or monitor via HDMI. IIRC it will use two RP2040's.
Huh, I was going to suggest that! There're 80 cents each, so why not? But it seems there's a purpose for it:
> The dual RP2040 chips on the DV Stick will allow it to have one CPU that does the software processing and another that just drives the display. Each of the chips has its own PS RAM chip, which means that there will be more memory than the 264K that comes standard with RP2040 chips / Raspberry Pi Picos.
> "Each of the chips has a PS RAM chip for the frame buffer and, on VSync they swap," Williamson said. "So we have an analog mux that basically swaps the chips between the two so the application processor writes into the frame buffer in one RAM chip then, when VSync occurs in the display, it hands that RAM chip over to the display processor which hands its RAM chip back to the application processor so the display outputs on the screen."
This is so awesome. Well done! I played a little with Pico/RP2040 (as a hobby), and it is so much fun. I wish educational content and institutions would embrace it more quickly.
This is fantastic! I am a huge fan of seeing limited hardware pushed to it's limits (I'm a SEGA Saturn homebrew developer at the moment, but in high school I was huge into GBA, and then eventually DS, programming) and this is the adorable and skill-laden kind of project I love to see on the front page of HN! Great work!
This is really great. I haven’t made much (any) progress, but I would like to do something similar for the Analogue Pocket. Still trying to discern the best use of the FPGA cores for a little 3D world. I’ll take a look and see if there are any nifty tricks here I can leverage.
No in this case the Pico part comes from its use of the Pi Foundation's Pico microcontroller. There are projects[1] that are working on porting PICO-8 to the Picosystem. Unfortunately it will never be fully compatible with the PICO-8 standards as it isn't powerful enough but some games work.
I wish I had the time to do this, but it looks like it would be relatively simple to modify render_rasterize.cpp [0] to do perspective-correct texture mapping [1]. I also wonder if going for a scanline approach [2] would be faster than iterating over the whole screen calculating barycentric coordinates?
[0] https://github.com/bernhardstrobl/Pico3D/blob/main/engine/re...
[1] https://gabrielgambetta.com/computer-graphics-from-scratch/1...
[2] https://gabrielgambetta.com/computer-graphics-from-scratch/0...