The Sega Saturn and Transparency
mattgreer.org
mattgreer.org
The best workaround is to just use VDP1 for everything. I'm not sure why you wouldn't in a cross-platform 2D game given that it would be most analogous to what you needed to do on the Playstation. It didn't have any dedicated hardware for backgrounds so you needed to use textured triangles for everything.
Heh, I was only 11 when the Saturn came out. I've been involved in the Sega homebrew/emulation community for a long time though. Mostly focused on the 16-bit stuff, but I've toyed with the idea of working with the Saturn and read some documentation.
The code should be quite easy to read, as I wrote it to be close to what the hardware does, without any additional complexity for optimizations.
Your code is quite clean, but I'm not sure I'd say the rendering code is all that close to what the hardware does.
For instance, the hardware does sprite rendering in 3 distinct phases (sprite list is scanned for sprites on the current line and the first 20/16 are recorded somewhere, the non-cached half of each of those 20/16 sprites is read and then up to 40/32 tiles worth of pixel data is drawn to the line buffer.
Background layer rendering is a bit different too. The VDP actually renders an extra 2 columns worth of background data (so 42 or 34 total) to enable fine scrolling. Rendering takes place 2 columns at a time to what I believe is a 32 pixel ring buffer. The data in the ring buffer is composited with the data in the sprite line buffer as it's output to the display. The "window bug" is just a consequence of the 2 column coarse scroll granularity and the fact that it literally replaces the Plane A draws to the ring buffer.
This is not intended as a criticism of your code. If you're only going for scanline granularity, most of the above is of little consequence (apart from the window bug) and would only add complexity. That said, I think my emulator, BlastEm[0], is probably a better reference for low-level VDP behavior as it has access slot granularity and mirrors the behavior above pretty closely. The code has gotten a bit messy though. There's also Exodus[1], which has a quite heavily commented VDP core (a bit too heavily for my taste, but I imagine others may disagree).
[0] http://rhope.retrodev.com/files/blastem.html [1] https://bitbucket.org/exodusemulator/exodus
EDIT: Fixed typo "line scrolling" should have ready "fine scrolling in the 3rd paragraph.
OK you're right, what I really meant is that my code is a clear description of the basic hardware features and how they work, at the level of the detail discussed in the blog post being discussed (OP). As you noticed, I'm not emulating anything sub-scanline.
If you look at the precise_dma_fifo branch, I've attempted some sub-scanline precision timing, while keeping the rendering at the scanline level. The result is encouraging: for instance, the 512C "your emulator suck" screen in Overdrive correctly works (at least in the PAL version IIRC). I think I hit a limit with the way timing was computed in the CPU cores I was using, and then dropped it for boredom. There were also a few regressions, visible in Overdrive itself (which is almost perfect on master, with the 512C screen being the big exception).
> I think my emulator, BlastEm[0]
Thanks for the reference, I'll have a look.
Overdrive is tough. It has some nasty race conditions in it and of course the 512C scene requires a reasonable approximation of the reduction in sprite capacity. I don't have it working 100% myself (wanted to get some other timing related things tightened up before trying to chase down the cause of race that doesn't happen on real hardware). I commend you on getting as far as you did.
The moose chase level of Mickey Mania is another good thing to check out as it also requires emulation of the sprite capacity reduction.
Another little thing I'm currently working on is a Nintendo DS emulator written 100% in Go: https://github.com/rasky/ndsemu
This is very early stage, it boots the BIOS but barely boots any game and they're all very garbled.
The nice thing is that I'm emulating graphics fully in parallel with goroutines, so the GPU runs in parallel with CPU. They even potentially access the same memory (VRAM) and I didn't put any mutex/lock there, as theoretically the undefined behavior is similar to what happens in the real hardware... :) I'm curious to see if the strategy pays and I'm able to complete the emulator like this. I'm going to also emulate sound in this way.
As for optimizations go, the approach is a little bit different: I had to optimize things here and there to work around (many) Go compiler deficiencies and achieve decent speed. So the code is less "barebone" than Genesis, and that adds up to the fact that the hardware is vastly more complex per-se.
I've also factored out generic code in the "emu" sub-package, that is a collection of generic emulation-related classes/packages that could be reused for different emulators in Go.
I would expect at least the BIOS to be needed, maybe the firmware is custom; it is certainly possible to emulate the BIOS via HLE (I know some emulators do it), but I find it a little outside of the scope of my projects. I might get to it, eventually.
I also dispute that owning a dump of a game/BIOS of a console you own is illegal, but that's a large discussion for lawyers :)
/annoyed at the "Let me turn three sentences into a YouTube video" phenomenon
http://www.theguardian.com/technology/2015/may/14/sega-satur...
Funnily enough we see Sony repeat the same mistake in the PS3, doubling down on a chip architecture aimed at parallelism (cell), while most developers expressed frustration adapting.
Didn't really hurt Sony in the big picture though as much as it hurt SEGA. By the time SEGA got so much right in the Dreamcast era, they were already swimming upstream thanks to the ground they lost with the Saturn.
This was another reason they got lots of flame with the PS3, as not only was it hard to program for, the SDK wasn't that great.
Hence why they spent around two years time bringing out a great graphics debugger developed with input of teams like the Gran Turism one, and a middleware for prototyping ideas, PyreEngine.
Years later Sonic Team released SGL 2.0, a much nicer high level C API which showed the true potential of the Saturn, but it was too late to claw back the lead Sony had built up.
Yes, but...
Double Fine has this Let's Play series with video game developers called -IIRC- Devs Play. One of the first videos is a playthrough of Aladdin and The Lion King on the Sega Genesis. One of the comments that the guy who worked on both titles makes is that you have to keep in mind the target display device [0] when evaluating the art and VFX choices for a given game. The art for both games -but Aladdin in particular- is really gorgeous, but loses a fair bit of its beauty when viewed as hard-edged pixel art on an LCD screen.
The hard-edged pixel art that we see on modern sets is likely not at all what the art and effects teams who worked on these games intended. Their design decisions took into account the blurring effect of the target display device.
[0] Namely, NTSC/PAL CRT TV sets.
I expect you have to keep pretty far away from that stuff, the same as ReactOS/WINE had to stay away from MS source code years ago.
Yet it increases quality because these games were back then developed to work best with old CRT TVs that could only show interlaced video.
Also OT: I had never heard of Wintersmith, which the author uses for his blog, but it looks like a pretty capable Jekyll-like site generator in node: http://wintersmith.io
Very cool article.