summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar archshift2015-02-26 19:11:39 -0800
committerGravatar archshift2015-02-27 19:15:08 -0800
commit7f9ee69a2bc769042433dba3970137b7be9afa03 (patch)
tree096b6debc487a7a87037808130484fe763bb4f6e /src
parentMerge pull request #599 from Subv/morton (diff)
downloadyuzu-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.h2
-rw-r--r--src/video_core/color.h19
-rw-r--r--src/video_core/pica.h1
-rw-r--r--src/video_core/rasterizer.cpp23
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
32static inline u8 Convert8To1(u8 value) {
33 return value >> 7;
34}
35
36/// Convert a 8-bit color component to 4 bit
37static inline u8 Convert8To4(u8 value) {
38 return value >> 4;
39}
40
41/// Convert a 8-bit color component to 5 bit
42static inline u8 Convert8To5(u8 value) {
43 return value >> 3;
44}
45
46/// Convert a 8-bit color component to 6 bit
47static 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();