Compare commits
1 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3a555a484 |
@@ -39,43 +39,4 @@ VirtualDir NgWord1() {
|
||||
return std::make_shared<VectorVfsDirectory>(files, std::vector<VirtualDir>{}, "data");
|
||||
}
|
||||
|
||||
namespace NgWord2Data {
|
||||
|
||||
constexpr std::size_t NUMBER_AC_NX_FILES = 0x10;
|
||||
|
||||
// Should this archive replacement mysteriously not work on a future game, consider updating.
|
||||
constexpr std::array<u8, 4> VERSION_DAT{0x0, 0x0, 0x0, 0x15}; // 5.1.0 System Version
|
||||
|
||||
constexpr std::array<u8, 0x2C> AC_NX_DATA{
|
||||
0x1F, 0x8B, 0x08, 0x08, 0xD5, 0x2C, 0x09, 0x5C, 0x04, 0x00, 0x61, 0x63, 0x72, 0x61, 0x77,
|
||||
0x00, 0xED, 0xC1, 0x01, 0x0D, 0x00, 0x00, 0x00, 0xC2, 0x20, 0xFB, 0xA7, 0xB6, 0xC7, 0x07,
|
||||
0x0C, 0x00, 0x00, 0x00, 0xC8, 0x3B, 0x11, 0x00, 0x1C, 0xC7, 0x00, 0x10, 0x00, 0x00,
|
||||
}; // Deserializes to no bad words
|
||||
|
||||
} // namespace NgWord2Data
|
||||
|
||||
VirtualDir NgWord2() {
|
||||
std::vector<VirtualFile> files(NgWord2Data::NUMBER_AC_NX_FILES * 3);
|
||||
|
||||
for (std::size_t i = 0; i < NgWord2Data::NUMBER_AC_NX_FILES; ++i) {
|
||||
files[3 * i] = std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
|
||||
NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b1_nx", i));
|
||||
files[3 * i + 1] = std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
|
||||
NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_b2_nx", i));
|
||||
files[3 * i + 2] = std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
|
||||
NgWord2Data::AC_NX_DATA, fmt::format("ac_{}_not_b_nx", i));
|
||||
}
|
||||
|
||||
files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
|
||||
NgWord2Data::AC_NX_DATA, "ac_common_b1_nx"));
|
||||
files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
|
||||
NgWord2Data::AC_NX_DATA, "ac_common_b2_nx"));
|
||||
files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::AC_NX_DATA.size()>>(
|
||||
NgWord2Data::AC_NX_DATA, "ac_common_not_b_nx"));
|
||||
files.push_back(std::make_shared<ArrayVfsFile<NgWord2Data::VERSION_DAT.size()>>(
|
||||
NgWord2Data::VERSION_DAT, "version.dat"));
|
||||
|
||||
return std::make_shared<VectorVfsDirectory>(files, std::vector<VirtualDir>{}, "data");
|
||||
}
|
||||
|
||||
} // namespace FileSys::SystemArchive
|
||||
|
||||
@@ -9,6 +9,5 @@
|
||||
namespace FileSys::SystemArchive {
|
||||
|
||||
VirtualDir NgWord1();
|
||||
VirtualDir NgWord2();
|
||||
|
||||
} // namespace FileSys::SystemArchive
|
||||
|
||||
@@ -56,7 +56,7 @@ constexpr std::array<SystemArchiveDescriptor, SYSTEM_ARCHIVE_COUNT> SYSTEM_ARCHI
|
||||
{0x0100000000000820, "PlatformConfigCopper", nullptr},
|
||||
{0x0100000000000821, "PlatformConfigHoag", nullptr},
|
||||
{0x0100000000000822, "ControllerFirmware", nullptr},
|
||||
{0x0100000000000823, "NgWord2", &NgWord2},
|
||||
{0x0100000000000823, "NgWord2", nullptr},
|
||||
{0x0100000000000824, "PlatformConfigIcosaMariko", nullptr},
|
||||
{0x0100000000000825, "ApplicationBlackList", nullptr},
|
||||
{0x0100000000000826, "RebootlessSystemUpdateVersion", nullptr},
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "core/frontend/framebuffer_layout.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
namespace Layout {
|
||||
|
||||
@@ -43,18 +42,4 @@ FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height) {
|
||||
return res;
|
||||
}
|
||||
|
||||
FramebufferLayout FrameLayoutFromResolutionScale(u16 res_scale) {
|
||||
int width, height;
|
||||
|
||||
if (Settings::values.use_docked_mode) {
|
||||
width = ScreenDocked::WidthDocked * res_scale;
|
||||
height = ScreenDocked::HeightDocked * res_scale;
|
||||
} else {
|
||||
width = ScreenUndocked::Width * res_scale;
|
||||
height = ScreenUndocked::Height * res_scale;
|
||||
}
|
||||
|
||||
return DefaultFrameLayout(width, height);
|
||||
}
|
||||
|
||||
} // namespace Layout
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
namespace Layout {
|
||||
|
||||
enum ScreenUndocked : unsigned { Width = 1280, Height = 720 };
|
||||
enum ScreenDocked : unsigned { WidthDocked = 1920, HeightDocked = 1080 };
|
||||
|
||||
/// Describes the layout of the window framebuffer
|
||||
struct FramebufferLayout {
|
||||
@@ -35,10 +34,4 @@ struct FramebufferLayout {
|
||||
*/
|
||||
FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height);
|
||||
|
||||
/**
|
||||
* Convenience method to get frame layout by resolution scale
|
||||
* @param res_scale resolution scale factor
|
||||
*/
|
||||
FramebufferLayout FrameLayoutFromResolutionScale(u16 res_scale);
|
||||
|
||||
} // namespace Layout
|
||||
|
||||
@@ -15,7 +15,6 @@ bool Object::IsWaitable() const {
|
||||
switch (GetHandleType()) {
|
||||
case HandleType::ReadableEvent:
|
||||
case HandleType::Thread:
|
||||
case HandleType::Process:
|
||||
case HandleType::Timer:
|
||||
case HandleType::ServerPort:
|
||||
case HandleType::ServerSession:
|
||||
@@ -24,6 +23,7 @@ bool Object::IsWaitable() const {
|
||||
case HandleType::Unknown:
|
||||
case HandleType::WritableEvent:
|
||||
case HandleType::SharedMemory:
|
||||
case HandleType::Process:
|
||||
case HandleType::AddressArbiter:
|
||||
case HandleType::ResourceLimit:
|
||||
case HandleType::ClientPort:
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/program_metadata.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/kernel/resource_limit.h"
|
||||
@@ -49,21 +48,6 @@ SharedPtr<ResourceLimit> Process::GetResourceLimit() const {
|
||||
return resource_limit;
|
||||
}
|
||||
|
||||
ResultCode Process::ClearSignalState() {
|
||||
if (status == ProcessStatus::Exited) {
|
||||
LOG_ERROR(Kernel, "called on a terminated process instance.");
|
||||
return ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!is_signaled) {
|
||||
LOG_ERROR(Kernel, "called on a process instance that isn't signaled.");
|
||||
return ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
is_signaled = false;
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata) {
|
||||
program_id = metadata.GetTitleID();
|
||||
is_64bit_process = metadata.Is64BitProgram();
|
||||
@@ -153,13 +137,13 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
|
||||
.Unwrap();
|
||||
|
||||
vm_manager.LogLayout();
|
||||
ChangeStatus(ProcessStatus::Running);
|
||||
status = ProcessStatus::Running;
|
||||
|
||||
Kernel::SetupMainThread(kernel, entry_point, main_thread_priority, *this);
|
||||
}
|
||||
|
||||
void Process::PrepareForTermination() {
|
||||
ChangeStatus(ProcessStatus::Exiting);
|
||||
status = ProcessStatus::Exited;
|
||||
|
||||
const auto stop_threads = [this](const std::vector<SharedPtr<Thread>>& thread_list) {
|
||||
for (auto& thread : thread_list) {
|
||||
@@ -183,8 +167,6 @@ void Process::PrepareForTermination() {
|
||||
stop_threads(system.Scheduler(1).GetThreadList());
|
||||
stop_threads(system.Scheduler(2).GetThreadList());
|
||||
stop_threads(system.Scheduler(3).GetThreadList());
|
||||
|
||||
ChangeStatus(ProcessStatus::Exited);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,25 +265,7 @@ ResultCode Process::UnmapMemory(VAddr dst_addr, VAddr /*src_addr*/, u64 size) {
|
||||
return vm_manager.UnmapRange(dst_addr, size);
|
||||
}
|
||||
|
||||
Kernel::Process::Process(KernelCore& kernel) : WaitObject{kernel} {}
|
||||
Kernel::Process::Process(KernelCore& kernel) : Object{kernel} {}
|
||||
Kernel::Process::~Process() {}
|
||||
|
||||
void Process::Acquire(Thread* thread) {
|
||||
ASSERT_MSG(!ShouldWait(thread), "Object unavailable!");
|
||||
}
|
||||
|
||||
bool Process::ShouldWait(Thread* thread) const {
|
||||
return !is_signaled;
|
||||
}
|
||||
|
||||
void Process::ChangeStatus(ProcessStatus new_status) {
|
||||
if (status == new_status) {
|
||||
return;
|
||||
}
|
||||
|
||||
status = new_status;
|
||||
is_signaled = true;
|
||||
WakeupAllWaitingThreads();
|
||||
}
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -14,10 +14,9 @@
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
#include "core/hle/kernel/object.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
#include "core/hle/kernel/vm_manager.h"
|
||||
#include "core/hle/kernel/wait_object.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace FileSys {
|
||||
class ProgramMetadata;
|
||||
@@ -118,7 +117,7 @@ struct CodeSet final {
|
||||
VAddr entrypoint = 0;
|
||||
};
|
||||
|
||||
class Process final : public WaitObject {
|
||||
class Process final : public Object {
|
||||
public:
|
||||
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
|
||||
|
||||
@@ -213,16 +212,6 @@ public:
|
||||
return random_entropy.at(index);
|
||||
}
|
||||
|
||||
/// Clears the signaled state of the process if and only if it's signaled.
|
||||
///
|
||||
/// @pre The process must not be already terminated. If this is called on a
|
||||
/// terminated process, then ERR_INVALID_STATE will be returned.
|
||||
///
|
||||
/// @pre The process must be in a signaled state. If this is called on a
|
||||
/// process instance that is not signaled, ERR_INVALID_STATE will be
|
||||
/// returned.
|
||||
ResultCode ClearSignalState();
|
||||
|
||||
/**
|
||||
* Loads process-specifics configuration info with metadata provided
|
||||
* by an executable.
|
||||
@@ -271,17 +260,6 @@ private:
|
||||
explicit Process(KernelCore& kernel);
|
||||
~Process() override;
|
||||
|
||||
/// Checks if the specified thread should wait until this process is available.
|
||||
bool ShouldWait(Thread* thread) const override;
|
||||
|
||||
/// Acquires/locks this process for the specified thread if it's available.
|
||||
void Acquire(Thread* thread) override;
|
||||
|
||||
/// Changes the process status. If the status is different
|
||||
/// from the current process status, then this will trigger
|
||||
/// a process signal.
|
||||
void ChangeStatus(ProcessStatus new_status);
|
||||
|
||||
/// Memory manager for this process.
|
||||
Kernel::VMManager vm_manager;
|
||||
|
||||
@@ -327,10 +305,6 @@ private:
|
||||
/// specified by metadata provided to the process during loading.
|
||||
bool is_64bit_process = true;
|
||||
|
||||
/// Whether or not this process is signaled. This occurs
|
||||
/// upon the process changing to a different state.
|
||||
bool is_signaled = false;
|
||||
|
||||
/// Total running time for the process in ticks.
|
||||
u64 total_process_running_time_ticks = 0;
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include "common/assert.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/object.h"
|
||||
#include "core/hle/kernel/readable_event.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
#include "core/hle/kernel/writable_event.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
@@ -34,16 +34,6 @@ void ReadableEvent::Clear() {
|
||||
signaled = false;
|
||||
}
|
||||
|
||||
ResultCode ReadableEvent::Reset() {
|
||||
if (!signaled) {
|
||||
return ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void ReadableEvent::WakeupAllWaitingThreads() {
|
||||
WaitObject::WakeupAllWaitingThreads();
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include "core/hle/kernel/object.h"
|
||||
#include "core/hle/kernel/wait_object.h"
|
||||
|
||||
union ResultCode;
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
class KernelCore;
|
||||
@@ -41,17 +39,8 @@ public:
|
||||
|
||||
void WakeupAllWaitingThreads() override;
|
||||
|
||||
/// Unconditionally clears the readable event's state.
|
||||
void Clear();
|
||||
|
||||
/// Clears the readable event's state if and only if it
|
||||
/// has already been signaled.
|
||||
///
|
||||
/// @pre The event must be in a signaled state. If this event
|
||||
/// is in an unsignaled state and this function is called,
|
||||
/// then ERR_INVALID_STATE will be returned.
|
||||
ResultCode Reset();
|
||||
|
||||
private:
|
||||
explicit ReadableEvent(KernelCore& kernel);
|
||||
|
||||
|
||||
@@ -1433,24 +1433,17 @@ static ResultCode CloseHandle(Handle handle) {
|
||||
return handle_table.Close(handle);
|
||||
}
|
||||
|
||||
/// Clears the signaled state of an event or process.
|
||||
/// Reset an event
|
||||
static ResultCode ResetSignal(Handle handle) {
|
||||
LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle);
|
||||
|
||||
const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
|
||||
|
||||
auto event = handle_table.Get<ReadableEvent>(handle);
|
||||
if (event) {
|
||||
return event->Reset();
|
||||
}
|
||||
|
||||
auto process = handle_table.Get<Process>(handle);
|
||||
if (process) {
|
||||
return process->ClearSignalState();
|
||||
}
|
||||
ASSERT(event != nullptr);
|
||||
|
||||
LOG_ERROR(Kernel_SVC, "Invalid handle (0x{:08X})", handle);
|
||||
return ERR_INVALID_HANDLE;
|
||||
event->Clear();
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Creates a TransferMemory object
|
||||
|
||||
@@ -796,9 +796,18 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext&
|
||||
void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
|
||||
enum class LogMode : u32 {
|
||||
Off,
|
||||
Log,
|
||||
RedirectToSdCard,
|
||||
LogToSdCard = Log | RedirectToSdCard,
|
||||
};
|
||||
|
||||
// Given we always want to receive logging information,
|
||||
// we always specify logging as enabled.
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(5);
|
||||
rb.PushEnum(LogMode::Log);
|
||||
}
|
||||
|
||||
void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
@@ -1049,7 +1049,6 @@ union Instruction {
|
||||
BitField<49, 1, u64> nodep_flag;
|
||||
BitField<50, 3, u64> component_mask_selector;
|
||||
BitField<53, 4, u64> texture_info;
|
||||
BitField<60, 1, u64> fp32_flag;
|
||||
|
||||
TextureType GetTextureType() const {
|
||||
// The TEXS instruction has a weird encoding for the texture type.
|
||||
@@ -1550,7 +1549,7 @@ private:
|
||||
INST("1110111011011---", Id::STG, Type::Memory, "STG"),
|
||||
INST("110000----111---", Id::TEX, Type::Memory, "TEX"),
|
||||
INST("1101111101001---", Id::TXQ, Type::Memory, "TXQ"),
|
||||
INST("1101-00---------", Id::TEXS, Type::Memory, "TEXS"),
|
||||
INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"),
|
||||
INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"),
|
||||
INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"),
|
||||
INST("1101111100------", Id::TLD4S, Type::Memory, "TLD4S"),
|
||||
|
||||
@@ -27,16 +27,4 @@ void RendererBase::UpdateCurrentFramebufferLayout() {
|
||||
render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height);
|
||||
}
|
||||
|
||||
void RendererBase::RequestScreenshot(void* data, std::function<void()> callback,
|
||||
const Layout::FramebufferLayout& layout) {
|
||||
if (renderer_settings.screenshot_requested) {
|
||||
LOG_ERROR(Render, "A screenshot is already requested or in progress, ignoring the request");
|
||||
return;
|
||||
}
|
||||
renderer_settings.screenshot_bits = data;
|
||||
renderer_settings.screenshot_complete_callback = std::move(callback);
|
||||
renderer_settings.screenshot_framebuffer_layout = layout;
|
||||
renderer_settings.screenshot_requested = true;
|
||||
}
|
||||
|
||||
} // namespace VideoCore
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <optional>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "video_core/gpu.h"
|
||||
#include "video_core/rasterizer_interface.h"
|
||||
|
||||
@@ -22,12 +21,6 @@ namespace VideoCore {
|
||||
struct RendererSettings {
|
||||
std::atomic_bool use_framelimiter{false};
|
||||
std::atomic_bool set_background_color{false};
|
||||
|
||||
// Screenshot
|
||||
std::atomic<bool> screenshot_requested{false};
|
||||
void* screenshot_bits;
|
||||
std::function<void()> screenshot_complete_callback;
|
||||
Layout::FramebufferLayout screenshot_framebuffer_layout;
|
||||
};
|
||||
|
||||
class RendererBase : NonCopyable {
|
||||
@@ -64,29 +57,9 @@ public:
|
||||
return *rasterizer;
|
||||
}
|
||||
|
||||
Core::Frontend::EmuWindow& GetRenderWindow() {
|
||||
return render_window;
|
||||
}
|
||||
|
||||
const Core::Frontend::EmuWindow& GetRenderWindow() const {
|
||||
return render_window;
|
||||
}
|
||||
|
||||
RendererSettings& Settings() {
|
||||
return renderer_settings;
|
||||
}
|
||||
|
||||
const RendererSettings& Settings() const {
|
||||
return renderer_settings;
|
||||
}
|
||||
|
||||
/// Refreshes the settings common to all renderers
|
||||
void RefreshBaseSettings();
|
||||
|
||||
/// Request a screenshot of the next frame
|
||||
void RequestScreenshot(void* data, std::function<void()> callback,
|
||||
const Layout::FramebufferLayout& layout);
|
||||
|
||||
protected:
|
||||
Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle.
|
||||
std::unique_ptr<RasterizerInterface> rasterizer;
|
||||
|
||||
@@ -79,26 +79,6 @@ struct DrawParameters {
|
||||
}
|
||||
};
|
||||
|
||||
struct FramebufferCacheKey {
|
||||
bool is_single_buffer = false;
|
||||
bool stencil_enable = false;
|
||||
|
||||
std::array<GLenum, Maxwell::NumRenderTargets> color_attachments{};
|
||||
std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> colors{};
|
||||
u32 colors_count = 0;
|
||||
|
||||
GLuint zeta = 0;
|
||||
|
||||
auto Tie() const {
|
||||
return std::tie(is_single_buffer, stencil_enable, color_attachments, colors, colors_count,
|
||||
zeta);
|
||||
}
|
||||
|
||||
bool operator<(const FramebufferCacheKey& rhs) const {
|
||||
return Tie() < rhs.Tie();
|
||||
}
|
||||
};
|
||||
|
||||
RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo& info)
|
||||
: res_cache{*this}, shader_cache{*this}, emu_window{window}, screen_info{info},
|
||||
buffer_cache(*this, STREAM_BUFFER_SIZE) {
|
||||
@@ -110,6 +90,9 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo
|
||||
|
||||
OpenGLState::ApplyDefaultState();
|
||||
|
||||
// Create render framebuffer
|
||||
framebuffer.Create();
|
||||
|
||||
shader_program_manager = std::make_unique<GLShader::ProgramManager>();
|
||||
state.draw.shader_program = 0;
|
||||
state.Apply();
|
||||
@@ -378,44 +361,6 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
|
||||
SyncClipEnabled(clip_distances);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SetupCachedFramebuffer(const FramebufferCacheKey& fbkey,
|
||||
OpenGLState& current_state) {
|
||||
const auto [entry, is_cache_miss] = framebuffer_cache.try_emplace(fbkey);
|
||||
auto& framebuffer = entry->second;
|
||||
|
||||
if (is_cache_miss)
|
||||
framebuffer.Create();
|
||||
|
||||
current_state.draw.draw_framebuffer = framebuffer.handle;
|
||||
current_state.ApplyFramebufferState();
|
||||
|
||||
if (!is_cache_miss)
|
||||
return;
|
||||
|
||||
if (fbkey.is_single_buffer) {
|
||||
if (fbkey.color_attachments[0] != GL_NONE) {
|
||||
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, fbkey.color_attachments[0], fbkey.colors[0],
|
||||
0);
|
||||
}
|
||||
glDrawBuffer(fbkey.color_attachments[0]);
|
||||
} else {
|
||||
for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
|
||||
if (fbkey.colors[index]) {
|
||||
glFramebufferTexture(GL_DRAW_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index),
|
||||
fbkey.colors[index], 0);
|
||||
}
|
||||
}
|
||||
glDrawBuffers(fbkey.colors_count, fbkey.color_attachments.data());
|
||||
}
|
||||
|
||||
if (fbkey.zeta) {
|
||||
GLenum zeta_attachment =
|
||||
fbkey.stencil_enable ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
|
||||
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, zeta_attachment, fbkey.zeta, 0);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
|
||||
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
|
||||
|
||||
@@ -499,10 +444,10 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
|
||||
UNIMPLEMENTED_IF(regs.rt_separate_frag_data != 0);
|
||||
|
||||
// Bind the framebuffer surfaces
|
||||
current_state.draw.draw_framebuffer = framebuffer.handle;
|
||||
current_state.ApplyFramebufferState();
|
||||
current_state.framebuffer_srgb.enabled = regs.framebuffer_srgb != 0;
|
||||
|
||||
FramebufferCacheKey fbkey;
|
||||
|
||||
if (using_color_fb) {
|
||||
if (single_color_target) {
|
||||
// Used when just a single color attachment is enabled, e.g. for clearing a color buffer
|
||||
@@ -518,12 +463,14 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
|
||||
state.framebuffer_srgb.enabled |= color_surface->GetSurfaceParams().srgb_conversion;
|
||||
}
|
||||
|
||||
fbkey.is_single_buffer = true;
|
||||
fbkey.color_attachments[0] =
|
||||
GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(*single_color_target);
|
||||
fbkey.colors[0] = color_surface != nullptr ? color_surface->Texture().handle : 0;
|
||||
glFramebufferTexture2D(
|
||||
GL_DRAW_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(*single_color_target), GL_TEXTURE_2D,
|
||||
color_surface != nullptr ? color_surface->Texture().handle : 0, 0);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(*single_color_target));
|
||||
} else {
|
||||
// Multiple color attachments are enabled
|
||||
std::array<GLenum, Maxwell::NumRenderTargets> buffers;
|
||||
for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
|
||||
Surface color_surface = res_cache.GetColorBufferSurface(index, preserve_contents);
|
||||
|
||||
@@ -538,17 +485,22 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
|
||||
color_surface->GetSurfaceParams().srgb_conversion;
|
||||
}
|
||||
|
||||
fbkey.color_attachments[index] =
|
||||
GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index);
|
||||
fbkey.colors[index] =
|
||||
color_surface != nullptr ? color_surface->Texture().handle : 0;
|
||||
buffers[index] = GL_COLOR_ATTACHMENT0 + regs.rt_control.GetMap(index);
|
||||
glFramebufferTexture2D(
|
||||
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index),
|
||||
GL_TEXTURE_2D, color_surface != nullptr ? color_surface->Texture().handle : 0,
|
||||
0);
|
||||
}
|
||||
fbkey.is_single_buffer = false;
|
||||
fbkey.colors_count = regs.rt_control.count;
|
||||
glDrawBuffers(regs.rt_control.count, buffers.data());
|
||||
}
|
||||
} else {
|
||||
// No color attachments are enabled - leave them as zero
|
||||
fbkey.is_single_buffer = true;
|
||||
// No color attachments are enabled - zero out all of them
|
||||
for (std::size_t index = 0; index < Maxwell::NumRenderTargets; ++index) {
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(index), GL_TEXTURE_2D,
|
||||
0, 0);
|
||||
}
|
||||
glDrawBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
if (depth_surface) {
|
||||
@@ -556,12 +508,22 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
|
||||
// the shader doesn't actually write to it.
|
||||
depth_surface->MarkAsModified(true, res_cache);
|
||||
|
||||
fbkey.zeta = depth_surface->Texture().handle;
|
||||
fbkey.stencil_enable = regs.stencil_enable;
|
||||
if (regs.stencil_enable) {
|
||||
// Attach both depth and stencil
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
|
||||
depth_surface->Texture().handle, 0);
|
||||
} else {
|
||||
// Attach depth
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
|
||||
depth_surface->Texture().handle, 0);
|
||||
// Clear stencil attachment
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||
}
|
||||
} else {
|
||||
// Clear both depth and stencil attachment
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
||||
0);
|
||||
}
|
||||
|
||||
SetupCachedFramebuffer(fbkey, current_state);
|
||||
|
||||
SyncViewport(current_state);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace OpenGL {
|
||||
|
||||
struct ScreenInfo;
|
||||
struct DrawParameters;
|
||||
struct FramebufferCacheKey;
|
||||
|
||||
class RasterizerOpenGL : public VideoCore::RasterizerInterface {
|
||||
public:
|
||||
@@ -196,12 +195,11 @@ private:
|
||||
OGLVertexArray>
|
||||
vertex_array_cache;
|
||||
|
||||
std::map<FramebufferCacheKey, OGLFramebuffer> framebuffer_cache;
|
||||
|
||||
std::array<SamplerInfo, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_samplers;
|
||||
|
||||
static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
|
||||
OGLBufferCache buffer_cache;
|
||||
OGLFramebuffer framebuffer;
|
||||
PrimitiveAssembler primitive_assembler{buffer_cache};
|
||||
GLint uniform_buffer_alignment;
|
||||
|
||||
@@ -216,8 +214,6 @@ private:
|
||||
|
||||
void SetupShaders(GLenum primitive_mode);
|
||||
|
||||
void SetupCachedFramebuffer(const FramebufferCacheKey& fbkey, OpenGLState& current_state);
|
||||
|
||||
enum class AccelDraw { Disabled, Arrays, Indexed };
|
||||
AccelDraw accelerate_draw = AccelDraw::Disabled;
|
||||
|
||||
|
||||
@@ -50,14 +50,6 @@ public:
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
/// Generates code to use for a swizzle operation.
|
||||
static std::string GetSwizzle(u64 elem) {
|
||||
ASSERT(elem <= 3);
|
||||
std::string swizzle = ".";
|
||||
swizzle += "xyzw"[elem];
|
||||
return swizzle;
|
||||
}
|
||||
|
||||
/// Translate topology
|
||||
static std::string GetTopologyName(Tegra::Shader::OutputTopology topology) {
|
||||
switch (topology) {
|
||||
@@ -1012,6 +1004,14 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates code to use for a swizzle operation.
|
||||
static std::string GetSwizzle(u64 elem) {
|
||||
ASSERT(elem <= 3);
|
||||
std::string swizzle = ".";
|
||||
swizzle += "xyzw"[elem];
|
||||
return swizzle;
|
||||
}
|
||||
|
||||
ShaderWriter& shader;
|
||||
ShaderWriter& declarations;
|
||||
std::vector<GLSLRegister> regs;
|
||||
@@ -1343,7 +1343,7 @@ private:
|
||||
regs.SetRegisterToInteger(dest, true, 0, result, 1, 1);
|
||||
}
|
||||
|
||||
void WriteTexsInstructionFloat(const Instruction& instr, const std::string& texture) {
|
||||
void WriteTexsInstruction(const Instruction& instr, const std::string& texture) {
|
||||
// TEXS has two destination registers and a swizzle. The first two elements in the swizzle
|
||||
// go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1
|
||||
|
||||
@@ -1368,38 +1368,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void WriteTexsInstructionHalfFloat(const Instruction& instr, const std::string& texture) {
|
||||
// TEXS.F16 destionation registers are packed in two registers in pairs (just like any half
|
||||
// float instruction).
|
||||
|
||||
std::array<std::string, 4> components;
|
||||
u32 written_components = 0;
|
||||
|
||||
for (u32 component = 0; component < 4; ++component) {
|
||||
if (!instr.texs.IsComponentEnabled(component))
|
||||
continue;
|
||||
components[written_components++] = texture + GetSwizzle(component);
|
||||
}
|
||||
if (written_components == 0)
|
||||
return;
|
||||
|
||||
const auto BuildComponent = [&](std::string low, std::string high, bool high_enabled) {
|
||||
return "vec2(" + low + ", " + (high_enabled ? high : "0") + ')';
|
||||
};
|
||||
|
||||
regs.SetRegisterToHalfFloat(
|
||||
instr.gpr0, 0, BuildComponent(components[0], components[1], written_components > 1),
|
||||
Tegra::Shader::HalfMerge::H0_H1, 1, 1);
|
||||
|
||||
if (written_components > 2) {
|
||||
ASSERT(instr.texs.HasTwoDestinations());
|
||||
regs.SetRegisterToHalfFloat(
|
||||
instr.gpr28, 0,
|
||||
BuildComponent(components[2], components[3], written_components > 3),
|
||||
Tegra::Shader::HalfMerge::H0_H1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static u32 TextureCoordinates(Tegra::Shader::TextureType texture_type) {
|
||||
switch (texture_type) {
|
||||
case Tegra::Shader::TextureType::Texture1D:
|
||||
@@ -2798,27 +2766,24 @@ private:
|
||||
const bool depth_compare =
|
||||
instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
|
||||
const auto process_mode = instr.texs.GetTextureProcessMode();
|
||||
|
||||
UNIMPLEMENTED_IF_MSG(instr.texs.UsesMiscMode(Tegra::Shader::TextureMiscMode::NODEP),
|
||||
"NODEP is not implemented");
|
||||
|
||||
const auto scope = shader.Scope();
|
||||
|
||||
auto [coord, texture] =
|
||||
const auto [coord, texture] =
|
||||
GetTEXSCode(instr, texture_type, process_mode, depth_compare, is_array);
|
||||
|
||||
shader.AddLine(coord);
|
||||
|
||||
if (depth_compare) {
|
||||
texture = "vec4(" + texture + ')';
|
||||
}
|
||||
shader.AddLine("vec4 texture_tmp = " + texture + ';');
|
||||
if (!depth_compare) {
|
||||
shader.AddLine("vec4 texture_tmp = " + texture + ';');
|
||||
|
||||
if (instr.texs.fp32_flag) {
|
||||
WriteTexsInstructionFloat(instr, "texture_tmp");
|
||||
} else {
|
||||
WriteTexsInstructionHalfFloat(instr, "texture_tmp");
|
||||
shader.AddLine("vec4 texture_tmp = vec4(" + texture + ");");
|
||||
}
|
||||
|
||||
WriteTexsInstruction(instr, "texture_tmp");
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::TLDS: {
|
||||
@@ -2877,7 +2842,7 @@ private:
|
||||
}
|
||||
}();
|
||||
|
||||
WriteTexsInstructionFloat(instr, texture);
|
||||
WriteTexsInstruction(instr, texture);
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::TLD4: {
|
||||
@@ -2975,8 +2940,7 @@ private:
|
||||
if (depth_compare) {
|
||||
texture = "vec4(" + texture + ')';
|
||||
}
|
||||
|
||||
WriteTexsInstructionFloat(instr, texture);
|
||||
WriteTexsInstruction(instr, texture);
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::TXQ: {
|
||||
|
||||
@@ -138,12 +138,7 @@ void RendererOpenGL::SwapBuffers(
|
||||
|
||||
// Load the framebuffer from memory, draw it to the screen, and swap buffers
|
||||
LoadFBToScreenInfo(*framebuffer);
|
||||
|
||||
if (renderer_settings.screenshot_requested)
|
||||
CaptureScreenshot();
|
||||
|
||||
DrawScreen(render_window.GetFramebufferLayout());
|
||||
|
||||
DrawScreen();
|
||||
render_window.SwapBuffers();
|
||||
}
|
||||
|
||||
@@ -388,13 +383,14 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
|
||||
/**
|
||||
* Draws the emulated screens to the emulator window.
|
||||
*/
|
||||
void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||
void RendererOpenGL::DrawScreen() {
|
||||
if (renderer_settings.set_background_color) {
|
||||
// Update background color before drawing
|
||||
glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
|
||||
0.0f);
|
||||
}
|
||||
|
||||
const auto& layout = render_window.GetFramebufferLayout();
|
||||
const auto& screen = layout.screen;
|
||||
|
||||
glViewport(0, 0, layout.width, layout.height);
|
||||
@@ -418,37 +414,6 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||
/// Updates the framerate
|
||||
void RendererOpenGL::UpdateFramerate() {}
|
||||
|
||||
void RendererOpenGL::CaptureScreenshot() {
|
||||
// Draw the current frame to the screenshot framebuffer
|
||||
screenshot_framebuffer.Create();
|
||||
GLuint old_read_fb = state.draw.read_framebuffer;
|
||||
GLuint old_draw_fb = state.draw.draw_framebuffer;
|
||||
state.draw.read_framebuffer = state.draw.draw_framebuffer = screenshot_framebuffer.handle;
|
||||
state.Apply();
|
||||
|
||||
Layout::FramebufferLayout layout{renderer_settings.screenshot_framebuffer_layout};
|
||||
|
||||
GLuint renderbuffer;
|
||||
glGenRenderbuffers(1, &renderbuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8, layout.width, layout.height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
|
||||
|
||||
DrawScreen(layout);
|
||||
|
||||
glReadPixels(0, 0, layout.width, layout.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
renderer_settings.screenshot_bits);
|
||||
|
||||
screenshot_framebuffer.Release();
|
||||
state.draw.read_framebuffer = old_read_fb;
|
||||
state.draw.draw_framebuffer = old_draw_fb;
|
||||
state.Apply();
|
||||
glDeleteRenderbuffers(1, &renderbuffer);
|
||||
|
||||
renderer_settings.screenshot_complete_callback();
|
||||
renderer_settings.screenshot_requested = false;
|
||||
}
|
||||
|
||||
static const char* GetSource(GLenum source) {
|
||||
#define RET(s) \
|
||||
case GL_DEBUG_SOURCE_##s: \
|
||||
|
||||
@@ -16,10 +16,6 @@ namespace Core::Frontend {
|
||||
class EmuWindow;
|
||||
}
|
||||
|
||||
namespace Layout {
|
||||
class FramebufferLayout;
|
||||
}
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
/// Structure used for storing information about the textures for the Switch screen
|
||||
@@ -70,12 +66,10 @@ private:
|
||||
|
||||
void ConfigureFramebufferTexture(TextureInfo& texture,
|
||||
const Tegra::FramebufferConfig& framebuffer);
|
||||
void DrawScreen(const Layout::FramebufferLayout& layout);
|
||||
void DrawScreen();
|
||||
void DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w, float h);
|
||||
void UpdateFramerate();
|
||||
|
||||
void CaptureScreenshot();
|
||||
|
||||
// Loads framebuffer from emulated memory into the display information structure
|
||||
void LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer);
|
||||
// Fills active OpenGL texture with the given RGBA color.
|
||||
@@ -88,7 +82,6 @@ private:
|
||||
OGLVertexArray vertex_array;
|
||||
OGLBuffer vertex_buffer;
|
||||
OGLProgram shader;
|
||||
OGLFramebuffer screenshot_framebuffer;
|
||||
|
||||
/// Display information for Switch screen
|
||||
ScreenInfo screen_info;
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <memory>
|
||||
#include "core/core.h"
|
||||
#include "core/settings.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/renderer_opengl/renderer_opengl.h"
|
||||
#include "video_core/video_core.h"
|
||||
@@ -15,10 +13,4 @@ std::unique_ptr<RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_wind
|
||||
return std::make_unique<OpenGL::RendererOpenGL>(emu_window);
|
||||
}
|
||||
|
||||
u16 GetResolutionScaleFactor(const RendererBase& renderer) {
|
||||
return !Settings::values.resolution_factor
|
||||
? renderer.GetRenderWindow().GetFramebufferLayout().GetScalingRatio()
|
||||
: Settings::values.resolution_factor;
|
||||
}
|
||||
|
||||
} // namespace VideoCore
|
||||
|
||||
@@ -22,6 +22,4 @@ class RendererBase;
|
||||
*/
|
||||
std::unique_ptr<RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_window);
|
||||
|
||||
u16 GetResolutionScaleFactor(const RendererBase& renderer);
|
||||
|
||||
} // namespace VideoCore
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include "input_common/keyboard.h"
|
||||
#include "input_common/main.h"
|
||||
#include "input_common/motion_emu.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/video_core.h"
|
||||
#include "yuzu/bootmanager.h"
|
||||
|
||||
EmuThread::EmuThread(GRenderWindow* render_window) : render_window(render_window) {}
|
||||
@@ -335,22 +333,6 @@ void GRenderWindow::InitRenderTarget() {
|
||||
BackupGeometry();
|
||||
}
|
||||
|
||||
void GRenderWindow::CaptureScreenshot(u16 res_scale, const QString& screenshot_path) {
|
||||
auto& renderer = Core::System::GetInstance().Renderer();
|
||||
|
||||
if (!res_scale)
|
||||
res_scale = VideoCore::GetResolutionScaleFactor(renderer);
|
||||
|
||||
const Layout::FramebufferLayout layout{Layout::FrameLayoutFromResolutionScale(res_scale)};
|
||||
screenshot_image = QImage(QSize(layout.width, layout.height), QImage::Format_RGB32);
|
||||
renderer.RequestScreenshot(screenshot_image.bits(),
|
||||
[=] {
|
||||
screenshot_image.mirrored(false, true).save(screenshot_path);
|
||||
LOG_INFO(Frontend, "The screenshot is saved.");
|
||||
},
|
||||
layout);
|
||||
}
|
||||
|
||||
void GRenderWindow::OnMinimalClientAreaChangeRequest(
|
||||
const std::pair<unsigned, unsigned>& minimal_size) {
|
||||
setMinimumSize(minimal_size.first, minimal_size.second);
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <QGLWidget>
|
||||
#include <QImage>
|
||||
#include <QThread>
|
||||
#include "common/thread.h"
|
||||
#include "core/core.h"
|
||||
@@ -140,8 +139,6 @@ public:
|
||||
|
||||
void InitRenderTarget();
|
||||
|
||||
void CaptureScreenshot(u16 res_scale, const QString& screenshot_path);
|
||||
|
||||
public slots:
|
||||
void moveContext(); // overridden
|
||||
|
||||
@@ -168,9 +165,6 @@ private:
|
||||
|
||||
EmuThread* emu_thread;
|
||||
|
||||
/// Temporary storage of the screenshot taken
|
||||
QImage screenshot_image;
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* event) override;
|
||||
};
|
||||
|
||||
@@ -206,57 +206,60 @@ const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> Config::default
|
||||
|
||||
void Config::ReadPlayerValues() {
|
||||
for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
|
||||
auto& player = Settings::values.players[p];
|
||||
Settings::values.players[p].connected =
|
||||
qt_config->value(QString("player_%1_connected").arg(p), false).toBool();
|
||||
|
||||
player.connected = qt_config->value(QString("player_%1_connected").arg(p), false).toBool();
|
||||
|
||||
player.type = static_cast<Settings::ControllerType>(
|
||||
Settings::values.players[p].type = static_cast<Settings::ControllerType>(
|
||||
qt_config
|
||||
->value(QString("player_%1_type").arg(p),
|
||||
static_cast<u8>(Settings::ControllerType::DualJoycon))
|
||||
.toUInt());
|
||||
|
||||
player.body_color_left = qt_config
|
||||
->value(QString("player_%1_body_color_left").arg(p),
|
||||
Settings::JOYCON_BODY_NEON_BLUE)
|
||||
.toUInt();
|
||||
player.body_color_right = qt_config
|
||||
->value(QString("player_%1_body_color_right").arg(p),
|
||||
Settings::JOYCON_BODY_NEON_RED)
|
||||
.toUInt();
|
||||
player.button_color_left = qt_config
|
||||
->value(QString("player_%1_button_color_left").arg(p),
|
||||
Settings::JOYCON_BUTTONS_NEON_BLUE)
|
||||
.toUInt();
|
||||
player.button_color_right = qt_config
|
||||
->value(QString("player_%1_button_color_right").arg(p),
|
||||
Settings::JOYCON_BUTTONS_NEON_RED)
|
||||
.toUInt();
|
||||
Settings::values.players[p].body_color_left =
|
||||
qt_config
|
||||
->value(QString("player_%1_body_color_left").arg(p),
|
||||
Settings::JOYCON_BODY_NEON_BLUE)
|
||||
.toUInt();
|
||||
Settings::values.players[p].body_color_right =
|
||||
qt_config
|
||||
->value(QString("player_%1_body_color_right").arg(p),
|
||||
Settings::JOYCON_BODY_NEON_RED)
|
||||
.toUInt();
|
||||
Settings::values.players[p].button_color_left =
|
||||
qt_config
|
||||
->value(QString("player_%1_button_color_left").arg(p),
|
||||
Settings::JOYCON_BUTTONS_NEON_BLUE)
|
||||
.toUInt();
|
||||
Settings::values.players[p].button_color_right =
|
||||
qt_config
|
||||
->value(QString("player_%1_button_color_right").arg(p),
|
||||
Settings::JOYCON_BUTTONS_NEON_RED)
|
||||
.toUInt();
|
||||
|
||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||
player.buttons[i] =
|
||||
Settings::values.players[p].buttons[i] =
|
||||
qt_config
|
||||
->value(QString("player_%1_").arg(p) + Settings::NativeButton::mapping[i],
|
||||
QString::fromStdString(default_param))
|
||||
.toString()
|
||||
.toStdString();
|
||||
if (player.buttons[i].empty())
|
||||
player.buttons[i] = default_param;
|
||||
if (Settings::values.players[p].buttons[i].empty())
|
||||
Settings::values.players[p].buttons[i] = default_param;
|
||||
}
|
||||
|
||||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
||||
std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
||||
default_analogs[i][3], default_analogs[i][4], 0.5f);
|
||||
player.analogs[i] =
|
||||
Settings::values.players[p].analogs[i] =
|
||||
qt_config
|
||||
->value(QString("player_%1_").arg(p) + Settings::NativeAnalog::mapping[i],
|
||||
QString::fromStdString(default_param))
|
||||
.toString()
|
||||
.toStdString();
|
||||
if (player.analogs[i].empty())
|
||||
player.analogs[i] = default_param;
|
||||
if (Settings::values.players[p].analogs[i].empty())
|
||||
Settings::values.players[p].analogs[i] = default_param;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,8 +448,6 @@ void Config::ReadValues() {
|
||||
UISettings::values.theme = qt_config->value("theme", UISettings::themes[0].second).toString();
|
||||
UISettings::values.enable_discord_presence =
|
||||
qt_config->value("enable_discord_presence", true).toBool();
|
||||
UISettings::values.screenshot_resolution_factor =
|
||||
static_cast<u16>(qt_config->value("screenshot_resolution_factor", 0).toUInt());
|
||||
|
||||
qt_config->beginGroup("UIGameList");
|
||||
UISettings::values.show_unknown = qt_config->value("show_unknown", true).toBool();
|
||||
@@ -510,28 +511,30 @@ void Config::ReadValues() {
|
||||
}
|
||||
|
||||
void Config::SavePlayerValues() {
|
||||
for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
|
||||
const auto& player = Settings::values.players[p];
|
||||
for (int p = 0; p < Settings::values.players.size(); ++p) {
|
||||
qt_config->setValue(QString("player_%1_connected").arg(p),
|
||||
Settings::values.players[p].connected);
|
||||
qt_config->setValue(QString("player_%1_type").arg(p),
|
||||
static_cast<u8>(Settings::values.players[p].type));
|
||||
|
||||
qt_config->setValue(QString("player_%1_connected").arg(p), player.connected);
|
||||
qt_config->setValue(QString("player_%1_type").arg(p), static_cast<u8>(player.type));
|
||||
|
||||
qt_config->setValue(QString("player_%1_body_color_left").arg(p), player.body_color_left);
|
||||
qt_config->setValue(QString("player_%1_body_color_right").arg(p), player.body_color_right);
|
||||
qt_config->setValue(QString("player_%1_body_color_left").arg(p),
|
||||
Settings::values.players[p].body_color_left);
|
||||
qt_config->setValue(QString("player_%1_body_color_right").arg(p),
|
||||
Settings::values.players[p].body_color_right);
|
||||
qt_config->setValue(QString("player_%1_button_color_left").arg(p),
|
||||
player.button_color_left);
|
||||
Settings::values.players[p].button_color_left);
|
||||
qt_config->setValue(QString("player_%1_button_color_right").arg(p),
|
||||
player.button_color_right);
|
||||
Settings::values.players[p].button_color_right);
|
||||
|
||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||
qt_config->setValue(QString("player_%1_").arg(p) +
|
||||
QString::fromStdString(Settings::NativeButton::mapping[i]),
|
||||
QString::fromStdString(player.buttons[i]));
|
||||
QString::fromStdString(Settings::values.players[p].buttons[i]));
|
||||
}
|
||||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
||||
qt_config->setValue(QString("player_%1_").arg(p) +
|
||||
QString::fromStdString(Settings::NativeAnalog::mapping[i]),
|
||||
QString::fromStdString(player.analogs[i]));
|
||||
QString::fromStdString(Settings::values.players[p].analogs[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -650,8 +653,6 @@ void Config::SaveValues() {
|
||||
qt_config->beginGroup("UI");
|
||||
qt_config->setValue("theme", UISettings::values.theme);
|
||||
qt_config->setValue("enable_discord_presence", UISettings::values.enable_discord_presence);
|
||||
qt_config->setValue("screenshot_resolution_factor",
|
||||
UISettings::values.screenshot_resolution_factor);
|
||||
|
||||
qt_config->beginGroup("UIGameList");
|
||||
qt_config->setValue("show_unknown", UISettings::values.show_unknown);
|
||||
@@ -673,7 +674,6 @@ void Config::SaveValues() {
|
||||
qt_config->beginGroup("Paths");
|
||||
qt_config->setValue("romsPath", UISettings::values.roms_path);
|
||||
qt_config->setValue("symbolsPath", UISettings::values.symbols_path);
|
||||
qt_config->setValue("screenshotPath", UISettings::values.screenshot_path);
|
||||
qt_config->setValue("gameListRootDir", UISettings::values.gamedir);
|
||||
qt_config->setValue("gameListDeepScan", UISettings::values.gamedir_deepscan);
|
||||
qt_config->setValue("recentFiles", UISettings::values.recent_files);
|
||||
|
||||
@@ -334,9 +334,6 @@ void GMainWindow::InitializeHotkeys() {
|
||||
Qt::ApplicationShortcut);
|
||||
hotkey_registry.RegisterHotkey("Main Window", "Load Amiibo", QKeySequence(Qt::Key_F2),
|
||||
Qt::ApplicationShortcut);
|
||||
hotkey_registry.RegisterHotkey("Main Window", "Capture Screenshot",
|
||||
QKeySequence(QKeySequence::Print));
|
||||
|
||||
hotkey_registry.LoadHotkeys();
|
||||
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated,
|
||||
@@ -396,12 +393,6 @@ void GMainWindow::InitializeHotkeys() {
|
||||
OnLoadAmiibo();
|
||||
}
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey("Main Window", "Capture Screenshot", this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
if (emu_thread->IsRunning()) {
|
||||
OnCaptureScreenshot();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void GMainWindow::SetDefaultUIGeometry() {
|
||||
@@ -497,10 +488,6 @@ void GMainWindow::ConnectMenuEvents() {
|
||||
hotkey_registry.GetHotkey("Main Window", "Fullscreen", this)->key());
|
||||
connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
|
||||
|
||||
// Movie
|
||||
connect(ui.action_Capture_Screenshot, &QAction::triggered, this,
|
||||
&GMainWindow::OnCaptureScreenshot);
|
||||
|
||||
// Help
|
||||
connect(ui.action_Open_yuzu_Folder, &QAction::triggered, this, &GMainWindow::OnOpenYuzuFolder);
|
||||
connect(ui.action_Rederive, &QAction::triggered, this,
|
||||
@@ -737,7 +724,6 @@ void GMainWindow::ShutdownGame() {
|
||||
ui.action_Restart->setEnabled(false);
|
||||
ui.action_Report_Compatibility->setEnabled(false);
|
||||
ui.action_Load_Amiibo->setEnabled(false);
|
||||
ui.action_Capture_Screenshot->setEnabled(false);
|
||||
render_window->hide();
|
||||
game_list->show();
|
||||
game_list->setFilterFocus();
|
||||
@@ -1275,7 +1261,6 @@ void GMainWindow::OnStartGame() {
|
||||
|
||||
discord_rpc->Update();
|
||||
ui.action_Load_Amiibo->setEnabled(true);
|
||||
ui.action_Capture_Screenshot->setEnabled(true);
|
||||
}
|
||||
|
||||
void GMainWindow::OnPauseGame() {
|
||||
@@ -1284,7 +1269,6 @@ void GMainWindow::OnPauseGame() {
|
||||
ui.action_Start->setEnabled(true);
|
||||
ui.action_Pause->setEnabled(false);
|
||||
ui.action_Stop->setEnabled(true);
|
||||
ui.action_Capture_Screenshot->setEnabled(false);
|
||||
}
|
||||
|
||||
void GMainWindow::OnStopGame() {
|
||||
@@ -1447,18 +1431,6 @@ void GMainWindow::OnToggleFilterBar() {
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::OnCaptureScreenshot() {
|
||||
OnPauseGame();
|
||||
const QString path =
|
||||
QFileDialog::getSaveFileName(this, tr("Capture Screenshot"),
|
||||
UISettings::values.screenshot_path, tr("PNG Image (*.png)"));
|
||||
if (!path.isEmpty()) {
|
||||
UISettings::values.screenshot_path = QFileInfo(path).path();
|
||||
render_window->CaptureScreenshot(UISettings::values.screenshot_resolution_factor, path);
|
||||
}
|
||||
OnStartGame();
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateStatusBar() {
|
||||
if (emu_thread == nullptr) {
|
||||
status_bar_update_timer.stop();
|
||||
|
||||
@@ -186,7 +186,6 @@ private slots:
|
||||
void ShowFullscreen();
|
||||
void HideFullscreen();
|
||||
void ToggleWindowMode();
|
||||
void OnCaptureScreenshot();
|
||||
void OnCoreError(Core::System::ResultStatus, std::string);
|
||||
void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
|
||||
|
||||
|
||||
@@ -101,13 +101,11 @@
|
||||
<addaction name="action_Show_Status_Bar"/>
|
||||
<addaction name="menu_View_Debugging"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_Tools">
|
||||
<widget class ="QMenu" name="menu_Tools">
|
||||
<property name="title">
|
||||
<string>Tools</string>
|
||||
</property>
|
||||
<addaction name="action_Rederive"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_Capture_Screenshot"/>
|
||||
<addaction name="action_Rederive" />
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_Help">
|
||||
<property name="title">
|
||||
@@ -120,7 +118,7 @@
|
||||
<addaction name="menu_File"/>
|
||||
<addaction name="menu_Emulation"/>
|
||||
<addaction name="menu_View"/>
|
||||
<addaction name="menu_Tools"/>
|
||||
<addaction name="menu_Tools" />
|
||||
<addaction name="menu_Help"/>
|
||||
</widget>
|
||||
<action name="action_Install_File_NAND">
|
||||
@@ -175,11 +173,11 @@
|
||||
<string>&Stop</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Rederive">
|
||||
<property name="text">
|
||||
<string>Reinitialize keys...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Rederive">
|
||||
<property name="text">
|
||||
<string>Reinitialize keys...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_About">
|
||||
<property name="text">
|
||||
<string>About yuzu</string>
|
||||
@@ -254,47 +252,39 @@
|
||||
<string>Fullscreen</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Restart">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Restart</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Restart">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Restart</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Load_Amiibo">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load Amiibo...</string>
|
||||
</property>
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load Amiibo...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Report_Compatibility">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Report Compatibility</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Open_yuzu_Folder">
|
||||
<property name="text">
|
||||
<string>Open yuzu Folder</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Capture_Screenshot">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Capture Screenshot</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<action name="action_Report_Compatibility">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Report Compatibility</string>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Open_yuzu_Folder">
|
||||
<property name="text">
|
||||
<string>Open yuzu Folder</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace UISettings {
|
||||
|
||||
@@ -43,11 +42,8 @@ struct Values {
|
||||
// Discord RPC
|
||||
bool enable_discord_presence;
|
||||
|
||||
u16 screenshot_resolution_factor;
|
||||
|
||||
QString roms_path;
|
||||
QString symbols_path;
|
||||
QString screenshot_path;
|
||||
QString gamedir;
|
||||
bool gamedir_deepscan;
|
||||
QStringList recent_files;
|
||||
|
||||
Reference in New Issue
Block a user