diff --git a/README.md b/README.md index a873bd080..8b5d2f66d 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3923. +This is the source code for early-access 3924. ## Legal Notice diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index f6119accc..8aac3842c 100755 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -1048,6 +1048,10 @@ void Image::Scale(bool up_scale) { } bool Image::ScaleUp(bool ignore) { + const auto& resolution = runtime->resolution; + if (!resolution.active) { + return false; + } if (True(flags & ImageFlagBits::Rescaled)) { return false; } @@ -1060,9 +1064,6 @@ bool Image::ScaleUp(bool ignore) { return false; } flags |= ImageFlagBits::Rescaled; - if (!runtime->resolution.active) { - return false; - } has_scaled = true; if (ignore) { current_texture = upscaled_backup.handle; @@ -1073,13 +1074,14 @@ bool Image::ScaleUp(bool ignore) { } bool Image::ScaleDown(bool ignore) { + const auto& resolution = runtime->resolution; + if (!resolution.active) { + return false; + } if (False(flags & ImageFlagBits::Rescaled)) { return false; } flags &= ~ImageFlagBits::Rescaled; - if (!runtime->resolution.active) { - return false; - } if (ignore) { current_texture = texture.handle; return true; diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index b3a5d389c..f4510a7b2 100755 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1532,15 +1532,15 @@ bool Image::IsRescaled() const noexcept { } bool Image::ScaleUp(bool ignore) { + const auto& resolution = runtime->resolution; + if (!resolution.active) { + return false; + } if (True(flags & ImageFlagBits::Rescaled)) { return false; } ASSERT(info.type != ImageType::Linear); flags |= ImageFlagBits::Rescaled; - const auto& resolution = runtime->resolution; - if (!resolution.active) { - return false; - } has_scaled = true; if (!scaled_image) { const bool is_2d = info.type == ImageType::e2D; @@ -1569,15 +1569,15 @@ bool Image::ScaleUp(bool ignore) { } bool Image::ScaleDown(bool ignore) { + const auto& resolution = runtime->resolution; + if (!resolution.active) { + return false; + } if (False(flags & ImageFlagBits::Rescaled)) { return false; } ASSERT(info.type != ImageType::Linear); flags &= ~ImageFlagBits::Rescaled; - const auto& resolution = runtime->resolution; - if (!resolution.active) { - return false; - } current_image = *original_image; if (ignore) { return true; diff --git a/src/yuzu/util/util.cpp b/src/yuzu/util/util.cpp index 19dc72ed1..be5f69335 100755 --- a/src/yuzu/util/util.cpp +++ b/src/yuzu/util/util.cpp @@ -63,25 +63,15 @@ bool SaveIconToFile(const std::string_view path, const QImage& image) { }; #pragma pack(pop) - QImage source_image = image.convertToFormat(QImage::Format_RGB32); + const QImage source_image = image.convertToFormat(QImage::Format_RGB32); + constexpr std::array scale_sizes{256, 128, 64, 48, 32, 24, 16}; constexpr int bytes_per_pixel = 4; - const int image_size = source_image.width() * source_image.height() * bytes_per_pixel; - BITMAPINFOHEADER info_header{}; - info_header.biSize = sizeof(BITMAPINFOHEADER), info_header.biWidth = source_image.width(), - info_header.biHeight = source_image.height() * 2, info_header.biPlanes = 1, - info_header.biBitCount = bytes_per_pixel * 8, info_header.biCompression = BI_RGB; - - const IconDir icon_dir{.id_reserved = 0, .id_type = 1, .id_count = 1}; - const IconDirEntry icon_entry{.width = static_cast(source_image.width()), - .height = static_cast(source_image.height() * 2), - .color_count = 0, - .reserved = 0, - .planes = 1, - .bit_count = bytes_per_pixel * 8, - .bytes_in_res = - static_cast(sizeof(BITMAPINFOHEADER) + image_size), - .image_offset = sizeof(IconDir) + sizeof(IconDirEntry)}; + const IconDir icon_dir{ + .id_reserved = 0, + .id_type = 1, + .id_count = static_cast(scale_sizes.size()), + }; Common::FS::IOFile icon_file(path, Common::FS::FileAccessMode::Write, Common::FS::FileType::BinaryFile); @@ -92,20 +82,55 @@ bool SaveIconToFile(const std::string_view path, const QImage& image) { if (!icon_file.Write(icon_dir)) { return false; } - if (!icon_file.Write(icon_entry)) { - return false; - } - if (!icon_file.Write(info_header)) { - return false; + + std::size_t image_offset = sizeof(IconDir) + (sizeof(IconDirEntry) * scale_sizes.size()); + for (std::size_t i = 0; i < scale_sizes.size(); i++) { + const int image_size = scale_sizes[i] * scale_sizes[i] * bytes_per_pixel; + const IconDirEntry icon_entry{ + .width = static_cast(scale_sizes[i]), + .height = static_cast(scale_sizes[i]), + .color_count = 0, + .reserved = 0, + .planes = 1, + .bit_count = bytes_per_pixel * 8, + .bytes_in_res = static_cast(sizeof(BITMAPINFOHEADER) + image_size), + .image_offset = static_cast(image_offset), + }; + image_offset += icon_entry.bytes_in_res; + if (!icon_file.Write(icon_entry)) { + return false; + } } - for (int y = 0; y < image.height(); y++) { - const auto* line = source_image.scanLine(source_image.height() - 1 - y); - std::vector line_data(source_image.width() * bytes_per_pixel); - std::memcpy(line_data.data(), line, line_data.size()); - if (!icon_file.Write(line_data)) { + for (std::size_t i = 0; i < scale_sizes.size(); i++) { + const QImage scaled_image = source_image.scaled( + scale_sizes[i], scale_sizes[i], Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + const BITMAPINFOHEADER info_header{ + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = scaled_image.width(), + .biHeight = scaled_image.height() * 2, + .biPlanes = 1, + .biBitCount = bytes_per_pixel * 8, + .biCompression = BI_RGB, + .biSizeImage{}, + .biXPelsPerMeter{}, + .biYPelsPerMeter{}, + .biClrUsed{}, + .biClrImportant{}, + }; + + if (!icon_file.Write(info_header)) { return false; } + + for (int y = 0; y < scaled_image.height(); y++) { + const auto* line = scaled_image.scanLine(scaled_image.height() - 1 - y); + std::vector line_data(scaled_image.width() * bytes_per_pixel); + std::memcpy(line_data.data(), line, line_data.size()); + if (!icon_file.Write(line_data)) { + return false; + } + } } icon_file.Close();