|
| Home | Downloads | Screenshots | Forums | Source code | RSS | Donate |
| Register | Log in |
| < OpenGL renderer: status update, and "fun" stuffBecoming a master mosaicist > |
|
blackmagic3: refactor finished! Jan 13th 2026, by Arisotura |
|
The blackmagic3 branch, a perfect example of a branch that has gone way past its original scope. The original goal was to "simply" implement hi-res display capture, and here we are, refactoring the entire thing. Speaking of refactor, it's mostly finished now. For a while, it made a mess of the codebase, with having to move everything around, leaving the codebase in a state where it wouldn't even compile, it even started to feel overwhelming. But now things are good again! As I said in the previous post, the point of the refactor was to introduce a global renderer object that keeps the 2D and 3D renderers together. The benefits are twofold. First, this is less prone to errors. Before, the frontend had to separately create 2D and 3D renderers for the melonDS core, with the possibility of having mismatched renderers. Having a unique renderer object avoids this entirely, and is overall easier to deal with for the frontend. Second, this is more accurate to hardware. Namely, the code structure more closely adheres to the way the DS hardware is structured. This makes it easier to maintain and expand, and more accurate in a natural kind of way. For example, implementing the POWCNT1 enable bits is easier. The previous post explains this more in detail, so I won't go over it again. I've also been making changes to the way 2D video registers are updated, and to the state machine that handles video timing, with the same aim of more closely reflecting the actual hardware operation. This will most likely not result in tangible improvements for the casual gamer, but if we can get more accurate with no performance penalty, that's a win. Reason is simple: in emulation, the more closely you follow the original hardware's logic and operation, the less likely you are to run into issues. But accuracy is also a tradeoff. I could write a more detailed post about this. If there are any tangible improvements, they will be about the mosaic feature, especially sprite mosaic, which melonDS still doesn't handle correctly. Not much of a big deal, mosaic seems seldom used in DS games... Since we're talking about accuracy, it brings me to this issue: 1-byte writes to DISPSTAT don't work. A simple case: 8-bit writes to DISPSTAT are just not handled. I addressed it in blackmagic3, as I was reworking that part of the code. But it's making me think about better ways to handle this. As of now, melonDS has I/O access handlers for all possible access types: 8-bit, 16-bit, 32-bit, reads and writes. It was done this way so that each case could be implemented correctly. The issue, however, is that I've only implemented the cases which I've run into during my testing, since my policy is to avoid implementing things without proper testing. Which leads to situations like this. It's not the first time this happens, either. So this has me thinking. The way memory reads work on hardware depends on the bus width. On the DS, some memory regions use a 32-bit bus, others use a 16-bit bus. So if you do a 16-bit read from a 32-bit bus region, for example, it is internally implemented as a full 32-bit read, and the unneeded part of the result is masked out. Memory writes work in a similar manner. What comes to my mind is the FPGA part of my WiiU gamepad project, and in particular how the SDRAM there works, but the SDRAM found in the DS works in a pretty similar way. This type of SDRAM has a 16-bit data bus, so any access will operate on a 16-bit word. Burst modes allow accessing consecutive addresses, but it's still 16 bits at a time. However, there are also two masking inputs: those can be used to mask out the lower or upper byte of a 16-bit word. So during a read, the part of the data bus which is masked out is unaffected, and during a write, it is ignored, meaning the corresponding bits in memory are untouched. This is how 8-bit accesses are implemented. On the DS, I/O regions seem to operate in a similar fashion: for example, writes smaller than a register's bit width will only update part of that register. However, I/O registers are not just memory: there are several of them which can trigger actions when read or written to. There are also registers (or individual register bits) which are read-only, or write-only. This is the part that needs extensive testing. As a fun example, register 0x04000068: DISP_MMEM_FIFO. This is the feature known as main memory display FIFO. The basic idea is that you have DMA feed a bitmap into the FIFO, and the video hardware renders it (or uses it as a source in display capture). Technically, the FIFO is implemented as a small circular buffer that holds 16 pixels. So writing a 32-bit word to DISP_MMEM_FIFO stores two pixels in the FIFO, and advances the write pointer by two. All fine and dandy. However, it's a little more complicated. Testing has shown that DISP_MMEM_FIFO is actually split into different parts, and reacts differently depending on which parts are accessed. If you write to it in 16-bit units, for example, writing to the lower halfword stores one pixel in the FIFO, but doesn't advance the write pointer - so subsequent writes to the same address will overwrite the same pixel. Writing to the higher halfword (0x0400006A) stores one pixel at the next write position (write pointer plus one), and advances the write pointer by two. Things get even weirder if you write to this register in 8-bit units. Writing to the first byte behaves like a 16-bit write to the lower halfword, but the input value is duplicated across the 16-bit range (so writing 0x23 will store a value of 0x2323). Writes to the second byte are ignored. Writes to the third byte behave like a 16-bit write to the upper halfword, with the same duplicating behavior, but the write pointer doesn't get incremented. Writing to the fourth byte increments the write pointer by two, but the input value is ignored. You can see how this register was designed to be accessed in either 32-bit units, or sequential 16-bit units, but not really 8-bit units - those get weird. Actually, this kind of stuff looks weird from a software perspective, but if you consider the way the hardware works, it makes sense. So this is another area of melonDS that likely warrants some refactoring and intensive testing. Would be great to finally close all the gaps in I/O handling once and for all. But this won't be part of blackmagic3 - it's way beyond the scope. As far as blackmagic3 is concerned, we're getting pretty close now. I still need to add mosaic support, the various bits like "forced blank", and do a bunch of cleanup, optimization, ... As a bonus, have an "epic fail" screenshot. Between things like this, and melonDS crashing in RenderDoc due to uninitialized variables, it's been a bit rocky to get the renderer working again... |
| 8 comments have been posted. |
| < OpenGL renderer: status update, and "fun" stuffBecoming a master mosaicist > |
|
Ian Macaya Gonzalez says: Jan 13th 2026 |
| Hello, good morning/evening depending on the time of day you're reading this. I don't mean to bother you, but suddenly, in the PC version of Melonsds, version 1.0 (the July 2025 update), at the end of November, I stopped being able to connect to the GTS in Pokémon Platinum, HeartGold, and SoulSilver to trade. Now that I can connect in the Android version of the emulator, I still can't connect to the GTS in those three games (I tried it a few minutes ago with Pokémon Platinum on Android and it didn't work). I'd like to know if this is due to a problem with the emulator or not, and if so, I'd appreciate it if you could fix it. Anyway, goodbye, sorry for the inconvenience. |
|
Klauserus says: Jan 14th 2026 |
| Home stretch. Great. Keep it up. |
|
Jase Vendor says: Jan 15th 2026 |
|
Heya, it's been far too long since I last posted here, good luck to you and your project this year captain, you've given a lot of folk hope to see this through no matter where it goes! Seriously, crush it good out there Arisotura, as well as whoever else is working on this! By the way, I was gonna ask on the forum how to get my settings from a previous MelonDS installation, Go figure I'm blind and didn't check inside the MelonDS.toml. Any possibility to change it's name to be something like MDSSettings so some people know? Less that's too much or not advisable, I understand fully that it'd be too much, or cause issues with past installations. |
|
LEGO_Vince says: Jan 15th 2026 |
| Hell yeah, my man. Keep it up. |
|
morelikejonarbuckle0 says: Jan 16th 2026 |
| *my lady (or them i guess idk) |
|
theaddict says: Jan 16th 2026 |
| I was wondering if frame deduplication will ever be implemented in melonds like it is in duckstation and PSCX2, displays the real frame rate of games that render at below 60 fps, (like games that are locked at 30), to allow for use of AFMF or LSFG to artificially increase frame rates without increasing the speed of the game. |
|
^o^ says: Jan 17th 2026 |
| I LOVE MELONDS! |
|
blub says: Jan 17th 2026 |
|
>that feel when you accidentally obliterate uVRAMMask in your UBOs when resetting the data Classic! |