1
0
Fork 0

Added RGBA5551 compatibility in the rasterizer

This allows Virtual Console games to display properly.
This commit is contained in:
archshift 2015-02-26 19:11:39 -08:00
parent c9ef377afa
commit 7f9ee69a2b
4 changed files with 42 additions and 3 deletions

View File

@ -46,7 +46,7 @@ struct Regs {
"Structure size and register block length don't match") "Structure size and register block length don't match")
#endif #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 { enum class PixelFormat : u32 {
RGBA8 = 0, RGBA8 = 0,
RGB8 = 1, RGB8 = 1,

View File

@ -28,5 +28,24 @@ static inline u8 Convert6To8(u8 value) {
return (value << 2) | (value >> 4); 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 } // namespace

View File

@ -409,6 +409,7 @@ struct Regs {
} output_merger; } output_merger;
struct { struct {
// Components are laid out in reverse byte order, most significant bits first.
enum ColorFormat : u32 { enum ColorFormat : u32 {
RGBA8 = 0, RGBA8 = 0,
RGB8 = 1, RGB8 = 1,

View File

@ -51,6 +51,16 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) {
break; 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: default:
LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value()); LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value());
UNIMPLEMENTED(); UNIMPLEMENTED();
@ -66,11 +76,11 @@ static const Math::Vec4<u8> GetPixel(int x, int y) {
const u32 coarse_y = y & ~7; const u32 coarse_y = y & ~7;
u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(registers.framebuffer.color_format.Value())); 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; 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) { switch (registers.framebuffer.color_format) {
case registers.framebuffer.RGBA8: case registers.framebuffer.RGBA8:
{ {
Math::Vec4<u8> ret;
u8* pixel = color_buffer + src_offset; u8* pixel = color_buffer + src_offset;
ret.r() = pixel[3]; ret.r() = pixel[3];
ret.g() = pixel[2]; ret.g() = pixel[2];
@ -81,7 +91,6 @@ static const Math::Vec4<u8> GetPixel(int x, int y) {
case registers.framebuffer.RGBA4: case registers.framebuffer.RGBA4:
{ {
Math::Vec4<u8> ret;
u8* pixel = color_buffer + src_offset; u8* pixel = color_buffer + src_offset;
ret.r() = Color::Convert4To8(pixel[1] >> 4); ret.r() = Color::Convert4To8(pixel[1] >> 4);
ret.g() = Color::Convert4To8(pixel[1] & 0x0F); ret.g() = Color::Convert4To8(pixel[1] & 0x0F);
@ -90,6 +99,16 @@ static const Math::Vec4<u8> GetPixel(int x, int y) {
return ret; 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: default:
LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value()); LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value());
UNIMPLEMENTED(); UNIMPLEMENTED();