diff options
| author | 2015-02-26 19:11:39 -0800 | |
|---|---|---|
| committer | 2015-02-27 19:15:08 -0800 | |
| commit | 7f9ee69a2bc769042433dba3970137b7be9afa03 (patch) | |
| tree | 096b6debc487a7a87037808130484fe763bb4f6e /src | |
| parent | Merge pull request #599 from Subv/morton (diff) | |
| download | yuzu-7f9ee69a2bc769042433dba3970137b7be9afa03.tar.gz yuzu-7f9ee69a2bc769042433dba3970137b7be9afa03.tar.xz yuzu-7f9ee69a2bc769042433dba3970137b7be9afa03.zip | |
Added RGBA5551 compatibility in the rasterizer
This allows Virtual Console games to display properly.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hw/gpu.h | 2 | ||||
| -rw-r--r-- | src/video_core/color.h | 19 | ||||
| -rw-r--r-- | src/video_core/pica.h | 1 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 23 |
4 files changed, 42 insertions, 3 deletions
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index ab1dcf91d..737b1e968 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h | |||
| @@ -46,7 +46,7 @@ struct Regs { | |||
| 46 | "Structure size and register block length don't match") | 46 | "Structure size and register block length don't match") |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | // All of those formats are described in reverse byte order, since the 3DS is little-endian. | 49 | // Components are laid out in reverse byte order, most significant bits first. |
| 50 | enum class PixelFormat : u32 { | 50 | enum class PixelFormat : u32 { |
| 51 | RGBA8 = 0, | 51 | RGBA8 = 0, |
| 52 | RGB8 = 1, | 52 | RGB8 = 1, |
diff --git a/src/video_core/color.h b/src/video_core/color.h index e86ac1265..f095d8ac5 100644 --- a/src/video_core/color.h +++ b/src/video_core/color.h | |||
| @@ -28,5 +28,24 @@ static inline u8 Convert6To8(u8 value) { | |||
| 28 | return (value << 2) | (value >> 4); | 28 | return (value << 2) | (value >> 4); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | /// Convert a 8-bit color component to 1 bit | ||
| 32 | static inline u8 Convert8To1(u8 value) { | ||
| 33 | return value >> 7; | ||
| 34 | } | ||
| 35 | |||
| 36 | /// Convert a 8-bit color component to 4 bit | ||
| 37 | static inline u8 Convert8To4(u8 value) { | ||
| 38 | return value >> 4; | ||
| 39 | } | ||
| 40 | |||
| 41 | /// Convert a 8-bit color component to 5 bit | ||
| 42 | static inline u8 Convert8To5(u8 value) { | ||
| 43 | return value >> 3; | ||
| 44 | } | ||
| 45 | |||
| 46 | /// Convert a 8-bit color component to 6 bit | ||
| 47 | static inline u8 Convert8To6(u8 value) { | ||
| 48 | return value >> 2; | ||
| 49 | } | ||
| 31 | 50 | ||
| 32 | } // namespace | 51 | } // namespace |
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index d03b811d3..96d0c72fe 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -409,6 +409,7 @@ struct Regs { | |||
| 409 | } output_merger; | 409 | } output_merger; |
| 410 | 410 | ||
| 411 | struct { | 411 | struct { |
| 412 | // Components are laid out in reverse byte order, most significant bits first. | ||
| 412 | enum ColorFormat : u32 { | 413 | enum ColorFormat : u32 { |
| 413 | RGBA8 = 0, | 414 | RGBA8 = 0, |
| 414 | RGB8 = 1, | 415 | RGB8 = 1, |
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index a7bb0612f..8c370781a 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -51,6 +51,16 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { | |||
| 51 | break; | 51 | break; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | case registers.framebuffer.RGBA5551: | ||
| 55 | { | ||
| 56 | u16_le* pixel = (u16_le*)(color_buffer + dst_offset); | ||
| 57 | *pixel = (Color::Convert8To5(color.r()) << 11) | | ||
| 58 | (Color::Convert8To5(color.g()) << 6) | | ||
| 59 | (Color::Convert8To5(color.b()) << 1) | | ||
| 60 | Color::Convert8To1(color.a()); | ||
| 61 | break; | ||
| 62 | } | ||
| 63 | |||
| 54 | default: | 64 | default: |
| 55 | LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value()); | 65 | LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value()); |
| 56 | UNIMPLEMENTED(); | 66 | UNIMPLEMENTED(); |
| @@ -66,11 +76,11 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { | |||
| 66 | const u32 coarse_y = y & ~7; | 76 | const u32 coarse_y = y & ~7; |
| 67 | u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(registers.framebuffer.color_format.Value())); | 77 | u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(registers.framebuffer.color_format.Value())); |
| 68 | u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * registers.framebuffer.width * bytes_per_pixel; | 78 | u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * registers.framebuffer.width * bytes_per_pixel; |
| 79 | Math::Vec4<u8> ret; | ||
| 69 | 80 | ||
| 70 | switch (registers.framebuffer.color_format) { | 81 | switch (registers.framebuffer.color_format) { |
| 71 | case registers.framebuffer.RGBA8: | 82 | case registers.framebuffer.RGBA8: |
| 72 | { | 83 | { |
| 73 | Math::Vec4<u8> ret; | ||
| 74 | u8* pixel = color_buffer + src_offset; | 84 | u8* pixel = color_buffer + src_offset; |
| 75 | ret.r() = pixel[3]; | 85 | ret.r() = pixel[3]; |
| 76 | ret.g() = pixel[2]; | 86 | ret.g() = pixel[2]; |
| @@ -81,7 +91,6 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { | |||
| 81 | 91 | ||
| 82 | case registers.framebuffer.RGBA4: | 92 | case registers.framebuffer.RGBA4: |
| 83 | { | 93 | { |
| 84 | Math::Vec4<u8> ret; | ||
| 85 | u8* pixel = color_buffer + src_offset; | 94 | u8* pixel = color_buffer + src_offset; |
| 86 | ret.r() = Color::Convert4To8(pixel[1] >> 4); | 95 | ret.r() = Color::Convert4To8(pixel[1] >> 4); |
| 87 | ret.g() = Color::Convert4To8(pixel[1] & 0x0F); | 96 | ret.g() = Color::Convert4To8(pixel[1] & 0x0F); |
| @@ -90,6 +99,16 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { | |||
| 90 | return ret; | 99 | return ret; |
| 91 | } | 100 | } |
| 92 | 101 | ||
| 102 | case registers.framebuffer.RGBA5551: | ||
| 103 | { | ||
| 104 | u16_le pixel = *(u16_le*)(color_buffer + src_offset); | ||
| 105 | ret.r() = Color::Convert5To8((pixel >> 11) & 0x1F); | ||
| 106 | ret.g() = Color::Convert5To8((pixel >> 6) & 0x1F); | ||
| 107 | ret.b() = Color::Convert5To8((pixel >> 1) & 0x1F); | ||
| 108 | ret.a() = Color::Convert1To8(pixel & 0x1); | ||
| 109 | return ret; | ||
| 110 | } | ||
| 111 | |||
| 93 | default: | 112 | default: |
| 94 | LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value()); | 113 | LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", registers.framebuffer.color_format.Value()); |
| 95 | UNIMPLEMENTED(); | 114 | UNIMPLEMENTED(); |