QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) { QImage decoded_image(info.width, info.height, QImage::Format_ARGB32); for (int y = 0; y < info.height; ++y) { for (int x = 0; x < info.width; ++x) { Math::Vec4<u8> color = Pica::DebugUtils::LookupTexture(src, x, y, info, true); decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), color.a())); } } return decoded_image; }
void GraphicsFramebufferWidget::OnUpdate() { QPixmap pixmap; switch (framebuffer_source) { case Source::PicaTarget: { // TODO: Store a reference to the registers in the debug context instead of accessing them directly... const auto& framebuffer = Pica::g_state.regs.framebuffer; framebuffer_address = framebuffer.GetColorBufferPhysicalAddress(); framebuffer_width = framebuffer.GetWidth(); framebuffer_height = framebuffer.GetHeight(); // TODO: It's unknown how this format is actually specified framebuffer_format = Format::RGBA8; break; } case Source::DepthBuffer: { const auto& framebuffer = Pica::g_state.regs.framebuffer; framebuffer_address = framebuffer.GetDepthBufferPhysicalAddress(); framebuffer_width = framebuffer.GetWidth(); framebuffer_height = framebuffer.GetHeight(); framebuffer_format = Format::D16; break; } case Source::Custom: { // Keep user-specified values break; } default: qDebug() << "Unknown framebuffer source " << static_cast<int>(framebuffer_source); break; } // TODO: Implement a good way to visualize alpha components! // TODO: Unify this decoding code with the texture decoder u32 bytes_per_pixel = GraphicsFramebufferWidget::BytesPerPixel(framebuffer_format); QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32); u8* buffer = Memory::GetPhysicalPointer(framebuffer_address); for (unsigned int y = 0; y < framebuffer_height; ++y) { for (unsigned int x = 0; x < framebuffer_width; ++x) { const u32 coarse_y = y & ~7; u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * framebuffer_width * bytes_per_pixel; const u8* pixel = buffer + offset; Math::Vec4<u8> color = { 0, 0, 0, 0 }; switch (framebuffer_format) { case Format::RGBA8: color = Color::DecodeRGBA8(pixel); break; case Format::RGB8: color = Color::DecodeRGB8(pixel); break; case Format::RGB5A1: color = Color::DecodeRGB5A1(pixel); break; case Format::RGB565: color = Color::DecodeRGB565(pixel); break; case Format::RGBA4: color = Color::DecodeRGBA4(pixel); break; case Format::D16: { u32 data = Color::DecodeD16(pixel); color.r() = data & 0xFF; color.g() = (data >> 8) & 0xFF; break; } case Format::D24: { u32 data = Color::DecodeD24(pixel); color.r() = data & 0xFF; color.g() = (data >> 8) & 0xFF; color.b() = (data >> 16) & 0xFF; break; } case Format::D24S8: { Math::Vec2<u32> data = Color::DecodeD24S8(pixel); color.r() = data.x & 0xFF; color.g() = (data.x >> 8) & 0xFF; color.b() = (data.x >> 16) & 0xFF; break; } default: qDebug() << "Unknown fb color format " << static_cast<int>(framebuffer_format); break; } decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), 255)); } } pixmap = QPixmap::fromImage(decoded_image); framebuffer_address_control->SetValue(framebuffer_address); framebuffer_width_control->setValue(framebuffer_width); framebuffer_height_control->setValue(framebuffer_height); framebuffer_format_control->setCurrentIndex(static_cast<int>(framebuffer_format)); framebuffer_picture_label->setPixmap(pixmap); }