Compare commits

..

3 Commits

Author SHA1 Message Date
cfdb10a7ba renderer_software: Add jit compiler for tev stages 2023-07-17 18:12:02 +03:00
8012b28b92 renderer_software: Move memory access out of the raster loop
* Profiling shows this has a significant impact
2023-07-16 03:45:57 +03:00
531d280461 renderer_software: Multi-thread processing
* Doubles the performance in most cases
2023-07-16 03:02:55 +03:00
308 changed files with 6573 additions and 7843 deletions

View File

@ -57,7 +57,6 @@ CMAKE_DEPENDENT_OPTION(ENABLE_TESTS "Enable generating tests executable" ON "NOT
CMAKE_DEPENDENT_OPTION(ENABLE_DEDICATED_ROOM "Enable generating dedicated room executable" ON "NOT ANDROID AND NOT IOS" OFF)
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
option(ENABLE_SCRIPTING "Enable RPC server for scripting" ON)
CMAKE_DEPENDENT_OPTION(ENABLE_CUBEB "Enables the cubeb audio backend" ON "NOT IOS" OFF)
option(ENABLE_OPENAL "Enables the OpenAL audio backend" ON)
@ -342,6 +341,13 @@ function(get_timestamp _var)
set(${_var} "${timestamp}" PARENT_SCOPE)
endfunction()
# Prevent boost from linking against libs when building
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
-DBOOST_SYSTEM_NO_LIB
-DBOOST_DATE_TIME_NO_LIB
-DBOOST_REGEX_NO_LIB
)
# generate git/build information
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REF_SPEC GIT_REV)
@ -349,23 +355,17 @@ git_describe(GIT_DESC --always --long --dirty)
git_branch_name(GIT_BRANCH)
get_timestamp(BUILD_DATE)
# Boost
# Prevent boost from linking against libs when building
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
-DBOOST_SYSTEM_NO_LIB
-DBOOST_DATE_TIME_NO_LIB
-DBOOST_REGEX_NO_LIB
)
if (USE_SYSTEM_BOOST)
find_package(Boost 1.70.0 COMPONENTS container locale serialization iostreams REQUIRED)
if (NOT USE_SYSTEM_BOOST)
add_definitions( -DBOOST_ALL_NO_LIB )
endif()
enable_testing()
add_subdirectory(externals)
# Boost (bundled)
if (NOT USE_SYSTEM_BOOST)
add_definitions( -DBOOST_ALL_NO_LIB )
# Boost
if (USE_SYSTEM_BOOST)
find_package(Boost 1.70.0 COMPONENTS serialization iostreams REQUIRED)
else()
add_library(Boost::boost ALIAS boost)
add_library(Boost::serialization ALIAS boost_serialization)
add_library(Boost::iostreams ALIAS boost_iostreams)

View File

@ -57,7 +57,9 @@ if (DEFINED ENV{CI})
set(BUILD_VERSION ${CMAKE_MATCH_1})
endif()
if (BUILD_VERSION)
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION}")
# This leaves a trailing space on the last word, but we actually want that
# because of how it's styled in the title bar.
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ")
else()
set(BUILD_FULLNAME "")
endif()

View File

@ -12,29 +12,27 @@ include(DownloadExternals)
include(ExternalProject)
# Boost
if (NOT USE_SYSTEM_BOOST)
message(STATUS "Including vendored Boost library")
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
set(Boost_NO_SYSTEM_PATHS ON CACHE BOOL "")
add_library(boost INTERFACE)
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
set(Boost_NO_SYSTEM_PATHS ON CACHE BOOL "")
add_library(boost INTERFACE)
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
# Boost::serialization
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
add_library(boost_serialization STATIC ${boost_serialization_SRC})
target_link_libraries(boost_serialization PUBLIC boost)
# Boost::serialization
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
add_library(boost_serialization STATIC ${boost_serialization_SRC})
target_link_libraries(boost_serialization PUBLIC boost)
# Boost::iostreams
add_library(
boost_iostreams
STATIC
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/file_descriptor.cpp
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/mapped_file.cpp
)
target_link_libraries(boost_iostreams PUBLIC boost)
# Boost::iostreams
add_library(
boost_iostreams
STATIC
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/file_descriptor.cpp
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/mapped_file.cpp
)
target_link_libraries(boost_iostreams PUBLIC boost)
# Add additional boost libs here; remember to ALIAS them in the root CMakeLists!
endif()
# Catch2
set(CATCH_INSTALL_DOCS OFF CACHE BOOL "")
@ -173,38 +171,37 @@ endif()
add_library(json-headers INTERFACE)
target_include_directories(json-headers INTERFACE ./json)
# OpenSSL
if (USE_SYSTEM_OPENSSL)
find_package(OpenSSL 1.1)
if (OPENSSL_FOUND)
set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
endif()
endif()
if (NOT OPENSSL_FOUND)
# LibreSSL
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
set(OPENSSLDIR "/etc/ssl/")
add_subdirectory(libressl EXCLUDE_FROM_ALL)
target_include_directories(ssl INTERFACE ./libressl/include)
target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
get_directory_property(OPENSSL_LIBRARIES
DIRECTORY libressl
DEFINITION OPENSSL_LIBS)
endif()
# httplib
add_library(httplib INTERFACE)
target_include_directories(httplib INTERFACE ./httplib)
target_compile_options(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
if(ANDROID)
add_subdirectory(android-ifaddrs)
endif()
# cpp-jwt
if (ENABLE_WEB_SERVICE)
if (USE_SYSTEM_OPENSSL)
find_package(OpenSSL 1.1)
if (OPENSSL_FOUND)
set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
endif()
endif()
if (NOT OPENSSL_FOUND)
# LibreSSL
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
set(OPENSSLDIR "/etc/ssl/")
add_subdirectory(libressl EXCLUDE_FROM_ALL)
target_include_directories(ssl INTERFACE ./libressl/include)
target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
get_directory_property(OPENSSL_LIBRARIES
DIRECTORY libressl
DEFINITION OPENSSL_LIBS)
endif()
if(ANDROID)
add_subdirectory(android-ifaddrs)
endif()
# httplib
add_library(httplib INTERFACE)
target_include_directories(httplib INTERFACE ./httplib)
target_compile_options(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
# cpp-jwt
add_library(cpp-jwt INTERFACE)
target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include)
target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)

View File

@ -29,7 +29,6 @@
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:name="org.citra.citra_emu.CitraApplication"

View File

@ -1,10 +1,7 @@
package org.citra.citra_emu.ui.main;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
@ -16,7 +13,6 @@ import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.core.splashscreen.SplashScreen;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.Collections;
@ -128,9 +124,6 @@ public final class MainActivity extends AppCompatActivity implements MainView {
);
});
private final ActivityResultLauncher<String> requestNotificationPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> { });
@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
@ -172,12 +165,6 @@ public final class MainActivity extends AppCompatActivity implements MainView {
EmulationActivity.tryDismissRunningNotification(this);
setInsets();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
requestNotificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
}
}
}
@Override

View File

@ -53,7 +53,7 @@ void AndroidMiiSelector::Setup(const Frontend::MiiSelectorConfig& config) {
const u32 return_code = static_cast<u32>(
env->GetLongField(data, env->GetFieldID(s_mii_selector_data_class, "return_code", "J")));
if (return_code == 1) {
Finalize(return_code, Mii::MiiData{});
Finalize(return_code, HLE::Applets::MiiData{});
return;
}

View File

@ -26,7 +26,6 @@
#include "core/hle/service/nfc/nfc.h"
#include "core/loader/loader.h"
#include "core/savestate.h"
#include "core/telemetry_session.h"
#include "jni/android_common/android_common.h"
#include "jni/applets/mii_selector.h"
#include "jni/applets/swkbd.h"
@ -157,7 +156,7 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
system.RegisterSoftwareKeyboard(std::make_shared<SoftwareKeyboard::AndroidKeyboard>());
// Register microphone permission check
system.RegisterMicPermissionCheck(&CheckMicPermission);
Core::System::GetInstance().RegisterMicPermissionCheck(&CheckMicPermission);
InputManager::Init();
@ -167,7 +166,7 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
return load_result;
}
auto& telemetry_session = system.TelemetrySession();
auto& telemetry_session = Core::System::GetInstance().TelemetrySession();
telemetry_session.AddField(Common::Telemetry::FieldType::App, "Frontend", "Android");
stop_run = false;
@ -188,7 +187,8 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
audio_stretching_event =
system.CoreTiming().RegisterEvent("AudioStretchingEvent", [&](u64, s64 cycles_late) {
if (Settings::values.enable_audio_stretching) {
system.DSP().EnableStretching(system.GetAndResetPerfStats().emulation_speed < 0.95);
Core::DSP().EnableStretching(
Core::System::GetInstance().GetAndResetPerfStats().emulation_speed < 0.95);
}
system.CoreTiming().ScheduleEvent(audio_stretching_ticks - cycles_late,
@ -219,7 +219,7 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
SCOPE_EXIT({ Settings::values.volume = volume; });
Settings::values.volume = 0;
std::unique_lock pause_lock{paused_mutex};
std::unique_lock<std::mutex> pause_lock(paused_mutex);
running_cv.wait(pause_lock, [] { return !pause_emulation || stop_run; });
window->PollEvents();
}
@ -621,7 +621,7 @@ jobjectArray Java_org_citra_citra_1emu_NativeLibrary_GetSavestateInfo(
return nullptr;
}
const auto savestates = Core::ListSaveStates(title_id, system.Movie().GetCurrentMovieID());
const auto savestates = Core::ListSaveStates(title_id);
const jobjectArray array =
env->NewObjectArray(static_cast<jsize>(savestates.size()), savestate_info_class, nullptr);
for (std::size_t i = 0; i < savestates.size(); ++i) {

View File

@ -5,24 +5,20 @@
#include "common/common_types.h"
namespace AudioCore {
struct ADTSData {
u8 header_length = 0;
bool mpeg2 = false;
u8 profile = 0;
u8 channels = 0;
u8 channel_idx = 0;
u8 framecount = 0;
u8 samplerate_idx = 0;
u32 length = 0;
u32 samplerate = 0;
u8 header_length;
bool MPEG2;
u8 profile;
u8 channels;
u8 channel_idx;
u8 framecount;
u8 samplerate_idx;
u32 length;
u32 samplerate;
};
ADTSData ParseADTS(const u8* buffer);
ADTSData ParseADTS(const char* buffer);
// last two bytes of MF AAC decoder user data
// see https://docs.microsoft.com/en-us/windows/desktop/medfound/aac-decoder#example-media-types
u16 MFGetAACTag(const ADTSData& input);
} // namespace AudioCore

View File

@ -3,59 +3,44 @@
// Refer to the license.txt file included.
#include <array>
#include "adts.h"
#include "common/bit_field.h"
namespace AudioCore {
constexpr std::array<u32, 16> freq_table = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
16000, 12000, 11025, 8000, 7350, 0, 0, 0};
constexpr std::array<u8, 8> channel_table = {0, 1, 2, 3, 4, 5, 6, 8};
struct ADTSHeader {
union {
std::array<u8, 7> raw{};
BitFieldBE<52, 12, u64> sync_word;
BitFieldBE<51, 1, u64> mpeg2;
BitFieldBE<49, 2, u64> layer;
BitFieldBE<48, 1, u64> protection_absent;
BitFieldBE<46, 2, u64> profile;
BitFieldBE<42, 4, u64> samplerate_idx;
BitFieldBE<41, 1, u64> private_bit;
BitFieldBE<38, 3, u64> channel_idx;
BitFieldBE<37, 1, u64> originality;
BitFieldBE<36, 1, u64> home;
BitFieldBE<35, 1, u64> copyright_id;
BitFieldBE<34, 1, u64> copyright_id_start;
BitFieldBE<21, 13, u64> frame_length;
BitFieldBE<10, 11, u64> buffer_fullness;
BitFieldBE<8, 2, u64> frame_count;
};
};
ADTSData ParseADTS(const u8* buffer) {
ADTSHeader header;
memcpy(header.raw.data(), buffer, sizeof(header.raw));
ADTSData ParseADTS(const char* buffer) {
u32 tmp = 0;
ADTSData out;
// sync word 0xfff
if (header.sync_word != 0xfff) {
return {};
tmp = (buffer[0] << 8) | (buffer[1] & 0xf0);
if ((tmp & 0xffff) != 0xfff0) {
out.length = 0;
return out;
}
ADTSData out{};
// bit 16 = no CRC
out.header_length = header.protection_absent ? 7 : 9;
out.mpeg2 = static_cast<bool>(header.mpeg2);
out.header_length = (buffer[1] & 0x1) ? 7 : 9;
out.MPEG2 = (buffer[1] >> 3) & 0x1;
// bit 17 to 18
out.profile = static_cast<u8>(header.profile) + 1;
out.profile = (buffer[2] >> 6) + 1;
// bit 19 to 22
out.samplerate_idx = static_cast<u8>(header.samplerate_idx);
out.samplerate = header.samplerate_idx > 15 ? 0 : freq_table[header.samplerate_idx];
tmp = (buffer[2] >> 2) & 0xf;
out.samplerate_idx = tmp;
out.samplerate = (tmp > 15) ? 0 : freq_table[tmp];
// bit 24 to 26
out.channel_idx = static_cast<u8>(header.channel_idx);
out.channels = (header.channel_idx > 7) ? 0 : channel_table[header.channel_idx];
tmp = ((buffer[2] & 0x1) << 2) | ((buffer[3] >> 6) & 0x3);
out.channel_idx = tmp;
out.channels = (tmp > 7) ? 0 : channel_table[tmp];
// bit 55 to 56
out.framecount = static_cast<u8>(header.frame_count + 1);
out.framecount = (buffer[6] & 0x3) + 1;
// bit 31 to 43
out.length = static_cast<u32>(header.frame_length);
tmp = (buffer[3] & 0x3) << 11;
tmp |= (buffer[4] << 3) & 0x7f8;
tmp |= (buffer[5] >> 5) & 0x7;
out.length = tmp;
return out;
}
@ -76,4 +61,3 @@ u16 MFGetAACTag(const ADTSData& input) {
return tag;
}
} // namespace AudioCore

View File

@ -24,7 +24,7 @@ private:
std::optional<BinaryMessage> Decode(const BinaryMessage& request);
void Clear();
bool InitializeDecoder(AudioCore::ADTSData& adts_header);
bool InitializeDecoder(ADTSData& adts_header);
static OSStatus DataFunc(AudioConverterRef in_audio_converter, u32* io_number_data_packets,
AudioBufferList* io_data,
@ -33,7 +33,7 @@ private:
Memory::MemorySystem& memory;
AudioCore::ADTSData adts_config;
ADTSData adts_config;
AudioStreamBasicDescription output_format = {};
AudioConverterRef converter = nullptr;
@ -85,11 +85,7 @@ std::optional<BinaryMessage> AudioToolboxDecoder::Impl::ProcessRequest(
case DecoderCommand::EncodeDecode: {
return Decode(request);
}
case DecoderCommand::Shutdown:
case DecoderCommand::SaveState:
case DecoderCommand::LoadState: {
LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}",
static_cast<u16>(request.header.cmd));
case DecoderCommand::Unknown: {
BinaryMessage response = request;
response.header.result = ResultStatus::Success;
return response;
@ -101,7 +97,7 @@ std::optional<BinaryMessage> AudioToolboxDecoder::Impl::ProcessRequest(
}
}
bool AudioToolboxDecoder::Impl::InitializeDecoder(AudioCore::ADTSData& adts_header) {
bool AudioToolboxDecoder::Impl::InitializeDecoder(ADTSData& adts_header) {
if (converter) {
if (adts_config.channels == adts_header.channels &&
adts_config.samplerate == adts_header.samplerate) {
@ -183,9 +179,8 @@ std::optional<BinaryMessage> AudioToolboxDecoder::Impl::Decode(const BinaryMessa
return {};
}
const auto data =
memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
auto adts_header = AudioCore::ParseADTS(data);
auto data = memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
auto adts_header = ParseADTS(reinterpret_cast<const char*>(data));
curr_data = data + adts_header.header_length;
curr_data_len = request.decode_aac_request.size - adts_header.header_length;

View File

@ -42,9 +42,7 @@ std::optional<BinaryMessage> NullDecoder::ProcessRequest(const BinaryMessage& re
BinaryMessage response{};
switch (request.header.cmd) {
case DecoderCommand::Init:
case DecoderCommand::Shutdown:
case DecoderCommand::SaveState:
case DecoderCommand::LoadState:
case DecoderCommand::Unknown:
response = request;
response.header.result = ResultStatus::Success;
return response;

View File

@ -14,16 +14,9 @@
namespace AudioCore::HLE {
enum class DecoderCommand : u16 {
/// Initializes the decoder.
Init = 0,
/// Decodes/encodes a data frame.
EncodeDecode = 1,
/// Shuts down the decoder.
Shutdown = 2,
/// Loads the saved decoder state. Used for DSP wake.
LoadState = 3,
/// Saves the decoder state. Used for DSP sleep.
SaveState = 4,
Unknown = 2, // Probably UnInit
};
enum class DecoderCodec : u16 {

View File

@ -111,11 +111,7 @@ std::optional<BinaryMessage> FDKDecoder::Impl::ProcessRequest(const BinaryMessag
case DecoderCommand::EncodeDecode: {
return Decode(request);
}
case DecoderCommand::Shutdown:
case DecoderCommand::SaveState:
case DecoderCommand::LoadState: {
LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}",
static_cast<u16>(request.header.cmd));
case DecoderCommand::Unknown: {
BinaryMessage response = request;
response.header.result = ResultStatus::Success;
return response;

View File

@ -80,11 +80,7 @@ std::optional<BinaryMessage> FFMPEGDecoder::Impl::ProcessRequest(const BinaryMes
case DecoderCommand::EncodeDecode: {
return Decode(request);
}
case DecoderCommand::Shutdown:
case DecoderCommand::SaveState:
case DecoderCommand::LoadState: {
LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}",
static_cast<u16>(request.header.cmd));
case DecoderCommand::Unknown: {
BinaryMessage response = request;
response.header.result = ResultStatus::Success;
return response;

View File

@ -8,7 +8,6 @@
#include <boost/serialization/vector.hpp>
#include <boost/serialization/weak_ptr.hpp>
#include "audio_core/audio_types.h"
#include "common/archives.h"
#ifdef HAVE_MF
#include "audio_core/hle/wmf_decoder.h"
#elif HAVE_AUDIOTOOLBOX
@ -320,10 +319,6 @@ void DspHle::Impl::PipeWrite(DspPipe pipe_number, std::span<const u8> buffer) {
pipe_data[static_cast<u32>(pipe_number)].resize(sizeof(value));
std::memcpy(pipe_data[static_cast<u32>(pipe_number)].data(), &value, sizeof(value));
}
auto dsp = dsp_dsp.lock();
if (dsp) {
dsp->SignalInterrupt(InterruptType::Pipe, DspPipe::Binary);
}
break;
}
default:
@ -466,6 +461,8 @@ void DspHle::Impl::AudioTickCallback(s64 cycles_late) {
// TODO(merry): Signal all the other interrupts as appropriate.
if (auto service = dsp_dsp.lock()) {
service->SignalInterrupt(InterruptType::Pipe, DspPipe::Audio);
// HACK(merry): Added to prevent regressions. Will remove soon.
service->SignalInterrupt(InterruptType::Pipe, DspPipe::Binary);
}
}

View File

@ -27,7 +27,7 @@ public:
~Impl();
std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request);
bool SetMediaType(const AudioCore::ADTSData& adts_data);
bool SetMediaType(const ADTSData& adts_data);
private:
std::optional<BinaryMessage> Initalize(const BinaryMessage& request);
@ -36,8 +36,8 @@ private:
Memory::MemorySystem& memory;
std::unique_ptr<AMediaCodec, AMediaCodecRelease> decoder;
// default: 2 channles, 48000 samplerate
AudioCore::ADTSData mADTSData{
/*header_length*/ 7, /*mpeg2*/ false, /*profile*/ 2,
ADTSData mADTSData{
/*header_length*/ 7, /*MPEG2*/ false, /*profile*/ 2,
/*channels*/ 2, /*channel_idx*/ 2, /*framecount*/ 0,
/*samplerate_idx*/ 3, /*length*/ 0, /*samplerate*/ 48000};
};
@ -54,7 +54,7 @@ std::optional<BinaryMessage> MediaNDKDecoder::Impl::Initalize(const BinaryMessag
return response;
}
bool MediaNDKDecoder::Impl::SetMediaType(const AudioCore::ADTSData& adts_data) {
bool MediaNDKDecoder::Impl::SetMediaType(const ADTSData& adts_data) {
const char* mime = "audio/mp4a-latm";
if (decoder && mADTSData.profile == adts_data.profile &&
mADTSData.channel_idx == adts_data.channel_idx &&
@ -110,11 +110,7 @@ std::optional<BinaryMessage> MediaNDKDecoder::Impl::ProcessRequest(const BinaryM
case DecoderCommand::EncodeDecode: {
return Decode(request);
}
case DecoderCommand::Shutdown:
case DecoderCommand::SaveState:
case DecoderCommand::LoadState: {
LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}",
static_cast<u16>(request.header.cmd));
case DecoderCommand::Unknown: {
BinaryMessage response = request;
response.header.result = ResultStatus::Success;
return response;
@ -141,9 +137,8 @@ std::optional<BinaryMessage> MediaNDKDecoder::Impl::Decode(const BinaryMessage&
return response;
}
const u8* data =
memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
ADTSData adts_data = AudioCore::ParseADTS(data);
u8* data = memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
ADTSData adts_data = ParseADTS(reinterpret_cast<const char*>(data));
SetMediaType(adts_data);
response.decode_aac_response.sample_rate = GetSampleRateEnum(adts_data.samplerate);
response.decode_aac_response.num_channels = adts_data.channels;

View File

@ -23,8 +23,7 @@ private:
std::optional<BinaryMessage> Decode(const BinaryMessage& request);
MFOutputState DecodingLoop(AudioCore::ADTSData adts_header,
std::array<std::vector<u8>, 2>& out_streams);
MFOutputState DecodingLoop(ADTSData adts_header, std::array<std::vector<u8>, 2>& out_streams);
bool transform_initialized = false;
bool format_selected = false;
@ -116,11 +115,7 @@ std::optional<BinaryMessage> WMFDecoder::Impl::ProcessRequest(const BinaryMessag
case DecoderCommand::EncodeDecode: {
return Decode(request);
}
case DecoderCommand::Shutdown:
case DecoderCommand::SaveState:
case DecoderCommand::LoadState: {
LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}",
static_cast<u16>(request.header.cmd));
case DecoderCommand::Unknown: {
BinaryMessage response = request;
response.header.result = ResultStatus::Success;
return response;
@ -140,7 +135,7 @@ std::optional<BinaryMessage> WMFDecoder::Impl::Initalize(const BinaryMessage& re
return response;
}
MFOutputState WMFDecoder::Impl::DecodingLoop(AudioCore::ADTSData adts_header,
MFOutputState WMFDecoder::Impl::DecodingLoop(ADTSData adts_header,
std::array<std::vector<u8>, 2>& out_streams) {
std::optional<std::vector<f32>> output_buffer;
@ -211,14 +206,14 @@ std::optional<BinaryMessage> WMFDecoder::Impl::Decode(const BinaryMessage& reque
request.decode_aac_request.src_addr);
return std::nullopt;
}
const u8* data =
memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
u8* data = memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
std::array<std::vector<u8>, 2> out_streams;
unique_mfptr<IMFSample> sample;
MFInputState input_status = MFInputState::OK;
MFOutputState output_status = MFOutputState::OK;
std::optional<ADTSMeta> adts_meta = DetectMediaType(data, request.decode_aac_request.size);
std::optional<ADTSMeta> adts_meta =
DetectMediaType((char*)data, request.decode_aac_request.size);
if (!adts_meta) {
LOG_ERROR(Audio_DSP, "Unable to deduce decoding parameters from ADTS stream");

View File

@ -110,9 +110,8 @@ unique_mfptr<IMFSample> CreateSample(const void* data, DWORD len, DWORD alignmen
return sample;
}
bool SelectInputMediaType(IMFTransform* transform, int in_stream_id,
const AudioCore::ADTSData& adts, const UINT8* user_data,
UINT32 user_data_len, GUID audio_format) {
bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts,
const UINT8* user_data, UINT32 user_data_len, GUID audio_format) {
HRESULT hr = S_OK;
unique_mfptr<IMFMediaType> t;
@ -191,12 +190,12 @@ bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id, GUID audi
return false;
}
std::optional<ADTSMeta> DetectMediaType(const u8* buffer, std::size_t len) {
std::optional<ADTSMeta> DetectMediaType(char* buffer, std::size_t len) {
if (len < 7) {
return std::nullopt;
}
AudioCore::ADTSData tmp;
ADTSData tmp;
ADTSMeta result;
// see https://docs.microsoft.com/en-us/windows/desktop/api/mmreg/ns-mmreg-heaacwaveinfo_tag
// for the meaning of the byte array below
@ -208,7 +207,7 @@ std::optional<ADTSMeta> DetectMediaType(const u8* buffer, std::size_t len) {
UINT8 aac_tmp[] = {0x01, 0x00, 0xfe, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x00, 0x00};
uint16_t tag = 0;
tmp = AudioCore::ParseADTS(buffer);
tmp = ParseADTS(buffer);
if (tmp.length == 0) {
return std::nullopt;
}
@ -216,7 +215,7 @@ std::optional<ADTSMeta> DetectMediaType(const u8* buffer, std::size_t len) {
tag = MFGetAACTag(tmp);
aac_tmp[12] |= (tag & 0xff00) >> 8;
aac_tmp[13] |= (tag & 0x00ff);
std::memcpy(&(result.ADTSHeader), &tmp, sizeof(AudioCore::ADTSData));
std::memcpy(&(result.ADTSHeader), &tmp, sizeof(ADTSData));
std::memcpy(&(result.AACTag), aac_tmp, 14);
return result;
}

View File

@ -99,7 +99,7 @@ void ReportError(std::string msg, HRESULT hr);
// data type for transferring ADTS metadata between functions
struct ADTSMeta {
AudioCore::ADTSData ADTSHeader;
ADTSData ADTSHeader;
u8 AACTag[14];
};
@ -110,10 +110,10 @@ bool InitMFDLL();
unique_mfptr<IMFTransform> MFDecoderInit(GUID audio_format = MFAudioFormat_AAC);
unique_mfptr<IMFSample> CreateSample(const void* data, DWORD len, DWORD alignment = 1,
LONGLONG duration = 0);
bool SelectInputMediaType(IMFTransform* transform, int in_stream_id,
const AudioCore::ADTSData& adts, const UINT8* user_data,
UINT32 user_data_len, GUID audio_format = MFAudioFormat_AAC);
std::optional<ADTSMeta> DetectMediaType(const u8* buffer, std::size_t len);
bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts,
const UINT8* user_data, UINT32 user_data_len,
GUID audio_format = MFAudioFormat_AAC);
std::optional<ADTSMeta> DetectMediaType(char* buffer, std::size_t len);
bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id,
GUID audio_format = MFAudioFormat_PCM);
void MFFlush(IMFTransform* transform);

View File

@ -19,6 +19,7 @@
#include "common/detached_tasks.h"
#include "common/file_util.h"
#include "common/logging/backend.h"
#include "common/logging/filter.h"
#include "common/logging/log.h"
#include "common/scm_rev.h"
#include "common/scope_exit.h"
@ -27,15 +28,18 @@
#include "core/core.h"
#include "core/dumping/backend.h"
#include "core/dumping/ffmpeg_backend.h"
#include "core/file_sys/cia_container.h"
#include "core/frontend/applets/default_applets.h"
#include "core/frontend/framebuffer_layout.h"
#include "core/gdbstub/gdbstub.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/cfg/cfg.h"
#include "core/loader/loader.h"
#include "core/movie.h"
#include "core/telemetry_session.h"
#include "input_common/main.h"
#include "network/network.h"
#include "video_core/renderer_base.h"
#include "video_core/video_core.h"
#undef _UNICODE
#include <getopt.h>
@ -327,7 +331,7 @@ int main(int argc, char** argv) {
}
auto& system = Core::System::GetInstance();
auto& movie = system.Movie();
auto& movie = Core::Movie::GetInstance();
if (!movie_record.empty()) {
movie.PrepareForRecording();

View File

@ -128,54 +128,16 @@ void EmuWindow_SDL2::InitializeSDL2() {
SDL_SetMainReady();
}
u32 EmuWindow_SDL2::GetEventWindowId(const SDL_Event& event) const {
switch (event.type) {
case SDL_WINDOWEVENT:
return event.window.windowID;
case SDL_KEYDOWN:
case SDL_KEYUP:
return event.key.windowID;
case SDL_MOUSEMOTION:
return event.motion.windowID;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
return event.button.windowID;
case SDL_MOUSEWHEEL:
return event.wheel.windowID;
case SDL_FINGERDOWN:
case SDL_FINGERMOTION:
case SDL_FINGERUP:
return event.tfinger.windowID;
case SDL_TEXTEDITING:
return event.edit.windowID;
case SDL_TEXTEDITING_EXT:
return event.editExt.windowID;
case SDL_TEXTINPUT:
return event.text.windowID;
case SDL_DROPBEGIN:
case SDL_DROPFILE:
case SDL_DROPTEXT:
case SDL_DROPCOMPLETE:
return event.drop.windowID;
case SDL_USEREVENT:
return event.user.windowID;
default:
// Event is not for any particular window, so we can just pretend it's for this one.
return render_window_id;
}
}
void EmuWindow_SDL2::PollEvents() {
SDL_Event event;
std::vector<SDL_Event> other_window_events;
// SDL_PollEvent returns 0 when there are no more events in the event queue
while (SDL_PollEvent(&event)) {
if (GetEventWindowId(event) != render_window_id) {
if (event.window.windowID != render_window_id) {
other_window_events.push_back(event);
continue;
}
switch (event.type) {
case SDL_WINDOWEVENT:
switch (event.window.event) {

View File

@ -8,7 +8,6 @@
#include "common/common_types.h"
#include "core/frontend/emu_window.h"
union SDL_Event;
struct SDL_Window;
namespace Core {
@ -36,9 +35,6 @@ public:
void RequestClose();
protected:
/// Gets the ID of the window an event originated from.
u32 GetEventWindowId(const SDL_Event& event) const;
/// Called by PollEvents when a key is pressed or released.
void OnKeyEvent(int key, u8 state);

View File

@ -67,5 +67,6 @@ void QtMiiSelector::OpenDialog() {
dialog.return_code, index);
const auto mii_data = dialog.miis.at(index);
Finalize(dialog.return_code, dialog.return_code == 0 ? std::move(mii_data) : Mii::MiiData{});
Finalize(dialog.return_code,
dialog.return_code == 0 ? std::move(mii_data) : HLE::Applets::MiiData{});
}

View File

@ -24,7 +24,7 @@ private:
QVBoxLayout* layout;
QtMiiSelector* mii_selector;
u32 return_code = 0;
std::vector<Mii::MiiData> miis;
std::vector<HLE::Applets::MiiData> miis;
friend class QtMiiSelector;
};

View File

@ -387,6 +387,10 @@ GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread_, Core::Sys
bool is_secondary_)
: QWidget(parent_), EmuWindow(is_secondary_), emu_thread(emu_thread_), system{system_} {
setWindowTitle(QStringLiteral("Citra %1 | %2-%3")
.arg(QString::fromUtf8(Common::g_build_name),
QString::fromUtf8(Common::g_scm_branch),
QString::fromUtf8(Common::g_scm_desc)));
setAttribute(Qt::WA_AcceptTouchEvents);
auto layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);

View File

@ -9,7 +9,6 @@
#include "citra_qt/compatdb.h"
#include "common/telemetry.h"
#include "core/core.h"
#include "core/telemetry_session.h"
#include "ui_compatdb.h"
CompatDB::CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent)

View File

@ -29,7 +29,7 @@ Config::~Config() {
const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = {
Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, Qt::Key_T, Qt::Key_G,
Qt::Key_F, Qt::Key_H, Qt::Key_Q, Qt::Key_W, Qt::Key_M, Qt::Key_N,
Qt::Key_O, Qt::Key_P, Qt::Key_1, Qt::Key_2, Qt::Key_B, Qt::Key_V,
Qt::Key_O, Qt::Key_P, Qt::Key_1, Qt::Key_2, Qt::Key_B,
};
const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> Config::default_analogs{{
@ -772,11 +772,6 @@ void Config::ReadUIGameListValues() {
ReadBasicSetting(UISettings::values.game_list_hide_no_icon);
ReadBasicSetting(UISettings::values.game_list_single_line_mode);
ReadBasicSetting(UISettings::values.show_compat_column);
ReadBasicSetting(UISettings::values.show_region_column);
ReadBasicSetting(UISettings::values.show_type_column);
ReadBasicSetting(UISettings::values.show_size_column);
qt_config->endGroup();
}
@ -1235,11 +1230,6 @@ void Config::SaveUIGameListValues() {
WriteBasicSetting(UISettings::values.game_list_hide_no_icon);
WriteBasicSetting(UISettings::values.game_list_single_line_mode);
WriteBasicSetting(UISettings::values.show_compat_column);
WriteBasicSetting(UISettings::values.show_region_column);
WriteBasicSetting(UISettings::values.show_type_column);
WriteBasicSetting(UISettings::values.show_size_column);
qt_config->endGroup();
}

View File

@ -21,8 +21,68 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>-1</number>
<number>0</number>
</property>
<widget class="ConfigureGeneral" name="generalTab">
<attribute name="title">
<string>General</string>
</attribute>
</widget>
<widget class="ConfigureSystem" name="systemTab">
<attribute name="title">
<string>System</string>
</attribute>
</widget>
<widget class="ConfigureInput" name="inputTab">
<attribute name="title">
<string>Input</string>
</attribute>
</widget>
<widget class="ConfigureHotkeys" name="hotkeysTab">
<attribute name="title">
<string>Hotkeys</string>
</attribute>
</widget>
<widget class="ConfigureGraphics" name="graphicsTab">
<attribute name="title">
<string>Graphics</string>
</attribute>
</widget>
<widget class="ConfigureEnhancements" name="enhancementsTab">
<attribute name="title">
<string>Enhancements</string>
</attribute>
</widget>
<widget class="ConfigureAudio" name="audioTab">
<attribute name="title">
<string>Audio</string>
</attribute>
</widget>
<widget class="ConfigureCamera" name="cameraTab">
<attribute name="title">
<string>Camera</string>
</attribute>
</widget>
<widget class="ConfigureDebug" name="debugTab">
<attribute name="title">
<string>Debug</string>
</attribute>
</widget>
<widget class="ConfigureStorage" name="storageTab">
<attribute name="title">
<string>Storage</string>
</attribute>
</widget>
<widget class="ConfigureWeb" name="webTab">
<attribute name="title">
<string>Web</string>
</attribute>
</widget>
<widget class="ConfigureUi" name="uiTab">
<attribute name="title">
<string>UI</string>
</attribute>
</widget>
</widget>
</item>
</layout>

View File

@ -10,13 +10,14 @@
#include "citra_qt/configuration/configuration_shared.h"
#include "citra_qt/configuration/configure_audio.h"
#include "common/settings.h"
#include "core/core.h"
#include "ui_configure_audio.h"
#if defined(__APPLE__)
#include "common/apple_authorization.h"
#endif
ConfigureAudio::ConfigureAudio(bool is_powered_on, QWidget* parent)
ConfigureAudio::ConfigureAudio(QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()) {
ui->setupUi(this);
@ -26,7 +27,8 @@ ConfigureAudio::ConfigureAudio(bool is_powered_on, QWidget* parent)
AudioCore::GetSinkName(static_cast<AudioCore::SinkType>(type)).data()));
}
ui->emulation_combo_box->setEnabled(!is_powered_on);
const bool is_running = Core::System::GetInstance().IsPoweredOn();
ui->emulation_combo_box->setEnabled(!is_running);
connect(ui->volume_slider, &QSlider::valueChanged, this,
&ConfigureAudio::SetVolumeIndicatorText);

View File

@ -19,7 +19,7 @@ class ConfigureAudio : public QWidget {
Q_OBJECT
public:
explicit ConfigureAudio(bool is_powered_on, QWidget* parent = nullptr);
explicit ConfigureAudio(QWidget* parent = nullptr);
~ConfigureAudio() override;
void ApplyConfiguration();

View File

@ -47,7 +47,8 @@ ConfigureCamera::~ConfigureCamera() {
}
void ConfigureCamera::ConnectEvents() {
connect(ui->image_source, qOverload<int>(&QComboBox::currentIndexChanged), this,
connect(ui->image_source,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
[this](int index) {
StopPreviewing();
UpdateImageSourceUI();
@ -57,33 +58,36 @@ void ConfigureCamera::ConnectEvents() {
}
#endif
});
connect(ui->camera_selection, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
StopPreviewing();
if (GetCameraSelection() != current_selected) {
RecordConfig();
}
if (ui->camera_selection->currentIndex() == 1) {
ui->camera_mode->setCurrentIndex(1); // Double
if (camera_name[0] == camera_name[2] && camera_config[0] == camera_config[2]) {
ui->camera_mode->setCurrentIndex(0); // Single
}
}
UpdateCameraMode();
SetConfiguration();
});
connect(ui->camera_mode, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
StopPreviewing();
ui->camera_position_label->setVisible(ui->camera_mode->currentIndex() == 1);
ui->camera_position->setVisible(ui->camera_mode->currentIndex() == 1);
current_selected = GetCameraSelection();
});
connect(ui->camera_position, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
StopPreviewing();
if (GetCameraSelection() != current_selected) {
RecordConfig();
}
SetConfiguration();
});
connect(ui->camera_selection,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [this] {
StopPreviewing();
if (GetCameraSelection() != current_selected) {
RecordConfig();
}
if (ui->camera_selection->currentIndex() == 1) {
ui->camera_mode->setCurrentIndex(1); // Double
if (camera_name[0] == camera_name[2] && camera_config[0] == camera_config[2]) {
ui->camera_mode->setCurrentIndex(0); // Single
}
}
UpdateCameraMode();
SetConfiguration();
});
connect(ui->camera_mode, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, [this] {
StopPreviewing();
ui->camera_position_label->setVisible(ui->camera_mode->currentIndex() == 1);
ui->camera_position->setVisible(ui->camera_mode->currentIndex() == 1);
current_selected = GetCameraSelection();
});
connect(ui->camera_position,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [this] {
StopPreviewing();
if (GetCameraSelection() != current_selected) {
RecordConfig();
}
SetConfiguration();
});
connect(ui->toolButton, &QToolButton::clicked, this, &ConfigureCamera::OnToolButtonClicked);
connect(ui->preview_button, &QPushButton::clicked, this, [this] { StartPreviewing(); });
connect(ui->prompt_before_load, &QCheckBox::stateChanged, this, [this](int state) {

View File

@ -9,9 +9,11 @@
#include "core/cheats/cheat_base.h"
#include "core/cheats/cheats.h"
#include "core/cheats/gateway_cheat.h"
#include "core/core.h"
#include "core/hle/kernel/process.h"
#include "ui_configure_cheats.h"
ConfigureCheats::ConfigureCheats(Core::System& system, u64 title_id_, QWidget* parent)
ConfigureCheats::ConfigureCheats(u64 title_id_, QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureCheats>()), title_id{title_id_} {
// Setup gui control settings
ui->setupUi(this);
@ -34,7 +36,7 @@ ConfigureCheats::ConfigureCheats(Core::System& system, u64 title_id_, QWidget* p
[this] { SaveCheat(ui->tableCheats->currentRow()); });
connect(ui->buttonDelete, &QPushButton::clicked, this, &ConfigureCheats::OnDeleteCheat);
cheat_engine = std::make_unique<Cheats::CheatEngine>(title_id, system);
cheat_engine = std::make_unique<Cheats::CheatEngine>(title_id, Core::System::GetInstance());
LoadCheats();
}

View File

@ -5,7 +5,6 @@
#pragma once
#include <memory>
#include <QWidget>
#include "common/common_types.h"
namespace Cheats {
@ -13,10 +12,6 @@ class CheatBase;
class CheatEngine;
} // namespace Cheats
namespace Core {
class System;
}
namespace Ui {
class ConfigureCheats;
} // namespace Ui
@ -25,7 +20,7 @@ class ConfigureCheats : public QWidget {
Q_OBJECT
public:
explicit ConfigureCheats(Core::System& system, u64 title_id, QWidget* parent = nullptr);
explicit ConfigureCheats(u64 title_id_, QWidget* parent = nullptr);
~ConfigureCheats();
bool ApplyConfiguration();

View File

@ -11,6 +11,7 @@
#include "common/file_util.h"
#include "common/logging/backend.h"
#include "common/settings.h"
#include "core/core.h"
#include "ui_configure_debug.h"
// The QSlider doesn't have an easy way to set a custom step amount,
@ -24,8 +25,8 @@ static constexpr int SettingsToSlider(int value) {
return (value - 5) / 5;
}
ConfigureDebug::ConfigureDebug(bool is_powered_on_, QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureDebug>()), is_powered_on{is_powered_on_} {
ConfigureDebug::ConfigureDebug(QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureDebug>()) {
ui->setupUi(this);
SetConfiguration();
@ -34,6 +35,7 @@ ConfigureDebug::ConfigureDebug(bool is_powered_on_, QWidget* parent)
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
});
const bool is_powered_on = Core::System::GetInstance().IsPoweredOn();
ui->toggle_cpu_jit->setEnabled(!is_powered_on);
ui->toggle_renderer_debug->setEnabled(!is_powered_on);
@ -57,7 +59,7 @@ void ConfigureDebug::SetConfiguration() {
ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub.GetValue());
ui->gdbport_spinbox->setEnabled(Settings::values.use_gdbstub.GetValue());
ui->gdbport_spinbox->setValue(Settings::values.gdbstub_port.GetValue());
ui->toggle_console->setEnabled(!is_powered_on);
ui->toggle_console->setEnabled(!Core::System::GetInstance().IsPoweredOn());
ui->toggle_console->setChecked(UISettings::values.show_console.GetValue());
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue()));
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue());

View File

@ -15,7 +15,7 @@ class ConfigureDebug : public QWidget {
Q_OBJECT
public:
explicit ConfigureDebug(bool is_powered_on, QWidget* parent = nullptr);
explicit ConfigureDebug(QWidget* parent = nullptr);
~ConfigureDebug() override;
void ApplyConfiguration();
@ -25,5 +25,4 @@ public:
private:
std::unique_ptr<Ui::ConfigureDebug> ui;
bool is_powered_on;
};

View File

@ -4,19 +4,8 @@
#include <map>
#include <QListWidgetItem>
#include "citra_qt/configuration/configure_audio.h"
#include "citra_qt/configuration/configure_camera.h"
#include "citra_qt/configuration/configure_debug.h"
#include "citra_qt/configuration/config.h"
#include "citra_qt/configuration/configure_dialog.h"
#include "citra_qt/configuration/configure_enhancements.h"
#include "citra_qt/configuration/configure_general.h"
#include "citra_qt/configuration/configure_graphics.h"
#include "citra_qt/configuration/configure_hotkeys.h"
#include "citra_qt/configuration/configure_input.h"
#include "citra_qt/configuration/configure_storage.h"
#include "citra_qt/configuration/configure_system.h"
#include "citra_qt/configuration/configure_ui.h"
#include "citra_qt/configuration/configure_web.h"
#include "citra_qt/hotkeys.h"
#include "common/settings.h"
#include "core/core.h"
@ -25,41 +14,16 @@
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, Core::System& system_,
bool enable_web_config)
: QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, registry{registry_},
system{system_}, is_powered_on{system.IsPoweredOn()},
general_tab{std::make_unique<ConfigureGeneral>(this)},
system_tab{std::make_unique<ConfigureSystem>(system, this)},
input_tab{std::make_unique<ConfigureInput>(this)},
hotkeys_tab{std::make_unique<ConfigureHotkeys>(this)},
graphics_tab{std::make_unique<ConfigureGraphics>(is_powered_on, this)},
enhancements_tab{std::make_unique<ConfigureEnhancements>(this)},
audio_tab{std::make_unique<ConfigureAudio>(is_powered_on, this)},
camera_tab{std::make_unique<ConfigureCamera>(this)},
debug_tab{std::make_unique<ConfigureDebug>(is_powered_on, this)},
storage_tab{std::make_unique<ConfigureStorage>(is_powered_on, this)},
web_tab{std::make_unique<ConfigureWeb>(this)}, ui_tab{std::make_unique<ConfigureUi>(this)} {
system{system_} {
Settings::SetConfiguringGlobal(true);
ui->setupUi(this);
ui->tabWidget->addTab(general_tab.get(), tr("General"));
ui->tabWidget->addTab(system_tab.get(), tr("System"));
ui->tabWidget->addTab(input_tab.get(), tr("Input"));
ui->tabWidget->addTab(hotkeys_tab.get(), tr("Hotkeys"));
ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
ui->tabWidget->addTab(enhancements_tab.get(), tr("Enhancements"));
ui->tabWidget->addTab(audio_tab.get(), tr("Audio"));
ui->tabWidget->addTab(camera_tab.get(), tr("Camera"));
ui->tabWidget->addTab(debug_tab.get(), tr("Debug"));
ui->tabWidget->addTab(storage_tab.get(), tr("Storage"));
ui->tabWidget->addTab(web_tab.get(), tr("Web"));
ui->tabWidget->addTab(ui_tab.get(), tr("UI"));
hotkeys_tab->Populate(registry);
web_tab->SetWebServiceConfigEnabled(enable_web_config);
ui->hotkeysTab->Populate(registry);
ui->webTab->SetWebServiceConfigEnabled(enable_web_config);
PopulateSelectionList();
connect(ui_tab.get(), &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged);
connect(ui->uiTab, &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged);
connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
&ConfigureDialog::UpdateVisibleTabs);
@ -67,46 +31,46 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, Cor
ui->selectorList->setCurrentRow(0);
// Set up used key list synchronisation
connect(input_tab.get(), &ConfigureInput::InputKeysChanged, hotkeys_tab.get(),
connect(ui->inputTab, &ConfigureInput::InputKeysChanged, ui->hotkeysTab,
&ConfigureHotkeys::OnInputKeysChanged);
connect(hotkeys_tab.get(), &ConfigureHotkeys::HotkeysChanged, input_tab.get(),
connect(ui->hotkeysTab, &ConfigureHotkeys::HotkeysChanged, ui->inputTab,
&ConfigureInput::OnHotkeysChanged);
// Synchronise lists upon initialisation
input_tab->EmitInputKeysChanged();
hotkeys_tab->EmitHotkeysChanged();
ui->inputTab->EmitInputKeysChanged();
ui->hotkeysTab->EmitHotkeysChanged();
}
ConfigureDialog::~ConfigureDialog() = default;
void ConfigureDialog::SetConfiguration() {
general_tab->SetConfiguration();
system_tab->SetConfiguration();
input_tab->LoadConfiguration();
graphics_tab->SetConfiguration();
enhancements_tab->SetConfiguration();
audio_tab->SetConfiguration();
camera_tab->SetConfiguration();
debug_tab->SetConfiguration();
web_tab->SetConfiguration();
ui_tab->SetConfiguration();
storage_tab->SetConfiguration();
ui->generalTab->SetConfiguration();
ui->systemTab->SetConfiguration();
ui->inputTab->LoadConfiguration();
ui->graphicsTab->SetConfiguration();
ui->enhancementsTab->SetConfiguration();
ui->audioTab->SetConfiguration();
ui->cameraTab->SetConfiguration();
ui->debugTab->SetConfiguration();
ui->webTab->SetConfiguration();
ui->uiTab->SetConfiguration();
ui->storageTab->SetConfiguration();
}
void ConfigureDialog::ApplyConfiguration() {
general_tab->ApplyConfiguration();
system_tab->ApplyConfiguration();
input_tab->ApplyConfiguration();
input_tab->ApplyProfile();
hotkeys_tab->ApplyConfiguration(registry);
graphics_tab->ApplyConfiguration();
enhancements_tab->ApplyConfiguration();
audio_tab->ApplyConfiguration();
camera_tab->ApplyConfiguration();
debug_tab->ApplyConfiguration();
web_tab->ApplyConfiguration();
ui_tab->ApplyConfiguration();
storage_tab->ApplyConfiguration();
ui->generalTab->ApplyConfiguration();
ui->systemTab->ApplyConfiguration();
ui->inputTab->ApplyConfiguration();
ui->inputTab->ApplyProfile();
ui->hotkeysTab->ApplyConfiguration(registry);
ui->graphicsTab->ApplyConfiguration();
ui->enhancementsTab->ApplyConfiguration();
ui->audioTab->ApplyConfiguration();
ui->cameraTab->ApplyConfiguration();
ui->debugTab->ApplyConfiguration();
ui->webTab->ApplyConfiguration();
ui->uiTab->ApplyConfiguration();
ui->storageTab->ApplyConfiguration();
system.ApplySettings();
Settings::LogSettings();
}
@ -117,11 +81,11 @@ void ConfigureDialog::PopulateSelectionList() {
ui->selectorList->clear();
const std::array<std::pair<QString, QList<QWidget*>>, 5> items{
{{tr("General"), {general_tab.get(), web_tab.get(), debug_tab.get(), ui_tab.get()}},
{tr("System"), {system_tab.get(), camera_tab.get(), storage_tab.get()}},
{tr("Graphics"), {enhancements_tab.get(), graphics_tab.get()}},
{tr("Audio"), {audio_tab.get()}},
{tr("Controls"), {input_tab.get(), hotkeys_tab.get()}}}};
{{tr("General"), {ui->generalTab, ui->webTab, ui->debugTab, ui->uiTab}},
{tr("System"), {ui->systemTab, ui->cameraTab, ui->storageTab}},
{tr("Graphics"), {ui->enhancementsTab, ui->graphicsTab}},
{tr("Audio"), {ui->audioTab}},
{tr("Controls"), {ui->inputTab, ui->hotkeysTab}}}};
for (const auto& entry : items) {
auto* const item = new QListWidgetItem(entry.first);
@ -148,18 +112,18 @@ void ConfigureDialog::RetranslateUI() {
ui->selectorList->setCurrentRow(old_row);
ui->tabWidget->setCurrentIndex(old_index);
general_tab->RetranslateUI();
system_tab->RetranslateUI();
input_tab->RetranslateUI();
hotkeys_tab->RetranslateUI();
graphics_tab->RetranslateUI();
enhancements_tab->RetranslateUI();
audio_tab->RetranslateUI();
camera_tab->RetranslateUI();
debug_tab->RetranslateUI();
web_tab->RetranslateUI();
ui_tab->RetranslateUI();
storage_tab->RetranslateUI();
ui->generalTab->RetranslateUI();
ui->systemTab->RetranslateUI();
ui->inputTab->RetranslateUI();
ui->hotkeysTab->RetranslateUI();
ui->graphicsTab->RetranslateUI();
ui->enhancementsTab->RetranslateUI();
ui->audioTab->RetranslateUI();
ui->cameraTab->RetranslateUI();
ui->debugTab->RetranslateUI();
ui->webTab->RetranslateUI();
ui->uiTab->RetranslateUI();
ui->storageTab->RetranslateUI();
}
void ConfigureDialog::UpdateVisibleTabs() {
@ -167,18 +131,18 @@ void ConfigureDialog::UpdateVisibleTabs() {
if (items.isEmpty())
return;
const std::map<QWidget*, QString> widgets = {{general_tab.get(), tr("General")},
{system_tab.get(), tr("System")},
{input_tab.get(), tr("Input")},
{hotkeys_tab.get(), tr("Hotkeys")},
{enhancements_tab.get(), tr("Enhancements")},
{graphics_tab.get(), tr("Advanced")},
{audio_tab.get(), tr("Audio")},
{camera_tab.get(), tr("Camera")},
{debug_tab.get(), tr("Debug")},
{storage_tab.get(), tr("Storage")},
{web_tab.get(), tr("Web")},
{ui_tab.get(), tr("UI")}};
const std::map<QWidget*, QString> widgets = {{ui->generalTab, tr("General")},
{ui->systemTab, tr("System")},
{ui->inputTab, tr("Input")},
{ui->hotkeysTab, tr("Hotkeys")},
{ui->enhancementsTab, tr("Enhancements")},
{ui->graphicsTab, tr("Advanced")},
{ui->audioTab, tr("Audio")},
{ui->cameraTab, tr("Camera")},
{ui->debugTab, tr("Debug")},
{ui->storageTab, tr("Storage")},
{ui->webTab, tr("Web")},
{ui->uiTab, tr("UI")}};
ui->tabWidget->clear();

View File

@ -17,19 +17,6 @@ namespace Core {
class System;
}
class ConfigureGeneral;
class ConfigureSystem;
class ConfigureInput;
class ConfigureHotkeys;
class ConfigureGraphics;
class ConfigureEnhancements;
class ConfigureAudio;
class ConfigureCamera;
class ConfigureDebug;
class ConfigureStorage;
class ConfigureWeb;
class ConfigureUi;
class ConfigureDialog : public QDialog {
Q_OBJECT
@ -55,18 +42,4 @@ private:
std::unique_ptr<Ui::ConfigureDialog> ui;
HotkeyRegistry& registry;
Core::System& system;
bool is_powered_on;
std::unique_ptr<ConfigureGeneral> general_tab;
std::unique_ptr<ConfigureSystem> system_tab;
std::unique_ptr<ConfigureInput> input_tab;
std::unique_ptr<ConfigureHotkeys> hotkeys_tab;
std::unique_ptr<ConfigureGraphics> graphics_tab;
std::unique_ptr<ConfigureEnhancements> enhancements_tab;
std::unique_ptr<ConfigureAudio> audio_tab;
std::unique_ptr<ConfigureCamera> camera_tab;
std::unique_ptr<ConfigureDebug> debug_tab;
std::unique_ptr<ConfigureStorage> storage_tab;
std::unique_ptr<ConfigureWeb> web_tab;
std::unique_ptr<ConfigureUi> ui_tab;
};

View File

@ -22,7 +22,8 @@ ConfigureEnhancements::ConfigureEnhancements(QWidget* parent)
const bool res_scale_enabled = graphics_api != Settings::GraphicsAPI::Software;
ui->resolution_factor_combobox->setEnabled(res_scale_enabled);
connect(ui->render_3d_combobox, qOverload<int>(&QComboBox::currentIndexChanged), this,
connect(ui->render_3d_combobox,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
[this](int currentIndex) {
updateShaders(static_cast<Settings::StereoRenderOption>(currentIndex));
});

View File

@ -6,14 +6,14 @@
#include "citra_qt/configuration/configuration_shared.h"
#include "citra_qt/configuration/configure_graphics.h"
#include "common/settings.h"
#include "core/core.h"
#include "ui_configure_graphics.h"
ConfigureGraphics::ConfigureGraphics(bool is_powered_on, QWidget* parent)
ConfigureGraphics::ConfigureGraphics(QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureGraphics>()) {
ui->setupUi(this);
ui->toggle_vsync_new->setEnabled(!is_powered_on);
ui->graphics_api_combo->setEnabled(!is_powered_on);
ui->toggle_vsync_new->setEnabled(!Core::System::GetInstance().IsPoweredOn());
// Set the index to -1 to ensure the below lambda is called with setCurrentIndex
ui->graphics_api_combo->setCurrentIndex(-1);
@ -29,10 +29,9 @@ ConfigureGraphics::ConfigureGraphics(bool is_powered_on, QWidget* parent)
});
connect(ui->toggle_hw_shader, &QCheckBox::toggled, this, [this] {
const bool enabled = ui->toggle_hw_shader->isEnabled();
const bool checked = ui->toggle_hw_shader->isChecked();
ui->hw_shader_group->setEnabled(checked && enabled);
ui->toggle_disk_shader_cache->setEnabled(checked && enabled);
ui->hw_shader_group->setEnabled(checked);
ui->toggle_disk_shader_cache->setEnabled(checked);
});
SetupPerGameUI();

View File

@ -19,7 +19,7 @@ class ConfigureGraphics : public QWidget {
Q_OBJECT
public:
explicit ConfigureGraphics(bool is_powered_on, QWidget* parent = nullptr);
explicit ConfigureGraphics(QWidget* parent = nullptr);
~ConfigureGraphics() override;
void ApplyConfiguration();

View File

@ -19,9 +19,6 @@
<property name="windowTitle">
<string>Form</string>
</property>
<property name="accessibleName">
<string>Graphics</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="apiBox">

View File

@ -9,6 +9,7 @@
#include "citra_qt/configuration/configure_hotkeys.h"
#include "citra_qt/hotkeys.h"
#include "citra_qt/util/sequence_dialog/sequence_dialog.h"
#include "common/settings.h"
#include "ui_configure_hotkeys.h"
constexpr int name_column = 0;
@ -188,9 +189,9 @@ void ConfigureHotkeys::PopupContextMenu(const QPoint& menu_location) {
QAction* clear = context_menu.addAction(tr("Clear"));
const auto hotkey_index = index.sibling(index.row(), hotkey_column);
connect(restore_default, &QAction::triggered, this,
connect(restore_default, &QAction::triggered,
[this, hotkey_index] { RestoreHotkey(hotkey_index); });
connect(clear, &QAction::triggered, this,
connect(clear, &QAction::triggered,
[this, hotkey_index] { model->setData(hotkey_index, QString{}); });
context_menu.exec(ui->hotkey_list->viewport()->mapToGlobal(menu_location));

View File

@ -162,7 +162,7 @@ ConfigureInput::ConfigureInput(QWidget* parent)
ui->buttonDpadUp, ui->buttonDpadDown, ui->buttonDpadLeft, ui->buttonDpadRight,
ui->buttonL, ui->buttonR, ui->buttonStart, ui->buttonSelect,
ui->buttonDebug, ui->buttonGpio14, ui->buttonZL, ui->buttonZR,
ui->buttonHome, ui->buttonPower,
ui->buttonHome,
};
analog_map_buttons = {{

View File

@ -305,24 +305,6 @@
</layout>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout_34">
<item>
<widget class="QLabel" name="label_37">
<property name="text">
<string>Power:</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonPower">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QVBoxLayout" name="verticalLayout_28">
<item>
<widget class="QLabel" name="label_36">
@ -358,7 +340,7 @@
</item>
</layout>
</item>
<item row="3" column="0">
<item row="2" column="0">
<layout class="QVBoxLayout" name="verticalLayout_32">
<item>
<widget class="QLabel" name="label_40">

View File

@ -27,18 +27,16 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString
Core::System& system_)
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()),
filename{file_name.toStdString()}, title_id{title_id_}, system{system_} {
const auto config_file_name = title_id == 0 ? std::string(FileUtil::GetFilename(filename))
: fmt::format("{:016X}", title_id);
const auto config_file_name = title_id == 0 ? filename : fmt::format("{:016X}", title_id);
game_config = std::make_unique<Config>(config_file_name, Config::ConfigType::PerGameConfig);
const bool is_powered_on = system.IsPoweredOn();
audio_tab = std::make_unique<ConfigureAudio>(is_powered_on, this);
audio_tab = std::make_unique<ConfigureAudio>(this);
general_tab = std::make_unique<ConfigureGeneral>(this);
enhancements_tab = std::make_unique<ConfigureEnhancements>(this);
graphics_tab = std::make_unique<ConfigureGraphics>(is_powered_on, this);
system_tab = std::make_unique<ConfigureSystem>(system, this);
debug_tab = std::make_unique<ConfigureDebug>(is_powered_on, this);
cheat_tab = std::make_unique<ConfigureCheats>(system, title_id, this);
graphics_tab = std::make_unique<ConfigureGraphics>(this);
system_tab = std::make_unique<ConfigureSystem>(this);
debug_tab = std::make_unique<ConfigureDebug>(this);
cheat_tab = std::make_unique<ConfigureCheats>(title_id, this);
ui->setupUi(this);

View File

@ -6,12 +6,12 @@
#include <QFileDialog>
#include <QUrl>
#include "citra_qt/configuration/configure_storage.h"
#include "common/file_util.h"
#include "common/settings.h"
#include "core/core.h"
#include "ui_configure_storage.h"
ConfigureStorage::ConfigureStorage(bool is_powered_on_, QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureStorage>()), is_powered_on{is_powered_on_} {
ConfigureStorage::ConfigureStorage(QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureStorage>()) {
ui->setupUi(this);
SetConfiguration();
@ -74,7 +74,7 @@ void ConfigureStorage::SetConfiguration() {
ui->toggle_virtual_sd->setChecked(Settings::values.use_virtual_sd.GetValue());
ui->toggle_custom_storage->setChecked(Settings::values.use_custom_storage.GetValue());
ui->storage_group->setEnabled(!is_powered_on);
ui->storage_group->setEnabled(!Core::System::GetInstance().IsPoweredOn());
}
void ConfigureStorage::ApplyConfiguration() {

View File

@ -15,7 +15,7 @@ class ConfigureStorage : public QWidget {
Q_OBJECT
public:
explicit ConfigureStorage(bool is_powered_on, QWidget* parent = nullptr);
explicit ConfigureStorage(QWidget* parent = nullptr);
~ConfigureStorage() override;
void ApplyConfiguration();
@ -23,5 +23,4 @@ public:
void SetConfiguration();
std::unique_ptr<Ui::ConfigureStorage> ui;
bool is_powered_on;
};

View File

@ -223,12 +223,14 @@ static const std::array<const char*, 187> country_names = {
QT_TRANSLATE_NOOP("ConfigureSystem", "Bermuda"), // 180-186
};
ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureSystem>()), system{system_} {
ConfigureSystem::ConfigureSystem(QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureSystem>()) {
ui->setupUi(this);
connect(ui->combo_birthmonth, qOverload<int>(&QComboBox::currentIndexChanged), this,
connect(ui->combo_birthmonth,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
&ConfigureSystem::UpdateBirthdayComboBox);
connect(ui->combo_init_clock, qOverload<int>(&QComboBox::currentIndexChanged), this,
connect(ui->combo_init_clock,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
&ConfigureSystem::UpdateInitTime);
connect(ui->button_regenerate_console_id, &QPushButton::clicked, this,
&ConfigureSystem::RefreshConsoleID);
@ -278,7 +280,7 @@ ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
ConfigureSystem::~ConfigureSystem() = default;
void ConfigureSystem::SetConfiguration() {
enabled = !system.IsPoweredOn();
enabled = !Core::System::GetInstance().IsPoweredOn();
ui->combo_init_clock->setCurrentIndex(static_cast<u8>(Settings::values.init_clock.GetValue()));
QDateTime date_time;
@ -294,7 +296,7 @@ void ConfigureSystem::SetConfiguration() {
ui->edit_init_time_offset_time->setTime(time);
if (!enabled) {
cfg = Service::CFG::GetModule(system);
cfg = Service::CFG::GetModule(Core::System::GetInstance());
ASSERT_MSG(cfg, "CFG Module missing!");
ReadSystemSettings();
ui->group_system_settings->setEnabled(false);

View File

@ -16,10 +16,6 @@ namespace ConfigurationShared {
enum class CheckState;
}
namespace Core {
class System;
}
namespace Service {
namespace CFG {
class Module;
@ -30,7 +26,7 @@ class ConfigureSystem : public QWidget {
Q_OBJECT
public:
explicit ConfigureSystem(Core::System& system, QWidget* parent = nullptr);
explicit ConfigureSystem(QWidget* parent = nullptr);
~ConfigureSystem() override;
void ApplyConfiguration();
@ -49,10 +45,8 @@ private:
void DownloadFromNUS();
private:
std::unique_ptr<Ui::ConfigureSystem> ui;
Core::System& system;
ConfigurationShared::CheckState is_new_3ds;
std::unique_ptr<Ui::ConfigureSystem> ui;
bool enabled = false;
std::shared_ptr<Service::CFG::Module> cfg;

View File

@ -16,6 +16,7 @@
#include "citra_qt/debugger/graphics/graphics_cmdlists.h"
#include "citra_qt/util/util.h"
#include "common/vector_math.h"
#include "core/core.h"
#include "core/memory.h"
#include "video_core/debug_utils/debug_utils.h"
#include "video_core/pica_state.h"
@ -166,7 +167,8 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) {
const auto format = texture.format;
const auto info = Pica::Texture::TextureInfo::FromPicaRegister(config, format);
const u8* src = memory.GetPhysicalPointer(config.GetPhysicalAddress());
const u8* src =
Core::System::GetInstance().Memory().GetPhysicalPointer(config.GetPhysicalAddress());
new_info_widget = new TextureInfoWidget(src, info);
}
if (command_info_widget) {
@ -180,8 +182,8 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) {
}
#undef COMMAND_IN_RANGE
GPUCommandListWidget::GPUCommandListWidget(Memory::MemorySystem& memory_, QWidget* parent)
: QDockWidget(tr("Pica Command List"), parent), memory{memory_} {
GPUCommandListWidget::GPUCommandListWidget(QWidget* parent)
: QDockWidget(tr("Pica Command List"), parent) {
setObjectName(QStringLiteral("Pica Command List"));
GPUCommandListModel* model = new GPUCommandListModel(this);

View File

@ -7,14 +7,11 @@
#include <QAbstractListModel>
#include <QDockWidget>
#include "video_core/debug_utils/debug_utils.h"
#include "video_core/gpu_debugger.h"
class QPushButton;
class QTreeView;
namespace Memory {
class MemorySystem;
}
class GPUCommandListModel : public QAbstractListModel {
Q_OBJECT
@ -42,7 +39,7 @@ class GPUCommandListWidget : public QDockWidget {
Q_OBJECT
public:
explicit GPUCommandListWidget(Memory::MemorySystem& memory, QWidget* parent = nullptr);
explicit GPUCommandListWidget(QWidget* parent = nullptr);
public slots:
void OnToggleTracing();
@ -57,7 +54,7 @@ signals:
private:
std::unique_ptr<Pica::DebugUtils::PicaTrace> pica_trace;
Memory::MemorySystem& memory;
QTreeView* list_widget;
QWidget* command_info_widget;
QPushButton* toggle_tracing;

View File

@ -15,6 +15,8 @@
#include "citra_qt/debugger/graphics/graphics_surface.h"
#include "citra_qt/util/spinbox.h"
#include "common/color.h"
#include "core/core.h"
#include "core/hw/gpu.h"
#include "core/memory.h"
#include "video_core/pica_state.h"
#include "video_core/regs_framebuffer.h"
@ -49,10 +51,9 @@ void SurfacePicture::mouseMoveEvent(QMouseEvent* event) {
mousePressEvent(event);
}
GraphicsSurfaceWidget::GraphicsSurfaceWidget(Memory::MemorySystem& memory_,
std::shared_ptr<Pica::DebugContext> debug_context,
GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context,
QWidget* parent)
: BreakPointObserverDock(debug_context, tr("Pica Surface Viewer"), parent), memory{memory_},
: BreakPointObserverDock(debug_context, tr("Pica Surface Viewer"), parent),
surface_source(Source::ColorBuffer) {
setObjectName(QStringLiteral("PicaSurface"));
@ -289,57 +290,57 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
return;
}
const u8* buffer = memory.GetPhysicalPointer(surface_address);
if (!buffer) {
u8* buffer = Core::System::GetInstance().Memory().GetPhysicalPointer(surface_address);
if (buffer == nullptr) {
surface_info_label->setText(tr("(unable to access pixel data)"));
surface_info_label->setAlignment(Qt::AlignCenter);
return;
}
const u32 nibbles_per_pixel = GraphicsSurfaceWidget::NibblesPerPixel(surface_format);
const u32 stride = nibbles_per_pixel * surface_width / 2;
const bool nibble_mode = (nibbles_per_pixel == 1);
const u32 bytes_per_pixel = [&] {
if (nibble_mode) {
// As nibbles are contained in a byte we still need to access one byte per nibble
return 1u;
} else {
return nibbles_per_pixel / 2;
}
}();
unsigned nibbles_per_pixel = GraphicsSurfaceWidget::NibblesPerPixel(surface_format);
unsigned stride = nibbles_per_pixel * surface_width / 2;
unsigned bytes_per_pixel;
bool nibble_mode = (nibbles_per_pixel == 1);
if (nibble_mode) {
// As nibbles are contained in a byte we still need to access one byte per nibble
bytes_per_pixel = 1;
} else {
bytes_per_pixel = nibbles_per_pixel / 2;
}
const u32 coarse_y = y & ~7;
const u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride;
const u8* pixel = buffer + (nibble_mode ? (offset / 2) : offset);
const auto get_text = [offset](Format format, const u8* pixel) {
auto GetText = [offset](Format format, const u8* pixel) {
switch (format) {
case Format::RGBA8: {
const auto value = Common::Color::DecodeRGBA8(pixel) / 255.0f;
auto value = Common::Color::DecodeRGBA8(pixel) / 255.0f;
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
}
case Format::RGB8: {
const auto value = Common::Color::DecodeRGB8(pixel) / 255.0f;
auto value = Common::Color::DecodeRGB8(pixel) / 255.0f;
return QStringLiteral("Red: %1, Green: %2, Blue: %3")
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
QString::number(value.b(), 'f', 2));
}
case Format::RGB5A1: {
const auto value = Common::Color::DecodeRGB5A1(pixel) / 255.0f;
auto value = Common::Color::DecodeRGB5A1(pixel) / 255.0f;
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
}
case Format::RGB565: {
const auto value = Common::Color::DecodeRGB565(pixel) / 255.0f;
auto value = Common::Color::DecodeRGB565(pixel) / 255.0f;
return QStringLiteral("Red: %1, Green: %2, Blue: %3")
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
QString::number(value.b(), 'f', 2));
}
case Format::RGBA4: {
const auto value = Common::Color::DecodeRGBA4(pixel) / 255.0f;
auto value = Common::Color::DecodeRGBA4(pixel) / 255.0f;
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
@ -347,7 +348,7 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
case Format::IA8:
return QStringLiteral("Index: %1, Alpha: %2").arg(pixel[0], pixel[1]);
case Format::RG8: {
const auto value = Common::Color::DecodeRG8(pixel) / 255.0f;
auto value = Common::Color::DecodeRG8(pixel) / 255.0f;
return QStringLiteral("Red: %1, Green: %2")
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2));
}
@ -358,11 +359,11 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
case Format::IA4:
return QStringLiteral("Index: %1, Alpha: %2").arg(*pixel & 0xF, (*pixel & 0xF0) >> 4);
case Format::I4: {
const u8 i = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF;
u8 i = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF;
return QStringLiteral("Index: %1").arg(i);
}
case Format::A4: {
const u8 a = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF;
u8 a = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF;
return QStringLiteral("Alpha: %1").arg(QString::number(a / 15.0f, 'f', 2));
}
case Format::ETC1:
@ -370,17 +371,17 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
// TODO: Display block information or channel values?
return QStringLiteral("Compressed data");
case Format::D16: {
const auto value = Common::Color::DecodeD16(pixel);
auto value = Common::Color::DecodeD16(pixel);
return QStringLiteral("Depth: %1").arg(QString::number(value / (float)0xFFFF, 'f', 4));
}
case Format::D24: {
const auto value = Common::Color::DecodeD24(pixel);
auto value = Common::Color::DecodeD24(pixel);
return QStringLiteral("Depth: %1")
.arg(QString::number(value / (float)0xFFFFFF, 'f', 4));
}
case Format::D24X8:
case Format::X24S8: {
const auto values = Common::Color::DecodeD24S8(pixel);
auto values = Common::Color::DecodeD24S8(pixel);
return QStringLiteral("Depth: %1, Stencil: %2")
.arg(QString::number(values[0] / (float)0xFFFFFF, 'f', 4), values[1]);
}
@ -397,13 +398,13 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
if (nibble_mode) {
nibble_index += (offset % 2) ? 0 : 1;
}
const u8 byte = pixel[nibble_index / 2];
const u8 nibble = (byte >> ((nibble_index % 2) ? 0 : 4)) & 0xF;
u8 byte = pixel[nibble_index / 2];
u8 nibble = (byte >> ((nibble_index % 2) ? 0 : 4)) & 0xF;
nibbles.append(QString::number(nibble, 16).toUpper());
}
surface_info_label->setText(
QStringLiteral("Raw: 0x%3\n(%4)").arg(nibbles, get_text(surface_format, pixel)));
QStringLiteral("Raw: 0x%3\n(%4)").arg(nibbles, GetText(surface_format, pixel)));
surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
}
@ -545,9 +546,9 @@ void GraphicsSurfaceWidget::OnUpdate() {
// TODO: Implement a good way to visualize alpha components!
QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32);
const u8* buffer = memory.GetPhysicalPointer(surface_address);
u8* buffer = Core::System::GetInstance().Memory().GetPhysicalPointer(surface_address);
if (!buffer) {
if (buffer == nullptr) {
surface_picture_label->hide();
surface_info_label->setText(tr("(invalid surface address)"));
surface_info_label->setAlignment(Qt::AlignCenter);
@ -681,8 +682,9 @@ void GraphicsSurfaceWidget::SaveSurface() {
tr("Failed to save surface data to file '%1'").arg(filename));
}
} else if (selected_filter == bin_filter) {
const u8* const buffer = memory.GetPhysicalPointer(surface_address);
ASSERT_MSG(buffer, "Memory not accessible");
const u8* const buffer =
Core::System::GetInstance().Memory().GetPhysicalPointer(surface_address);
ASSERT_MSG(buffer != nullptr, "Memory not accessible");
QFile file{filename};
if (!file.open(QIODevice::WriteOnly)) {

View File

@ -14,10 +14,6 @@ class CSpinBox;
class GraphicsSurfaceWidget;
namespace Memory {
class MemorySystem;
}
class SurfacePicture : public QLabel {
Q_OBJECT
@ -76,8 +72,7 @@ class GraphicsSurfaceWidget : public BreakPointObserverDock {
static unsigned int NibblesPerPixel(Format format);
public:
explicit GraphicsSurfaceWidget(Memory::MemorySystem& memory,
std::shared_ptr<Pica::DebugContext> debug_context,
explicit GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context,
QWidget* parent = nullptr);
void Pick(int x, int y);
@ -100,7 +95,6 @@ private:
void SaveSurface();
Memory::MemorySystem& memory;
QComboBox* surface_source_list;
CSpinBox* surface_address_control;
QSpinBox* surface_width_control;

View File

@ -16,13 +16,13 @@
#include "core/hle/service/sm/sm.h"
#include "ui_recorder.h"
IPCRecorderWidget::IPCRecorderWidget(Core::System& system_, QWidget* parent)
: QDockWidget(parent), ui(std::make_unique<Ui::IPCRecorder>()), system{system_} {
IPCRecorderWidget::IPCRecorderWidget(QWidget* parent)
: QDockWidget(parent), ui(std::make_unique<Ui::IPCRecorder>()) {
ui->setupUi(this);
qRegisterMetaType<IPCDebugger::RequestRecord>();
connect(ui->enabled, &QCheckBox::stateChanged, this,
connect(ui->enabled, &QCheckBox::stateChanged,
[this](int new_state) { SetEnabled(new_state == Qt::Checked); });
connect(ui->clearButton, &QPushButton::clicked, this, &IPCRecorderWidget::Clear);
connect(ui->filter, &QLineEdit::textChanged, this, &IPCRecorderWidget::ApplyFilterToAll);
@ -90,7 +90,7 @@ void IPCRecorderWidget::OnEntryUpdated(IPCDebugger::RequestRecord record) {
(record.status == IPCDebugger::RequestStatus::Handled &&
record.translated_reply_cmdbuf[1] != RESULT_SUCCESS.raw)) { // Unimplemented / Error
auto item = ui->main->invisibleRootItem()->child(row_id);
auto* item = ui->main->invisibleRootItem()->child(row_id);
for (int column = 0; column < item->columnCount(); ++column) {
item->setBackground(column, QBrush(QColor::fromRgb(255, 0, 0)));
}
@ -100,11 +100,11 @@ void IPCRecorderWidget::OnEntryUpdated(IPCDebugger::RequestRecord record) {
}
void IPCRecorderWidget::SetEnabled(bool enabled) {
if (!system.IsPoweredOn()) {
if (!Core::System::GetInstance().IsPoweredOn()) {
return;
}
auto& ipc_recorder = system.Kernel().GetIPCRecorder();
auto& ipc_recorder = Core::System::GetInstance().Kernel().GetIPCRecorder();
ipc_recorder.SetEnabled(enabled);
if (enabled) {
@ -123,10 +123,10 @@ void IPCRecorderWidget::Clear() {
}
QString IPCRecorderWidget::GetServiceName(const IPCDebugger::RequestRecord& record) const {
if (system.IsPoweredOn() && record.client_port.id != -1) {
const Service::SM::ServiceManager& sm = system.ServiceManager();
const u32 port_id = static_cast<u32>(record.client_port.id);
const auto service_name = sm.GetServiceNameByPortId(port_id);
if (Core::System::GetInstance().IsPoweredOn() && record.client_port.id != -1) {
const auto service_name =
Core::System::GetInstance().ServiceManager().GetServiceNameByPortId(
static_cast<u32>(record.client_port.id));
if (!service_name.empty()) {
return QString::fromStdString(service_name);

View File

@ -14,15 +14,11 @@ namespace Ui {
class IPCRecorder;
}
namespace Core {
class System;
}
class IPCRecorderWidget : public QDockWidget {
Q_OBJECT
public:
explicit IPCRecorderWidget(Core::System& system, QWidget* parent = nullptr);
explicit IPCRecorderWidget(QWidget* parent = nullptr);
~IPCRecorderWidget();
void OnEmulationStarting();
@ -41,10 +37,9 @@ private:
QString GetFunctionName(const IPCDebugger::RequestRecord& record) const;
void OpenRecordDialog(QTreeWidgetItem* item, int column);
private:
std::unique_ptr<Ui::IPCRecorder> ui;
IPCDebugger::CallbackHandle handle;
Core::System& system;
// The offset between record id and row id, assuming record ids are assigned
// continuously and only the 'Clear' action can be performed, this is enough.
// The initial value is 1, which means record 1 = row 0.

View File

@ -9,8 +9,8 @@
#include "core/core.h"
#include "ui_registers.h"
RegistersWidget::RegistersWidget(const Core::System& system_, QWidget* parent)
: QDockWidget(parent), cpu_regs_ui(std::make_unique<Ui::ARMRegisters>()), system{system_} {
RegistersWidget::RegistersWidget(QWidget* parent)
: QDockWidget(parent), cpu_regs_ui(std::make_unique<Ui::ARMRegisters>()) {
cpu_regs_ui->setupUi(this);
tree = cpu_regs_ui->treeWidget;
@ -62,21 +62,17 @@ RegistersWidget::RegistersWidget(const Core::System& system_, QWidget* parent)
RegistersWidget::~RegistersWidget() = default;
void RegistersWidget::OnDebugModeEntered() {
if (!system.IsPoweredOn()) {
if (!Core::System::GetInstance().IsPoweredOn())
return;
}
// TODO: Handle all cores
const ARM_Interface& core = system.GetCore(0);
for (int i = 0; i < core_registers->childCount(); ++i) {
// Todo: Handle all cores
for (int i = 0; i < core_registers->childCount(); ++i)
core_registers->child(i)->setText(
1, QStringLiteral("0x%1").arg(core.GetReg(i), 8, 16, QLatin1Char('0')));
}
1, QStringLiteral("0x%1").arg(Core::GetCore(0).GetReg(i), 8, 16, QLatin1Char('0')));
for (int i = 0; i < vfp_registers->childCount(); ++i) {
for (int i = 0; i < vfp_registers->childCount(); ++i)
vfp_registers->child(i)->setText(
1, QStringLiteral("0x%1").arg(core.GetVFPReg(i), 8, 16, QLatin1Char('0')));
}
1, QStringLiteral("0x%1").arg(Core::GetCore(0).GetVFPReg(i), 8, 16, QLatin1Char('0')));
UpdateCPSRValues();
UpdateVFPSystemRegisterValues();
@ -90,29 +86,24 @@ void RegistersWidget::OnEmulationStarting(EmuThread* emu_thread) {
void RegistersWidget::OnEmulationStopping() {
// Reset widget text
for (int i = 0; i < core_registers->childCount(); ++i) {
for (int i = 0; i < core_registers->childCount(); ++i)
core_registers->child(i)->setText(1, QString{});
}
for (int i = 0; i < vfp_registers->childCount(); ++i) {
for (int i = 0; i < vfp_registers->childCount(); ++i)
vfp_registers->child(i)->setText(1, QString{});
}
for (int i = 0; i < cpsr->childCount(); ++i) {
for (int i = 0; i < cpsr->childCount(); ++i)
cpsr->child(i)->setText(1, QString{});
}
cpsr->setText(1, QString{});
// FPSCR
for (int i = 0; i < vfp_system_registers->child(0)->childCount(); ++i) {
for (int i = 0; i < vfp_system_registers->child(0)->childCount(); ++i)
vfp_system_registers->child(0)->child(i)->setText(1, QString{});
}
// FPEXC
for (int i = 0; i < vfp_system_registers->child(1)->childCount(); ++i) {
for (int i = 0; i < vfp_system_registers->child(1)->childCount(); ++i)
vfp_system_registers->child(1)->child(i)->setText(1, QString{});
}
vfp_system_registers->child(0)->setText(1, QString{});
vfp_system_registers->child(1)->setText(1, QString{});
@ -139,8 +130,8 @@ void RegistersWidget::CreateCPSRChildren() {
}
void RegistersWidget::UpdateCPSRValues() {
// TODO: Handle all cores
const u32 cpsr_val = system.GetCore(0).GetCPSR();
// Todo: Handle all cores
const u32 cpsr_val = Core::GetCore(0).GetCPSR();
cpsr->setText(1, QStringLiteral("0x%1").arg(cpsr_val, 8, 16, QLatin1Char('0')));
cpsr->child(0)->setText(
@ -202,10 +193,9 @@ void RegistersWidget::CreateVFPSystemRegisterChildren() {
}
void RegistersWidget::UpdateVFPSystemRegisterValues() {
// TODO: handle all cores
const ARM_Interface& core = system.GetCore(0);
const u32 fpscr_val = core.GetVFPSystemReg(VFP_FPSCR);
const u32 fpexc_val = core.GetVFPSystemReg(VFP_FPEXC);
// Todo: handle all cores
const u32 fpscr_val = Core::GetCore(0).GetVFPSystemReg(VFP_FPSCR);
const u32 fpexc_val = Core::GetCore(0).GetVFPSystemReg(VFP_FPEXC);
QTreeWidgetItem* const fpscr = vfp_system_registers->child(0);
fpscr->setText(1, QStringLiteral("0x%1").arg(fpscr_val, 8, 16, QLatin1Char('0')));

View File

@ -15,15 +15,11 @@ namespace Ui {
class ARMRegisters;
}
namespace Core {
class System;
}
class RegistersWidget : public QDockWidget {
Q_OBJECT
public:
explicit RegistersWidget(const Core::System& system, QWidget* parent = nullptr);
explicit RegistersWidget(QWidget* parent = nullptr);
~RegistersWidget();
public slots:
@ -41,7 +37,7 @@ private:
void UpdateVFPSystemRegisterValues();
std::unique_ptr<Ui::ARMRegisters> cpu_regs_ui;
const Core::System& system;
QTreeWidget* tree;
QTreeWidgetItem* core_registers;

View File

@ -5,10 +5,11 @@
#include <array>
#include "citra_qt/debugger/wait_tree.h"
#include "citra_qt/uisettings.h"
#include "citra_qt/util/util.h"
#include "common/assert.h"
#include "common/settings.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/mutex.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/semaphore.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
@ -75,13 +76,13 @@ std::size_t WaitTreeItem::Row() const {
return row;
}
std::vector<std::unique_ptr<WaitTreeThread>> WaitTreeItem::MakeThreadItemList(
Core::System& system) {
const u32 num_cores = system.GetNumCores();
std::vector<std::unique_ptr<WaitTreeThread>> WaitTreeItem::MakeThreadItemList() {
const u32 num_cores = Core::GetNumCores();
std::vector<std::unique_ptr<WaitTreeThread>> item_list;
item_list.reserve(num_cores);
for (u32 i = 0; i < num_cores; ++i) {
const auto threads = system.Kernel().GetThreadManager(i).GetThreadList();
const auto& threads =
Core::System::GetInstance().Kernel().GetThreadManager(i).GetThreadList();
item_list.reserve(item_list.size() + threads.size());
for (std::size_t j = 0; j < threads.size(); ++j) {
item_list.push_back(std::make_unique<WaitTreeThread>(*threads[j]));
@ -435,12 +436,11 @@ void WaitTreeModel::ClearItems() {
thread_items.clear();
}
void WaitTreeModel::InitItems(Core::System& system) {
thread_items = WaitTreeItem::MakeThreadItemList(system);
void WaitTreeModel::InitItems() {
thread_items = WaitTreeItem::MakeThreadItemList();
}
WaitTreeWidget::WaitTreeWidget(Core::System& system_, QWidget* parent)
: QDockWidget(tr("Wait Tree"), parent), system{system_} {
WaitTreeWidget::WaitTreeWidget(QWidget* parent) : QDockWidget(tr("Wait Tree"), parent) {
setObjectName(QStringLiteral("WaitTreeWidget"));
view = new QTreeView(this);
view->setHeaderHidden(true);
@ -449,10 +449,9 @@ WaitTreeWidget::WaitTreeWidget(Core::System& system_, QWidget* parent)
}
void WaitTreeWidget::OnDebugModeEntered() {
if (!system.IsPoweredOn()) {
if (!Core::System::GetInstance().IsPoweredOn())
return;
}
model->InitItems(system);
model->InitItems();
view->setModel(model);
setEnabled(true);
}

View File

@ -23,10 +23,6 @@ class Thread;
class Timer;
} // namespace Kernel
namespace Core {
class System;
}
class WaitTreeThread;
class WaitTreeItem : public QObject {
@ -43,7 +39,7 @@ public:
WaitTreeItem* Parent() const;
std::span<const std::unique_ptr<WaitTreeItem>> Children() const;
std::size_t Row() const;
static std::vector<std::unique_ptr<WaitTreeThread>> MakeThreadItemList(Core::System& system);
static std::vector<std::unique_ptr<WaitTreeThread>> MakeThreadItemList();
private:
std::size_t row;
@ -170,7 +166,7 @@ public:
int columnCount(const QModelIndex& parent) const override;
void ClearItems();
void InitItems(Core::System& system);
void InitItems();
private:
std::vector<std::unique_ptr<WaitTreeThread>> thread_items;
@ -180,7 +176,7 @@ class WaitTreeWidget : public QDockWidget {
Q_OBJECT
public:
explicit WaitTreeWidget(Core::System& system, QWidget* parent = nullptr);
explicit WaitTreeWidget(QWidget* parent = nullptr);
public slots:
void OnDebugModeEntered();
@ -192,5 +188,4 @@ public slots:
private:
QTreeView* view;
WaitTreeModel* model;
Core::System& system;
};

View File

@ -9,11 +9,10 @@
#include "citra_qt/uisettings.h"
#include "common/common_types.h"
#include "core/core.h"
#include "core/loader/loader.h"
namespace DiscordRPC {
DiscordImpl::DiscordImpl(const Core::System& system_) : system{system_} {
DiscordImpl::DiscordImpl() {
DiscordEventHandlers handlers{};
// The number is the client ID for Citra, it's used for images and the
@ -35,15 +34,12 @@ void DiscordImpl::Update() {
std::chrono::system_clock::now().time_since_epoch())
.count();
std::string title;
const bool is_powered_on = system.IsPoweredOn();
if (is_powered_on) {
system.GetAppLoader().ReadTitle(title);
}
if (Core::System::GetInstance().IsPoweredOn())
Core::System::GetInstance().GetAppLoader().ReadTitle(title);
DiscordRichPresence presence{};
presence.largeImageKey = "citra";
presence.largeImageText = "Citra is an emulator for the Nintendo 3DS";
if (is_powered_on) {
if (Core::System::GetInstance().IsPoweredOn()) {
presence.state = title.c_str();
presence.details = "Currently in game";
} else {

View File

@ -6,22 +6,15 @@
#include "citra_qt/discord.h"
namespace Core {
class System;
}
namespace DiscordRPC {
class DiscordImpl : public DiscordInterface {
public:
DiscordImpl(const Core::System& system);
DiscordImpl();
~DiscordImpl() override;
void Pause() override;
void Update() override;
private:
const Core::System& system;
};
} // namespace DiscordRPC

View File

@ -2,7 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <QActionGroup>
#include <QApplication>
#include <QDir>
#include <QFileInfo>
@ -308,9 +307,6 @@ GameList::GameList(GMainWindow* parent) : QWidget{parent} {
tree_view->setEditTriggers(QHeaderView::NoEditTriggers);
tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }"));
tree_view->header()->setContextMenuPolicy(Qt::CustomContextMenu);
UpdateColumnVisibility();
item_model->insertColumns(0, COLUMN_COUNT);
RetranslateUI();
@ -321,8 +317,6 @@ GameList::GameList(GMainWindow* parent) : QWidget{parent} {
connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu);
connect(tree_view, &QTreeView::expanded, this, &GameList::OnItemExpanded);
connect(tree_view, &QTreeView::collapsed, this, &GameList::OnItemExpanded);
connect(tree_view->header(), &QHeaderView::customContextMenuRequested, this,
&GameList::PopupHeaderContextMenu);
// We must register all custom types with the Qt Automoc system so that we are able to use
// it with signals/slots. In this case, QList falls under the umbrells of custom types.
@ -477,41 +471,6 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location));
}
void GameList::PopupHeaderContextMenu(const QPoint& menu_location) {
const QModelIndex item = tree_view->indexAt(menu_location);
if (!item.isValid()) {
return;
}
QMenu context_menu;
static const QMap<QString, Settings::Setting<bool>*> columns{
{tr("Compatibility"), &UISettings::values.show_compat_column},
{tr("Region"), &UISettings::values.show_region_column},
{tr("File type"), &UISettings::values.show_type_column},
{tr("Size"), &UISettings::values.show_size_column}};
QActionGroup* column_group = new QActionGroup(this);
column_group->setExclusive(false);
for (const auto& key : columns.keys()) {
QAction* action = column_group->addAction(context_menu.addAction(key));
action->setCheckable(true);
action->setChecked(columns[key]->GetValue());
connect(action, &QAction::toggled, [this, key](bool value) {
*columns[key] = !columns[key]->GetValue();
UpdateColumnVisibility();
});
}
context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location));
}
void GameList::UpdateColumnVisibility() {
tree_view->setColumnHidden(COLUMN_COMPATIBILITY, !UISettings::values.show_compat_column);
tree_view->setColumnHidden(COLUMN_REGION, !UISettings::values.show_region_column);
tree_view->setColumnHidden(COLUMN_FILE_TYPE, !UISettings::values.show_type_column);
tree_view->setColumnHidden(COLUMN_SIZE, !UISettings::values.show_size_column);
}
void ForEachOpenGLCacheFile(u64 program_id, auto func) {
for (const std::string_view cache_type : {"separable", "conventional"}) {
const std::string path = fmt::format("{}opengl/precompiled/{}/{:016X}.bin",
@ -791,10 +750,6 @@ QStandardItemModel* GameList::GetModel() const {
void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs) {
tree_view->setEnabled(false);
// Update the columns in case UISettings has changed
UpdateColumnVisibility();
// Delete any rows that might already exist if we're repopulating
item_model->removeRows(0, item_model->rowCount());
search_field->clear();

View File

@ -104,11 +104,9 @@ private:
void DonePopulating(const QStringList& watch_list);
void PopupContextMenu(const QPoint& menu_location);
void PopupHeaderContextMenu(const QPoint& menu_location);
void AddGamePopup(QMenu& context_menu, const QString& path, u64 program_id, u64 extdata_id);
void AddCustomDirPopup(QMenu& context_menu, QModelIndex selected);
void AddPermDirPopup(QMenu& context_menu, QModelIndex selected);
void UpdateColumnVisibility();
QString FindGameByProgramID(QStandardItem* current_item, u64 program_id, int role);

View File

@ -14,7 +14,6 @@
#include <QtGui>
#include <QtWidgets>
#include <fmt/format.h>
#include "core/telemetry_session.h"
#ifdef __APPLE__
#include <unistd.h> // for chdir
#endif
@ -74,6 +73,7 @@
#include "common/microprofile.h"
#include "common/scm_rev.h"
#include "common/scope_exit.h"
#include "common/string_util.h"
#if CITRA_ARCH(x86_64)
#include "common/x64/cpu_detect.h"
#endif
@ -173,7 +173,7 @@ static QString PrettyProductName() {
}
GMainWindow::GMainWindow(Core::System& system_)
: ui{std::make_unique<Ui::MainWindow>()}, system{system_}, movie{system.Movie()},
: ui{std::make_unique<Ui::MainWindow>()}, system{system_}, movie{Core::Movie::GetInstance()},
config{std::make_unique<Config>()}, emu_thread{nullptr} {
Common::Log::Initialize();
Common::Log::Start();
@ -353,8 +353,8 @@ void GMainWindow::InitializeWidgets() {
});
InputCommon::Init();
multiplayer_state = new MultiplayerState(system, this, game_list->GetModel(),
ui->action_Leave_Room, ui->action_Show_Room);
multiplayer_state = new MultiplayerState(this, game_list->GetModel(), ui->action_Leave_Room,
ui->action_Show_Room);
multiplayer_state->setVisible(false);
#if ENABLE_QT_UPDATER
@ -434,7 +434,7 @@ void GMainWindow::InitializeDebugWidgets() {
debug_menu->addAction(microProfileDialog->toggleViewAction());
#endif
registersWidget = new RegistersWidget(system, this);
registersWidget = new RegistersWidget(this);
addDockWidget(Qt::RightDockWidgetArea, registersWidget);
registersWidget->hide();
debug_menu->addAction(registersWidget->toggleViewAction());
@ -448,7 +448,7 @@ void GMainWindow::InitializeDebugWidgets() {
graphicsWidget->hide();
debug_menu->addAction(graphicsWidget->toggleViewAction());
graphicsCommandsWidget = new GPUCommandListWidget(system.Memory(), this);
graphicsCommandsWidget = new GPUCommandListWidget(this);
addDockWidget(Qt::RightDockWidgetArea, graphicsCommandsWidget);
graphicsCommandsWidget->hide();
debug_menu->addAction(graphicsCommandsWidget->toggleViewAction());
@ -472,7 +472,7 @@ void GMainWindow::InitializeDebugWidgets() {
connect(this, &GMainWindow::EmulationStopping, graphicsTracingWidget,
&GraphicsTracingWidget::OnEmulationStopping);
waitTreeWidget = new WaitTreeWidget(system, this);
waitTreeWidget = new WaitTreeWidget(this);
addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget);
waitTreeWidget->hide();
debug_menu->addAction(waitTreeWidget->toggleViewAction());
@ -490,7 +490,7 @@ void GMainWindow::InitializeDebugWidgets() {
connect(this, &GMainWindow::EmulationStopping, waitTreeWidget,
[this] { lleServiceModulesWidget->setDisabled(false); });
ipcRecorderWidget = new IPCRecorderWidget(system, this);
ipcRecorderWidget = new IPCRecorderWidget(this);
addDockWidget(Qt::RightDockWidgetArea, ipcRecorderWidget);
ipcRecorderWidget->hide();
debug_menu->addAction(ipcRecorderWidget->toggleViewAction());
@ -1171,18 +1171,20 @@ void GMainWindow::BootGame(const QString& filename) {
movie.PrepareForPlayback(movie_playback_path.toStdString());
}
u64 title_id{0};
const std::string path = filename.toStdString();
const auto loader = Loader::GetLoader(path);
u64 title_id{0};
loader->ReadProgramId(title_id);
if (loader && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success) {
// Load per game settings
const std::string name{FileUtil::GetFilename(filename.toStdString())};
const std::string config_file_name =
title_id == 0 ? name : fmt::format("{:016X}", title_id);
Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig);
system.ApplySettings();
// Load per game settings
const std::string name{FileUtil::GetFilename(filename.toStdString())};
const std::string config_file_name = title_id == 0 ? name : fmt::format("{:016X}", title_id);
LOG_INFO(Frontend, "Loading per game config file for title {}", config_file_name);
Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig);
system.ApplySettings();
LOG_INFO(Frontend, "Using per game config file for title id {}", config_file_name);
}
Settings::LogSettings();
@ -1413,7 +1415,7 @@ void GMainWindow::UpdateSaveStates() {
if (system.GetAppLoader().ReadProgramId(title_id) != Loader::ResultStatus::Success) {
return;
}
auto savestates = Core::ListSaveStates(title_id, movie.GetCurrentMovieID());
auto savestates = Core::ListSaveStates(title_id);
for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) {
actions_load_state[i]->setEnabled(false);
actions_load_state[i]->setText(tr("Slot %1").arg(i + 1));
@ -2046,6 +2048,7 @@ void GMainWindow::OnLoadAmiibo() {
return;
}
Core::System& system{Core::System::GetInstance()};
Service::SM::ServiceManager& sm = system.ServiceManager();
auto nfc = sm.GetService<Service::NFC::Module::Interface>("nfc:u");
if (nfc == nullptr) {
@ -2117,15 +2120,14 @@ void GMainWindow::OnToggleFilterBar() {
}
void GMainWindow::OnCreateGraphicsSurfaceViewer() {
auto graphicsSurfaceViewerWidget =
new GraphicsSurfaceWidget(system.Memory(), Pica::g_debug_context, this);
auto graphicsSurfaceViewerWidget = new GraphicsSurfaceWidget(Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsSurfaceViewerWidget);
// TODO: Maybe graphicsSurfaceViewerWidget->setFloating(true);
graphicsSurfaceViewerWidget->show();
}
void GMainWindow::OnRecordMovie() {
MovieRecordDialog dialog(this, system);
MovieRecordDialog dialog(this);
if (dialog.exec() != QDialog::Accepted) {
return;
}
@ -2142,7 +2144,7 @@ void GMainWindow::OnRecordMovie() {
}
void GMainWindow::OnPlayMovie() {
MoviePlayDialog dialog(this, game_list, system);
MoviePlayDialog dialog(this, game_list);
if (dialog.exec() != QDialog::Accepted) {
return;
}
@ -2783,13 +2785,9 @@ void GMainWindow::UpdateWindowTitle() {
const QString full_name = QString::fromUtf8(Common::g_build_fullname);
if (game_title.isEmpty()) {
setWindowTitle(QStringLiteral("Citra %1").arg(full_name));
setWindowTitle(tr("Citra %1").arg(full_name));
} else {
setWindowTitle(QStringLiteral("Citra %1 | %2").arg(full_name, game_title));
render_window->setWindowTitle(
QStringLiteral("Citra %1 | %2 | %3").arg(full_name, game_title, tr("Primary Window")));
secondary_window->setWindowTitle(QStringLiteral("Citra %1 | %2 | %3")
.arg(full_name, game_title, tr("Secondary Window")));
setWindowTitle(tr("Citra %1| %2").arg(full_name, game_title));
}
}
@ -2847,7 +2845,7 @@ void GMainWindow::RetranslateStatusBar() {
void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
#ifdef USE_DISCORD_PRESENCE
if (state) {
discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>(system);
discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>();
} else {
discord_rpc = std::make_unique<DiscordRPC::NullImpl>();
}

View File

@ -15,9 +15,8 @@
#include "core/movie.h"
#include "ui_movie_play_dialog.h"
MoviePlayDialog::MoviePlayDialog(QWidget* parent, GameList* game_list_, const Core::System& system_)
: QDialog(parent),
ui(std::make_unique<Ui::MoviePlayDialog>()), game_list{game_list_}, system{system_} {
MoviePlayDialog::MoviePlayDialog(QWidget* parent, GameList* game_list_)
: QDialog(parent), ui(std::make_unique<Ui::MoviePlayDialog>()), game_list(game_list_) {
ui->setupUi(this);
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
@ -27,10 +26,10 @@ MoviePlayDialog::MoviePlayDialog(QWidget* parent, GameList* game_list_, const Co
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &MoviePlayDialog::accept);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MoviePlayDialog::reject);
if (system.IsPoweredOn()) {
if (Core::System::GetInstance().IsPoweredOn()) {
QString note_text;
note_text = tr("Current running game will be stopped.");
if (system.Movie().GetPlayMode() == Core::Movie::PlayMode::Recording) {
if (Core::Movie::GetInstance().GetPlayMode() == Core::Movie::PlayMode::Recording) {
note_text.append(tr("<br>Current recording will be discarded."));
}
ui->note2Label->setText(note_text);
@ -44,7 +43,7 @@ QString MoviePlayDialog::GetMoviePath() const {
}
QString MoviePlayDialog::GetGamePath() const {
const auto metadata = system.Movie().GetMovieMetadata(GetMoviePath().toStdString());
const auto metadata = Core::Movie::GetInstance().GetMovieMetadata(GetMoviePath().toStdString());
return game_list->FindGameByProgramID(metadata.program_id, GameListItemPath::FullPathRole);
}
@ -68,10 +67,9 @@ void MoviePlayDialog::UpdateUIDisplay() {
ui->lengthLineEdit->clear();
ui->note1Label->setVisible(true);
const auto& movie = system.Movie();
const auto path = GetMoviePath().toStdString();
const auto validation_result = movie.ValidateMovie(path);
const auto validation_result = Core::Movie::GetInstance().ValidateMovie(path);
if (validation_result == Core::Movie::ValidationResult::Invalid) {
ui->note1Label->setText(tr("Invalid movie file."));
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
@ -96,7 +94,7 @@ void MoviePlayDialog::UpdateUIDisplay() {
UNREACHABLE();
}
const auto metadata = movie.GetMovieMetadata(path);
const auto metadata = Core::Movie::GetInstance().GetMovieMetadata(path);
// Format game title
const auto title =

View File

@ -11,15 +11,11 @@ namespace Ui {
class MoviePlayDialog;
}
namespace Core {
class System;
}
class MoviePlayDialog : public QDialog {
Q_OBJECT
public:
explicit MoviePlayDialog(QWidget* parent, GameList* game_list, const Core::System& system);
explicit MoviePlayDialog(QWidget* parent, GameList* game_list);
~MoviePlayDialog() override;
QString GetMoviePath() const;
@ -31,5 +27,4 @@ private:
std::unique_ptr<Ui::MoviePlayDialog> ui;
GameList* game_list;
const Core::System& system;
};

View File

@ -10,8 +10,8 @@
#include "core/movie.h"
#include "ui_movie_record_dialog.h"
MovieRecordDialog::MovieRecordDialog(QWidget* parent, const Core::System& system_)
: QDialog(parent), ui(std::make_unique<Ui::MovieRecordDialog>()), system{system_} {
MovieRecordDialog::MovieRecordDialog(QWidget* parent)
: QDialog(parent), ui(std::make_unique<Ui::MovieRecordDialog>()) {
ui->setupUi(this);
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
@ -23,9 +23,9 @@ MovieRecordDialog::MovieRecordDialog(QWidget* parent, const Core::System& system
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MovieRecordDialog::reject);
QString note_text;
if (system.IsPoweredOn()) {
if (Core::System::GetInstance().IsPoweredOn()) {
note_text = tr("Current running game will be restarted.");
if (system.Movie().GetPlayMode() == Core::Movie::PlayMode::Recording) {
if (Core::Movie::GetInstance().GetPlayMode() == Core::Movie::PlayMode::Recording) {
note_text.append(tr("<br>Current recording will be discarded."));
}
} else {

View File

@ -9,15 +9,11 @@ namespace Ui {
class MovieRecordDialog;
}
namespace Core {
class System;
}
class MovieRecordDialog : public QDialog {
Q_OBJECT
public:
explicit MovieRecordDialog(QWidget* parent, const Core::System& system);
explicit MovieRecordDialog(QWidget* parent);
~MovieRecordDialog() override;
QString GetPath() const;
@ -28,5 +24,4 @@ private:
void UpdateUIDisplay();
std::unique_ptr<Ui::MovieRecordDialog> ui;
const Core::System& system;
};

View File

@ -9,8 +9,10 @@
#include <QString>
#include <QtConcurrent/QtConcurrentRun>
#include "citra_qt/main.h"
#include "citra_qt/multiplayer/client_room.h"
#include "citra_qt/multiplayer/direct_connect.h"
#include "citra_qt/multiplayer/message.h"
#include "citra_qt/multiplayer/state.h"
#include "citra_qt/multiplayer/validation.h"
#include "citra_qt/uisettings.h"
#include "core/hle/service/cfg/cfg.h"
@ -20,9 +22,9 @@
enum class ConnectionType : u8 { TraversalServer, IP };
DirectConnectWindow::DirectConnectWindow(Core::System& system_, QWidget* parent)
DirectConnectWindow::DirectConnectWindow(QWidget* parent)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
ui(std::make_unique<Ui::DirectConnect>()), system{system_} {
ui(std::make_unique<Ui::DirectConnect>()) {
ui->setupUi(this);
@ -89,7 +91,7 @@ void DirectConnectWindow::Connect() {
if (auto room_member = Network::GetRoomMember().lock()) {
auto port = UISettings::values.port.toUInt();
room_member->Join(ui->nickname->text().toStdString(),
Service::CFG::GetConsoleIdHash(system),
Service::CFG::GetConsoleIdHash(Core::System::GetInstance()),
ui->ip->text().toStdString().c_str(), port, 0,
Network::NoPreferredMac, ui->password->text().toStdString().c_str());
}

View File

@ -13,15 +13,11 @@ namespace Ui {
class DirectConnect;
}
namespace Core {
class System;
}
class DirectConnectWindow : public QDialog {
Q_OBJECT
public:
explicit DirectConnectWindow(Core::System& system, QWidget* parent = nullptr);
explicit DirectConnectWindow(QWidget* parent = nullptr);
~DirectConnectWindow();
void RetranslateUi();
@ -43,6 +39,5 @@ private:
QFutureWatcher<void>* watcher;
std::unique_ptr<Ui::DirectConnect> ui;
Core::System& system;
Validation validation;
};

View File

@ -12,6 +12,7 @@
#include <QTime>
#include <QtConcurrent/QtConcurrentRun>
#include "citra_qt/game_list_p.h"
#include "citra_qt/main.h"
#include "citra_qt/multiplayer/host_room.h"
#include "citra_qt/multiplayer/message.h"
#include "citra_qt/multiplayer/state.h"
@ -26,10 +27,10 @@
#include "web_service/verify_user_jwt.h"
#endif
HostRoomWindow::HostRoomWindow(Core::System& system_, QWidget* parent, QStandardItemModel* list,
HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list,
std::shared_ptr<Network::AnnounceMultiplayerSession> session)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
ui(std::make_unique<Ui::HostRoom>()), system{system_}, announce_multiplayer_session(session) {
ui(std::make_unique<Ui::HostRoom>()), announce_multiplayer_session(session) {
ui->setupUi(this);
// set up validation for all of the fields
@ -195,8 +196,9 @@ void HostRoomWindow::Host() {
}
}
#endif
member->Join(ui->username->text().toStdString(), Service::CFG::GetConsoleIdHash(system),
"127.0.0.1", port, 0, Network::NoPreferredMac, password, token);
member->Join(ui->username->text().toStdString(),
Service::CFG::GetConsoleIdHash(Core::System::GetInstance()), "127.0.0.1", port,
0, Network::NoPreferredMac, password, token);
// Store settings
UISettings::values.room_nickname = ui->username->text();

View File

@ -9,16 +9,14 @@
#include <QSortFilterProxyModel>
#include <QStandardItemModel>
#include <QVariant>
#include "citra_qt/multiplayer/chat_room.h"
#include "citra_qt/multiplayer/validation.h"
#include "network/network.h"
namespace Ui {
class HostRoom;
}
namespace Core {
class System;
}
namespace Network {
class AnnounceMultiplayerSession;
}
@ -36,7 +34,7 @@ class HostRoomWindow : public QDialog {
Q_OBJECT
public:
explicit HostRoomWindow(Core::System& system, QWidget* parent, QStandardItemModel* list,
explicit HostRoomWindow(QWidget* parent, QStandardItemModel* list,
std::shared_ptr<Network::AnnounceMultiplayerSession> session);
~HostRoomWindow();
@ -52,7 +50,6 @@ private:
std::unique_ptr<Network::VerifyUser::Backend> CreateVerifyBackend(bool use_validation) const;
std::unique_ptr<Ui::HostRoom> ui;
Core::System& system;
std::weak_ptr<Network::AnnounceMultiplayerSession> announce_multiplayer_session;
QStandardItemModel* game_list;
ComboBoxProxyModel* proxy;

View File

@ -7,9 +7,11 @@
#include <QtConcurrent/QtConcurrentRun>
#include "citra_qt/game_list_p.h"
#include "citra_qt/main.h"
#include "citra_qt/multiplayer/client_room.h"
#include "citra_qt/multiplayer/lobby.h"
#include "citra_qt/multiplayer/lobby_p.h"
#include "citra_qt/multiplayer/message.h"
#include "citra_qt/multiplayer/state.h"
#include "citra_qt/multiplayer/validation.h"
#include "citra_qt/uisettings.h"
#include "common/logging/log.h"
@ -21,10 +23,10 @@
#include "web_service/web_backend.h"
#endif
Lobby::Lobby(Core::System& system_, QWidget* parent, QStandardItemModel* list,
Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
std::shared_ptr<Network::AnnounceMultiplayerSession> session)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
ui(std::make_unique<Ui::Lobby>()), system{system_}, announce_multiplayer_session(session) {
ui(std::make_unique<Ui::Lobby>()), announce_multiplayer_session(session) {
ui->setupUi(this);
// setup the watcher for background connections
@ -150,8 +152,8 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
const std::string verify_UID =
proxy->data(connection_index, LobbyItemHost::HostVerifyUIDRole).toString().toStdString();
// Attempt to connect in a different thread
QFuture<void> f = QtConcurrent::run([this, nickname, ip, port, password, verify_UID] {
// attempt to connect in a different thread
QFuture<void> f = QtConcurrent::run([nickname, ip, port, password, verify_UID] {
std::string token;
#ifdef ENABLE_WEB_SERVICE
if (!NetSettings::values.citra_username.empty() &&
@ -168,8 +170,8 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
}
#endif
if (auto room_member = Network::GetRoomMember().lock()) {
room_member->Join(nickname, Service::CFG::GetConsoleIdHash(system), ip.c_str(), port, 0,
Network::NoPreferredMac, password, token);
room_member->Join(nickname, Service::CFG::GetConsoleIdHash(Core::System::GetInstance()),
ip.c_str(), port, 0, Network::NoPreferredMac, password, token);
}
});
watcher->setFuture(f);

View File

@ -12,16 +12,12 @@
#include "citra_qt/multiplayer/validation.h"
#include "common/announce_multiplayer_room.h"
#include "network/announce_multiplayer_session.h"
#include "network/room_member.h"
#include "network/network.h"
namespace Ui {
class Lobby;
}
namespace Core {
class System;
}
class LobbyModel;
class LobbyFilterProxyModel;
@ -33,7 +29,7 @@ class Lobby : public QDialog {
Q_OBJECT
public:
explicit Lobby(Core::System& system, QWidget* parent, QStandardItemModel* list,
explicit Lobby(QWidget* parent, QStandardItemModel* list,
std::shared_ptr<Network::AnnounceMultiplayerSession> session);
~Lobby() override;
@ -88,9 +84,7 @@ private:
*/
QString PasswordPrompt();
private:
std::unique_ptr<Ui::Lobby> ui;
Core::System& system;
QStandardItemModel* model{};
QStandardItemModel* game_list{};

View File

@ -17,10 +17,9 @@
#include "citra_qt/util/clickable_label.h"
#include "common/logging/log.h"
MultiplayerState::MultiplayerState(Core::System& system_, QWidget* parent,
QStandardItemModel* game_list_model, QAction* leave_room,
QAction* show_room)
: QWidget(parent), system{system_}, game_list_model(game_list_model), leave_room(leave_room),
MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_list_model,
QAction* leave_room, QAction* show_room)
: QWidget(parent), game_list_model(game_list_model), leave_room(leave_room),
show_room(show_room) {
if (auto member = Network::GetRoomMember().lock()) {
// register the network structs to use in slots and signals
@ -204,14 +203,14 @@ static void BringWidgetToFront(QWidget* widget) {
void MultiplayerState::OnViewLobby() {
if (lobby == nullptr) {
lobby = new Lobby(system, this, game_list_model, announce_multiplayer_session);
lobby = new Lobby(this, game_list_model, announce_multiplayer_session);
}
BringWidgetToFront(lobby);
}
void MultiplayerState::OnCreateRoom() {
if (host_room == nullptr) {
host_room = new HostRoomWindow(system, this, game_list_model, announce_multiplayer_session);
host_room = new HostRoomWindow(this, game_list_model, announce_multiplayer_session);
}
BringWidgetToFront(host_room);
}
@ -275,7 +274,7 @@ void MultiplayerState::OnOpenNetworkRoom() {
void MultiplayerState::OnDirectConnectToRoom() {
if (direct_connect == nullptr) {
direct_connect = new DirectConnectWindow(system, this);
direct_connect = new DirectConnectWindow(this);
}
BringWidgetToFront(direct_connect);
}

View File

@ -15,16 +15,12 @@ class ClientRoomWindow;
class DirectConnectWindow;
class ClickableLabel;
namespace Core {
class System;
}
class MultiplayerState : public QWidget {
Q_OBJECT;
public:
explicit MultiplayerState(Core::System& system, QWidget* parent, QStandardItemModel* game_list,
QAction* leave_room, QAction* show_room);
explicit MultiplayerState(QWidget* parent, QStandardItemModel* game_list, QAction* leave_room,
QAction* show_room);
~MultiplayerState();
/**
@ -75,7 +71,6 @@ signals:
void AnnounceFailed(const Common::WebResult&);
private:
Core::System& system;
Lobby* lobby = nullptr;
HostRoomWindow* host_room = nullptr;
ClientRoomWindow* client_room = nullptr;

View File

@ -97,12 +97,6 @@ struct Values {
Settings::Setting<bool> game_list_hide_no_icon{false, "hideNoIcon"};
Settings::Setting<bool> game_list_single_line_mode{false, "singleLineMode"};
// Compatibility List
Settings::Setting<bool> show_compat_column{true, "show_compat_column"};
Settings::Setting<bool> show_region_column{true, "show_region_column"};
Settings::Setting<bool> show_type_column{true, "show_type_column"};
Settings::Setting<bool> show_size_column{true, "show_size_column"};
Settings::Setting<u16> screenshot_resolution_factor{0, "screenshot_resolution_factor"};
Settings::SwitchableSetting<std::string> screenshot_path{"", "screenshotPath"};

View File

@ -130,9 +130,11 @@ bool UpdaterPrivate::StartUpdateCheck() {
main_process->setProgram(tool_info.absoluteFilePath());
main_process->setArguments({QStringLiteral("--checkupdates"), QStringLiteral("-v")});
connect(main_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this,
connect(main_process,
static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this,
&UpdaterPrivate::UpdaterReady, Qt::QueuedConnection);
connect(main_process, qOverload<QProcess::ProcessError>(&QProcess::errorOccurred), this,
connect(main_process,
static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::errorOccurred), this,
&UpdaterPrivate::UpdaterError, Qt::QueuedConnection);
main_process->start(QIODevice::ReadOnly);
@ -154,7 +156,7 @@ void UpdaterPrivate::StopUpdateCheck(int delay, bool async) {
QTimer* timer = new QTimer(this);
timer->setSingleShot(true);
connect(timer, &QTimer::timeout, this, [this, timer]() {
connect(timer, &QTimer::timeout, [this, timer]() {
StopUpdateCheck(0, false);
timer->deleteLater();
});

View File

@ -176,9 +176,6 @@ endif()
if (CITRA_USE_PRECOMPILED_HEADERS)
target_precompile_headers(citra_common PRIVATE precompiled_headers.h)
endif()
find_library(BACKTRACE_LIBRARY backtrace)
if (BACKTRACE_LIBRARY AND ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND CMAKE_CXX_COMPILER_ID STREQUAL GNU)
target_link_libraries(citra_common PRIVATE ${BACKTRACE_LIBRARY} dl)
target_compile_definitions(citra_common PRIVATE CITRA_LINUX_GCC_BACKTRACE)
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND CMAKE_CXX_COMPILER_ID STREQUAL GNU)
target_link_libraries(citra_common PRIVATE backtrace dl)
endif()

View File

@ -13,11 +13,12 @@
#define _SH_DENYWR 0
#endif
#ifdef CITRA_LINUX_GCC_BACKTRACE
#if defined(__linux__) && defined(__GNUG__) && !defined(__clang__)
#define BOOST_STACKTRACE_USE_BACKTRACE
#include <boost/stacktrace.hpp>
#undef BOOST_STACKTRACE_USE_BACKTRACE
#include <signal.h>
#define CITRA_LINUX_GCC_BACKTRACE
#endif
#include "common/bounded_threadsafe_queue.h"

View File

@ -100,14 +100,13 @@ enum Values {
ZR,
Home,
Power,
NumButtons,
};
constexpr int BUTTON_HID_BEGIN = A;
constexpr int BUTTON_IR_BEGIN = ZL;
constexpr int BUTTON_NS_BEGIN = Power;
constexpr int BUTTON_NS_BEGIN = Home;
constexpr int BUTTON_HID_END = BUTTON_IR_BEGIN;
constexpr int BUTTON_IR_END = BUTTON_NS_BEGIN;
@ -135,7 +134,6 @@ static const std::array<const char*, NumButtons> mapping = {{
"button_zl",
"button_zr",
"button_home",
"button_power",
}};
} // namespace NativeButton

View File

@ -62,29 +62,12 @@ public:
return SlotId{index};
}
template <typename... Args>
[[nodiscard]] SlotId swap_and_insert(SlotId existing_id, Args&&... args) noexcept {
const u32 index = FreeValueIndex();
T& existing_value = values[existing_id.index].object;
new (&values[index].object) T(std::move(existing_value));
existing_value.~T();
new (&values[existing_id.index].object) T(std::forward<Args>(args)...);
SetStorageBit(index);
return SlotId{index};
}
void erase(SlotId id) noexcept {
values[id.index].object.~T();
free_list.push_back(id.index);
ResetStorageBit(id.index);
}
size_t size() const noexcept {
return values_capacity - free_list.size();
}
private:
struct NonTrivialDummy {
NonTrivialDummy() noexcept {}
@ -110,7 +93,7 @@ private:
return ((stored_bitset[index / 64] >> (index % 64)) & 1) != 0;
}
void ValidateIndex([[maybe_unused]] SlotId id) const noexcept {
void ValidateIndex(SlotId id) const noexcept {
DEBUG_ASSERT(id);
DEBUG_ASSERT(id.index / 64 < stored_bitset.size());
DEBUG_ASSERT(((stored_bitset[id.index / 64] >> (id.index % 64)) & 1) != 0);

View File

@ -184,8 +184,6 @@ add_library(citra_core STATIC
hle/kernel/wait_object.h
hle/lock.cpp
hle/lock.h
hle/mii.h
hle/mii.cpp
hle/result.h
hle/romfs.cpp
hle/romfs.h
@ -247,8 +245,6 @@ add_library(citra_core STATIC
hle/service/cam/cam_s.h
hle/service/cam/cam_u.cpp
hle/service/cam/cam_u.h
hle/service/cam/y2r_u.cpp
hle/service/cam/y2r_u.h
hle/service/cecd/cecd.cpp
hle/service/cecd/cecd.h
hle/service/cecd/cecd_ndm.cpp
@ -259,8 +255,6 @@ add_library(citra_core STATIC
hle/service/cecd/cecd_u.h
hle/service/cfg/cfg.cpp
hle/service/cfg/cfg.h
hle/service/cfg/cfg_defaults.cpp
hle/service/cfg/cfg_defaults.h
hle/service/cfg/cfg_i.cpp
hle/service/cfg/cfg_i.h
hle/service/cfg/cfg_nor.cpp
@ -281,8 +275,8 @@ add_library(citra_core STATIC
hle/service/dlp/dlp_srvr.h
hle/service/dsp/dsp_dsp.cpp
hle/service/dsp/dsp_dsp.h
hle/service/err/err_f.cpp
hle/service/err/err_f.h
hle/service/err_f.cpp
hle/service/err_f.h
hle/service/frd/frd.cpp
hle/service/frd/frd.h
hle/service/frd/frd_a.cpp
@ -309,8 +303,8 @@ add_library(citra_core STATIC
hle/service/hid/hid_spvr.h
hle/service/hid/hid_user.cpp
hle/service/hid/hid_user.h
hle/service/http/http_c.cpp
hle/service/http/http_c.h
hle/service/http_c.cpp
hle/service/http_c.h
hle/service/ir/extra_hid.cpp
hle/service/ir/extra_hid.h
hle/service/ir/ir.cpp
@ -325,8 +319,8 @@ add_library(citra_core STATIC
hle/service/ldr_ro/cro_helper.h
hle/service/ldr_ro/ldr_ro.cpp
hle/service/ldr_ro/ldr_ro.h
hle/service/mic/mic_u.cpp
hle/service/mic/mic_u.h
hle/service/mic_u.cpp
hle/service/mic_u.h
hle/service/mvd/mvd.cpp
hle/service/mvd/mvd.h
hle/service/mvd/mvd_std.cpp
@ -423,10 +417,12 @@ add_library(citra_core STATIC
hle/service/sm/sm.h
hle/service/sm/srv.cpp
hle/service/sm/srv.h
hle/service/soc/soc_u.cpp
hle/service/soc/soc_u.h
hle/service/ssl/ssl_c.cpp
hle/service/ssl/ssl_c.h
hle/service/soc_u.cpp
hle/service/soc_u.h
hle/service/ssl_c.cpp
hle/service/ssl_c.h
hle/service/y2r_u.cpp
hle/service/y2r_u.h
hw/aes/arithmetic128.cpp
hw/aes/arithmetic128.h
hw/aes/ccm.cpp
@ -461,6 +457,14 @@ add_library(citra_core STATIC
perf_stats.cpp
perf_stats.h
precompiled_headers.h
rpc/packet.cpp
rpc/packet.h
rpc/rpc_server.cpp
rpc/rpc_server.h
rpc/server.cpp
rpc/server.h
rpc/udp_server.cpp
rpc/udp_server.h
savestate.cpp
savestate.h
system_titles.cpp
@ -475,32 +479,18 @@ add_library(citra_core STATIC
create_target_directory_groups(citra_core)
target_link_libraries(citra_core PUBLIC citra_common PRIVATE audio_core network video_core)
target_link_libraries(citra_core PRIVATE Boost::boost Boost::serialization Boost::iostreams httplib)
target_link_libraries(citra_core PRIVATE Boost::boost Boost::serialization Boost::iostreams)
target_link_libraries(citra_core PUBLIC dds-ktx PRIVATE cryptopp fmt::fmt lodepng open_source_archives)
set_target_properties(citra_core PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${ENABLE_LTO})
if (ENABLE_WEB_SERVICE)
target_compile_definitions(citra_core PRIVATE -DENABLE_WEB_SERVICE)
target_link_libraries(citra_core PRIVATE web_service)
target_compile_definitions(citra_core PRIVATE -DENABLE_WEB_SERVICE -DCPPHTTPLIB_OPENSSL_SUPPORT)
target_link_libraries(citra_core PRIVATE web_service ${OPENSSL_LIBS} httplib)
if (ANDROID)
target_link_libraries(citra_core PRIVATE ifaddrs)
endif()
endif()
if (ENABLE_SCRIPTING)
target_compile_definitions(citra_core PRIVATE -DENABLE_SCRIPTING)
target_sources(citra_core PRIVATE
rpc/packet.cpp
rpc/packet.h
rpc/rpc_server.cpp
rpc/rpc_server.h
rpc/server.cpp
rpc/server.h
rpc/udp_server.cpp
rpc/udp_server.h
)
endif()
if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE)
target_sources(citra_core PRIVATE
arm/dynarmic/arm_dynarmic.cpp

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <exception>
#include <memory>
#include <stdexcept>
#include <utility>
#include <boost/serialization/array.hpp>
@ -14,8 +16,6 @@
#include "core/arm/arm_interface.h"
#include "core/arm/exclusive_monitor.h"
#include "core/hle/service/cam/cam.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/ir/ir_user.h"
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
#include "core/arm/dynarmic/arm_dynarmic.h"
#endif
@ -35,8 +35,10 @@
#include "core/hle/service/cam/cam.h"
#include "core/hle/service/fs/archive.h"
#include "core/hle/service/gsp/gsp.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/ir/ir_rst.h"
#include "core/hle/service/mic/mic_u.h"
#include "core/hle/service/ir/ir_user.h"
#include "core/hle/service/mic_u.h"
#include "core/hle/service/plgldr/plgldr.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
@ -45,10 +47,7 @@
#include "core/hw/lcd.h"
#include "core/loader/loader.h"
#include "core/movie.h"
#ifdef ENABLE_SCRIPTING
#include "core/rpc/server.h"
#endif
#include "core/telemetry_session.h"
#include "core/rpc/rpc_server.h"
#include "network/network.h"
#include "video_core/custom_textures/custom_tex_manager.h"
#include "video_core/renderer_base.h"
@ -73,8 +72,6 @@ Core::Timing& Global() {
return System::GetInstance().CoreTiming();
}
System::System() : movie{*this} {}
System::~System() = default;
System::ResultStatus System::RunLoop(bool tight_loop) {
@ -88,7 +85,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
if (thread && running_core) {
running_core->SaveContext(thread->context);
}
GDBStub::HandlePacket(*this);
GDBStub::HandlePacket();
// If the loop is halted and we want to step, use a tiny (1) number of instructions to
// execute. Otherwise, get out of the loop function.
@ -262,13 +259,14 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
return ResultStatus::ErrorGetLoader;
}
std::pair<std::optional<u32>, Loader::ResultStatus> system_mode =
app_loader->LoadKernelSystemMode();
auto memory_mode = app_loader->LoadKernelMemoryMode();
if (memory_mode.second != Loader::ResultStatus::Success) {
if (system_mode.second != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to determine system mode (Error {})!",
static_cast<int>(memory_mode.second));
static_cast<int>(system_mode.second));
switch (memory_mode.second) {
switch (system_mode.second) {
case Loader::ResultStatus::ErrorEncrypted:
return ResultStatus::ErrorLoader_ErrorEncrypted;
case Loader::ResultStatus::ErrorInvalidFormat:
@ -280,15 +278,15 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
}
}
ASSERT(memory_mode.first);
auto n3ds_hw_caps = app_loader->LoadNew3dsHwCapabilities();
ASSERT(n3ds_hw_caps.first);
ASSERT(system_mode.first);
auto n3ds_mode = app_loader->LoadKernelN3dsMode();
ASSERT(n3ds_mode.first);
u32 num_cores = 2;
if (Settings::values.is_new_3ds) {
num_cores = 4;
}
ResultStatus init_result{
Init(emu_window, secondary_window, *memory_mode.first, *n3ds_hw_caps.first, num_cores)};
Init(emu_window, secondary_window, *system_mode.first, *n3ds_mode.first, num_cores)};
if (init_result != ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<u32>(init_result));
@ -323,12 +321,12 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
cheat_engine = std::make_unique<Cheats::CheatEngine>(title_id, *this);
perf_stats = std::make_unique<PerfStats>(title_id);
if (Settings::values.dump_textures) {
custom_tex_manager->PrepareDumping(title_id);
}
if (Settings::values.custom_textures) {
custom_tex_manager->FindCustomTextures();
}
if (Settings::values.dump_textures) {
custom_tex_manager->WriteConfig();
}
status = ResultStatus::Success;
m_emu_window = &emu_window;
@ -365,18 +363,16 @@ void System::Reschedule() {
}
System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
Frontend::EmuWindow* secondary_window,
Kernel::MemoryMode memory_mode,
const Kernel::New3dsHwCapabilities& n3ds_hw_caps, u32 num_cores) {
Frontend::EmuWindow* secondary_window, u32 system_mode,
u8 n3ds_mode, u32 num_cores) {
LOG_DEBUG(HW_Memory, "initialized OK");
memory = std::make_unique<Memory::MemorySystem>(*this);
memory = std::make_unique<Memory::MemorySystem>();
timing = std::make_unique<Timing>(num_cores, Settings::values.cpu_clock_percentage.GetValue());
kernel = std::make_unique<Kernel::KernelSystem>(
*memory, *timing, [this] { PrepareReschedule(); }, memory_mode, num_cores, n3ds_hw_caps,
movie.GetOverrideInitTime());
*memory, *timing, [this] { PrepareReschedule(); }, system_mode, num_cores, n3ds_mode);
exclusive_monitor = MakeExclusiveMonitor(*memory, num_cores);
cpu_cores.reserve(num_cores);
@ -420,9 +416,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
telemetry_session = std::make_unique<Core::TelemetrySession>();
#ifdef ENABLE_SCRIPTING
rpc_server = std::make_unique<RPC::Server>(*this);
#endif
rpc_server = std::make_unique<RPC::RPCServer>();
service_manager = std::make_unique<Service::SM::ServiceManager>(*this);
archive_manager = std::make_unique<Service::FS::ArchiveManager>(*this);
@ -514,14 +508,6 @@ const VideoCore::CustomTexManager& System::CustomTexManager() const {
return *custom_tex_manager;
}
Core::Movie& System::Movie() {
return movie;
}
const Core::Movie& System::Movie() const {
return movie;
}
void System::RegisterMiiSelector(std::shared_ptr<Frontend::MiiSelector> mii_selector) {
registered_mii_selector = std::move(mii_selector);
}
@ -559,9 +545,7 @@ void System::Shutdown(bool is_deserializing) {
}
custom_tex_manager.reset();
telemetry_session.reset();
#ifdef ENABLE_SCRIPTING
rpc_server.reset();
#endif
archive_manager.reset();
service_manager.reset();
dsp_core.reset();
@ -633,14 +617,16 @@ void System::ApplySettings() {
if (VideoCore::g_renderer) {
auto& settings = VideoCore::g_renderer->Settings();
settings.bg_color_update_requested = true;
settings.sampler_update_requested = true;
settings.shader_update_requested = true;
settings.texture_filter_update_requested = true;
}
if (IsPoweredOn()) {
CoreTiming().UpdateClockSpeed(Settings::values.cpu_clock_percentage.GetValue());
dsp_core->SetSink(Settings::values.output_type.GetValue(),
Settings::values.output_device.GetValue());
dsp_core->EnableStretching(Settings::values.enable_audio_stretching.GetValue());
Core::DSP().SetSink(Settings::values.output_type.GetValue(),
Settings::values.output_device.GetValue());
Core::DSP().EnableStretching(Settings::values.enable_audio_stretching.GetValue());
auto hid = Service::HID::GetModule(*this);
if (hid) {
@ -687,10 +673,10 @@ void System::serialize(Archive& ar, const unsigned int file_version) {
Shutdown(true);
// Re-initialize everything like it was before
auto memory_mode = this->app_loader->LoadKernelMemoryMode();
auto n3ds_hw_caps = this->app_loader->LoadNew3dsHwCapabilities();
auto system_mode = this->app_loader->LoadKernelSystemMode();
auto n3ds_mode = this->app_loader->LoadKernelN3dsMode();
[[maybe_unused]] const System::ResultStatus result = Init(
*m_emu_window, m_secondary_window, *memory_mode.first, *n3ds_hw_caps.first, num_cores);
*m_emu_window, m_secondary_window, *system_mode.first, *n3ds_mode.first, num_cores);
}
// flush on save, don't flush on load
@ -718,7 +704,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) {
ar&* kernel.get();
VideoCore::serialize(ar, file_version);
if (file_version >= 1) {
ar& movie;
ar& Movie::GetInstance();
}
// This needs to be set from somewhere - might as well be here!

View File

@ -10,17 +10,18 @@
#include <string>
#include <boost/serialization/version.hpp>
#include "common/common_types.h"
#include "core/arm/arm_interface.h"
#include "core/movie.h"
#include "core/frontend/applets/mii_selector.h"
#include "core/frontend/applets/swkbd.h"
#include "core/loader/loader.h"
#include "core/memory.h"
#include "core/perf_stats.h"
#include "core/telemetry_session.h"
class ARM_Interface;
namespace Frontend {
class EmuWindow;
class ImageInterface;
class MiiSelector;
class SoftwareKeyboard;
} // namespace Frontend
namespace Memory {
@ -31,8 +32,8 @@ namespace AudioCore {
class DspInterface;
}
namespace Core::RPC {
class Server;
namespace RPC {
class RPCServer;
}
namespace Service {
@ -46,9 +47,7 @@ class ArchiveManager;
namespace Kernel {
class KernelSystem;
struct New3dsHwCapabilities;
enum class MemoryMode : u8;
} // namespace Kernel
}
namespace Cheats {
class CheatEngine;
@ -63,13 +62,8 @@ class CustomTexManager;
class RendererBase;
} // namespace VideoCore
namespace Loader {
class AppLoader;
}
namespace Core {
class TelemetrySession;
class ExclusiveMonitor;
class Timing;
@ -101,7 +95,6 @@ public:
ErrorUnknown ///< Any other error
};
explicit System();
~System();
/**
@ -194,10 +187,6 @@ public:
return *cpu_cores[core_id];
};
[[nodiscard]] const ARM_Interface& GetCore(u32 core_id) const {
return *cpu_cores[core_id];
};
[[nodiscard]] u32 GetNumCores() const {
return static_cast<u32>(cpu_cores.size());
}
@ -269,12 +258,6 @@ public:
/// Gets a const reference to the custom texture cache system
[[nodiscard]] const VideoCore::CustomTexManager& CustomTexManager() const;
/// Gets a reference to the movie recorder
[[nodiscard]] Core::Movie& Movie();
/// Gets a const reference to the movie recorder
[[nodiscard]] const Core::Movie& Movie() const;
/// Video Dumper interface
void RegisterVideoDumper(std::shared_ptr<VideoDumper::Backend> video_dumper);
@ -359,10 +342,8 @@ private:
* @return ResultStatus code, indicating if the operation succeeded.
*/
[[nodiscard]] ResultStatus Init(Frontend::EmuWindow& emu_window,
Frontend::EmuWindow* secondary_window,
Kernel::MemoryMode memory_mode,
const Kernel::New3dsHwCapabilities& n3ds_hw_caps,
u32 num_cores);
Frontend::EmuWindow* secondary_window, u32 system_mode,
u8 n3ds_mode, u32 num_cores);
/// Reschedule the core emulation
void Reschedule();
@ -390,9 +371,6 @@ private:
std::shared_ptr<Frontend::MiiSelector> registered_mii_selector;
std::shared_ptr<Frontend::SoftwareKeyboard> registered_swkbd;
/// Movie recorder
Core::Movie movie;
/// Cheats manager
std::unique_ptr<Cheats::CheatEngine> cheat_engine;
@ -405,10 +383,8 @@ private:
/// Image interface
std::shared_ptr<Frontend::ImageInterface> registered_image_interface;
#ifdef ENABLE_SCRIPTING
/// RPC Server for scripting support
std::unique_ptr<RPC::Server> rpc_server;
#endif
std::unique_ptr<RPC::RPCServer> rpc_server;
std::unique_ptr<Service::FS::ArchiveManager> archive_manager;
@ -457,6 +433,10 @@ private:
return System::GetInstance().GetNumCores();
}
[[nodiscard]] inline AudioCore::DspInterface& DSP() {
return System::GetInstance().DSP();
}
} // namespace Core
BOOST_CLASS_VERSION(Core::System, 1)

View File

@ -12,8 +12,8 @@
#include "common/common_types.h"
#include "common/file_util.h"
#include "common/swap.h"
#include "core/core.h"
#include "core/file_sys/romfs_reader.h"
#include "core/loader/loader.h"
enum NCSDContentIndex { Main = 0, Manual = 1, DLP = 2, New3DSUpdate = 6, Update = 7 };
@ -165,11 +165,7 @@ struct ExHeader_StorageInfo {
struct ExHeader_ARM11_SystemLocalCaps {
u64_le program_id;
u32_le core_version;
union {
u8 n3ds_cpu_flags;
BitField<0, 1, u8> enable_l2_cache;
BitField<1, 1, u8> enable_804MHz_cpu;
};
u8 reserved_flag;
u8 n3ds_mode;
union {
u8 flags0;

View File

@ -181,12 +181,6 @@ std::array<u8, 16> TitleMetadata::GetContentCTRByIndex(std::size_t index) const
return ctr;
}
bool TitleMetadata::HasEncryptedContent() const {
return std::any_of(tmd_chunks.begin(), tmd_chunks.end(), [](auto& chunk) {
return (static_cast<u16>(chunk.type) & FileSys::TMDContentTypeFlag::Encrypted) != 0;
});
}
void TitleMetadata::SetTitleID(u64 title_id) {
tmd_body.title_id = title_id;
}

View File

@ -98,7 +98,6 @@ public:
u16 GetContentTypeByIndex(std::size_t index) const;
u64 GetContentSizeByIndex(std::size_t index) const;
std::array<u8, 16> GetContentCTRByIndex(std::size_t index) const;
bool HasEncryptedContent() const;
void SetTitleID(u64 title_id);
void SetTitleType(u32 type);

View File

@ -11,12 +11,12 @@
namespace Frontend {
void MiiSelector::Finalize(u32 return_code, Mii::MiiData mii) {
void MiiSelector::Finalize(u32 return_code, HLE::Applets::MiiData mii) {
data = {return_code, mii};
}
std::vector<Mii::MiiData> LoadMiis() {
std::vector<Mii::MiiData> miis;
std::vector<HLE::Applets::MiiData> LoadMiis() {
std::vector<HLE::Applets::MiiData> miis;
std::string nand_directory{FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)};
FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true);
@ -36,7 +36,7 @@ std::vector<Mii::MiiData> LoadMiis() {
u32 saved_miis_offset = 0x8;
// The Mii Maker has a 100 Mii limit on the 3ds
for (int i = 0; i < 100; ++i) {
Mii::MiiData mii;
HLE::Applets::MiiData mii;
std::array<u8, sizeof(mii)> mii_raw;
file->Read(saved_miis_offset, sizeof(mii), mii_raw.data());
std::memcpy(&mii, mii_raw.data(), sizeof(mii));

View File

@ -25,7 +25,7 @@ struct MiiSelectorConfig {
struct MiiSelectorData {
u32 return_code;
Mii::MiiData mii;
HLE::Applets::MiiData mii;
};
class MiiSelector {
@ -43,14 +43,14 @@ public:
* Stores the data so that the HLE applet in core can
* send this to the calling application
*/
void Finalize(u32 return_code, Mii::MiiData mii);
void Finalize(u32 return_code, HLE::Applets::MiiData mii);
protected:
MiiSelectorConfig config;
MiiSelectorData data;
};
std::vector<Mii::MiiData> LoadMiis();
std::vector<HLE::Applets::MiiData> LoadMiis();
class DefaultMiiSelector final : public MiiSelector {
public:

View File

@ -55,17 +55,15 @@ EmuWindow::EmuWindow(bool is_secondary_) : is_secondary{is_secondary_} {
}
EmuWindow::~EmuWindow() = default;
bool EmuWindow::IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x,
unsigned framebuffer_y) {
#ifndef ANDROID
// If separate windows and the touch is in the primary (top) screen, ignore it.
if (Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows &&
!is_secondary && !Settings::values.swap_screen.GetValue()) {
return false;
}
#endif
/**
* Check if the given x/y coordinates are within the touchpad specified by the framebuffer layout
* @param layout FramebufferLayout object describing the framebuffer size and screen positions
* @param framebuffer_x Framebuffer x-coordinate to check
* @param framebuffer_y Framebuffer y-coordinate to check
* @return True if the coordinates are within the touchpad, otherwise false
*/
static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x,
unsigned framebuffer_y) {
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) {
return (framebuffer_y >= layout.bottom_screen.top &&
framebuffer_y < layout.bottom_screen.bottom &&

View File

@ -288,17 +288,6 @@ private:
void CreateTouchState();
/**
* Check if the given x/y coordinates are within the touchpad specified by the framebuffer
* layout
* @param layout FramebufferLayout object describing the framebuffer size and screen positions
* @param framebuffer_x Framebuffer x-coordinate to check
* @param framebuffer_y Framebuffer y-coordinate to check
* @return True if the coordinates are within the touchpad, otherwise false
*/
bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x,
unsigned framebuffer_y);
Layout::FramebufferLayout framebuffer_layout; ///< Current framebuffer layout
WindowConfig config{}; ///< Internal configuration (changes pending for being applied in

View File

@ -36,6 +36,7 @@
#include "core/gdbstub/gdbstub.h"
#include "core/gdbstub/hio.h"
#include "core/hle/kernel/process.h"
#include "core/loader/loader.h"
#include "core/memory.h"
namespace GDBStub {
@ -1034,7 +1035,7 @@ static void RemoveBreakpoint() {
SendReply("OK");
}
void HandlePacket(Core::System& system) {
void HandlePacket() {
if (!IsConnected()) {
if (defer_start) {
ToggleServer(true);
@ -1075,7 +1076,7 @@ void HandlePacket(Core::System& system) {
Continue();
return;
case 'F':
HandleHioReply(system, command_buffer, command_length);
HandleHioReply(command_buffer, command_length);
break;
case 'g':
ReadRegisters();

View File

@ -10,10 +10,6 @@
#include "common/common_types.h"
#include "core/hle/kernel/thread.h"
namespace Core {
class System;
}
namespace GDBStub {
/// Breakpoint Method
@ -74,7 +70,7 @@ void Break(bool is_memory_break = false);
bool IsMemoryBreak();
/// Read and handle packet from gdb client.
void HandlePacket(Core::System& system);
void HandlePacket();
/**
* Get the nearest breakpoint of the specified type at the given address.

View File

@ -54,7 +54,7 @@ static void SendErrorReply(int error_code, int retval = -1) {
SendReply(packet.data());
}
void SetHioRequest(Core::System& system, const VAddr addr) {
void SetHioRequest(const VAddr addr) {
if (!IsServerEnabled()) {
LOG_WARNING(Debug_GDBStub, "HIO requested but GDB stub is not running");
return;
@ -69,15 +69,15 @@ void SetHioRequest(Core::System& system, const VAddr addr) {
LOG_INFO(Debug_GDBStub, "overwriting existing HIO request that was not sent yet");
}
auto& memory = system.Memory();
const auto process = system.Kernel().GetCurrentProcess();
auto& memory = Core::System::GetInstance().Memory();
const auto process = Core::System::GetInstance().Kernel().GetCurrentProcess();
if (!memory.IsValidVirtualAddress(*process, addr)) {
LOG_WARNING(Debug_GDBStub, "Invalid address for HIO request");
return;
}
memory.ReadBlock(addr, &current_hio_request, sizeof(PackedGdbHioRequest));
memory.ReadBlock(*process, addr, &current_hio_request, sizeof(PackedGdbHioRequest));
if (current_hio_request.magic != std::array{'G', 'D', 'B', '\0'}) {
std::string_view bad_magic{
@ -105,11 +105,10 @@ void SetHioRequest(Core::System& system, const VAddr addr) {
Break();
SetCpuHaltFlag(true);
SetCpuStepFlag(false);
system.GetRunningCore().ClearInstructionCache();
Core::GetRunningCore().ClearInstructionCache();
}
void HandleHioReply(Core::System& system, const u8* const command_buffer,
const u32 command_length) {
void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
if (!IsWaitingForHioReply()) {
LOG_WARNING(Debug_GDBStub, "Got HIO reply but never sent a request");
return;
@ -177,8 +176,8 @@ void HandleHioReply(Core::System& system, const u8* const command_buffer,
current_hio_request.retval, current_hio_request.gdb_errno,
current_hio_request.ctrl_c);
const auto process = system.Kernel().GetCurrentProcess();
auto& memory = system.Memory();
const auto process = Core::System::GetInstance().Kernel().GetCurrentProcess();
auto& memory = Core::System::GetInstance().Memory();
// should have been checked when we first initialized the request,
// but just double check again before we write to memory
@ -188,7 +187,8 @@ void HandleHioReply(Core::System& system, const u8* const command_buffer,
return;
}
memory.WriteBlock(current_hio_request_addr, &current_hio_request, sizeof(PackedGdbHioRequest));
memory.WriteBlock(*process, current_hio_request_addr, &current_hio_request,
sizeof(PackedGdbHioRequest));
current_hio_request = {};
current_hio_request_addr = 0;
@ -197,7 +197,7 @@ void HandleHioReply(Core::System& system, const u8* const command_buffer,
// Restore state from before the request came in
SetCpuStepFlag(was_stepping);
SetCpuHaltFlag(was_halted);
system.GetRunningCore().ClearInstructionCache();
Core::GetRunningCore().ClearInstructionCache();
}
bool HandlePendingHioRequestPacket() {

View File

@ -6,10 +6,6 @@
#include "common/common_types.h"
namespace Core {
class System;
}
namespace GDBStub {
/**
@ -51,7 +47,7 @@ static_assert(sizeof(PackedGdbHioRequest) == 152,
*
* @param address The memory address of the \ref PackedGdbHioRequest.
*/
void SetHioRequest(Core::System& system, const VAddr address);
void SetHioRequest(const VAddr address);
/**
* If there is a pending HIO request, send it to the client.
@ -63,6 +59,6 @@ bool HandlePendingHioRequestPacket();
/**
* Process an HIO reply from the client.
*/
void HandleHioReply(Core::System& system, const u8* const command_buffer, const u32 command_length);
void HandleHioReply(const u8* const command_buffer, const u32 command_length);
} // namespace GDBStub

View File

@ -71,6 +71,9 @@ void MiiSelector::Update() {
const MiiSelectorData& data = frontend_applet->ReceiveData();
result.return_code = data.return_code;
result.selected_mii_data = data.mii;
// Calculate the checksum of the selected Mii, see https://www.3dbrew.org/wiki/Mii#Checksum
result.mii_data_checksum = boost::crc<16, 0x1021, 0, 0, false, false>(
&result.selected_mii_data, sizeof(HLE::Applets::MiiData) + sizeof(result.unknown1));
result.selected_guest_mii_index = 0xFFFFFFFF;
// TODO(Subv): We're finalizing the applet immediately after it's started,
@ -89,31 +92,29 @@ MiiResult MiiSelector::GetStandardMiiResult() {
// This data was obtained by writing the returned buffer in AppletManager::GlanceParameter of
// the LLEd Mii picker of version system version 11.8.0 to a file and then matching the values
// to the members of the MiiResult struct
Mii::MiiData mii_data;
mii_data.magic = 0x03;
mii_data.mii_options.raw = 0x00;
mii_data.mii_pos.raw = 0x10;
mii_data.console_identity.raw = 0x30;
MiiData mii_data;
mii_data.mii_id = 0x03001030;
mii_data.system_id = 0xD285B6B300C8850A;
mii_data.mii_id = 0x98391EE4;
mii_data.mac = {0x40, 0xF4, 0x07, 0xB7, 0x37, 0x10};
mii_data.pad = 0x0000;
mii_data.mii_details.raw = 0xA600;
mii_data.specialness_and_creation_date = 0x98391EE4;
mii_data.creator_mac = {0x40, 0xF4, 0x07, 0xB7, 0x37, 0x10};
mii_data.padding = 0x0;
mii_data.mii_information = 0xA600;
mii_data.mii_name = {'C', 'i', 't', 'r', 'a', 0x0, 0x0, 0x0, 0x0, 0x0};
mii_data.height = 0x40;
mii_data.width = 0x40;
mii_data.face_style.raw = 0x00;
mii_data.face_details.raw = 0x00;
mii_data.width_height = 0x4040;
mii_data.appearance_bits1.raw = 0x0;
mii_data.appearance_bits2.raw = 0x0;
mii_data.hair_style = 0x21;
mii_data.hair_details.raw = 0x01;
mii_data.eye_details.raw = 0x02684418;
mii_data.eyebrow_details.raw = 0x26344614;
mii_data.nose_details.raw = 0x8112;
mii_data.mouth_details.raw = 0x1768;
mii_data.mustache_details.raw = 0x0D00;
mii_data.beard_details.raw = 0x0029;
mii_data.glasses_details.raw = 0x0052;
mii_data.mole_details.raw = 0x4850;
mii_data.appearance_bits3.hair_color.Assign(0x1);
mii_data.appearance_bits3.flip_hair.Assign(0x0);
mii_data.unknown1 = 0x02684418;
mii_data.appearance_bits4.eyebrow_style.Assign(0x6);
mii_data.appearance_bits4.eyebrow_color.Assign(0x1);
mii_data.appearance_bits5.eyebrow_scale.Assign(0x4);
mii_data.appearance_bits5.eyebrow_yscale.Assign(0x3);
mii_data.appearance_bits6 = 0x4614;
mii_data.unknown2 = 0x81121768;
mii_data.allow_copying = 0x0D;
mii_data.unknown3 = {0x0, 0x0, 0x29, 0x0, 0x52, 0x48, 0x50};
mii_data.author_name = {'f', 'l', 'T', 'o', 'b', 'i', 0x0, 0x0, 0x0, 0x0};
MiiResult result;
@ -121,6 +122,8 @@ MiiResult MiiSelector::GetStandardMiiResult() {
result.is_guest_mii_selected = 0x0;
result.selected_guest_mii_index = 0xFFFFFFFF;
result.selected_mii_data = mii_data;
result.unknown1 = 0x0;
result.mii_data_checksum = 0x056C;
result.guest_mii_name.fill(0x0);
return result;

View File

@ -9,7 +9,6 @@
#include "common/common_types.h"
#include "core/hle/applets/applet.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/mii.h"
#include "core/hle/result.h"
#include "core/hle/service/apt/apt.h"
@ -45,11 +44,65 @@ ASSERT_REG_POSITION(initially_selected_mii_index, 0x90);
ASSERT_REG_POSITION(guest_mii_whitelist, 0x94);
#undef ASSERT_REG_POSITION
#pragma pack(push, 1)
struct MiiData {
u32_be mii_id;
u64_be system_id;
u32_be specialness_and_creation_date;
std::array<u8, 0x6> creator_mac;
u16_be padding;
u16_be mii_information;
std::array<u16_le, 0xA> mii_name;
u16_be width_height;
union {
u8 raw;
BitField<0, 1, u8> disable_sharing;
BitField<1, 4, u8> face_shape;
BitField<5, 3, u8> skin_color;
} appearance_bits1;
union {
u8 raw;
BitField<0, 4, u8> wrinkles;
BitField<4, 4, u8> makeup;
} appearance_bits2;
u8 hair_style;
union {
u8 raw;
BitField<0, 3, u8> hair_color;
BitField<3, 1, u8> flip_hair;
} appearance_bits3;
u32_be unknown1;
union {
u8 raw;
BitField<0, 5, u8> eyebrow_style;
BitField<5, 3, u8> eyebrow_color;
} appearance_bits4;
union {
u8 raw;
BitField<0, 4, u8> eyebrow_scale;
BitField<4, 3, u8> eyebrow_yscale;
} appearance_bits5;
u16_be appearance_bits6;
u32_be unknown2;
u8 allow_copying;
std::array<u8, 0x7> unknown3;
std::array<u16_le, 0xA> author_name;
};
static_assert(sizeof(MiiData) == 0x5C, "MiiData structure has incorrect size");
#pragma pack(pop)
struct MiiResult {
u32_be return_code;
u32_be is_guest_mii_selected;
u32_be selected_guest_mii_index;
Mii::ChecksummedMiiData selected_mii_data;
MiiData selected_mii_data;
u16_be unknown1;
u16_be mii_data_checksum;
std::array<u16_le, 0xC> guest_mii_name;
};
static_assert(sizeof(MiiResult) == 0x84, "MiiResult structure has incorrect size");

View File

@ -210,8 +210,14 @@ inline void RequestBuilder::PushMappedBuffer(const Kernel::MappedBuffer& mapped_
class RequestParser : public RequestHelperBase {
public:
RequestParser(Kernel::HLERequestContext& context)
: RequestHelperBase(context, context.CommandHeader()) {}
RequestParser(Kernel::HLERequestContext& context, Header desired_header)
: RequestHelperBase(context, desired_header) {}
RequestParser(Kernel::HLERequestContext& context, u16 command_id, unsigned normal_params_size,
unsigned translate_params_size)
: RequestParser(context,
Header{MakeHeader(command_id, normal_params_size, translate_params_size)}) {
}
RequestBuilder MakeBuilder(u32 normal_params_size, u32 translate_params_size,
bool validateHeader = true) {

View File

@ -4,7 +4,6 @@
#include <algorithm>
#include <vector>
#include "common/archives.h"
#include "common/assert.h"
#include "common/common_types.h"
#include "core/core.h"

Some files were not shown because too many files have changed in this diff Show More