Post subject: BSNES Core color calculation & background color
Joined: 4/2/2008
Posts: 6
Location: Quebec
Hi everyone! My main hobby is making accurate screenshot maps for various game and to achieve this, I'm looking for emulators with as many tools and features as possible. In fact, I discovered VBA-ReRecording on this forum and it has helped me achieve my greatest work so far (full maps for Castlevania: Circle of the Moon and Aria of Sorrow). I've done maps for many different systems but one system I've been mostly avoiding for the longest time is the SNES. I was so used to using ZSNES that for the longest time I *dreaded* shifting to a better emulator. 8 years ago (in 2012), a regular poster here, feos, tried to get the members of the VGMaps forum excited for BizHawk and to get us to suggest features for future development. A few were made but nobody on our end (including me) really followed through and our forum has been extremely quiet for a few years now. It's probably too late to make any suggestion now but I figured asking a few questions about issues we had at the time wouldn't hurt... 1) Color rendering One of the problem we had is that BizHawk (both cores at the moment) doesn't render the color the same way as older emulators and tools did, namely ZSNES and vSNES. There are things right now such as capturing the content of the graphic buffer for a Mode 7 map that I can't do in BizHawk but can in vSNES. Except, the colors don't match (I think it's because the 15-bits to 16-bits color conversion isn't done the same way) so while trying to map Equinox, the colors of the overworld map captured with vSNES don't match with the sprites' as captured in BizHawk. I'm not asking for a option to render colors the old way (though it would be nice) but if anyone could share the formula for the way the colors are rendered in BizHawk, I could probably write a small program to convert the colors for the few graphics that would require it. 2) Background color This is one of the most essential feature for mappers like me, i.e. being able to change the background color in order to make sprites and layers easier to capture. Usually, that color is black and since many other graphical elements also feature black, being able to alter that color makes it trivial to capture specific graphics while playing instead of having to use the Graphical Debugger (which is still very useful). Not being very knowledgeable about the SNES itself, I have no idea if the background color is always located at the same address in memory and thus, could easily be altered with a simple memory cheat that would work for every game. I remember doing that in VBA-RR with a Lua script and it seemed to work without any change for many different games. Is that something that already exists in BizHawk but I just haven't found it? Or could I implement a similar effect through a Lua script or simple memory hack? Any help at all would be greatly appreciated!
Masterjun
He/Him
Site Developer, Skilled player (1987)
Joined: 10/12/2010
Posts: 1185
Location: Germany
1) You can find the code for the 3 supported palette conversions in BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/SnesColors.cs. 2) The SNES Graphics Debugger has a "User Backdrop" checkbox which allows you to set a background color for the debugger display. Alternatively the backdrop color for backgrounds is the 16-bit value at CGRAM address 0, and the Fixed Color Data at register $2132 is probably also important.
Warning: Might glitch to credits I will finish this ACE soon as possible (or will I?)
Joined: 4/2/2008
Posts: 6
Location: Quebec
Thanks for the fast reply! I'll take a more in-depth look at your suggestions later today to see how I can put this information to use. *** EDIT *** After looking on the GitHub, I found that WDude already mentioned that the BSNES core made the CGRAM accessible so I was quickly able to make a cheat code to produce a pink background (CGRAM address 0000, value 7C1F) that I can toggle on and off as needed. One problem solved!
Joined: 4/2/2008
Posts: 6
Location: Quebec
As for converting an existing graphic's colours from the old method (ZSNES, vSNES) to the new one, the operation is rather easy (each result is rounded *down* to the nearest integer) : R = R / 248 * 255 G = R / 248 * 255 B = R / 248 * 255 In essence, you're simply adjusting the colour scale from 0-248 to 0-255. So far, every file I've run through my little program comes out with the exact same colours that BizHawk displays. If anyone thinks I'm making a mistake, be sure to tell me!
creaothceann
He/Him
Editor
Joined: 4/7/2005
Posts: 1874
Location: Germany
SNES graphics use 5 bits per color channel (i.e. 0..31); emulator authors can choose how they want to expand that to 6 bits per channel (DOS emulators with VGA screen modes), 8 bits per channel (SVGA) or 10 bits per channel (Deep Color). The fastest way is to fill the extra bits with zeroes, and the 'correct' way (using the full color range) is to fill the extra space with a copy of the top bit (VGA) / 3 bits (SVGA) / 5 bits (DC). Removing 3 bits is as easy as dividing each color channel by 8 and then multiplying it again with 8, or applying a bitmask.
const
        Bits_per_channel__SNES = 5;
        Bits_per_channel__PC   = 8;
        delta_bpc              = Bits_per_channel__PC - Bits_per_channel__SNES;

        Mask_bpc = (%11111111 SHR delta_bpc) SHL delta_bpc;

// version 1
R := (R SHR delta_bpc) SHL delta_bpc;
G := (G SHR delta_bpc) SHL delta_bpc;
B := (B SHR delta_bpc) SHL delta_bpc;

// version 2
R := R AND Mask_bpc;
G := G AND Mask_bpc;
B := B AND Mask_bpc;
The SNES screen can show more than 256 colors per frame, thanks to raster effects (one or several colors and/or the brightness register can be changed between lines) and/or color addition/subtraction. So you should be careful when using the emulator's main graphics output.