Added RGBA5551 compatibility in the rasterizer
This allows Virtual Console games to display properly.
This commit is contained in:
		
							parent
							
								
									c9ef377afa
								
							
						
					
					
						commit
						7f9ee69a2b
					
				@ -46,7 +46,7 @@ struct Regs {
 | 
			
		||||
                  "Structure size and register block length don't match")
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // All of those formats are described in reverse byte order, since the 3DS is little-endian.
 | 
			
		||||
    // Components are laid out in reverse byte order, most significant bits first.
 | 
			
		||||
    enum class PixelFormat : u32 {
 | 
			
		||||
        RGBA8  = 0,
 | 
			
		||||
        RGB8   = 1,
 | 
			
		||||
 | 
			
		||||
@ -28,5 +28,24 @@ static inline u8 Convert6To8(u8 value) {
 | 
			
		||||
    return (value << 2) | (value >> 4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Convert a 8-bit color component to 1 bit
 | 
			
		||||
static inline u8 Convert8To1(u8 value) {
 | 
			
		||||
    return value >> 7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Convert a 8-bit color component to 4 bit
 | 
			
		||||
static inline u8 Convert8To4(u8 value) {
 | 
			
		||||
    return value >> 4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Convert a 8-bit color component to 5 bit
 | 
			
		||||
static inline u8 Convert8To5(u8 value) {
 | 
			
		||||
    return value >> 3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Convert a 8-bit color component to 6 bit
 | 
			
		||||
static inline u8 Convert8To6(u8 value) {
 | 
			
		||||
    return value >> 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
@ -409,6 +409,7 @@ struct Regs {
 | 
			
		||||
    } output_merger;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
        // Components are laid out in reverse byte order, most significant bits first.
 | 
			
		||||
        enum ColorFormat : u32 {
 | 
			
		||||
            RGBA8    = 0,
 | 
			
		||||
            RGB8     = 1,
 | 
			
		||||
 | 
			
		||||
@ -51,6 +51,16 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case registers.framebuffer.RGBA5551:
 | 
			
		||||
    {
 | 
			
		||||
        u16_le* pixel = (u16_le*)(color_buffer + dst_offset);
 | 
			
		||||
        *pixel = (Color::Convert8To5(color.r()) << 11) |
 | 
			
		||||
                 (Color::Convert8To5(color.g()) << 6)  |
 | 
			
		||||
                 (Color::Convert8To5(color.b()) << 1)  |
 | 
			
		||||
                 Color::Convert8To1(color.a());
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value());
 | 
			
		||||
        UNIMPLEMENTED();
 | 
			
		||||
@ -66,11 +76,11 @@ static const Math::Vec4<u8> GetPixel(int x, int y) {
 | 
			
		||||
    const u32 coarse_y = y & ~7;
 | 
			
		||||
    u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(registers.framebuffer.color_format.Value()));
 | 
			
		||||
    u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * registers.framebuffer.width * bytes_per_pixel;
 | 
			
		||||
    Math::Vec4<u8> ret;
 | 
			
		||||
 | 
			
		||||
    switch (registers.framebuffer.color_format) {
 | 
			
		||||
    case registers.framebuffer.RGBA8:
 | 
			
		||||
    {
 | 
			
		||||
        Math::Vec4<u8> ret;
 | 
			
		||||
        u8* pixel = color_buffer + src_offset;
 | 
			
		||||
        ret.r() = pixel[3];
 | 
			
		||||
        ret.g() = pixel[2];
 | 
			
		||||
@ -81,7 +91,6 @@ static const Math::Vec4<u8> GetPixel(int x, int y) {
 | 
			
		||||
 | 
			
		||||
    case registers.framebuffer.RGBA4:
 | 
			
		||||
    {
 | 
			
		||||
        Math::Vec4<u8> ret;
 | 
			
		||||
        u8* pixel = color_buffer + src_offset;
 | 
			
		||||
        ret.r() = Color::Convert4To8(pixel[1] >> 4);
 | 
			
		||||
        ret.g() = Color::Convert4To8(pixel[1] & 0x0F);
 | 
			
		||||
@ -90,6 +99,16 @@ static const Math::Vec4<u8> GetPixel(int x, int y) {
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case registers.framebuffer.RGBA5551:
 | 
			
		||||
    {
 | 
			
		||||
        u16_le pixel = *(u16_le*)(color_buffer + src_offset);
 | 
			
		||||
        ret.r() = Color::Convert5To8((pixel >> 11) & 0x1F);
 | 
			
		||||
        ret.g() = Color::Convert5To8((pixel >>  6) & 0x1F);
 | 
			
		||||
        ret.b() = Color::Convert5To8((pixel >>  1) & 0x1F);
 | 
			
		||||
        ret.a() = Color::Convert1To8(pixel & 0x1);
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value());
 | 
			
		||||
        UNIMPLEMENTED();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user