Compare commits
3 Commits
custom-tex
...
tev-jit
Author | SHA1 | Date | |
---|---|---|---|
cfdb10a7ba | |||
8012b28b92 | |||
531d280461 |
@ -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)
|
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_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)
|
CMAKE_DEPENDENT_OPTION(ENABLE_CUBEB "Enables the cubeb audio backend" ON "NOT IOS" OFF)
|
||||||
option(ENABLE_OPENAL "Enables the OpenAL audio backend" ON)
|
option(ENABLE_OPENAL "Enables the OpenAL audio backend" ON)
|
||||||
@ -342,6 +341,13 @@ function(get_timestamp _var)
|
|||||||
set(${_var} "${timestamp}" PARENT_SCOPE)
|
set(${_var} "${timestamp}" PARENT_SCOPE)
|
||||||
endfunction()
|
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
|
# generate git/build information
|
||||||
include(GetGitRevisionDescription)
|
include(GetGitRevisionDescription)
|
||||||
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
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)
|
git_branch_name(GIT_BRANCH)
|
||||||
get_timestamp(BUILD_DATE)
|
get_timestamp(BUILD_DATE)
|
||||||
|
|
||||||
# Boost
|
if (NOT USE_SYSTEM_BOOST)
|
||||||
# Prevent boost from linking against libs when building
|
add_definitions( -DBOOST_ALL_NO_LIB )
|
||||||
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)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_subdirectory(externals)
|
add_subdirectory(externals)
|
||||||
|
|
||||||
# Boost (bundled)
|
# Boost
|
||||||
if (NOT USE_SYSTEM_BOOST)
|
if (USE_SYSTEM_BOOST)
|
||||||
add_definitions( -DBOOST_ALL_NO_LIB )
|
find_package(Boost 1.70.0 COMPONENTS serialization iostreams REQUIRED)
|
||||||
|
else()
|
||||||
add_library(Boost::boost ALIAS boost)
|
add_library(Boost::boost ALIAS boost)
|
||||||
add_library(Boost::serialization ALIAS boost_serialization)
|
add_library(Boost::serialization ALIAS boost_serialization)
|
||||||
add_library(Boost::iostreams ALIAS boost_iostreams)
|
add_library(Boost::iostreams ALIAS boost_iostreams)
|
||||||
|
@ -57,7 +57,9 @@ if (DEFINED ENV{CI})
|
|||||||
set(BUILD_VERSION ${CMAKE_MATCH_1})
|
set(BUILD_VERSION ${CMAKE_MATCH_1})
|
||||||
endif()
|
endif()
|
||||||
if (BUILD_VERSION)
|
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()
|
else()
|
||||||
set(BUILD_FULLNAME "")
|
set(BUILD_FULLNAME "")
|
||||||
endif()
|
endif()
|
||||||
|
5
dist/qt_themes/qdarkstyle/style.qss
vendored
5
dist/qt_themes/qdarkstyle/style.qss
vendored
@ -298,11 +298,6 @@ QAbstractItemView:read-only {
|
|||||||
alternate-background-color: #232629;
|
alternate-background-color: #232629;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Workaround for https://bugreports.qt.io/browse/QTBUG-115529 */
|
|
||||||
QAbstractItemView:item {
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget:focus {
|
QWidget:focus {
|
||||||
border: 1px solid #3daee9;
|
border: 1px solid #3daee9;
|
||||||
}
|
}
|
||||||
|
@ -481,11 +481,6 @@ QAbstractItemView QLineEdit {
|
|||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Workaround for https://bugreports.qt.io/browse/QTBUG-115529 */
|
|
||||||
QAbstractItemView:item {
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* QAbstractScrollArea ----------------------------------------------------
|
/* QAbstractScrollArea ----------------------------------------------------
|
||||||
|
|
||||||
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea
|
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea
|
||||||
|
100
externals/CMakeLists.txt
vendored
100
externals/CMakeLists.txt
vendored
@ -12,29 +12,27 @@ include(DownloadExternals)
|
|||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
|
||||||
# Boost
|
# Boost
|
||||||
if (NOT USE_SYSTEM_BOOST)
|
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
|
||||||
message(STATUS "Including vendored Boost library")
|
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
|
||||||
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
|
set(Boost_NO_SYSTEM_PATHS ON CACHE BOOL "")
|
||||||
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
|
add_library(boost INTERFACE)
|
||||||
set(Boost_NO_SYSTEM_PATHS ON CACHE BOOL "")
|
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
|
||||||
add_library(boost INTERFACE)
|
|
||||||
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
|
|
||||||
|
|
||||||
# Boost::serialization
|
# Boost::serialization
|
||||||
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
|
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
|
||||||
add_library(boost_serialization STATIC ${boost_serialization_SRC})
|
add_library(boost_serialization STATIC ${boost_serialization_SRC})
|
||||||
target_link_libraries(boost_serialization PUBLIC boost)
|
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!
|
# Add additional boost libs here; remember to ALIAS them in the root CMakeLists!
|
||||||
endif()
|
|
||||||
|
|
||||||
# Catch2
|
# Catch2
|
||||||
set(CATCH_INSTALL_DOCS OFF CACHE BOOL "")
|
set(CATCH_INSTALL_DOCS OFF CACHE BOOL "")
|
||||||
@ -173,39 +171,37 @@ endif()
|
|||||||
add_library(json-headers INTERFACE)
|
add_library(json-headers INTERFACE)
|
||||||
target_include_directories(json-headers INTERFACE ./json)
|
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)
|
|
||||||
target_link_libraries(httplib INTERFACE ifaddrs)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# cpp-jwt
|
|
||||||
if (ENABLE_WEB_SERVICE)
|
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)
|
add_library(cpp-jwt INTERFACE)
|
||||||
target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include)
|
target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include)
|
||||||
target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)
|
target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="org.citra.citra_emu.CitraApplication"
|
android:name="org.citra.citra_emu.CitraApplication"
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package org.citra.citra_emu.ui.main;
|
package org.citra.citra_emu.ui.main;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
@ -16,7 +13,6 @@ import androidx.activity.result.contract.ActivityResultContracts;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.core.splashscreen.SplashScreen;
|
import androidx.core.splashscreen.SplashScreen;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import java.util.Collections;
|
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
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
|
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
|
||||||
@ -172,12 +165,6 @@ public final class MainActivity extends AppCompatActivity implements MainView {
|
|||||||
EmulationActivity.tryDismissRunningNotification(this);
|
EmulationActivity.tryDismissRunningNotification(this);
|
||||||
|
|
||||||
setInsets();
|
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
|
@Override
|
||||||
|
@ -53,7 +53,7 @@ void AndroidMiiSelector::Setup(const Frontend::MiiSelectorConfig& config) {
|
|||||||
const u32 return_code = static_cast<u32>(
|
const u32 return_code = static_cast<u32>(
|
||||||
env->GetLongField(data, env->GetFieldID(s_mii_selector_data_class, "return_code", "J")));
|
env->GetLongField(data, env->GetFieldID(s_mii_selector_data_class, "return_code", "J")));
|
||||||
if (return_code == 1) {
|
if (return_code == 1) {
|
||||||
Finalize(return_code, Mii::MiiData{});
|
Finalize(return_code, HLE::Applets::MiiData{});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include "core/hle/service/nfc/nfc.h"
|
#include "core/hle/service/nfc/nfc.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/savestate.h"
|
#include "core/savestate.h"
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "jni/android_common/android_common.h"
|
#include "jni/android_common/android_common.h"
|
||||||
#include "jni/applets/mii_selector.h"
|
#include "jni/applets/mii_selector.h"
|
||||||
#include "jni/applets/swkbd.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>());
|
system.RegisterSoftwareKeyboard(std::make_shared<SoftwareKeyboard::AndroidKeyboard>());
|
||||||
|
|
||||||
// Register microphone permission check
|
// Register microphone permission check
|
||||||
system.RegisterMicPermissionCheck(&CheckMicPermission);
|
Core::System::GetInstance().RegisterMicPermissionCheck(&CheckMicPermission);
|
||||||
|
|
||||||
InputManager::Init();
|
InputManager::Init();
|
||||||
|
|
||||||
@ -167,7 +166,7 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
|||||||
return load_result;
|
return load_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& telemetry_session = system.TelemetrySession();
|
auto& telemetry_session = Core::System::GetInstance().TelemetrySession();
|
||||||
telemetry_session.AddField(Common::Telemetry::FieldType::App, "Frontend", "Android");
|
telemetry_session.AddField(Common::Telemetry::FieldType::App, "Frontend", "Android");
|
||||||
|
|
||||||
stop_run = false;
|
stop_run = false;
|
||||||
@ -188,7 +187,8 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
|||||||
audio_stretching_event =
|
audio_stretching_event =
|
||||||
system.CoreTiming().RegisterEvent("AudioStretchingEvent", [&](u64, s64 cycles_late) {
|
system.CoreTiming().RegisterEvent("AudioStretchingEvent", [&](u64, s64 cycles_late) {
|
||||||
if (Settings::values.enable_audio_stretching) {
|
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,
|
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; });
|
SCOPE_EXIT({ Settings::values.volume = volume; });
|
||||||
Settings::values.volume = 0;
|
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; });
|
running_cv.wait(pause_lock, [] { return !pause_emulation || stop_run; });
|
||||||
window->PollEvents();
|
window->PollEvents();
|
||||||
}
|
}
|
||||||
@ -621,7 +621,7 @@ jobjectArray Java_org_citra_citra_1emu_NativeLibrary_GetSavestateInfo(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto savestates = Core::ListSaveStates(title_id, system.Movie().GetCurrentMovieID());
|
const auto savestates = Core::ListSaveStates(title_id);
|
||||||
const jobjectArray array =
|
const jobjectArray array =
|
||||||
env->NewObjectArray(static_cast<jsize>(savestates.size()), savestate_info_class, nullptr);
|
env->NewObjectArray(static_cast<jsize>(savestates.size()), savestate_info_class, nullptr);
|
||||||
for (std::size_t i = 0; i < savestates.size(); ++i) {
|
for (std::size_t i = 0; i < savestates.size(); ++i) {
|
||||||
|
@ -5,24 +5,20 @@
|
|||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace AudioCore {
|
|
||||||
|
|
||||||
struct ADTSData {
|
struct ADTSData {
|
||||||
u8 header_length = 0;
|
u8 header_length;
|
||||||
bool mpeg2 = false;
|
bool MPEG2;
|
||||||
u8 profile = 0;
|
u8 profile;
|
||||||
u8 channels = 0;
|
u8 channels;
|
||||||
u8 channel_idx = 0;
|
u8 channel_idx;
|
||||||
u8 framecount = 0;
|
u8 framecount;
|
||||||
u8 samplerate_idx = 0;
|
u8 samplerate_idx;
|
||||||
u32 length = 0;
|
u32 length;
|
||||||
u32 samplerate = 0;
|
u32 samplerate;
|
||||||
};
|
};
|
||||||
|
|
||||||
ADTSData ParseADTS(const u8* buffer);
|
ADTSData ParseADTS(const char* buffer);
|
||||||
|
|
||||||
// last two bytes of MF AAC decoder user data
|
// last two bytes of MF AAC decoder user data
|
||||||
// see https://docs.microsoft.com/en-us/windows/desktop/medfound/aac-decoder#example-media-types
|
// see https://docs.microsoft.com/en-us/windows/desktop/medfound/aac-decoder#example-media-types
|
||||||
u16 MFGetAACTag(const ADTSData& input);
|
u16 MFGetAACTag(const ADTSData& input);
|
||||||
|
|
||||||
} // namespace AudioCore
|
|
||||||
|
@ -3,59 +3,44 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
#include <array>
|
#include <array>
|
||||||
#include "adts.h"
|
#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,
|
constexpr std::array<u32, 16> freq_table = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
|
||||||
16000, 12000, 11025, 8000, 7350, 0, 0, 0};
|
16000, 12000, 11025, 8000, 7350, 0, 0, 0};
|
||||||
constexpr std::array<u8, 8> channel_table = {0, 1, 2, 3, 4, 5, 6, 8};
|
constexpr std::array<u8, 8> channel_table = {0, 1, 2, 3, 4, 5, 6, 8};
|
||||||
|
|
||||||
struct ADTSHeader {
|
ADTSData ParseADTS(const char* buffer) {
|
||||||
union {
|
u32 tmp = 0;
|
||||||
std::array<u8, 7> raw{};
|
ADTSData out;
|
||||||
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));
|
|
||||||
|
|
||||||
// sync word 0xfff
|
// sync word 0xfff
|
||||||
if (header.sync_word != 0xfff) {
|
tmp = (buffer[0] << 8) | (buffer[1] & 0xf0);
|
||||||
return {};
|
if ((tmp & 0xffff) != 0xfff0) {
|
||||||
|
out.length = 0;
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADTSData out{};
|
|
||||||
// bit 16 = no CRC
|
// bit 16 = no CRC
|
||||||
out.header_length = header.protection_absent ? 7 : 9;
|
out.header_length = (buffer[1] & 0x1) ? 7 : 9;
|
||||||
out.mpeg2 = static_cast<bool>(header.mpeg2);
|
out.MPEG2 = (buffer[1] >> 3) & 0x1;
|
||||||
// bit 17 to 18
|
// bit 17 to 18
|
||||||
out.profile = static_cast<u8>(header.profile) + 1;
|
out.profile = (buffer[2] >> 6) + 1;
|
||||||
// bit 19 to 22
|
// bit 19 to 22
|
||||||
out.samplerate_idx = static_cast<u8>(header.samplerate_idx);
|
tmp = (buffer[2] >> 2) & 0xf;
|
||||||
out.samplerate = header.samplerate_idx > 15 ? 0 : freq_table[header.samplerate_idx];
|
out.samplerate_idx = tmp;
|
||||||
|
out.samplerate = (tmp > 15) ? 0 : freq_table[tmp];
|
||||||
// bit 24 to 26
|
// bit 24 to 26
|
||||||
out.channel_idx = static_cast<u8>(header.channel_idx);
|
tmp = ((buffer[2] & 0x1) << 2) | ((buffer[3] >> 6) & 0x3);
|
||||||
out.channels = (header.channel_idx > 7) ? 0 : channel_table[header.channel_idx];
|
out.channel_idx = tmp;
|
||||||
|
out.channels = (tmp > 7) ? 0 : channel_table[tmp];
|
||||||
|
|
||||||
// bit 55 to 56
|
// bit 55 to 56
|
||||||
out.framecount = static_cast<u8>(header.frame_count + 1);
|
out.framecount = (buffer[6] & 0x3) + 1;
|
||||||
|
|
||||||
// bit 31 to 43
|
// 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;
|
return out;
|
||||||
}
|
}
|
||||||
@ -76,4 +61,3 @@ u16 MFGetAACTag(const ADTSData& input) {
|
|||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
} // namespace AudioCore
|
|
||||||
|
@ -24,7 +24,7 @@ private:
|
|||||||
std::optional<BinaryMessage> Decode(const BinaryMessage& request);
|
std::optional<BinaryMessage> Decode(const BinaryMessage& request);
|
||||||
|
|
||||||
void Clear();
|
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,
|
static OSStatus DataFunc(AudioConverterRef in_audio_converter, u32* io_number_data_packets,
|
||||||
AudioBufferList* io_data,
|
AudioBufferList* io_data,
|
||||||
@ -33,7 +33,7 @@ private:
|
|||||||
|
|
||||||
Memory::MemorySystem& memory;
|
Memory::MemorySystem& memory;
|
||||||
|
|
||||||
AudioCore::ADTSData adts_config;
|
ADTSData adts_config;
|
||||||
AudioStreamBasicDescription output_format = {};
|
AudioStreamBasicDescription output_format = {};
|
||||||
AudioConverterRef converter = nullptr;
|
AudioConverterRef converter = nullptr;
|
||||||
|
|
||||||
@ -85,11 +85,7 @@ std::optional<BinaryMessage> AudioToolboxDecoder::Impl::ProcessRequest(
|
|||||||
case DecoderCommand::EncodeDecode: {
|
case DecoderCommand::EncodeDecode: {
|
||||||
return Decode(request);
|
return Decode(request);
|
||||||
}
|
}
|
||||||
case DecoderCommand::Shutdown:
|
case DecoderCommand::Unknown: {
|
||||||
case DecoderCommand::SaveState:
|
|
||||||
case DecoderCommand::LoadState: {
|
|
||||||
LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}",
|
|
||||||
static_cast<u16>(request.header.cmd));
|
|
||||||
BinaryMessage response = request;
|
BinaryMessage response = request;
|
||||||
response.header.result = ResultStatus::Success;
|
response.header.result = ResultStatus::Success;
|
||||||
return response;
|
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 (converter) {
|
||||||
if (adts_config.channels == adts_header.channels &&
|
if (adts_config.channels == adts_header.channels &&
|
||||||
adts_config.samplerate == adts_header.samplerate) {
|
adts_config.samplerate == adts_header.samplerate) {
|
||||||
@ -183,9 +179,8 @@ std::optional<BinaryMessage> AudioToolboxDecoder::Impl::Decode(const BinaryMessa
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto data =
|
auto data = memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
|
||||||
memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
|
auto adts_header = ParseADTS(reinterpret_cast<const char*>(data));
|
||||||
auto adts_header = AudioCore::ParseADTS(data);
|
|
||||||
curr_data = data + adts_header.header_length;
|
curr_data = data + adts_header.header_length;
|
||||||
curr_data_len = request.decode_aac_request.size - adts_header.header_length;
|
curr_data_len = request.decode_aac_request.size - adts_header.header_length;
|
||||||
|
|
||||||
|
@ -42,9 +42,7 @@ std::optional<BinaryMessage> NullDecoder::ProcessRequest(const BinaryMessage& re
|
|||||||
BinaryMessage response{};
|
BinaryMessage response{};
|
||||||
switch (request.header.cmd) {
|
switch (request.header.cmd) {
|
||||||
case DecoderCommand::Init:
|
case DecoderCommand::Init:
|
||||||
case DecoderCommand::Shutdown:
|
case DecoderCommand::Unknown:
|
||||||
case DecoderCommand::SaveState:
|
|
||||||
case DecoderCommand::LoadState:
|
|
||||||
response = request;
|
response = request;
|
||||||
response.header.result = ResultStatus::Success;
|
response.header.result = ResultStatus::Success;
|
||||||
return response;
|
return response;
|
||||||
|
@ -14,16 +14,9 @@
|
|||||||
namespace AudioCore::HLE {
|
namespace AudioCore::HLE {
|
||||||
|
|
||||||
enum class DecoderCommand : u16 {
|
enum class DecoderCommand : u16 {
|
||||||
/// Initializes the decoder.
|
|
||||||
Init = 0,
|
Init = 0,
|
||||||
/// Decodes/encodes a data frame.
|
|
||||||
EncodeDecode = 1,
|
EncodeDecode = 1,
|
||||||
/// Shuts down the decoder.
|
Unknown = 2, // Probably UnInit
|
||||||
Shutdown = 2,
|
|
||||||
/// Loads the saved decoder state. Used for DSP wake.
|
|
||||||
LoadState = 3,
|
|
||||||
/// Saves the decoder state. Used for DSP sleep.
|
|
||||||
SaveState = 4,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class DecoderCodec : u16 {
|
enum class DecoderCodec : u16 {
|
||||||
|
@ -111,11 +111,7 @@ std::optional<BinaryMessage> FDKDecoder::Impl::ProcessRequest(const BinaryMessag
|
|||||||
case DecoderCommand::EncodeDecode: {
|
case DecoderCommand::EncodeDecode: {
|
||||||
return Decode(request);
|
return Decode(request);
|
||||||
}
|
}
|
||||||
case DecoderCommand::Shutdown:
|
case DecoderCommand::Unknown: {
|
||||||
case DecoderCommand::SaveState:
|
|
||||||
case DecoderCommand::LoadState: {
|
|
||||||
LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}",
|
|
||||||
static_cast<u16>(request.header.cmd));
|
|
||||||
BinaryMessage response = request;
|
BinaryMessage response = request;
|
||||||
response.header.result = ResultStatus::Success;
|
response.header.result = ResultStatus::Success;
|
||||||
return response;
|
return response;
|
||||||
|
@ -80,11 +80,7 @@ std::optional<BinaryMessage> FFMPEGDecoder::Impl::ProcessRequest(const BinaryMes
|
|||||||
case DecoderCommand::EncodeDecode: {
|
case DecoderCommand::EncodeDecode: {
|
||||||
return Decode(request);
|
return Decode(request);
|
||||||
}
|
}
|
||||||
case DecoderCommand::Shutdown:
|
case DecoderCommand::Unknown: {
|
||||||
case DecoderCommand::SaveState:
|
|
||||||
case DecoderCommand::LoadState: {
|
|
||||||
LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}",
|
|
||||||
static_cast<u16>(request.header.cmd));
|
|
||||||
BinaryMessage response = request;
|
BinaryMessage response = request;
|
||||||
response.header.result = ResultStatus::Success;
|
response.header.result = ResultStatus::Success;
|
||||||
return response;
|
return response;
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <boost/serialization/vector.hpp>
|
#include <boost/serialization/vector.hpp>
|
||||||
#include <boost/serialization/weak_ptr.hpp>
|
#include <boost/serialization/weak_ptr.hpp>
|
||||||
#include "audio_core/audio_types.h"
|
#include "audio_core/audio_types.h"
|
||||||
#include "common/archives.h"
|
|
||||||
#ifdef HAVE_MF
|
#ifdef HAVE_MF
|
||||||
#include "audio_core/hle/wmf_decoder.h"
|
#include "audio_core/hle/wmf_decoder.h"
|
||||||
#elif HAVE_AUDIOTOOLBOX
|
#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));
|
pipe_data[static_cast<u32>(pipe_number)].resize(sizeof(value));
|
||||||
std::memcpy(pipe_data[static_cast<u32>(pipe_number)].data(), &value, 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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -466,6 +461,8 @@ void DspHle::Impl::AudioTickCallback(s64 cycles_late) {
|
|||||||
// TODO(merry): Signal all the other interrupts as appropriate.
|
// TODO(merry): Signal all the other interrupts as appropriate.
|
||||||
if (auto service = dsp_dsp.lock()) {
|
if (auto service = dsp_dsp.lock()) {
|
||||||
service->SignalInterrupt(InterruptType::Pipe, DspPipe::Audio);
|
service->SignalInterrupt(InterruptType::Pipe, DspPipe::Audio);
|
||||||
|
// HACK(merry): Added to prevent regressions. Will remove soon.
|
||||||
|
service->SignalInterrupt(InterruptType::Pipe, DspPipe::Binary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
~Impl();
|
~Impl();
|
||||||
std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request);
|
std::optional<BinaryMessage> ProcessRequest(const BinaryMessage& request);
|
||||||
|
|
||||||
bool SetMediaType(const AudioCore::ADTSData& adts_data);
|
bool SetMediaType(const ADTSData& adts_data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<BinaryMessage> Initalize(const BinaryMessage& request);
|
std::optional<BinaryMessage> Initalize(const BinaryMessage& request);
|
||||||
@ -36,8 +36,8 @@ private:
|
|||||||
Memory::MemorySystem& memory;
|
Memory::MemorySystem& memory;
|
||||||
std::unique_ptr<AMediaCodec, AMediaCodecRelease> decoder;
|
std::unique_ptr<AMediaCodec, AMediaCodecRelease> decoder;
|
||||||
// default: 2 channles, 48000 samplerate
|
// default: 2 channles, 48000 samplerate
|
||||||
AudioCore::ADTSData mADTSData{
|
ADTSData mADTSData{
|
||||||
/*header_length*/ 7, /*mpeg2*/ false, /*profile*/ 2,
|
/*header_length*/ 7, /*MPEG2*/ false, /*profile*/ 2,
|
||||||
/*channels*/ 2, /*channel_idx*/ 2, /*framecount*/ 0,
|
/*channels*/ 2, /*channel_idx*/ 2, /*framecount*/ 0,
|
||||||
/*samplerate_idx*/ 3, /*length*/ 0, /*samplerate*/ 48000};
|
/*samplerate_idx*/ 3, /*length*/ 0, /*samplerate*/ 48000};
|
||||||
};
|
};
|
||||||
@ -54,7 +54,7 @@ std::optional<BinaryMessage> MediaNDKDecoder::Impl::Initalize(const BinaryMessag
|
|||||||
return response;
|
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";
|
const char* mime = "audio/mp4a-latm";
|
||||||
if (decoder && mADTSData.profile == adts_data.profile &&
|
if (decoder && mADTSData.profile == adts_data.profile &&
|
||||||
mADTSData.channel_idx == adts_data.channel_idx &&
|
mADTSData.channel_idx == adts_data.channel_idx &&
|
||||||
@ -110,11 +110,7 @@ std::optional<BinaryMessage> MediaNDKDecoder::Impl::ProcessRequest(const BinaryM
|
|||||||
case DecoderCommand::EncodeDecode: {
|
case DecoderCommand::EncodeDecode: {
|
||||||
return Decode(request);
|
return Decode(request);
|
||||||
}
|
}
|
||||||
case DecoderCommand::Shutdown:
|
case DecoderCommand::Unknown: {
|
||||||
case DecoderCommand::SaveState:
|
|
||||||
case DecoderCommand::LoadState: {
|
|
||||||
LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}",
|
|
||||||
static_cast<u16>(request.header.cmd));
|
|
||||||
BinaryMessage response = request;
|
BinaryMessage response = request;
|
||||||
response.header.result = ResultStatus::Success;
|
response.header.result = ResultStatus::Success;
|
||||||
return response;
|
return response;
|
||||||
@ -141,9 +137,8 @@ std::optional<BinaryMessage> MediaNDKDecoder::Impl::Decode(const BinaryMessage&
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8* data =
|
u8* data = memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
|
||||||
memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
|
ADTSData adts_data = ParseADTS(reinterpret_cast<const char*>(data));
|
||||||
ADTSData adts_data = AudioCore::ParseADTS(data);
|
|
||||||
SetMediaType(adts_data);
|
SetMediaType(adts_data);
|
||||||
response.decode_aac_response.sample_rate = GetSampleRateEnum(adts_data.samplerate);
|
response.decode_aac_response.sample_rate = GetSampleRateEnum(adts_data.samplerate);
|
||||||
response.decode_aac_response.num_channels = adts_data.channels;
|
response.decode_aac_response.num_channels = adts_data.channels;
|
||||||
|
@ -23,8 +23,7 @@ private:
|
|||||||
|
|
||||||
std::optional<BinaryMessage> Decode(const BinaryMessage& request);
|
std::optional<BinaryMessage> Decode(const BinaryMessage& request);
|
||||||
|
|
||||||
MFOutputState DecodingLoop(AudioCore::ADTSData adts_header,
|
MFOutputState DecodingLoop(ADTSData adts_header, std::array<std::vector<u8>, 2>& out_streams);
|
||||||
std::array<std::vector<u8>, 2>& out_streams);
|
|
||||||
|
|
||||||
bool transform_initialized = false;
|
bool transform_initialized = false;
|
||||||
bool format_selected = false;
|
bool format_selected = false;
|
||||||
@ -116,11 +115,7 @@ std::optional<BinaryMessage> WMFDecoder::Impl::ProcessRequest(const BinaryMessag
|
|||||||
case DecoderCommand::EncodeDecode: {
|
case DecoderCommand::EncodeDecode: {
|
||||||
return Decode(request);
|
return Decode(request);
|
||||||
}
|
}
|
||||||
case DecoderCommand::Shutdown:
|
case DecoderCommand::Unknown: {
|
||||||
case DecoderCommand::SaveState:
|
|
||||||
case DecoderCommand::LoadState: {
|
|
||||||
LOG_WARNING(Audio_DSP, "Got unimplemented binary request: {}",
|
|
||||||
static_cast<u16>(request.header.cmd));
|
|
||||||
BinaryMessage response = request;
|
BinaryMessage response = request;
|
||||||
response.header.result = ResultStatus::Success;
|
response.header.result = ResultStatus::Success;
|
||||||
return response;
|
return response;
|
||||||
@ -140,7 +135,7 @@ std::optional<BinaryMessage> WMFDecoder::Impl::Initalize(const BinaryMessage& re
|
|||||||
return response;
|
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::array<std::vector<u8>, 2>& out_streams) {
|
||||||
std::optional<std::vector<f32>> output_buffer;
|
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);
|
request.decode_aac_request.src_addr);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
const u8* data =
|
u8* data = memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
|
||||||
memory.GetFCRAMPointer(request.decode_aac_request.src_addr - Memory::FCRAM_PADDR);
|
|
||||||
|
|
||||||
std::array<std::vector<u8>, 2> out_streams;
|
std::array<std::vector<u8>, 2> out_streams;
|
||||||
unique_mfptr<IMFSample> sample;
|
unique_mfptr<IMFSample> sample;
|
||||||
MFInputState input_status = MFInputState::OK;
|
MFInputState input_status = MFInputState::OK;
|
||||||
MFOutputState output_status = MFOutputState::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) {
|
if (!adts_meta) {
|
||||||
LOG_ERROR(Audio_DSP, "Unable to deduce decoding parameters from ADTS stream");
|
LOG_ERROR(Audio_DSP, "Unable to deduce decoding parameters from ADTS stream");
|
||||||
|
@ -110,9 +110,8 @@ unique_mfptr<IMFSample> CreateSample(const void* data, DWORD len, DWORD alignmen
|
|||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SelectInputMediaType(IMFTransform* transform, int in_stream_id,
|
bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts,
|
||||||
const AudioCore::ADTSData& adts, const UINT8* user_data,
|
const UINT8* user_data, UINT32 user_data_len, GUID audio_format) {
|
||||||
UINT32 user_data_len, GUID audio_format) {
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
unique_mfptr<IMFMediaType> t;
|
unique_mfptr<IMFMediaType> t;
|
||||||
|
|
||||||
@ -191,12 +190,12 @@ bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id, GUID audi
|
|||||||
return false;
|
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) {
|
if (len < 7) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioCore::ADTSData tmp;
|
ADTSData tmp;
|
||||||
ADTSMeta result;
|
ADTSMeta result;
|
||||||
// see https://docs.microsoft.com/en-us/windows/desktop/api/mmreg/ns-mmreg-heaacwaveinfo_tag
|
// see https://docs.microsoft.com/en-us/windows/desktop/api/mmreg/ns-mmreg-heaacwaveinfo_tag
|
||||||
// for the meaning of the byte array below
|
// 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};
|
UINT8 aac_tmp[] = {0x01, 0x00, 0xfe, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x00, 0x00};
|
||||||
uint16_t tag = 0;
|
uint16_t tag = 0;
|
||||||
|
|
||||||
tmp = AudioCore::ParseADTS(buffer);
|
tmp = ParseADTS(buffer);
|
||||||
if (tmp.length == 0) {
|
if (tmp.length == 0) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
@ -216,7 +215,7 @@ std::optional<ADTSMeta> DetectMediaType(const u8* buffer, std::size_t len) {
|
|||||||
tag = MFGetAACTag(tmp);
|
tag = MFGetAACTag(tmp);
|
||||||
aac_tmp[12] |= (tag & 0xff00) >> 8;
|
aac_tmp[12] |= (tag & 0xff00) >> 8;
|
||||||
aac_tmp[13] |= (tag & 0x00ff);
|
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);
|
std::memcpy(&(result.AACTag), aac_tmp, 14);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ void ReportError(std::string msg, HRESULT hr);
|
|||||||
|
|
||||||
// data type for transferring ADTS metadata between functions
|
// data type for transferring ADTS metadata between functions
|
||||||
struct ADTSMeta {
|
struct ADTSMeta {
|
||||||
AudioCore::ADTSData ADTSHeader;
|
ADTSData ADTSHeader;
|
||||||
u8 AACTag[14];
|
u8 AACTag[14];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -110,10 +110,10 @@ bool InitMFDLL();
|
|||||||
unique_mfptr<IMFTransform> MFDecoderInit(GUID audio_format = MFAudioFormat_AAC);
|
unique_mfptr<IMFTransform> MFDecoderInit(GUID audio_format = MFAudioFormat_AAC);
|
||||||
unique_mfptr<IMFSample> CreateSample(const void* data, DWORD len, DWORD alignment = 1,
|
unique_mfptr<IMFSample> CreateSample(const void* data, DWORD len, DWORD alignment = 1,
|
||||||
LONGLONG duration = 0);
|
LONGLONG duration = 0);
|
||||||
bool SelectInputMediaType(IMFTransform* transform, int in_stream_id,
|
bool SelectInputMediaType(IMFTransform* transform, int in_stream_id, const ADTSData& adts,
|
||||||
const AudioCore::ADTSData& adts, const UINT8* user_data,
|
const UINT8* user_data, UINT32 user_data_len,
|
||||||
UINT32 user_data_len, GUID audio_format = MFAudioFormat_AAC);
|
GUID audio_format = MFAudioFormat_AAC);
|
||||||
std::optional<ADTSMeta> DetectMediaType(const u8* buffer, std::size_t len);
|
std::optional<ADTSMeta> DetectMediaType(char* buffer, std::size_t len);
|
||||||
bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id,
|
bool SelectOutputMediaType(IMFTransform* transform, int out_stream_id,
|
||||||
GUID audio_format = MFAudioFormat_PCM);
|
GUID audio_format = MFAudioFormat_PCM);
|
||||||
void MFFlush(IMFTransform* transform);
|
void MFFlush(IMFTransform* transform);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "common/detached_tasks.h"
|
#include "common/detached_tasks.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/backend.h"
|
#include "common/logging/backend.h"
|
||||||
|
#include "common/logging/filter.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
@ -27,15 +28,18 @@
|
|||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/dumping/backend.h"
|
#include "core/dumping/backend.h"
|
||||||
#include "core/dumping/ffmpeg_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/applets/default_applets.h"
|
||||||
#include "core/frontend/framebuffer_layout.h"
|
#include "core/frontend/framebuffer_layout.h"
|
||||||
|
#include "core/gdbstub/gdbstub.h"
|
||||||
#include "core/hle/service/am/am.h"
|
#include "core/hle/service/am/am.h"
|
||||||
#include "core/hle/service/cfg/cfg.h"
|
#include "core/hle/service/cfg/cfg.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
|
#include "video_core/video_core.h"
|
||||||
|
|
||||||
#undef _UNICODE
|
#undef _UNICODE
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -327,7 +331,7 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& movie = system.Movie();
|
auto& movie = Core::Movie::GetInstance();
|
||||||
|
|
||||||
if (!movie_record.empty()) {
|
if (!movie_record.empty()) {
|
||||||
movie.PrepareForRecording();
|
movie.PrepareForRecording();
|
||||||
|
@ -128,54 +128,16 @@ void EmuWindow_SDL2::InitializeSDL2() {
|
|||||||
SDL_SetMainReady();
|
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() {
|
void EmuWindow_SDL2::PollEvents() {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
std::vector<SDL_Event> other_window_events;
|
std::vector<SDL_Event> other_window_events;
|
||||||
|
|
||||||
// SDL_PollEvent returns 0 when there are no more events in the event queue
|
// SDL_PollEvent returns 0 when there are no more events in the event queue
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
if (GetEventWindowId(event) != render_window_id) {
|
if (event.window.windowID != render_window_id) {
|
||||||
other_window_events.push_back(event);
|
other_window_events.push_back(event);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
switch (event.window.event) {
|
switch (event.window.event) {
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
|
|
||||||
union SDL_Event;
|
|
||||||
struct SDL_Window;
|
struct SDL_Window;
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
@ -36,9 +35,6 @@ public:
|
|||||||
void RequestClose();
|
void RequestClose();
|
||||||
|
|
||||||
protected:
|
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.
|
/// Called by PollEvents when a key is pressed or released.
|
||||||
void OnKeyEvent(int key, u8 state);
|
void OnKeyEvent(int key, u8 state);
|
||||||
|
|
||||||
|
@ -341,6 +341,10 @@ if (USE_DISCORD_PRESENCE)
|
|||||||
target_compile_definitions(citra-qt PRIVATE -DUSE_DISCORD_PRESENCE)
|
target_compile_definitions(citra-qt PRIVATE -DUSE_DISCORD_PRESENCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (ENABLE_WEB_SERVICE)
|
||||||
|
target_compile_definitions(citra-qt PRIVATE -DENABLE_WEB_SERVICE)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
install(TARGETS citra-qt RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
|
install(TARGETS citra-qt RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
|
||||||
endif()
|
endif()
|
||||||
|
@ -67,5 +67,6 @@ void QtMiiSelector::OpenDialog() {
|
|||||||
dialog.return_code, index);
|
dialog.return_code, index);
|
||||||
|
|
||||||
const auto mii_data = dialog.miis.at(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{});
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ private:
|
|||||||
QVBoxLayout* layout;
|
QVBoxLayout* layout;
|
||||||
QtMiiSelector* mii_selector;
|
QtMiiSelector* mii_selector;
|
||||||
u32 return_code = 0;
|
u32 return_code = 0;
|
||||||
std::vector<Mii::MiiData> miis;
|
std::vector<HLE::Applets::MiiData> miis;
|
||||||
|
|
||||||
friend class QtMiiSelector;
|
friend class QtMiiSelector;
|
||||||
};
|
};
|
||||||
|
@ -387,6 +387,10 @@ GRenderWindow::GRenderWindow(QWidget* parent_, EmuThread* emu_thread_, Core::Sys
|
|||||||
bool is_secondary_)
|
bool is_secondary_)
|
||||||
: QWidget(parent_), EmuWindow(is_secondary_), emu_thread(emu_thread_), system{system_} {
|
: 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);
|
setAttribute(Qt::WA_AcceptTouchEvents);
|
||||||
auto layout = new QHBoxLayout(this);
|
auto layout = new QHBoxLayout(this);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "citra_qt/compatdb.h"
|
#include "citra_qt/compatdb.h"
|
||||||
#include "common/telemetry.h"
|
#include "common/telemetry.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "ui_compatdb.h"
|
#include "ui_compatdb.h"
|
||||||
|
|
||||||
CompatDB::CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent)
|
CompatDB::CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent)
|
||||||
|
@ -29,7 +29,7 @@ Config::~Config() {
|
|||||||
const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = {
|
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_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_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{{
|
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_hide_no_icon);
|
||||||
ReadBasicSetting(UISettings::values.game_list_single_line_mode);
|
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();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1235,11 +1230,6 @@ void Config::SaveUIGameListValues() {
|
|||||||
WriteBasicSetting(UISettings::values.game_list_hide_no_icon);
|
WriteBasicSetting(UISettings::values.game_list_hide_no_icon);
|
||||||
WriteBasicSetting(UISettings::values.game_list_single_line_mode);
|
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();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,68 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>-1</number>
|
<number>0</number>
|
||||||
</property>
|
</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>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -10,13 +10,14 @@
|
|||||||
#include "citra_qt/configuration/configuration_shared.h"
|
#include "citra_qt/configuration/configuration_shared.h"
|
||||||
#include "citra_qt/configuration/configure_audio.h"
|
#include "citra_qt/configuration/configure_audio.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "ui_configure_audio.h"
|
#include "ui_configure_audio.h"
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include "common/apple_authorization.h"
|
#include "common/apple_authorization.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ConfigureAudio::ConfigureAudio(bool is_powered_on, QWidget* parent)
|
ConfigureAudio::ConfigureAudio(QWidget* parent)
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()) {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
@ -26,7 +27,8 @@ ConfigureAudio::ConfigureAudio(bool is_powered_on, QWidget* parent)
|
|||||||
AudioCore::GetSinkName(static_cast<AudioCore::SinkType>(type)).data()));
|
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,
|
connect(ui->volume_slider, &QSlider::valueChanged, this,
|
||||||
&ConfigureAudio::SetVolumeIndicatorText);
|
&ConfigureAudio::SetVolumeIndicatorText);
|
||||||
|
@ -19,7 +19,7 @@ class ConfigureAudio : public QWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigureAudio(bool is_powered_on, QWidget* parent = nullptr);
|
explicit ConfigureAudio(QWidget* parent = nullptr);
|
||||||
~ConfigureAudio() override;
|
~ConfigureAudio() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration();
|
||||||
|
@ -47,7 +47,8 @@ ConfigureCamera::~ConfigureCamera() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureCamera::ConnectEvents() {
|
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) {
|
[this](int index) {
|
||||||
StopPreviewing();
|
StopPreviewing();
|
||||||
UpdateImageSourceUI();
|
UpdateImageSourceUI();
|
||||||
@ -57,33 +58,36 @@ void ConfigureCamera::ConnectEvents() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
connect(ui->camera_selection, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
|
connect(ui->camera_selection,
|
||||||
StopPreviewing();
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [this] {
|
||||||
if (GetCameraSelection() != current_selected) {
|
StopPreviewing();
|
||||||
RecordConfig();
|
if (GetCameraSelection() != current_selected) {
|
||||||
}
|
RecordConfig();
|
||||||
if (ui->camera_selection->currentIndex() == 1) {
|
}
|
||||||
ui->camera_mode->setCurrentIndex(1); // Double
|
if (ui->camera_selection->currentIndex() == 1) {
|
||||||
if (camera_name[0] == camera_name[2] && camera_config[0] == camera_config[2]) {
|
ui->camera_mode->setCurrentIndex(1); // Double
|
||||||
ui->camera_mode->setCurrentIndex(0); // Single
|
if (camera_name[0] == camera_name[2] && camera_config[0] == camera_config[2]) {
|
||||||
}
|
ui->camera_mode->setCurrentIndex(0); // Single
|
||||||
}
|
}
|
||||||
UpdateCameraMode();
|
}
|
||||||
SetConfiguration();
|
UpdateCameraMode();
|
||||||
});
|
SetConfiguration();
|
||||||
connect(ui->camera_mode, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
|
});
|
||||||
StopPreviewing();
|
connect(ui->camera_mode, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||||
ui->camera_position_label->setVisible(ui->camera_mode->currentIndex() == 1);
|
this, [this] {
|
||||||
ui->camera_position->setVisible(ui->camera_mode->currentIndex() == 1);
|
StopPreviewing();
|
||||||
current_selected = GetCameraSelection();
|
ui->camera_position_label->setVisible(ui->camera_mode->currentIndex() == 1);
|
||||||
});
|
ui->camera_position->setVisible(ui->camera_mode->currentIndex() == 1);
|
||||||
connect(ui->camera_position, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
|
current_selected = GetCameraSelection();
|
||||||
StopPreviewing();
|
});
|
||||||
if (GetCameraSelection() != current_selected) {
|
connect(ui->camera_position,
|
||||||
RecordConfig();
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [this] {
|
||||||
}
|
StopPreviewing();
|
||||||
SetConfiguration();
|
if (GetCameraSelection() != current_selected) {
|
||||||
});
|
RecordConfig();
|
||||||
|
}
|
||||||
|
SetConfiguration();
|
||||||
|
});
|
||||||
connect(ui->toolButton, &QToolButton::clicked, this, &ConfigureCamera::OnToolButtonClicked);
|
connect(ui->toolButton, &QToolButton::clicked, this, &ConfigureCamera::OnToolButtonClicked);
|
||||||
connect(ui->preview_button, &QPushButton::clicked, this, [this] { StartPreviewing(); });
|
connect(ui->preview_button, &QPushButton::clicked, this, [this] { StartPreviewing(); });
|
||||||
connect(ui->prompt_before_load, &QCheckBox::stateChanged, this, [this](int state) {
|
connect(ui->prompt_before_load, &QCheckBox::stateChanged, this, [this](int state) {
|
||||||
|
@ -9,9 +9,11 @@
|
|||||||
#include "core/cheats/cheat_base.h"
|
#include "core/cheats/cheat_base.h"
|
||||||
#include "core/cheats/cheats.h"
|
#include "core/cheats/cheats.h"
|
||||||
#include "core/cheats/gateway_cheat.h"
|
#include "core/cheats/gateway_cheat.h"
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/hle/kernel/process.h"
|
||||||
#include "ui_configure_cheats.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_} {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureCheats>()), title_id{title_id_} {
|
||||||
// Setup gui control settings
|
// Setup gui control settings
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@ -34,7 +36,7 @@ ConfigureCheats::ConfigureCheats(Core::System& system, u64 title_id_, QWidget* p
|
|||||||
[this] { SaveCheat(ui->tableCheats->currentRow()); });
|
[this] { SaveCheat(ui->tableCheats->currentRow()); });
|
||||||
connect(ui->buttonDelete, &QPushButton::clicked, this, &ConfigureCheats::OnDeleteCheat);
|
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();
|
LoadCheats();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QWidget>
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Cheats {
|
namespace Cheats {
|
||||||
@ -13,10 +12,6 @@ class CheatBase;
|
|||||||
class CheatEngine;
|
class CheatEngine;
|
||||||
} // namespace Cheats
|
} // namespace Cheats
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ConfigureCheats;
|
class ConfigureCheats;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
@ -25,7 +20,7 @@ class ConfigureCheats : public QWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigureCheats(Core::System& system, u64 title_id, QWidget* parent = nullptr);
|
explicit ConfigureCheats(u64 title_id_, QWidget* parent = nullptr);
|
||||||
~ConfigureCheats();
|
~ConfigureCheats();
|
||||||
bool ApplyConfiguration();
|
bool ApplyConfiguration();
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/backend.h"
|
#include "common/logging/backend.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "ui_configure_debug.h"
|
#include "ui_configure_debug.h"
|
||||||
|
|
||||||
// The QSlider doesn't have an easy way to set a custom step amount,
|
// 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;
|
return (value - 5) / 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureDebug::ConfigureDebug(bool is_powered_on_, QWidget* parent)
|
ConfigureDebug::ConfigureDebug(QWidget* parent)
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureDebug>()), is_powered_on{is_powered_on_} {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureDebug>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ ConfigureDebug::ConfigureDebug(bool is_powered_on_, QWidget* parent)
|
|||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const bool is_powered_on = Core::System::GetInstance().IsPoweredOn();
|
||||||
ui->toggle_cpu_jit->setEnabled(!is_powered_on);
|
ui->toggle_cpu_jit->setEnabled(!is_powered_on);
|
||||||
ui->toggle_renderer_debug->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->toggle_gdbstub->setChecked(Settings::values.use_gdbstub.GetValue());
|
||||||
ui->gdbport_spinbox->setEnabled(Settings::values.use_gdbstub.GetValue());
|
ui->gdbport_spinbox->setEnabled(Settings::values.use_gdbstub.GetValue());
|
||||||
ui->gdbport_spinbox->setValue(Settings::values.gdbstub_port.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->toggle_console->setChecked(UISettings::values.show_console.GetValue());
|
||||||
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue()));
|
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue()));
|
||||||
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue());
|
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue());
|
||||||
|
@ -15,7 +15,7 @@ class ConfigureDebug : public QWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigureDebug(bool is_powered_on, QWidget* parent = nullptr);
|
explicit ConfigureDebug(QWidget* parent = nullptr);
|
||||||
~ConfigureDebug() override;
|
~ConfigureDebug() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration();
|
||||||
@ -25,5 +25,4 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::ConfigureDebug> ui;
|
std::unique_ptr<Ui::ConfigureDebug> ui;
|
||||||
bool is_powered_on;
|
|
||||||
};
|
};
|
||||||
|
@ -4,19 +4,8 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <QListWidgetItem>
|
#include <QListWidgetItem>
|
||||||
#include "citra_qt/configuration/configure_audio.h"
|
#include "citra_qt/configuration/config.h"
|
||||||
#include "citra_qt/configuration/configure_camera.h"
|
|
||||||
#include "citra_qt/configuration/configure_debug.h"
|
|
||||||
#include "citra_qt/configuration/configure_dialog.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 "citra_qt/hotkeys.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
@ -25,41 +14,16 @@
|
|||||||
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, Core::System& system_,
|
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, Core::System& system_,
|
||||||
bool enable_web_config)
|
bool enable_web_config)
|
||||||
: QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, registry{registry_},
|
: QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, registry{registry_},
|
||||||
system{system_}, is_powered_on{system.IsPoweredOn()},
|
system{system_} {
|
||||||
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)} {
|
|
||||||
Settings::SetConfiguringGlobal(true);
|
Settings::SetConfiguringGlobal(true);
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
ui->hotkeysTab->Populate(registry);
|
||||||
ui->tabWidget->addTab(general_tab.get(), tr("General"));
|
ui->webTab->SetWebServiceConfigEnabled(enable_web_config);
|
||||||
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);
|
|
||||||
|
|
||||||
PopulateSelectionList();
|
PopulateSelectionList();
|
||||||
|
|
||||||
connect(ui_tab.get(), &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged);
|
connect(ui->uiTab, &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged);
|
||||||
connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
|
connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
|
||||||
&ConfigureDialog::UpdateVisibleTabs);
|
&ConfigureDialog::UpdateVisibleTabs);
|
||||||
|
|
||||||
@ -67,46 +31,46 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, Cor
|
|||||||
ui->selectorList->setCurrentRow(0);
|
ui->selectorList->setCurrentRow(0);
|
||||||
|
|
||||||
// Set up used key list synchronisation
|
// Set up used key list synchronisation
|
||||||
connect(input_tab.get(), &ConfigureInput::InputKeysChanged, hotkeys_tab.get(),
|
connect(ui->inputTab, &ConfigureInput::InputKeysChanged, ui->hotkeysTab,
|
||||||
&ConfigureHotkeys::OnInputKeysChanged);
|
&ConfigureHotkeys::OnInputKeysChanged);
|
||||||
connect(hotkeys_tab.get(), &ConfigureHotkeys::HotkeysChanged, input_tab.get(),
|
connect(ui->hotkeysTab, &ConfigureHotkeys::HotkeysChanged, ui->inputTab,
|
||||||
&ConfigureInput::OnHotkeysChanged);
|
&ConfigureInput::OnHotkeysChanged);
|
||||||
|
|
||||||
// Synchronise lists upon initialisation
|
// Synchronise lists upon initialisation
|
||||||
input_tab->EmitInputKeysChanged();
|
ui->inputTab->EmitInputKeysChanged();
|
||||||
hotkeys_tab->EmitHotkeysChanged();
|
ui->hotkeysTab->EmitHotkeysChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigureDialog::~ConfigureDialog() = default;
|
ConfigureDialog::~ConfigureDialog() = default;
|
||||||
|
|
||||||
void ConfigureDialog::SetConfiguration() {
|
void ConfigureDialog::SetConfiguration() {
|
||||||
general_tab->SetConfiguration();
|
ui->generalTab->SetConfiguration();
|
||||||
system_tab->SetConfiguration();
|
ui->systemTab->SetConfiguration();
|
||||||
input_tab->LoadConfiguration();
|
ui->inputTab->LoadConfiguration();
|
||||||
graphics_tab->SetConfiguration();
|
ui->graphicsTab->SetConfiguration();
|
||||||
enhancements_tab->SetConfiguration();
|
ui->enhancementsTab->SetConfiguration();
|
||||||
audio_tab->SetConfiguration();
|
ui->audioTab->SetConfiguration();
|
||||||
camera_tab->SetConfiguration();
|
ui->cameraTab->SetConfiguration();
|
||||||
debug_tab->SetConfiguration();
|
ui->debugTab->SetConfiguration();
|
||||||
web_tab->SetConfiguration();
|
ui->webTab->SetConfiguration();
|
||||||
ui_tab->SetConfiguration();
|
ui->uiTab->SetConfiguration();
|
||||||
storage_tab->SetConfiguration();
|
ui->storageTab->SetConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureDialog::ApplyConfiguration() {
|
void ConfigureDialog::ApplyConfiguration() {
|
||||||
general_tab->ApplyConfiguration();
|
ui->generalTab->ApplyConfiguration();
|
||||||
system_tab->ApplyConfiguration();
|
ui->systemTab->ApplyConfiguration();
|
||||||
input_tab->ApplyConfiguration();
|
ui->inputTab->ApplyConfiguration();
|
||||||
input_tab->ApplyProfile();
|
ui->inputTab->ApplyProfile();
|
||||||
hotkeys_tab->ApplyConfiguration(registry);
|
ui->hotkeysTab->ApplyConfiguration(registry);
|
||||||
graphics_tab->ApplyConfiguration();
|
ui->graphicsTab->ApplyConfiguration();
|
||||||
enhancements_tab->ApplyConfiguration();
|
ui->enhancementsTab->ApplyConfiguration();
|
||||||
audio_tab->ApplyConfiguration();
|
ui->audioTab->ApplyConfiguration();
|
||||||
camera_tab->ApplyConfiguration();
|
ui->cameraTab->ApplyConfiguration();
|
||||||
debug_tab->ApplyConfiguration();
|
ui->debugTab->ApplyConfiguration();
|
||||||
web_tab->ApplyConfiguration();
|
ui->webTab->ApplyConfiguration();
|
||||||
ui_tab->ApplyConfiguration();
|
ui->uiTab->ApplyConfiguration();
|
||||||
storage_tab->ApplyConfiguration();
|
ui->storageTab->ApplyConfiguration();
|
||||||
system.ApplySettings();
|
system.ApplySettings();
|
||||||
Settings::LogSettings();
|
Settings::LogSettings();
|
||||||
}
|
}
|
||||||
@ -117,11 +81,11 @@ void ConfigureDialog::PopulateSelectionList() {
|
|||||||
ui->selectorList->clear();
|
ui->selectorList->clear();
|
||||||
|
|
||||||
const std::array<std::pair<QString, QList<QWidget*>>, 5> items{
|
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("General"), {ui->generalTab, ui->webTab, ui->debugTab, ui->uiTab}},
|
||||||
{tr("System"), {system_tab.get(), camera_tab.get(), storage_tab.get()}},
|
{tr("System"), {ui->systemTab, ui->cameraTab, ui->storageTab}},
|
||||||
{tr("Graphics"), {enhancements_tab.get(), graphics_tab.get()}},
|
{tr("Graphics"), {ui->enhancementsTab, ui->graphicsTab}},
|
||||||
{tr("Audio"), {audio_tab.get()}},
|
{tr("Audio"), {ui->audioTab}},
|
||||||
{tr("Controls"), {input_tab.get(), hotkeys_tab.get()}}}};
|
{tr("Controls"), {ui->inputTab, ui->hotkeysTab}}}};
|
||||||
|
|
||||||
for (const auto& entry : items) {
|
for (const auto& entry : items) {
|
||||||
auto* const item = new QListWidgetItem(entry.first);
|
auto* const item = new QListWidgetItem(entry.first);
|
||||||
@ -148,18 +112,18 @@ void ConfigureDialog::RetranslateUI() {
|
|||||||
ui->selectorList->setCurrentRow(old_row);
|
ui->selectorList->setCurrentRow(old_row);
|
||||||
ui->tabWidget->setCurrentIndex(old_index);
|
ui->tabWidget->setCurrentIndex(old_index);
|
||||||
|
|
||||||
general_tab->RetranslateUI();
|
ui->generalTab->RetranslateUI();
|
||||||
system_tab->RetranslateUI();
|
ui->systemTab->RetranslateUI();
|
||||||
input_tab->RetranslateUI();
|
ui->inputTab->RetranslateUI();
|
||||||
hotkeys_tab->RetranslateUI();
|
ui->hotkeysTab->RetranslateUI();
|
||||||
graphics_tab->RetranslateUI();
|
ui->graphicsTab->RetranslateUI();
|
||||||
enhancements_tab->RetranslateUI();
|
ui->enhancementsTab->RetranslateUI();
|
||||||
audio_tab->RetranslateUI();
|
ui->audioTab->RetranslateUI();
|
||||||
camera_tab->RetranslateUI();
|
ui->cameraTab->RetranslateUI();
|
||||||
debug_tab->RetranslateUI();
|
ui->debugTab->RetranslateUI();
|
||||||
web_tab->RetranslateUI();
|
ui->webTab->RetranslateUI();
|
||||||
ui_tab->RetranslateUI();
|
ui->uiTab->RetranslateUI();
|
||||||
storage_tab->RetranslateUI();
|
ui->storageTab->RetranslateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureDialog::UpdateVisibleTabs() {
|
void ConfigureDialog::UpdateVisibleTabs() {
|
||||||
@ -167,18 +131,18 @@ void ConfigureDialog::UpdateVisibleTabs() {
|
|||||||
if (items.isEmpty())
|
if (items.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::map<QWidget*, QString> widgets = {{general_tab.get(), tr("General")},
|
const std::map<QWidget*, QString> widgets = {{ui->generalTab, tr("General")},
|
||||||
{system_tab.get(), tr("System")},
|
{ui->systemTab, tr("System")},
|
||||||
{input_tab.get(), tr("Input")},
|
{ui->inputTab, tr("Input")},
|
||||||
{hotkeys_tab.get(), tr("Hotkeys")},
|
{ui->hotkeysTab, tr("Hotkeys")},
|
||||||
{enhancements_tab.get(), tr("Enhancements")},
|
{ui->enhancementsTab, tr("Enhancements")},
|
||||||
{graphics_tab.get(), tr("Advanced")},
|
{ui->graphicsTab, tr("Advanced")},
|
||||||
{audio_tab.get(), tr("Audio")},
|
{ui->audioTab, tr("Audio")},
|
||||||
{camera_tab.get(), tr("Camera")},
|
{ui->cameraTab, tr("Camera")},
|
||||||
{debug_tab.get(), tr("Debug")},
|
{ui->debugTab, tr("Debug")},
|
||||||
{storage_tab.get(), tr("Storage")},
|
{ui->storageTab, tr("Storage")},
|
||||||
{web_tab.get(), tr("Web")},
|
{ui->webTab, tr("Web")},
|
||||||
{ui_tab.get(), tr("UI")}};
|
{ui->uiTab, tr("UI")}};
|
||||||
|
|
||||||
ui->tabWidget->clear();
|
ui->tabWidget->clear();
|
||||||
|
|
||||||
|
@ -17,19 +17,6 @@ namespace Core {
|
|||||||
class System;
|
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 {
|
class ConfigureDialog : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -55,18 +42,4 @@ private:
|
|||||||
std::unique_ptr<Ui::ConfigureDialog> ui;
|
std::unique_ptr<Ui::ConfigureDialog> ui;
|
||||||
HotkeyRegistry& registry;
|
HotkeyRegistry& registry;
|
||||||
Core::System& system;
|
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;
|
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,8 @@ ConfigureEnhancements::ConfigureEnhancements(QWidget* parent)
|
|||||||
const bool res_scale_enabled = graphics_api != Settings::GraphicsAPI::Software;
|
const bool res_scale_enabled = graphics_api != Settings::GraphicsAPI::Software;
|
||||||
ui->resolution_factor_combobox->setEnabled(res_scale_enabled);
|
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) {
|
[this](int currentIndex) {
|
||||||
updateShaders(static_cast<Settings::StereoRenderOption>(currentIndex));
|
updateShaders(static_cast<Settings::StereoRenderOption>(currentIndex));
|
||||||
});
|
});
|
||||||
|
@ -6,14 +6,14 @@
|
|||||||
#include "citra_qt/configuration/configuration_shared.h"
|
#include "citra_qt/configuration/configuration_shared.h"
|
||||||
#include "citra_qt/configuration/configure_graphics.h"
|
#include "citra_qt/configuration/configure_graphics.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "ui_configure_graphics.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>()) {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureGraphics>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
ui->toggle_vsync_new->setEnabled(!is_powered_on);
|
ui->toggle_vsync_new->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||||
ui->graphics_api_combo->setEnabled(!is_powered_on);
|
|
||||||
// Set the index to -1 to ensure the below lambda is called with setCurrentIndex
|
// Set the index to -1 to ensure the below lambda is called with setCurrentIndex
|
||||||
ui->graphics_api_combo->setCurrentIndex(-1);
|
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] {
|
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();
|
const bool checked = ui->toggle_hw_shader->isChecked();
|
||||||
ui->hw_shader_group->setEnabled(checked && enabled);
|
ui->hw_shader_group->setEnabled(checked);
|
||||||
ui->toggle_disk_shader_cache->setEnabled(checked && enabled);
|
ui->toggle_disk_shader_cache->setEnabled(checked);
|
||||||
});
|
});
|
||||||
|
|
||||||
SetupPerGameUI();
|
SetupPerGameUI();
|
||||||
|
@ -19,7 +19,7 @@ class ConfigureGraphics : public QWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigureGraphics(bool is_powered_on, QWidget* parent = nullptr);
|
explicit ConfigureGraphics(QWidget* parent = nullptr);
|
||||||
~ConfigureGraphics() override;
|
~ConfigureGraphics() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration();
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="accessibleName">
|
|
||||||
<string>Graphics</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="apiBox">
|
<widget class="QGroupBox" name="apiBox">
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "citra_qt/configuration/configure_hotkeys.h"
|
#include "citra_qt/configuration/configure_hotkeys.h"
|
||||||
#include "citra_qt/hotkeys.h"
|
#include "citra_qt/hotkeys.h"
|
||||||
#include "citra_qt/util/sequence_dialog/sequence_dialog.h"
|
#include "citra_qt/util/sequence_dialog/sequence_dialog.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "ui_configure_hotkeys.h"
|
#include "ui_configure_hotkeys.h"
|
||||||
|
|
||||||
constexpr int name_column = 0;
|
constexpr int name_column = 0;
|
||||||
@ -188,9 +189,9 @@ void ConfigureHotkeys::PopupContextMenu(const QPoint& menu_location) {
|
|||||||
QAction* clear = context_menu.addAction(tr("Clear"));
|
QAction* clear = context_menu.addAction(tr("Clear"));
|
||||||
|
|
||||||
const auto hotkey_index = index.sibling(index.row(), hotkey_column);
|
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); });
|
[this, hotkey_index] { RestoreHotkey(hotkey_index); });
|
||||||
connect(clear, &QAction::triggered, this,
|
connect(clear, &QAction::triggered,
|
||||||
[this, hotkey_index] { model->setData(hotkey_index, QString{}); });
|
[this, hotkey_index] { model->setData(hotkey_index, QString{}); });
|
||||||
|
|
||||||
context_menu.exec(ui->hotkey_list->viewport()->mapToGlobal(menu_location));
|
context_menu.exec(ui->hotkey_list->viewport()->mapToGlobal(menu_location));
|
||||||
|
@ -162,7 +162,7 @@ ConfigureInput::ConfigureInput(QWidget* parent)
|
|||||||
ui->buttonDpadUp, ui->buttonDpadDown, ui->buttonDpadLeft, ui->buttonDpadRight,
|
ui->buttonDpadUp, ui->buttonDpadDown, ui->buttonDpadLeft, ui->buttonDpadRight,
|
||||||
ui->buttonL, ui->buttonR, ui->buttonStart, ui->buttonSelect,
|
ui->buttonL, ui->buttonR, ui->buttonStart, ui->buttonSelect,
|
||||||
ui->buttonDebug, ui->buttonGpio14, ui->buttonZL, ui->buttonZR,
|
ui->buttonDebug, ui->buttonGpio14, ui->buttonZL, ui->buttonZR,
|
||||||
ui->buttonHome, ui->buttonPower,
|
ui->buttonHome,
|
||||||
};
|
};
|
||||||
|
|
||||||
analog_map_buttons = {{
|
analog_map_buttons = {{
|
||||||
|
@ -305,24 +305,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<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">
|
<layout class="QVBoxLayout" name="verticalLayout_28">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_36">
|
<widget class="QLabel" name="label_36">
|
||||||
@ -358,7 +340,7 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="2" column="0">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_32">
|
<layout class="QVBoxLayout" name="verticalLayout_32">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_40">
|
<widget class="QLabel" name="label_40">
|
||||||
|
@ -27,18 +27,16 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString
|
|||||||
Core::System& system_)
|
Core::System& system_)
|
||||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()),
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()),
|
||||||
filename{file_name.toStdString()}, title_id{title_id_}, system{system_} {
|
filename{file_name.toStdString()}, title_id{title_id_}, system{system_} {
|
||||||
const auto config_file_name = title_id == 0 ? std::string(FileUtil::GetFilename(filename))
|
const auto config_file_name = title_id == 0 ? filename : fmt::format("{:016X}", title_id);
|
||||||
: fmt::format("{:016X}", title_id);
|
|
||||||
game_config = std::make_unique<Config>(config_file_name, Config::ConfigType::PerGameConfig);
|
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>(this);
|
||||||
audio_tab = std::make_unique<ConfigureAudio>(is_powered_on, this);
|
|
||||||
general_tab = std::make_unique<ConfigureGeneral>(this);
|
general_tab = std::make_unique<ConfigureGeneral>(this);
|
||||||
enhancements_tab = std::make_unique<ConfigureEnhancements>(this);
|
enhancements_tab = std::make_unique<ConfigureEnhancements>(this);
|
||||||
graphics_tab = std::make_unique<ConfigureGraphics>(is_powered_on, this);
|
graphics_tab = std::make_unique<ConfigureGraphics>(this);
|
||||||
system_tab = std::make_unique<ConfigureSystem>(system, this);
|
system_tab = std::make_unique<ConfigureSystem>(this);
|
||||||
debug_tab = std::make_unique<ConfigureDebug>(is_powered_on, this);
|
debug_tab = std::make_unique<ConfigureDebug>(this);
|
||||||
cheat_tab = std::make_unique<ConfigureCheats>(system, title_id, this);
|
cheat_tab = std::make_unique<ConfigureCheats>(title_id, this);
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include "citra_qt/configuration/configure_storage.h"
|
#include "citra_qt/configuration/configure_storage.h"
|
||||||
#include "common/file_util.h"
|
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "ui_configure_storage.h"
|
#include "ui_configure_storage.h"
|
||||||
|
|
||||||
ConfigureStorage::ConfigureStorage(bool is_powered_on_, QWidget* parent)
|
ConfigureStorage::ConfigureStorage(QWidget* parent)
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureStorage>()), is_powered_on{is_powered_on_} {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureStorage>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ void ConfigureStorage::SetConfiguration() {
|
|||||||
ui->toggle_virtual_sd->setChecked(Settings::values.use_virtual_sd.GetValue());
|
ui->toggle_virtual_sd->setChecked(Settings::values.use_virtual_sd.GetValue());
|
||||||
ui->toggle_custom_storage->setChecked(Settings::values.use_custom_storage.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() {
|
void ConfigureStorage::ApplyConfiguration() {
|
||||||
|
@ -15,7 +15,7 @@ class ConfigureStorage : public QWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigureStorage(bool is_powered_on, QWidget* parent = nullptr);
|
explicit ConfigureStorage(QWidget* parent = nullptr);
|
||||||
~ConfigureStorage() override;
|
~ConfigureStorage() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration();
|
||||||
@ -23,5 +23,4 @@ public:
|
|||||||
void SetConfiguration();
|
void SetConfiguration();
|
||||||
|
|
||||||
std::unique_ptr<Ui::ConfigureStorage> ui;
|
std::unique_ptr<Ui::ConfigureStorage> ui;
|
||||||
bool is_powered_on;
|
|
||||||
};
|
};
|
||||||
|
@ -223,12 +223,14 @@ static const std::array<const char*, 187> country_names = {
|
|||||||
QT_TRANSLATE_NOOP("ConfigureSystem", "Bermuda"), // 180-186
|
QT_TRANSLATE_NOOP("ConfigureSystem", "Bermuda"), // 180-186
|
||||||
};
|
};
|
||||||
|
|
||||||
ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
|
ConfigureSystem::ConfigureSystem(QWidget* parent)
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureSystem>()), system{system_} {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureSystem>()) {
|
||||||
ui->setupUi(this);
|
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);
|
&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);
|
&ConfigureSystem::UpdateInitTime);
|
||||||
connect(ui->button_regenerate_console_id, &QPushButton::clicked, this,
|
connect(ui->button_regenerate_console_id, &QPushButton::clicked, this,
|
||||||
&ConfigureSystem::RefreshConsoleID);
|
&ConfigureSystem::RefreshConsoleID);
|
||||||
@ -278,7 +280,7 @@ ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
|
|||||||
ConfigureSystem::~ConfigureSystem() = default;
|
ConfigureSystem::~ConfigureSystem() = default;
|
||||||
|
|
||||||
void ConfigureSystem::SetConfiguration() {
|
void ConfigureSystem::SetConfiguration() {
|
||||||
enabled = !system.IsPoweredOn();
|
enabled = !Core::System::GetInstance().IsPoweredOn();
|
||||||
|
|
||||||
ui->combo_init_clock->setCurrentIndex(static_cast<u8>(Settings::values.init_clock.GetValue()));
|
ui->combo_init_clock->setCurrentIndex(static_cast<u8>(Settings::values.init_clock.GetValue()));
|
||||||
QDateTime date_time;
|
QDateTime date_time;
|
||||||
@ -294,7 +296,7 @@ void ConfigureSystem::SetConfiguration() {
|
|||||||
ui->edit_init_time_offset_time->setTime(time);
|
ui->edit_init_time_offset_time->setTime(time);
|
||||||
|
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
cfg = Service::CFG::GetModule(system);
|
cfg = Service::CFG::GetModule(Core::System::GetInstance());
|
||||||
ASSERT_MSG(cfg, "CFG Module missing!");
|
ASSERT_MSG(cfg, "CFG Module missing!");
|
||||||
ReadSystemSettings();
|
ReadSystemSettings();
|
||||||
ui->group_system_settings->setEnabled(false);
|
ui->group_system_settings->setEnabled(false);
|
||||||
|
@ -16,10 +16,6 @@ namespace ConfigurationShared {
|
|||||||
enum class CheckState;
|
enum class CheckState;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Service {
|
namespace Service {
|
||||||
namespace CFG {
|
namespace CFG {
|
||||||
class Module;
|
class Module;
|
||||||
@ -30,7 +26,7 @@ class ConfigureSystem : public QWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigureSystem(Core::System& system, QWidget* parent = nullptr);
|
explicit ConfigureSystem(QWidget* parent = nullptr);
|
||||||
~ConfigureSystem() override;
|
~ConfigureSystem() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration();
|
||||||
@ -49,10 +45,8 @@ private:
|
|||||||
|
|
||||||
void DownloadFromNUS();
|
void DownloadFromNUS();
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<Ui::ConfigureSystem> ui;
|
|
||||||
Core::System& system;
|
|
||||||
ConfigurationShared::CheckState is_new_3ds;
|
ConfigurationShared::CheckState is_new_3ds;
|
||||||
|
std::unique_ptr<Ui::ConfigureSystem> ui;
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
|
|
||||||
std::shared_ptr<Service::CFG::Module> cfg;
|
std::shared_ptr<Service::CFG::Module> cfg;
|
||||||
|
@ -167,7 +167,8 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) {
|
|||||||
const auto format = texture.format;
|
const auto format = texture.format;
|
||||||
|
|
||||||
const auto info = Pica::Texture::TextureInfo::FromPicaRegister(config, format);
|
const auto info = Pica::Texture::TextureInfo::FromPicaRegister(config, format);
|
||||||
const u8* src = system.Memory().GetPhysicalPointer(config.GetPhysicalAddress());
|
const u8* src =
|
||||||
|
Core::System::GetInstance().Memory().GetPhysicalPointer(config.GetPhysicalAddress());
|
||||||
new_info_widget = new TextureInfoWidget(src, info);
|
new_info_widget = new TextureInfoWidget(src, info);
|
||||||
}
|
}
|
||||||
if (command_info_widget) {
|
if (command_info_widget) {
|
||||||
@ -181,8 +182,8 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) {
|
|||||||
}
|
}
|
||||||
#undef COMMAND_IN_RANGE
|
#undef COMMAND_IN_RANGE
|
||||||
|
|
||||||
GPUCommandListWidget::GPUCommandListWidget(Core::System& system_, QWidget* parent)
|
GPUCommandListWidget::GPUCommandListWidget(QWidget* parent)
|
||||||
: QDockWidget(tr("Pica Command List"), parent), system{system_} {
|
: QDockWidget(tr("Pica Command List"), parent) {
|
||||||
setObjectName(QStringLiteral("Pica Command List"));
|
setObjectName(QStringLiteral("Pica Command List"));
|
||||||
GPUCommandListModel* model = new GPUCommandListModel(this);
|
GPUCommandListModel* model = new GPUCommandListModel(this);
|
||||||
|
|
||||||
|
@ -7,14 +7,11 @@
|
|||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include "video_core/debug_utils/debug_utils.h"
|
#include "video_core/debug_utils/debug_utils.h"
|
||||||
|
#include "video_core/gpu_debugger.h"
|
||||||
|
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QTreeView;
|
class QTreeView;
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
class GPUCommandListModel : public QAbstractListModel {
|
class GPUCommandListModel : public QAbstractListModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -42,7 +39,7 @@ class GPUCommandListWidget : public QDockWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GPUCommandListWidget(Core::System& system, QWidget* parent = nullptr);
|
explicit GPUCommandListWidget(QWidget* parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnToggleTracing();
|
void OnToggleTracing();
|
||||||
@ -57,7 +54,7 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Pica::DebugUtils::PicaTrace> pica_trace;
|
std::unique_ptr<Pica::DebugUtils::PicaTrace> pica_trace;
|
||||||
Core::System& system;
|
|
||||||
QTreeView* list_widget;
|
QTreeView* list_widget;
|
||||||
QWidget* command_info_widget;
|
QWidget* command_info_widget;
|
||||||
QPushButton* toggle_tracing;
|
QPushButton* toggle_tracing;
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include "citra_qt/debugger/graphics/graphics_surface.h"
|
#include "citra_qt/debugger/graphics/graphics_surface.h"
|
||||||
#include "citra_qt/util/spinbox.h"
|
#include "citra_qt/util/spinbox.h"
|
||||||
#include "common/color.h"
|
#include "common/color.h"
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/hw/gpu.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "video_core/pica_state.h"
|
#include "video_core/pica_state.h"
|
||||||
#include "video_core/regs_framebuffer.h"
|
#include "video_core/regs_framebuffer.h"
|
||||||
@ -49,10 +51,9 @@ void SurfacePicture::mouseMoveEvent(QMouseEvent* event) {
|
|||||||
mousePressEvent(event);
|
mousePressEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsSurfaceWidget::GraphicsSurfaceWidget(Memory::MemorySystem& memory_,
|
GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context,
|
||||||
std::shared_ptr<Pica::DebugContext> debug_context,
|
|
||||||
QWidget* parent)
|
QWidget* parent)
|
||||||
: BreakPointObserverDock(debug_context, tr("Pica Surface Viewer"), parent), memory{memory_},
|
: BreakPointObserverDock(debug_context, tr("Pica Surface Viewer"), parent),
|
||||||
surface_source(Source::ColorBuffer) {
|
surface_source(Source::ColorBuffer) {
|
||||||
setObjectName(QStringLiteral("PicaSurface"));
|
setObjectName(QStringLiteral("PicaSurface"));
|
||||||
|
|
||||||
@ -289,57 +290,57 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8* buffer = memory.GetPhysicalPointer(surface_address);
|
u8* buffer = Core::System::GetInstance().Memory().GetPhysicalPointer(surface_address);
|
||||||
if (!buffer) {
|
if (buffer == nullptr) {
|
||||||
surface_info_label->setText(tr("(unable to access pixel data)"));
|
surface_info_label->setText(tr("(unable to access pixel data)"));
|
||||||
surface_info_label->setAlignment(Qt::AlignCenter);
|
surface_info_label->setAlignment(Qt::AlignCenter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 nibbles_per_pixel = GraphicsSurfaceWidget::NibblesPerPixel(surface_format);
|
unsigned nibbles_per_pixel = GraphicsSurfaceWidget::NibblesPerPixel(surface_format);
|
||||||
const u32 stride = nibbles_per_pixel * surface_width / 2;
|
unsigned stride = nibbles_per_pixel * surface_width / 2;
|
||||||
const bool nibble_mode = (nibbles_per_pixel == 1);
|
|
||||||
const u32 bytes_per_pixel = [&] {
|
unsigned bytes_per_pixel;
|
||||||
if (nibble_mode) {
|
bool nibble_mode = (nibbles_per_pixel == 1);
|
||||||
// As nibbles are contained in a byte we still need to access one byte per nibble
|
if (nibble_mode) {
|
||||||
return 1u;
|
// As nibbles are contained in a byte we still need to access one byte per nibble
|
||||||
} else {
|
bytes_per_pixel = 1;
|
||||||
return nibbles_per_pixel / 2;
|
} else {
|
||||||
}
|
bytes_per_pixel = nibbles_per_pixel / 2;
|
||||||
}();
|
}
|
||||||
|
|
||||||
const u32 coarse_y = y & ~7;
|
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 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) {
|
switch (format) {
|
||||||
case Format::RGBA8: {
|
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")
|
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
.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));
|
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
||||||
}
|
}
|
||||||
case Format::RGB8: {
|
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")
|
return QStringLiteral("Red: %1, Green: %2, Blue: %3")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||||
QString::number(value.b(), 'f', 2));
|
QString::number(value.b(), 'f', 2));
|
||||||
}
|
}
|
||||||
case Format::RGB5A1: {
|
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")
|
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
.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));
|
QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2));
|
||||||
}
|
}
|
||||||
case Format::RGB565: {
|
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")
|
return QStringLiteral("Red: %1, Green: %2, Blue: %3")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
||||||
QString::number(value.b(), 'f', 2));
|
QString::number(value.b(), 'f', 2));
|
||||||
}
|
}
|
||||||
case Format::RGBA4: {
|
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")
|
return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2),
|
.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));
|
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:
|
case Format::IA8:
|
||||||
return QStringLiteral("Index: %1, Alpha: %2").arg(pixel[0], pixel[1]);
|
return QStringLiteral("Index: %1, Alpha: %2").arg(pixel[0], pixel[1]);
|
||||||
case Format::RG8: {
|
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")
|
return QStringLiteral("Red: %1, Green: %2")
|
||||||
.arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 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:
|
case Format::IA4:
|
||||||
return QStringLiteral("Index: %1, Alpha: %2").arg(*pixel & 0xF, (*pixel & 0xF0) >> 4);
|
return QStringLiteral("Index: %1, Alpha: %2").arg(*pixel & 0xF, (*pixel & 0xF0) >> 4);
|
||||||
case Format::I4: {
|
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);
|
return QStringLiteral("Index: %1").arg(i);
|
||||||
}
|
}
|
||||||
case Format::A4: {
|
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));
|
return QStringLiteral("Alpha: %1").arg(QString::number(a / 15.0f, 'f', 2));
|
||||||
}
|
}
|
||||||
case Format::ETC1:
|
case Format::ETC1:
|
||||||
@ -370,17 +371,17 @@ void GraphicsSurfaceWidget::Pick(int x, int y) {
|
|||||||
// TODO: Display block information or channel values?
|
// TODO: Display block information or channel values?
|
||||||
return QStringLiteral("Compressed data");
|
return QStringLiteral("Compressed data");
|
||||||
case Format::D16: {
|
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));
|
return QStringLiteral("Depth: %1").arg(QString::number(value / (float)0xFFFF, 'f', 4));
|
||||||
}
|
}
|
||||||
case Format::D24: {
|
case Format::D24: {
|
||||||
const auto value = Common::Color::DecodeD24(pixel);
|
auto value = Common::Color::DecodeD24(pixel);
|
||||||
return QStringLiteral("Depth: %1")
|
return QStringLiteral("Depth: %1")
|
||||||
.arg(QString::number(value / (float)0xFFFFFF, 'f', 4));
|
.arg(QString::number(value / (float)0xFFFFFF, 'f', 4));
|
||||||
}
|
}
|
||||||
case Format::D24X8:
|
case Format::D24X8:
|
||||||
case Format::X24S8: {
|
case Format::X24S8: {
|
||||||
const auto values = Common::Color::DecodeD24S8(pixel);
|
auto values = Common::Color::DecodeD24S8(pixel);
|
||||||
return QStringLiteral("Depth: %1, Stencil: %2")
|
return QStringLiteral("Depth: %1, Stencil: %2")
|
||||||
.arg(QString::number(values[0] / (float)0xFFFFFF, 'f', 4), values[1]);
|
.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) {
|
if (nibble_mode) {
|
||||||
nibble_index += (offset % 2) ? 0 : 1;
|
nibble_index += (offset % 2) ? 0 : 1;
|
||||||
}
|
}
|
||||||
const u8 byte = pixel[nibble_index / 2];
|
u8 byte = pixel[nibble_index / 2];
|
||||||
const u8 nibble = (byte >> ((nibble_index % 2) ? 0 : 4)) & 0xF;
|
u8 nibble = (byte >> ((nibble_index % 2) ? 0 : 4)) & 0xF;
|
||||||
nibbles.append(QString::number(nibble, 16).toUpper());
|
nibbles.append(QString::number(nibble, 16).toUpper());
|
||||||
}
|
}
|
||||||
|
|
||||||
surface_info_label->setText(
|
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);
|
surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,9 +546,9 @@ void GraphicsSurfaceWidget::OnUpdate() {
|
|||||||
// TODO: Implement a good way to visualize alpha components!
|
// TODO: Implement a good way to visualize alpha components!
|
||||||
|
|
||||||
QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32);
|
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_picture_label->hide();
|
||||||
surface_info_label->setText(tr("(invalid surface address)"));
|
surface_info_label->setText(tr("(invalid surface address)"));
|
||||||
surface_info_label->setAlignment(Qt::AlignCenter);
|
surface_info_label->setAlignment(Qt::AlignCenter);
|
||||||
@ -681,8 +682,9 @@ void GraphicsSurfaceWidget::SaveSurface() {
|
|||||||
tr("Failed to save surface data to file '%1'").arg(filename));
|
tr("Failed to save surface data to file '%1'").arg(filename));
|
||||||
}
|
}
|
||||||
} else if (selected_filter == bin_filter) {
|
} else if (selected_filter == bin_filter) {
|
||||||
const u8* const buffer = memory.GetPhysicalPointer(surface_address);
|
const u8* const buffer =
|
||||||
ASSERT_MSG(buffer, "Memory not accessible");
|
Core::System::GetInstance().Memory().GetPhysicalPointer(surface_address);
|
||||||
|
ASSERT_MSG(buffer != nullptr, "Memory not accessible");
|
||||||
|
|
||||||
QFile file{filename};
|
QFile file{filename};
|
||||||
if (!file.open(QIODevice::WriteOnly)) {
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
|
@ -14,10 +14,6 @@ class CSpinBox;
|
|||||||
|
|
||||||
class GraphicsSurfaceWidget;
|
class GraphicsSurfaceWidget;
|
||||||
|
|
||||||
namespace Memory {
|
|
||||||
class MemorySystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SurfacePicture : public QLabel {
|
class SurfacePicture : public QLabel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -76,8 +72,7 @@ class GraphicsSurfaceWidget : public BreakPointObserverDock {
|
|||||||
static unsigned int NibblesPerPixel(Format format);
|
static unsigned int NibblesPerPixel(Format format);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GraphicsSurfaceWidget(Memory::MemorySystem& memory,
|
explicit GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context,
|
||||||
std::shared_ptr<Pica::DebugContext> debug_context,
|
|
||||||
QWidget* parent = nullptr);
|
QWidget* parent = nullptr);
|
||||||
void Pick(int x, int y);
|
void Pick(int x, int y);
|
||||||
|
|
||||||
@ -100,7 +95,6 @@ private:
|
|||||||
|
|
||||||
void SaveSurface();
|
void SaveSurface();
|
||||||
|
|
||||||
Memory::MemorySystem& memory;
|
|
||||||
QComboBox* surface_source_list;
|
QComboBox* surface_source_list;
|
||||||
CSpinBox* surface_address_control;
|
CSpinBox* surface_address_control;
|
||||||
QSpinBox* surface_width_control;
|
QSpinBox* surface_width_control;
|
||||||
|
@ -16,13 +16,13 @@
|
|||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
#include "ui_recorder.h"
|
#include "ui_recorder.h"
|
||||||
|
|
||||||
IPCRecorderWidget::IPCRecorderWidget(Core::System& system_, QWidget* parent)
|
IPCRecorderWidget::IPCRecorderWidget(QWidget* parent)
|
||||||
: QDockWidget(parent), ui(std::make_unique<Ui::IPCRecorder>()), system{system_} {
|
: QDockWidget(parent), ui(std::make_unique<Ui::IPCRecorder>()) {
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
qRegisterMetaType<IPCDebugger::RequestRecord>();
|
qRegisterMetaType<IPCDebugger::RequestRecord>();
|
||||||
|
|
||||||
connect(ui->enabled, &QCheckBox::stateChanged, this,
|
connect(ui->enabled, &QCheckBox::stateChanged,
|
||||||
[this](int new_state) { SetEnabled(new_state == Qt::Checked); });
|
[this](int new_state) { SetEnabled(new_state == Qt::Checked); });
|
||||||
connect(ui->clearButton, &QPushButton::clicked, this, &IPCRecorderWidget::Clear);
|
connect(ui->clearButton, &QPushButton::clicked, this, &IPCRecorderWidget::Clear);
|
||||||
connect(ui->filter, &QLineEdit::textChanged, this, &IPCRecorderWidget::ApplyFilterToAll);
|
connect(ui->filter, &QLineEdit::textChanged, this, &IPCRecorderWidget::ApplyFilterToAll);
|
||||||
@ -90,7 +90,7 @@ void IPCRecorderWidget::OnEntryUpdated(IPCDebugger::RequestRecord record) {
|
|||||||
(record.status == IPCDebugger::RequestStatus::Handled &&
|
(record.status == IPCDebugger::RequestStatus::Handled &&
|
||||||
record.translated_reply_cmdbuf[1] != RESULT_SUCCESS.raw)) { // Unimplemented / Error
|
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) {
|
for (int column = 0; column < item->columnCount(); ++column) {
|
||||||
item->setBackground(column, QBrush(QColor::fromRgb(255, 0, 0)));
|
item->setBackground(column, QBrush(QColor::fromRgb(255, 0, 0)));
|
||||||
}
|
}
|
||||||
@ -100,11 +100,11 @@ void IPCRecorderWidget::OnEntryUpdated(IPCDebugger::RequestRecord record) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IPCRecorderWidget::SetEnabled(bool enabled) {
|
void IPCRecorderWidget::SetEnabled(bool enabled) {
|
||||||
if (!system.IsPoweredOn()) {
|
if (!Core::System::GetInstance().IsPoweredOn()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& ipc_recorder = system.Kernel().GetIPCRecorder();
|
auto& ipc_recorder = Core::System::GetInstance().Kernel().GetIPCRecorder();
|
||||||
ipc_recorder.SetEnabled(enabled);
|
ipc_recorder.SetEnabled(enabled);
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
@ -123,10 +123,10 @@ void IPCRecorderWidget::Clear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString IPCRecorderWidget::GetServiceName(const IPCDebugger::RequestRecord& record) const {
|
QString IPCRecorderWidget::GetServiceName(const IPCDebugger::RequestRecord& record) const {
|
||||||
if (system.IsPoweredOn() && record.client_port.id != -1) {
|
if (Core::System::GetInstance().IsPoweredOn() && record.client_port.id != -1) {
|
||||||
const Service::SM::ServiceManager& sm = system.ServiceManager();
|
const auto service_name =
|
||||||
const u32 port_id = static_cast<u32>(record.client_port.id);
|
Core::System::GetInstance().ServiceManager().GetServiceNameByPortId(
|
||||||
const auto service_name = sm.GetServiceNameByPortId(port_id);
|
static_cast<u32>(record.client_port.id));
|
||||||
|
|
||||||
if (!service_name.empty()) {
|
if (!service_name.empty()) {
|
||||||
return QString::fromStdString(service_name);
|
return QString::fromStdString(service_name);
|
||||||
|
@ -14,15 +14,11 @@ namespace Ui {
|
|||||||
class IPCRecorder;
|
class IPCRecorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
class IPCRecorderWidget : public QDockWidget {
|
class IPCRecorderWidget : public QDockWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit IPCRecorderWidget(Core::System& system, QWidget* parent = nullptr);
|
explicit IPCRecorderWidget(QWidget* parent = nullptr);
|
||||||
~IPCRecorderWidget();
|
~IPCRecorderWidget();
|
||||||
|
|
||||||
void OnEmulationStarting();
|
void OnEmulationStarting();
|
||||||
@ -41,10 +37,9 @@ private:
|
|||||||
QString GetFunctionName(const IPCDebugger::RequestRecord& record) const;
|
QString GetFunctionName(const IPCDebugger::RequestRecord& record) const;
|
||||||
void OpenRecordDialog(QTreeWidgetItem* item, int column);
|
void OpenRecordDialog(QTreeWidgetItem* item, int column);
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<Ui::IPCRecorder> ui;
|
std::unique_ptr<Ui::IPCRecorder> ui;
|
||||||
IPCDebugger::CallbackHandle handle;
|
IPCDebugger::CallbackHandle handle;
|
||||||
Core::System& system;
|
|
||||||
// The offset between record id and row id, assuming record ids are assigned
|
// 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.
|
// continuously and only the 'Clear' action can be performed, this is enough.
|
||||||
// The initial value is 1, which means record 1 = row 0.
|
// The initial value is 1, which means record 1 = row 0.
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "ui_registers.h"
|
#include "ui_registers.h"
|
||||||
|
|
||||||
RegistersWidget::RegistersWidget(const Core::System& system_, QWidget* parent)
|
RegistersWidget::RegistersWidget(QWidget* parent)
|
||||||
: QDockWidget(parent), cpu_regs_ui(std::make_unique<Ui::ARMRegisters>()), system{system_} {
|
: QDockWidget(parent), cpu_regs_ui(std::make_unique<Ui::ARMRegisters>()) {
|
||||||
cpu_regs_ui->setupUi(this);
|
cpu_regs_ui->setupUi(this);
|
||||||
|
|
||||||
tree = cpu_regs_ui->treeWidget;
|
tree = cpu_regs_ui->treeWidget;
|
||||||
@ -62,21 +62,17 @@ RegistersWidget::RegistersWidget(const Core::System& system_, QWidget* parent)
|
|||||||
RegistersWidget::~RegistersWidget() = default;
|
RegistersWidget::~RegistersWidget() = default;
|
||||||
|
|
||||||
void RegistersWidget::OnDebugModeEntered() {
|
void RegistersWidget::OnDebugModeEntered() {
|
||||||
if (!system.IsPoweredOn()) {
|
if (!Core::System::GetInstance().IsPoweredOn())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Handle all cores
|
// Todo: Handle all cores
|
||||||
const ARM_Interface& core = system.GetCore(0);
|
for (int i = 0; i < core_registers->childCount(); ++i)
|
||||||
for (int i = 0; i < core_registers->childCount(); ++i) {
|
|
||||||
core_registers->child(i)->setText(
|
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(
|
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();
|
UpdateCPSRValues();
|
||||||
UpdateVFPSystemRegisterValues();
|
UpdateVFPSystemRegisterValues();
|
||||||
@ -90,29 +86,24 @@ void RegistersWidget::OnEmulationStarting(EmuThread* emu_thread) {
|
|||||||
|
|
||||||
void RegistersWidget::OnEmulationStopping() {
|
void RegistersWidget::OnEmulationStopping() {
|
||||||
// Reset widget text
|
// 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{});
|
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{});
|
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->child(i)->setText(1, QString{});
|
||||||
}
|
|
||||||
|
|
||||||
cpsr->setText(1, QString{});
|
cpsr->setText(1, QString{});
|
||||||
|
|
||||||
// FPSCR
|
// 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{});
|
vfp_system_registers->child(0)->child(i)->setText(1, QString{});
|
||||||
}
|
|
||||||
|
|
||||||
// FPEXC
|
// 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(1)->child(i)->setText(1, QString{});
|
||||||
}
|
|
||||||
|
|
||||||
vfp_system_registers->child(0)->setText(1, QString{});
|
vfp_system_registers->child(0)->setText(1, QString{});
|
||||||
vfp_system_registers->child(1)->setText(1, QString{});
|
vfp_system_registers->child(1)->setText(1, QString{});
|
||||||
@ -139,8 +130,8 @@ void RegistersWidget::CreateCPSRChildren() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RegistersWidget::UpdateCPSRValues() {
|
void RegistersWidget::UpdateCPSRValues() {
|
||||||
// TODO: Handle all cores
|
// Todo: Handle all cores
|
||||||
const u32 cpsr_val = system.GetCore(0).GetCPSR();
|
const u32 cpsr_val = Core::GetCore(0).GetCPSR();
|
||||||
|
|
||||||
cpsr->setText(1, QStringLiteral("0x%1").arg(cpsr_val, 8, 16, QLatin1Char('0')));
|
cpsr->setText(1, QStringLiteral("0x%1").arg(cpsr_val, 8, 16, QLatin1Char('0')));
|
||||||
cpsr->child(0)->setText(
|
cpsr->child(0)->setText(
|
||||||
@ -202,10 +193,9 @@ void RegistersWidget::CreateVFPSystemRegisterChildren() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RegistersWidget::UpdateVFPSystemRegisterValues() {
|
void RegistersWidget::UpdateVFPSystemRegisterValues() {
|
||||||
// TODO: handle all cores
|
// Todo: handle all cores
|
||||||
const ARM_Interface& core = system.GetCore(0);
|
const u32 fpscr_val = Core::GetCore(0).GetVFPSystemReg(VFP_FPSCR);
|
||||||
const u32 fpscr_val = core.GetVFPSystemReg(VFP_FPSCR);
|
const u32 fpexc_val = Core::GetCore(0).GetVFPSystemReg(VFP_FPEXC);
|
||||||
const u32 fpexc_val = core.GetVFPSystemReg(VFP_FPEXC);
|
|
||||||
|
|
||||||
QTreeWidgetItem* const fpscr = vfp_system_registers->child(0);
|
QTreeWidgetItem* const fpscr = vfp_system_registers->child(0);
|
||||||
fpscr->setText(1, QStringLiteral("0x%1").arg(fpscr_val, 8, 16, QLatin1Char('0')));
|
fpscr->setText(1, QStringLiteral("0x%1").arg(fpscr_val, 8, 16, QLatin1Char('0')));
|
||||||
|
@ -15,15 +15,11 @@ namespace Ui {
|
|||||||
class ARMRegisters;
|
class ARMRegisters;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
class RegistersWidget : public QDockWidget {
|
class RegistersWidget : public QDockWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RegistersWidget(const Core::System& system, QWidget* parent = nullptr);
|
explicit RegistersWidget(QWidget* parent = nullptr);
|
||||||
~RegistersWidget();
|
~RegistersWidget();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@ -41,7 +37,7 @@ private:
|
|||||||
void UpdateVFPSystemRegisterValues();
|
void UpdateVFPSystemRegisterValues();
|
||||||
|
|
||||||
std::unique_ptr<Ui::ARMRegisters> cpu_regs_ui;
|
std::unique_ptr<Ui::ARMRegisters> cpu_regs_ui;
|
||||||
const Core::System& system;
|
|
||||||
QTreeWidget* tree;
|
QTreeWidget* tree;
|
||||||
|
|
||||||
QTreeWidgetItem* core_registers;
|
QTreeWidgetItem* core_registers;
|
||||||
|
@ -5,10 +5,11 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include "citra_qt/debugger/wait_tree.h"
|
#include "citra_qt/debugger/wait_tree.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
|
#include "citra_qt/util/util.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/kernel/mutex.h"
|
#include "core/hle/kernel/mutex.h"
|
||||||
#include "core/hle/kernel/process.h"
|
|
||||||
#include "core/hle/kernel/semaphore.h"
|
#include "core/hle/kernel/semaphore.h"
|
||||||
#include "core/hle/kernel/thread.h"
|
#include "core/hle/kernel/thread.h"
|
||||||
#include "core/hle/kernel/timer.h"
|
#include "core/hle/kernel/timer.h"
|
||||||
@ -75,13 +76,13 @@ std::size_t WaitTreeItem::Row() const {
|
|||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<WaitTreeThread>> WaitTreeItem::MakeThreadItemList(
|
std::vector<std::unique_ptr<WaitTreeThread>> WaitTreeItem::MakeThreadItemList() {
|
||||||
Core::System& system) {
|
const u32 num_cores = Core::GetNumCores();
|
||||||
const u32 num_cores = system.GetNumCores();
|
|
||||||
std::vector<std::unique_ptr<WaitTreeThread>> item_list;
|
std::vector<std::unique_ptr<WaitTreeThread>> item_list;
|
||||||
item_list.reserve(num_cores);
|
item_list.reserve(num_cores);
|
||||||
for (u32 i = 0; i < num_cores; ++i) {
|
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());
|
item_list.reserve(item_list.size() + threads.size());
|
||||||
for (std::size_t j = 0; j < threads.size(); ++j) {
|
for (std::size_t j = 0; j < threads.size(); ++j) {
|
||||||
item_list.push_back(std::make_unique<WaitTreeThread>(*threads[j]));
|
item_list.push_back(std::make_unique<WaitTreeThread>(*threads[j]));
|
||||||
@ -435,12 +436,11 @@ void WaitTreeModel::ClearItems() {
|
|||||||
thread_items.clear();
|
thread_items.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitTreeModel::InitItems(Core::System& system) {
|
void WaitTreeModel::InitItems() {
|
||||||
thread_items = WaitTreeItem::MakeThreadItemList(system);
|
thread_items = WaitTreeItem::MakeThreadItemList();
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitTreeWidget::WaitTreeWidget(Core::System& system_, QWidget* parent)
|
WaitTreeWidget::WaitTreeWidget(QWidget* parent) : QDockWidget(tr("Wait Tree"), parent) {
|
||||||
: QDockWidget(tr("Wait Tree"), parent), system{system_} {
|
|
||||||
setObjectName(QStringLiteral("WaitTreeWidget"));
|
setObjectName(QStringLiteral("WaitTreeWidget"));
|
||||||
view = new QTreeView(this);
|
view = new QTreeView(this);
|
||||||
view->setHeaderHidden(true);
|
view->setHeaderHidden(true);
|
||||||
@ -449,10 +449,9 @@ WaitTreeWidget::WaitTreeWidget(Core::System& system_, QWidget* parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WaitTreeWidget::OnDebugModeEntered() {
|
void WaitTreeWidget::OnDebugModeEntered() {
|
||||||
if (!system.IsPoweredOn()) {
|
if (!Core::System::GetInstance().IsPoweredOn())
|
||||||
return;
|
return;
|
||||||
}
|
model->InitItems();
|
||||||
model->InitItems(system);
|
|
||||||
view->setModel(model);
|
view->setModel(model);
|
||||||
setEnabled(true);
|
setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,6 @@ class Thread;
|
|||||||
class Timer;
|
class Timer;
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
class WaitTreeThread;
|
class WaitTreeThread;
|
||||||
|
|
||||||
class WaitTreeItem : public QObject {
|
class WaitTreeItem : public QObject {
|
||||||
@ -43,7 +39,7 @@ public:
|
|||||||
WaitTreeItem* Parent() const;
|
WaitTreeItem* Parent() const;
|
||||||
std::span<const std::unique_ptr<WaitTreeItem>> Children() const;
|
std::span<const std::unique_ptr<WaitTreeItem>> Children() const;
|
||||||
std::size_t Row() 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:
|
private:
|
||||||
std::size_t row;
|
std::size_t row;
|
||||||
@ -170,7 +166,7 @@ public:
|
|||||||
int columnCount(const QModelIndex& parent) const override;
|
int columnCount(const QModelIndex& parent) const override;
|
||||||
|
|
||||||
void ClearItems();
|
void ClearItems();
|
||||||
void InitItems(Core::System& system);
|
void InitItems();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<WaitTreeThread>> thread_items;
|
std::vector<std::unique_ptr<WaitTreeThread>> thread_items;
|
||||||
@ -180,7 +176,7 @@ class WaitTreeWidget : public QDockWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WaitTreeWidget(Core::System& system, QWidget* parent = nullptr);
|
explicit WaitTreeWidget(QWidget* parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnDebugModeEntered();
|
void OnDebugModeEntered();
|
||||||
@ -192,5 +188,4 @@ public slots:
|
|||||||
private:
|
private:
|
||||||
QTreeView* view;
|
QTreeView* view;
|
||||||
WaitTreeModel* model;
|
WaitTreeModel* model;
|
||||||
Core::System& system;
|
|
||||||
};
|
};
|
||||||
|
@ -9,11 +9,10 @@
|
|||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/loader/loader.h"
|
|
||||||
|
|
||||||
namespace DiscordRPC {
|
namespace DiscordRPC {
|
||||||
|
|
||||||
DiscordImpl::DiscordImpl(const Core::System& system_) : system{system_} {
|
DiscordImpl::DiscordImpl() {
|
||||||
DiscordEventHandlers handlers{};
|
DiscordEventHandlers handlers{};
|
||||||
|
|
||||||
// The number is the client ID for Citra, it's used for images and the
|
// 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())
|
std::chrono::system_clock::now().time_since_epoch())
|
||||||
.count();
|
.count();
|
||||||
std::string title;
|
std::string title;
|
||||||
const bool is_powered_on = system.IsPoweredOn();
|
if (Core::System::GetInstance().IsPoweredOn())
|
||||||
if (is_powered_on) {
|
Core::System::GetInstance().GetAppLoader().ReadTitle(title);
|
||||||
system.GetAppLoader().ReadTitle(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
DiscordRichPresence presence{};
|
DiscordRichPresence presence{};
|
||||||
presence.largeImageKey = "citra";
|
presence.largeImageKey = "citra";
|
||||||
presence.largeImageText = "Citra is an emulator for the Nintendo 3DS";
|
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.state = title.c_str();
|
||||||
presence.details = "Currently in game";
|
presence.details = "Currently in game";
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,22 +6,15 @@
|
|||||||
|
|
||||||
#include "citra_qt/discord.h"
|
#include "citra_qt/discord.h"
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace DiscordRPC {
|
namespace DiscordRPC {
|
||||||
|
|
||||||
class DiscordImpl : public DiscordInterface {
|
class DiscordImpl : public DiscordInterface {
|
||||||
public:
|
public:
|
||||||
DiscordImpl(const Core::System& system);
|
DiscordImpl();
|
||||||
~DiscordImpl() override;
|
~DiscordImpl() override;
|
||||||
|
|
||||||
void Pause() override;
|
void Pause() override;
|
||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
private:
|
|
||||||
const Core::System& system;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DiscordRPC
|
} // namespace DiscordRPC
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <QActionGroup>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
@ -308,9 +307,6 @@ GameList::GameList(GMainWindow* parent) : QWidget{parent} {
|
|||||||
tree_view->setEditTriggers(QHeaderView::NoEditTriggers);
|
tree_view->setEditTriggers(QHeaderView::NoEditTriggers);
|
||||||
tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }"));
|
tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }"));
|
||||||
tree_view->header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
|
|
||||||
UpdateColumnVisibility();
|
|
||||||
|
|
||||||
item_model->insertColumns(0, COLUMN_COUNT);
|
item_model->insertColumns(0, COLUMN_COUNT);
|
||||||
RetranslateUI();
|
RetranslateUI();
|
||||||
@ -321,8 +317,6 @@ GameList::GameList(GMainWindow* parent) : QWidget{parent} {
|
|||||||
connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu);
|
connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu);
|
||||||
connect(tree_view, &QTreeView::expanded, this, &GameList::OnItemExpanded);
|
connect(tree_view, &QTreeView::expanded, this, &GameList::OnItemExpanded);
|
||||||
connect(tree_view, &QTreeView::collapsed, 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
|
// 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.
|
// 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));
|
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) {
|
void ForEachOpenGLCacheFile(u64 program_id, auto func) {
|
||||||
for (const std::string_view cache_type : {"separable", "conventional"}) {
|
for (const std::string_view cache_type : {"separable", "conventional"}) {
|
||||||
const std::string path = fmt::format("{}opengl/precompiled/{}/{:016X}.bin",
|
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) {
|
void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs) {
|
||||||
tree_view->setEnabled(false);
|
tree_view->setEnabled(false);
|
||||||
|
|
||||||
// Update the columns in case UISettings has changed
|
|
||||||
UpdateColumnVisibility();
|
|
||||||
|
|
||||||
// Delete any rows that might already exist if we're repopulating
|
// Delete any rows that might already exist if we're repopulating
|
||||||
item_model->removeRows(0, item_model->rowCount());
|
item_model->removeRows(0, item_model->rowCount());
|
||||||
search_field->clear();
|
search_field->clear();
|
||||||
|
@ -104,11 +104,9 @@ private:
|
|||||||
void DonePopulating(const QStringList& watch_list);
|
void DonePopulating(const QStringList& watch_list);
|
||||||
|
|
||||||
void PopupContextMenu(const QPoint& menu_location);
|
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 AddGamePopup(QMenu& context_menu, const QString& path, u64 program_id, u64 extdata_id);
|
||||||
void AddCustomDirPopup(QMenu& context_menu, QModelIndex selected);
|
void AddCustomDirPopup(QMenu& context_menu, QModelIndex selected);
|
||||||
void AddPermDirPopup(QMenu& context_menu, QModelIndex selected);
|
void AddPermDirPopup(QMenu& context_menu, QModelIndex selected);
|
||||||
void UpdateColumnVisibility();
|
|
||||||
|
|
||||||
QString FindGameByProgramID(QStandardItem* current_item, u64 program_id, int role);
|
QString FindGameByProgramID(QStandardItem* current_item, u64 program_id, int role);
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <unistd.h> // for chdir
|
#include <unistd.h> // for chdir
|
||||||
#endif
|
#endif
|
||||||
@ -74,6 +73,7 @@
|
|||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
|
#include "common/string_util.h"
|
||||||
#if CITRA_ARCH(x86_64)
|
#if CITRA_ARCH(x86_64)
|
||||||
#include "common/x64/cpu_detect.h"
|
#include "common/x64/cpu_detect.h"
|
||||||
#endif
|
#endif
|
||||||
@ -173,7 +173,7 @@ static QString PrettyProductName() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GMainWindow::GMainWindow(Core::System& system_)
|
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} {
|
config{std::make_unique<Config>()}, emu_thread{nullptr} {
|
||||||
Common::Log::Initialize();
|
Common::Log::Initialize();
|
||||||
Common::Log::Start();
|
Common::Log::Start();
|
||||||
@ -353,8 +353,8 @@ void GMainWindow::InitializeWidgets() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
InputCommon::Init();
|
InputCommon::Init();
|
||||||
multiplayer_state = new MultiplayerState(system, this, game_list->GetModel(),
|
multiplayer_state = new MultiplayerState(this, game_list->GetModel(), ui->action_Leave_Room,
|
||||||
ui->action_Leave_Room, ui->action_Show_Room);
|
ui->action_Show_Room);
|
||||||
multiplayer_state->setVisible(false);
|
multiplayer_state->setVisible(false);
|
||||||
|
|
||||||
#if ENABLE_QT_UPDATER
|
#if ENABLE_QT_UPDATER
|
||||||
@ -434,7 +434,7 @@ void GMainWindow::InitializeDebugWidgets() {
|
|||||||
debug_menu->addAction(microProfileDialog->toggleViewAction());
|
debug_menu->addAction(microProfileDialog->toggleViewAction());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
registersWidget = new RegistersWidget(system, this);
|
registersWidget = new RegistersWidget(this);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, registersWidget);
|
addDockWidget(Qt::RightDockWidgetArea, registersWidget);
|
||||||
registersWidget->hide();
|
registersWidget->hide();
|
||||||
debug_menu->addAction(registersWidget->toggleViewAction());
|
debug_menu->addAction(registersWidget->toggleViewAction());
|
||||||
@ -448,7 +448,7 @@ void GMainWindow::InitializeDebugWidgets() {
|
|||||||
graphicsWidget->hide();
|
graphicsWidget->hide();
|
||||||
debug_menu->addAction(graphicsWidget->toggleViewAction());
|
debug_menu->addAction(graphicsWidget->toggleViewAction());
|
||||||
|
|
||||||
graphicsCommandsWidget = new GPUCommandListWidget(system, this);
|
graphicsCommandsWidget = new GPUCommandListWidget(this);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, graphicsCommandsWidget);
|
addDockWidget(Qt::RightDockWidgetArea, graphicsCommandsWidget);
|
||||||
graphicsCommandsWidget->hide();
|
graphicsCommandsWidget->hide();
|
||||||
debug_menu->addAction(graphicsCommandsWidget->toggleViewAction());
|
debug_menu->addAction(graphicsCommandsWidget->toggleViewAction());
|
||||||
@ -472,7 +472,7 @@ void GMainWindow::InitializeDebugWidgets() {
|
|||||||
connect(this, &GMainWindow::EmulationStopping, graphicsTracingWidget,
|
connect(this, &GMainWindow::EmulationStopping, graphicsTracingWidget,
|
||||||
&GraphicsTracingWidget::OnEmulationStopping);
|
&GraphicsTracingWidget::OnEmulationStopping);
|
||||||
|
|
||||||
waitTreeWidget = new WaitTreeWidget(system, this);
|
waitTreeWidget = new WaitTreeWidget(this);
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget);
|
addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget);
|
||||||
waitTreeWidget->hide();
|
waitTreeWidget->hide();
|
||||||
debug_menu->addAction(waitTreeWidget->toggleViewAction());
|
debug_menu->addAction(waitTreeWidget->toggleViewAction());
|
||||||
@ -490,7 +490,7 @@ void GMainWindow::InitializeDebugWidgets() {
|
|||||||
connect(this, &GMainWindow::EmulationStopping, waitTreeWidget,
|
connect(this, &GMainWindow::EmulationStopping, waitTreeWidget,
|
||||||
[this] { lleServiceModulesWidget->setDisabled(false); });
|
[this] { lleServiceModulesWidget->setDisabled(false); });
|
||||||
|
|
||||||
ipcRecorderWidget = new IPCRecorderWidget(system, this);
|
ipcRecorderWidget = new IPCRecorderWidget(this);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, ipcRecorderWidget);
|
addDockWidget(Qt::RightDockWidgetArea, ipcRecorderWidget);
|
||||||
ipcRecorderWidget->hide();
|
ipcRecorderWidget->hide();
|
||||||
debug_menu->addAction(ipcRecorderWidget->toggleViewAction());
|
debug_menu->addAction(ipcRecorderWidget->toggleViewAction());
|
||||||
@ -1171,18 +1171,20 @@ void GMainWindow::BootGame(const QString& filename) {
|
|||||||
movie.PrepareForPlayback(movie_playback_path.toStdString());
|
movie.PrepareForPlayback(movie_playback_path.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 title_id{0};
|
||||||
const std::string path = filename.toStdString();
|
const std::string path = filename.toStdString();
|
||||||
const auto loader = Loader::GetLoader(path);
|
const auto loader = Loader::GetLoader(path);
|
||||||
|
|
||||||
u64 title_id{0};
|
if (loader && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success) {
|
||||||
loader->ReadProgramId(title_id);
|
// 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
|
LOG_INFO(Frontend, "Using per game config file for title id {}", config_file_name);
|
||||||
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();
|
|
||||||
|
|
||||||
Settings::LogSettings();
|
Settings::LogSettings();
|
||||||
|
|
||||||
@ -1413,7 +1415,7 @@ void GMainWindow::UpdateSaveStates() {
|
|||||||
if (system.GetAppLoader().ReadProgramId(title_id) != Loader::ResultStatus::Success) {
|
if (system.GetAppLoader().ReadProgramId(title_id) != Loader::ResultStatus::Success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto savestates = Core::ListSaveStates(title_id, movie.GetCurrentMovieID());
|
auto savestates = Core::ListSaveStates(title_id);
|
||||||
for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) {
|
for (u32 i = 0; i < Core::SaveStateSlotCount; ++i) {
|
||||||
actions_load_state[i]->setEnabled(false);
|
actions_load_state[i]->setEnabled(false);
|
||||||
actions_load_state[i]->setText(tr("Slot %1").arg(i + 1));
|
actions_load_state[i]->setText(tr("Slot %1").arg(i + 1));
|
||||||
@ -2046,6 +2048,7 @@ void GMainWindow::OnLoadAmiibo() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Core::System& system{Core::System::GetInstance()};
|
||||||
Service::SM::ServiceManager& sm = system.ServiceManager();
|
Service::SM::ServiceManager& sm = system.ServiceManager();
|
||||||
auto nfc = sm.GetService<Service::NFC::Module::Interface>("nfc:u");
|
auto nfc = sm.GetService<Service::NFC::Module::Interface>("nfc:u");
|
||||||
if (nfc == nullptr) {
|
if (nfc == nullptr) {
|
||||||
@ -2117,15 +2120,14 @@ void GMainWindow::OnToggleFilterBar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnCreateGraphicsSurfaceViewer() {
|
void GMainWindow::OnCreateGraphicsSurfaceViewer() {
|
||||||
auto graphicsSurfaceViewerWidget =
|
auto graphicsSurfaceViewerWidget = new GraphicsSurfaceWidget(Pica::g_debug_context, this);
|
||||||
new GraphicsSurfaceWidget(system.Memory(), Pica::g_debug_context, this);
|
|
||||||
addDockWidget(Qt::RightDockWidgetArea, graphicsSurfaceViewerWidget);
|
addDockWidget(Qt::RightDockWidgetArea, graphicsSurfaceViewerWidget);
|
||||||
// TODO: Maybe graphicsSurfaceViewerWidget->setFloating(true);
|
// TODO: Maybe graphicsSurfaceViewerWidget->setFloating(true);
|
||||||
graphicsSurfaceViewerWidget->show();
|
graphicsSurfaceViewerWidget->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnRecordMovie() {
|
void GMainWindow::OnRecordMovie() {
|
||||||
MovieRecordDialog dialog(this, system);
|
MovieRecordDialog dialog(this);
|
||||||
if (dialog.exec() != QDialog::Accepted) {
|
if (dialog.exec() != QDialog::Accepted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2142,7 +2144,7 @@ void GMainWindow::OnRecordMovie() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnPlayMovie() {
|
void GMainWindow::OnPlayMovie() {
|
||||||
MoviePlayDialog dialog(this, game_list, system);
|
MoviePlayDialog dialog(this, game_list);
|
||||||
if (dialog.exec() != QDialog::Accepted) {
|
if (dialog.exec() != QDialog::Accepted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2783,13 +2785,9 @@ void GMainWindow::UpdateWindowTitle() {
|
|||||||
const QString full_name = QString::fromUtf8(Common::g_build_fullname);
|
const QString full_name = QString::fromUtf8(Common::g_build_fullname);
|
||||||
|
|
||||||
if (game_title.isEmpty()) {
|
if (game_title.isEmpty()) {
|
||||||
setWindowTitle(QStringLiteral("Citra %1").arg(full_name));
|
setWindowTitle(tr("Citra %1").arg(full_name));
|
||||||
} else {
|
} else {
|
||||||
setWindowTitle(QStringLiteral("Citra %1 | %2").arg(full_name, game_title));
|
setWindowTitle(tr("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")));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2847,7 +2845,7 @@ void GMainWindow::RetranslateStatusBar() {
|
|||||||
void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
|
void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
|
||||||
#ifdef USE_DISCORD_PRESENCE
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
if (state) {
|
if (state) {
|
||||||
discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>(system);
|
discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>();
|
||||||
} else {
|
} else {
|
||||||
discord_rpc = std::make_unique<DiscordRPC::NullImpl>();
|
discord_rpc = std::make_unique<DiscordRPC::NullImpl>();
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,8 @@
|
|||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "ui_movie_play_dialog.h"
|
#include "ui_movie_play_dialog.h"
|
||||||
|
|
||||||
MoviePlayDialog::MoviePlayDialog(QWidget* parent, GameList* game_list_, const Core::System& system_)
|
MoviePlayDialog::MoviePlayDialog(QWidget* parent, GameList* game_list_)
|
||||||
: QDialog(parent),
|
: QDialog(parent), ui(std::make_unique<Ui::MoviePlayDialog>()), game_list(game_list_) {
|
||||||
ui(std::make_unique<Ui::MoviePlayDialog>()), game_list{game_list_}, system{system_} {
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
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::accepted, this, &MoviePlayDialog::accept);
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MoviePlayDialog::reject);
|
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MoviePlayDialog::reject);
|
||||||
|
|
||||||
if (system.IsPoweredOn()) {
|
if (Core::System::GetInstance().IsPoweredOn()) {
|
||||||
QString note_text;
|
QString note_text;
|
||||||
note_text = tr("Current running game will be stopped.");
|
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."));
|
note_text.append(tr("<br>Current recording will be discarded."));
|
||||||
}
|
}
|
||||||
ui->note2Label->setText(note_text);
|
ui->note2Label->setText(note_text);
|
||||||
@ -44,7 +43,7 @@ QString MoviePlayDialog::GetMoviePath() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString MoviePlayDialog::GetGamePath() 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);
|
return game_list->FindGameByProgramID(metadata.program_id, GameListItemPath::FullPathRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,10 +67,9 @@ void MoviePlayDialog::UpdateUIDisplay() {
|
|||||||
ui->lengthLineEdit->clear();
|
ui->lengthLineEdit->clear();
|
||||||
ui->note1Label->setVisible(true);
|
ui->note1Label->setVisible(true);
|
||||||
|
|
||||||
const auto& movie = system.Movie();
|
|
||||||
const auto path = GetMoviePath().toStdString();
|
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) {
|
if (validation_result == Core::Movie::ValidationResult::Invalid) {
|
||||||
ui->note1Label->setText(tr("Invalid movie file."));
|
ui->note1Label->setText(tr("Invalid movie file."));
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||||
@ -96,7 +94,7 @@ void MoviePlayDialog::UpdateUIDisplay() {
|
|||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto metadata = movie.GetMovieMetadata(path);
|
const auto metadata = Core::Movie::GetInstance().GetMovieMetadata(path);
|
||||||
|
|
||||||
// Format game title
|
// Format game title
|
||||||
const auto title =
|
const auto title =
|
||||||
|
@ -11,15 +11,11 @@ namespace Ui {
|
|||||||
class MoviePlayDialog;
|
class MoviePlayDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
class MoviePlayDialog : public QDialog {
|
class MoviePlayDialog : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MoviePlayDialog(QWidget* parent, GameList* game_list, const Core::System& system);
|
explicit MoviePlayDialog(QWidget* parent, GameList* game_list);
|
||||||
~MoviePlayDialog() override;
|
~MoviePlayDialog() override;
|
||||||
|
|
||||||
QString GetMoviePath() const;
|
QString GetMoviePath() const;
|
||||||
@ -31,5 +27,4 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<Ui::MoviePlayDialog> ui;
|
std::unique_ptr<Ui::MoviePlayDialog> ui;
|
||||||
GameList* game_list;
|
GameList* game_list;
|
||||||
const Core::System& system;
|
|
||||||
};
|
};
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "ui_movie_record_dialog.h"
|
#include "ui_movie_record_dialog.h"
|
||||||
|
|
||||||
MovieRecordDialog::MovieRecordDialog(QWidget* parent, const Core::System& system_)
|
MovieRecordDialog::MovieRecordDialog(QWidget* parent)
|
||||||
: QDialog(parent), ui(std::make_unique<Ui::MovieRecordDialog>()), system{system_} {
|
: QDialog(parent), ui(std::make_unique<Ui::MovieRecordDialog>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
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);
|
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &MovieRecordDialog::reject);
|
||||||
|
|
||||||
QString note_text;
|
QString note_text;
|
||||||
if (system.IsPoweredOn()) {
|
if (Core::System::GetInstance().IsPoweredOn()) {
|
||||||
note_text = tr("Current running game will be restarted.");
|
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."));
|
note_text.append(tr("<br>Current recording will be discarded."));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -9,15 +9,11 @@ namespace Ui {
|
|||||||
class MovieRecordDialog;
|
class MovieRecordDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
class MovieRecordDialog : public QDialog {
|
class MovieRecordDialog : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MovieRecordDialog(QWidget* parent, const Core::System& system);
|
explicit MovieRecordDialog(QWidget* parent);
|
||||||
~MovieRecordDialog() override;
|
~MovieRecordDialog() override;
|
||||||
|
|
||||||
QString GetPath() const;
|
QString GetPath() const;
|
||||||
@ -28,5 +24,4 @@ private:
|
|||||||
void UpdateUIDisplay();
|
void UpdateUIDisplay();
|
||||||
|
|
||||||
std::unique_ptr<Ui::MovieRecordDialog> ui;
|
std::unique_ptr<Ui::MovieRecordDialog> ui;
|
||||||
const Core::System& system;
|
|
||||||
};
|
};
|
||||||
|
@ -9,8 +9,10 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QtConcurrent/QtConcurrentRun>
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
#include "citra_qt/main.h"
|
#include "citra_qt/main.h"
|
||||||
|
#include "citra_qt/multiplayer/client_room.h"
|
||||||
#include "citra_qt/multiplayer/direct_connect.h"
|
#include "citra_qt/multiplayer/direct_connect.h"
|
||||||
#include "citra_qt/multiplayer/message.h"
|
#include "citra_qt/multiplayer/message.h"
|
||||||
|
#include "citra_qt/multiplayer/state.h"
|
||||||
#include "citra_qt/multiplayer/validation.h"
|
#include "citra_qt/multiplayer/validation.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "core/hle/service/cfg/cfg.h"
|
#include "core/hle/service/cfg/cfg.h"
|
||||||
@ -20,9 +22,9 @@
|
|||||||
|
|
||||||
enum class ConnectionType : u8 { TraversalServer, IP };
|
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),
|
: 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);
|
ui->setupUi(this);
|
||||||
|
|
||||||
@ -89,7 +91,7 @@ void DirectConnectWindow::Connect() {
|
|||||||
if (auto room_member = Network::GetRoomMember().lock()) {
|
if (auto room_member = Network::GetRoomMember().lock()) {
|
||||||
auto port = UISettings::values.port.toUInt();
|
auto port = UISettings::values.port.toUInt();
|
||||||
room_member->Join(ui->nickname->text().toStdString(),
|
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,
|
ui->ip->text().toStdString().c_str(), port, 0,
|
||||||
Network::NoPreferredMac, ui->password->text().toStdString().c_str());
|
Network::NoPreferredMac, ui->password->text().toStdString().c_str());
|
||||||
}
|
}
|
||||||
|
@ -13,15 +13,11 @@ namespace Ui {
|
|||||||
class DirectConnect;
|
class DirectConnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
class DirectConnectWindow : public QDialog {
|
class DirectConnectWindow : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DirectConnectWindow(Core::System& system, QWidget* parent = nullptr);
|
explicit DirectConnectWindow(QWidget* parent = nullptr);
|
||||||
~DirectConnectWindow();
|
~DirectConnectWindow();
|
||||||
|
|
||||||
void RetranslateUi();
|
void RetranslateUi();
|
||||||
@ -43,6 +39,5 @@ private:
|
|||||||
|
|
||||||
QFutureWatcher<void>* watcher;
|
QFutureWatcher<void>* watcher;
|
||||||
std::unique_ptr<Ui::DirectConnect> ui;
|
std::unique_ptr<Ui::DirectConnect> ui;
|
||||||
Core::System& system;
|
|
||||||
Validation validation;
|
Validation validation;
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QtConcurrent/QtConcurrentRun>
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
#include "citra_qt/game_list_p.h"
|
#include "citra_qt/game_list_p.h"
|
||||||
|
#include "citra_qt/main.h"
|
||||||
#include "citra_qt/multiplayer/host_room.h"
|
#include "citra_qt/multiplayer/host_room.h"
|
||||||
#include "citra_qt/multiplayer/message.h"
|
#include "citra_qt/multiplayer/message.h"
|
||||||
#include "citra_qt/multiplayer/state.h"
|
#include "citra_qt/multiplayer/state.h"
|
||||||
@ -26,10 +27,10 @@
|
|||||||
#include "web_service/verify_user_jwt.h"
|
#include "web_service/verify_user_jwt.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HostRoomWindow::HostRoomWindow(Core::System& system_, QWidget* parent, QStandardItemModel* list,
|
HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list,
|
||||||
std::shared_ptr<Network::AnnounceMultiplayerSession> session)
|
std::shared_ptr<Network::AnnounceMultiplayerSession> session)
|
||||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
|
: 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);
|
ui->setupUi(this);
|
||||||
|
|
||||||
// set up validation for all of the fields
|
// set up validation for all of the fields
|
||||||
@ -195,8 +196,9 @@ void HostRoomWindow::Host() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
member->Join(ui->username->text().toStdString(), Service::CFG::GetConsoleIdHash(system),
|
member->Join(ui->username->text().toStdString(),
|
||||||
"127.0.0.1", port, 0, Network::NoPreferredMac, password, token);
|
Service::CFG::GetConsoleIdHash(Core::System::GetInstance()), "127.0.0.1", port,
|
||||||
|
0, Network::NoPreferredMac, password, token);
|
||||||
|
|
||||||
// Store settings
|
// Store settings
|
||||||
UISettings::values.room_nickname = ui->username->text();
|
UISettings::values.room_nickname = ui->username->text();
|
||||||
|
@ -9,16 +9,14 @@
|
|||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include "citra_qt/multiplayer/chat_room.h"
|
||||||
#include "citra_qt/multiplayer/validation.h"
|
#include "citra_qt/multiplayer/validation.h"
|
||||||
|
#include "network/network.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class HostRoom;
|
class HostRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Network {
|
namespace Network {
|
||||||
class AnnounceMultiplayerSession;
|
class AnnounceMultiplayerSession;
|
||||||
}
|
}
|
||||||
@ -36,7 +34,7 @@ class HostRoomWindow : public QDialog {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit HostRoomWindow(Core::System& system, QWidget* parent, QStandardItemModel* list,
|
explicit HostRoomWindow(QWidget* parent, QStandardItemModel* list,
|
||||||
std::shared_ptr<Network::AnnounceMultiplayerSession> session);
|
std::shared_ptr<Network::AnnounceMultiplayerSession> session);
|
||||||
~HostRoomWindow();
|
~HostRoomWindow();
|
||||||
|
|
||||||
@ -52,7 +50,6 @@ private:
|
|||||||
std::unique_ptr<Network::VerifyUser::Backend> CreateVerifyBackend(bool use_validation) const;
|
std::unique_ptr<Network::VerifyUser::Backend> CreateVerifyBackend(bool use_validation) const;
|
||||||
|
|
||||||
std::unique_ptr<Ui::HostRoom> ui;
|
std::unique_ptr<Ui::HostRoom> ui;
|
||||||
Core::System& system;
|
|
||||||
std::weak_ptr<Network::AnnounceMultiplayerSession> announce_multiplayer_session;
|
std::weak_ptr<Network::AnnounceMultiplayerSession> announce_multiplayer_session;
|
||||||
QStandardItemModel* game_list;
|
QStandardItemModel* game_list;
|
||||||
ComboBoxProxyModel* proxy;
|
ComboBoxProxyModel* proxy;
|
||||||
|
@ -7,9 +7,11 @@
|
|||||||
#include <QtConcurrent/QtConcurrentRun>
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
#include "citra_qt/game_list_p.h"
|
#include "citra_qt/game_list_p.h"
|
||||||
#include "citra_qt/main.h"
|
#include "citra_qt/main.h"
|
||||||
|
#include "citra_qt/multiplayer/client_room.h"
|
||||||
#include "citra_qt/multiplayer/lobby.h"
|
#include "citra_qt/multiplayer/lobby.h"
|
||||||
#include "citra_qt/multiplayer/lobby_p.h"
|
#include "citra_qt/multiplayer/lobby_p.h"
|
||||||
#include "citra_qt/multiplayer/message.h"
|
#include "citra_qt/multiplayer/message.h"
|
||||||
|
#include "citra_qt/multiplayer/state.h"
|
||||||
#include "citra_qt/multiplayer/validation.h"
|
#include "citra_qt/multiplayer/validation.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
@ -21,10 +23,10 @@
|
|||||||
#include "web_service/web_backend.h"
|
#include "web_service/web_backend.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Lobby::Lobby(Core::System& system_, QWidget* parent, QStandardItemModel* list,
|
Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
|
||||||
std::shared_ptr<Network::AnnounceMultiplayerSession> session)
|
std::shared_ptr<Network::AnnounceMultiplayerSession> session)
|
||||||
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
|
: 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);
|
ui->setupUi(this);
|
||||||
|
|
||||||
// setup the watcher for background connections
|
// setup the watcher for background connections
|
||||||
@ -150,8 +152,8 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
|
|||||||
const std::string verify_UID =
|
const std::string verify_UID =
|
||||||
proxy->data(connection_index, LobbyItemHost::HostVerifyUIDRole).toString().toStdString();
|
proxy->data(connection_index, LobbyItemHost::HostVerifyUIDRole).toString().toStdString();
|
||||||
|
|
||||||
// Attempt to connect in a different thread
|
// attempt to connect in a different thread
|
||||||
QFuture<void> f = QtConcurrent::run([this, nickname, ip, port, password, verify_UID] {
|
QFuture<void> f = QtConcurrent::run([nickname, ip, port, password, verify_UID] {
|
||||||
std::string token;
|
std::string token;
|
||||||
#ifdef ENABLE_WEB_SERVICE
|
#ifdef ENABLE_WEB_SERVICE
|
||||||
if (!NetSettings::values.citra_username.empty() &&
|
if (!NetSettings::values.citra_username.empty() &&
|
||||||
@ -168,8 +170,8 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (auto room_member = Network::GetRoomMember().lock()) {
|
if (auto room_member = Network::GetRoomMember().lock()) {
|
||||||
room_member->Join(nickname, Service::CFG::GetConsoleIdHash(system), ip.c_str(), port, 0,
|
room_member->Join(nickname, Service::CFG::GetConsoleIdHash(Core::System::GetInstance()),
|
||||||
Network::NoPreferredMac, password, token);
|
ip.c_str(), port, 0, Network::NoPreferredMac, password, token);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
watcher->setFuture(f);
|
watcher->setFuture(f);
|
||||||
|
@ -12,16 +12,12 @@
|
|||||||
#include "citra_qt/multiplayer/validation.h"
|
#include "citra_qt/multiplayer/validation.h"
|
||||||
#include "common/announce_multiplayer_room.h"
|
#include "common/announce_multiplayer_room.h"
|
||||||
#include "network/announce_multiplayer_session.h"
|
#include "network/announce_multiplayer_session.h"
|
||||||
#include "network/room_member.h"
|
#include "network/network.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class Lobby;
|
class Lobby;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
class LobbyModel;
|
class LobbyModel;
|
||||||
class LobbyFilterProxyModel;
|
class LobbyFilterProxyModel;
|
||||||
|
|
||||||
@ -33,7 +29,7 @@ class Lobby : public QDialog {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Lobby(Core::System& system, QWidget* parent, QStandardItemModel* list,
|
explicit Lobby(QWidget* parent, QStandardItemModel* list,
|
||||||
std::shared_ptr<Network::AnnounceMultiplayerSession> session);
|
std::shared_ptr<Network::AnnounceMultiplayerSession> session);
|
||||||
~Lobby() override;
|
~Lobby() override;
|
||||||
|
|
||||||
@ -88,9 +84,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
QString PasswordPrompt();
|
QString PasswordPrompt();
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<Ui::Lobby> ui;
|
std::unique_ptr<Ui::Lobby> ui;
|
||||||
Core::System& system;
|
|
||||||
|
|
||||||
QStandardItemModel* model{};
|
QStandardItemModel* model{};
|
||||||
QStandardItemModel* game_list{};
|
QStandardItemModel* game_list{};
|
||||||
|
@ -17,10 +17,9 @@
|
|||||||
#include "citra_qt/util/clickable_label.h"
|
#include "citra_qt/util/clickable_label.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
|
||||||
MultiplayerState::MultiplayerState(Core::System& system_, QWidget* parent,
|
MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_list_model,
|
||||||
QStandardItemModel* game_list_model, QAction* leave_room,
|
QAction* leave_room, QAction* show_room)
|
||||||
QAction* show_room)
|
: QWidget(parent), game_list_model(game_list_model), leave_room(leave_room),
|
||||||
: QWidget(parent), system{system_}, game_list_model(game_list_model), leave_room(leave_room),
|
|
||||||
show_room(show_room) {
|
show_room(show_room) {
|
||||||
if (auto member = Network::GetRoomMember().lock()) {
|
if (auto member = Network::GetRoomMember().lock()) {
|
||||||
// register the network structs to use in slots and signals
|
// register the network structs to use in slots and signals
|
||||||
@ -204,14 +203,14 @@ static void BringWidgetToFront(QWidget* widget) {
|
|||||||
|
|
||||||
void MultiplayerState::OnViewLobby() {
|
void MultiplayerState::OnViewLobby() {
|
||||||
if (lobby == nullptr) {
|
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);
|
BringWidgetToFront(lobby);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiplayerState::OnCreateRoom() {
|
void MultiplayerState::OnCreateRoom() {
|
||||||
if (host_room == nullptr) {
|
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);
|
BringWidgetToFront(host_room);
|
||||||
}
|
}
|
||||||
@ -275,7 +274,7 @@ void MultiplayerState::OnOpenNetworkRoom() {
|
|||||||
|
|
||||||
void MultiplayerState::OnDirectConnectToRoom() {
|
void MultiplayerState::OnDirectConnectToRoom() {
|
||||||
if (direct_connect == nullptr) {
|
if (direct_connect == nullptr) {
|
||||||
direct_connect = new DirectConnectWindow(system, this);
|
direct_connect = new DirectConnectWindow(this);
|
||||||
}
|
}
|
||||||
BringWidgetToFront(direct_connect);
|
BringWidgetToFront(direct_connect);
|
||||||
}
|
}
|
||||||
|
@ -15,16 +15,12 @@ class ClientRoomWindow;
|
|||||||
class DirectConnectWindow;
|
class DirectConnectWindow;
|
||||||
class ClickableLabel;
|
class ClickableLabel;
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
class MultiplayerState : public QWidget {
|
class MultiplayerState : public QWidget {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MultiplayerState(Core::System& system, QWidget* parent, QStandardItemModel* game_list,
|
explicit MultiplayerState(QWidget* parent, QStandardItemModel* game_list, QAction* leave_room,
|
||||||
QAction* leave_room, QAction* show_room);
|
QAction* show_room);
|
||||||
~MultiplayerState();
|
~MultiplayerState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,7 +71,6 @@ signals:
|
|||||||
void AnnounceFailed(const Common::WebResult&);
|
void AnnounceFailed(const Common::WebResult&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Core::System& system;
|
|
||||||
Lobby* lobby = nullptr;
|
Lobby* lobby = nullptr;
|
||||||
HostRoomWindow* host_room = nullptr;
|
HostRoomWindow* host_room = nullptr;
|
||||||
ClientRoomWindow* client_room = nullptr;
|
ClientRoomWindow* client_room = nullptr;
|
||||||
|
@ -97,12 +97,6 @@ struct Values {
|
|||||||
Settings::Setting<bool> game_list_hide_no_icon{false, "hideNoIcon"};
|
Settings::Setting<bool> game_list_hide_no_icon{false, "hideNoIcon"};
|
||||||
Settings::Setting<bool> game_list_single_line_mode{false, "singleLineMode"};
|
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::Setting<u16> screenshot_resolution_factor{0, "screenshot_resolution_factor"};
|
||||||
Settings::SwitchableSetting<std::string> screenshot_path{"", "screenshotPath"};
|
Settings::SwitchableSetting<std::string> screenshot_path{"", "screenshotPath"};
|
||||||
|
|
||||||
|
@ -130,9 +130,11 @@ bool UpdaterPrivate::StartUpdateCheck() {
|
|||||||
main_process->setProgram(tool_info.absoluteFilePath());
|
main_process->setProgram(tool_info.absoluteFilePath());
|
||||||
main_process->setArguments({QStringLiteral("--checkupdates"), QStringLiteral("-v")});
|
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);
|
&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);
|
&UpdaterPrivate::UpdaterError, Qt::QueuedConnection);
|
||||||
|
|
||||||
main_process->start(QIODevice::ReadOnly);
|
main_process->start(QIODevice::ReadOnly);
|
||||||
@ -154,7 +156,7 @@ void UpdaterPrivate::StopUpdateCheck(int delay, bool async) {
|
|||||||
QTimer* timer = new QTimer(this);
|
QTimer* timer = new QTimer(this);
|
||||||
timer->setSingleShot(true);
|
timer->setSingleShot(true);
|
||||||
|
|
||||||
connect(timer, &QTimer::timeout, this, [this, timer]() {
|
connect(timer, &QTimer::timeout, [this, timer]() {
|
||||||
StopUpdateCheck(0, false);
|
StopUpdateCheck(0, false);
|
||||||
timer->deleteLater();
|
timer->deleteLater();
|
||||||
});
|
});
|
||||||
|
@ -176,9 +176,6 @@ endif()
|
|||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
if (CITRA_USE_PRECOMPILED_HEADERS)
|
||||||
target_precompile_headers(citra_common PRIVATE precompiled_headers.h)
|
target_precompile_headers(citra_common PRIVATE precompiled_headers.h)
|
||||||
endif()
|
endif()
|
||||||
|
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND CMAKE_CXX_COMPILER_ID STREQUAL GNU)
|
||||||
find_library(BACKTRACE_LIBRARY backtrace)
|
target_link_libraries(citra_common PRIVATE backtrace dl)
|
||||||
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)
|
|
||||||
endif()
|
endif()
|
||||||
|
@ -13,11 +13,12 @@
|
|||||||
#define _SH_DENYWR 0
|
#define _SH_DENYWR 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CITRA_LINUX_GCC_BACKTRACE
|
#if defined(__linux__) && defined(__GNUG__) && !defined(__clang__)
|
||||||
#define BOOST_STACKTRACE_USE_BACKTRACE
|
#define BOOST_STACKTRACE_USE_BACKTRACE
|
||||||
#include <boost/stacktrace.hpp>
|
#include <boost/stacktrace.hpp>
|
||||||
#undef BOOST_STACKTRACE_USE_BACKTRACE
|
#undef BOOST_STACKTRACE_USE_BACKTRACE
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#define CITRA_LINUX_GCC_BACKTRACE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common/bounded_threadsafe_queue.h"
|
#include "common/bounded_threadsafe_queue.h"
|
||||||
|
@ -100,14 +100,13 @@ enum Values {
|
|||||||
ZR,
|
ZR,
|
||||||
|
|
||||||
Home,
|
Home,
|
||||||
Power,
|
|
||||||
|
|
||||||
NumButtons,
|
NumButtons,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr int BUTTON_HID_BEGIN = A;
|
constexpr int BUTTON_HID_BEGIN = A;
|
||||||
constexpr int BUTTON_IR_BEGIN = ZL;
|
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_HID_END = BUTTON_IR_BEGIN;
|
||||||
constexpr int BUTTON_IR_END = BUTTON_NS_BEGIN;
|
constexpr int BUTTON_IR_END = BUTTON_NS_BEGIN;
|
||||||
@ -135,7 +134,6 @@ static const std::array<const char*, NumButtons> mapping = {{
|
|||||||
"button_zl",
|
"button_zl",
|
||||||
"button_zr",
|
"button_zr",
|
||||||
"button_home",
|
"button_home",
|
||||||
"button_power",
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
} // namespace NativeButton
|
} // namespace NativeButton
|
||||||
|
@ -62,29 +62,12 @@ public:
|
|||||||
return SlotId{index};
|
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 {
|
void erase(SlotId id) noexcept {
|
||||||
values[id.index].object.~T();
|
values[id.index].object.~T();
|
||||||
free_list.push_back(id.index);
|
free_list.push_back(id.index);
|
||||||
ResetStorageBit(id.index);
|
ResetStorageBit(id.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const noexcept {
|
|
||||||
return values_capacity - free_list.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct NonTrivialDummy {
|
struct NonTrivialDummy {
|
||||||
NonTrivialDummy() noexcept {}
|
NonTrivialDummy() noexcept {}
|
||||||
@ -110,7 +93,7 @@ private:
|
|||||||
return ((stored_bitset[index / 64] >> (index % 64)) & 1) != 0;
|
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);
|
||||||
DEBUG_ASSERT(id.index / 64 < stored_bitset.size());
|
DEBUG_ASSERT(id.index / 64 < stored_bitset.size());
|
||||||
DEBUG_ASSERT(((stored_bitset[id.index / 64] >> (id.index % 64)) & 1) != 0);
|
DEBUG_ASSERT(((stored_bitset[id.index / 64] >> (id.index % 64)) & 1) != 0);
|
||||||
|
@ -184,8 +184,6 @@ add_library(citra_core STATIC
|
|||||||
hle/kernel/wait_object.h
|
hle/kernel/wait_object.h
|
||||||
hle/lock.cpp
|
hle/lock.cpp
|
||||||
hle/lock.h
|
hle/lock.h
|
||||||
hle/mii.h
|
|
||||||
hle/mii.cpp
|
|
||||||
hle/result.h
|
hle/result.h
|
||||||
hle/romfs.cpp
|
hle/romfs.cpp
|
||||||
hle/romfs.h
|
hle/romfs.h
|
||||||
@ -247,8 +245,6 @@ add_library(citra_core STATIC
|
|||||||
hle/service/cam/cam_s.h
|
hle/service/cam/cam_s.h
|
||||||
hle/service/cam/cam_u.cpp
|
hle/service/cam/cam_u.cpp
|
||||||
hle/service/cam/cam_u.h
|
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.cpp
|
||||||
hle/service/cecd/cecd.h
|
hle/service/cecd/cecd.h
|
||||||
hle/service/cecd/cecd_ndm.cpp
|
hle/service/cecd/cecd_ndm.cpp
|
||||||
@ -259,8 +255,6 @@ add_library(citra_core STATIC
|
|||||||
hle/service/cecd/cecd_u.h
|
hle/service/cecd/cecd_u.h
|
||||||
hle/service/cfg/cfg.cpp
|
hle/service/cfg/cfg.cpp
|
||||||
hle/service/cfg/cfg.h
|
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.cpp
|
||||||
hle/service/cfg/cfg_i.h
|
hle/service/cfg/cfg_i.h
|
||||||
hle/service/cfg/cfg_nor.cpp
|
hle/service/cfg/cfg_nor.cpp
|
||||||
@ -281,8 +275,8 @@ add_library(citra_core STATIC
|
|||||||
hle/service/dlp/dlp_srvr.h
|
hle/service/dlp/dlp_srvr.h
|
||||||
hle/service/dsp/dsp_dsp.cpp
|
hle/service/dsp/dsp_dsp.cpp
|
||||||
hle/service/dsp/dsp_dsp.h
|
hle/service/dsp/dsp_dsp.h
|
||||||
hle/service/err/err_f.cpp
|
hle/service/err_f.cpp
|
||||||
hle/service/err/err_f.h
|
hle/service/err_f.h
|
||||||
hle/service/frd/frd.cpp
|
hle/service/frd/frd.cpp
|
||||||
hle/service/frd/frd.h
|
hle/service/frd/frd.h
|
||||||
hle/service/frd/frd_a.cpp
|
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_spvr.h
|
||||||
hle/service/hid/hid_user.cpp
|
hle/service/hid/hid_user.cpp
|
||||||
hle/service/hid/hid_user.h
|
hle/service/hid/hid_user.h
|
||||||
hle/service/http/http_c.cpp
|
hle/service/http_c.cpp
|
||||||
hle/service/http/http_c.h
|
hle/service/http_c.h
|
||||||
hle/service/ir/extra_hid.cpp
|
hle/service/ir/extra_hid.cpp
|
||||||
hle/service/ir/extra_hid.h
|
hle/service/ir/extra_hid.h
|
||||||
hle/service/ir/ir.cpp
|
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/cro_helper.h
|
||||||
hle/service/ldr_ro/ldr_ro.cpp
|
hle/service/ldr_ro/ldr_ro.cpp
|
||||||
hle/service/ldr_ro/ldr_ro.h
|
hle/service/ldr_ro/ldr_ro.h
|
||||||
hle/service/mic/mic_u.cpp
|
hle/service/mic_u.cpp
|
||||||
hle/service/mic/mic_u.h
|
hle/service/mic_u.h
|
||||||
hle/service/mvd/mvd.cpp
|
hle/service/mvd/mvd.cpp
|
||||||
hle/service/mvd/mvd.h
|
hle/service/mvd/mvd.h
|
||||||
hle/service/mvd/mvd_std.cpp
|
hle/service/mvd/mvd_std.cpp
|
||||||
@ -423,10 +417,12 @@ add_library(citra_core STATIC
|
|||||||
hle/service/sm/sm.h
|
hle/service/sm/sm.h
|
||||||
hle/service/sm/srv.cpp
|
hle/service/sm/srv.cpp
|
||||||
hle/service/sm/srv.h
|
hle/service/sm/srv.h
|
||||||
hle/service/soc/soc_u.cpp
|
hle/service/soc_u.cpp
|
||||||
hle/service/soc/soc_u.h
|
hle/service/soc_u.h
|
||||||
hle/service/ssl/ssl_c.cpp
|
hle/service/ssl_c.cpp
|
||||||
hle/service/ssl/ssl_c.h
|
hle/service/ssl_c.h
|
||||||
|
hle/service/y2r_u.cpp
|
||||||
|
hle/service/y2r_u.h
|
||||||
hw/aes/arithmetic128.cpp
|
hw/aes/arithmetic128.cpp
|
||||||
hw/aes/arithmetic128.h
|
hw/aes/arithmetic128.h
|
||||||
hw/aes/ccm.cpp
|
hw/aes/ccm.cpp
|
||||||
@ -461,6 +457,14 @@ add_library(citra_core STATIC
|
|||||||
perf_stats.cpp
|
perf_stats.cpp
|
||||||
perf_stats.h
|
perf_stats.h
|
||||||
precompiled_headers.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.cpp
|
||||||
savestate.h
|
savestate.h
|
||||||
system_titles.cpp
|
system_titles.cpp
|
||||||
@ -475,26 +479,16 @@ add_library(citra_core STATIC
|
|||||||
create_target_directory_groups(citra_core)
|
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 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)
|
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})
|
set_target_properties(citra_core PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${ENABLE_LTO})
|
||||||
|
|
||||||
if (ENABLE_WEB_SERVICE)
|
if (ENABLE_WEB_SERVICE)
|
||||||
target_link_libraries(citra_core PRIVATE web_service)
|
target_compile_definitions(citra_core PRIVATE -DENABLE_WEB_SERVICE -DCPPHTTPLIB_OPENSSL_SUPPORT)
|
||||||
endif()
|
target_link_libraries(citra_core PRIVATE web_service ${OPENSSL_LIBS} httplib)
|
||||||
|
if (ANDROID)
|
||||||
if (ENABLE_SCRIPTING)
|
target_link_libraries(citra_core PRIVATE ifaddrs)
|
||||||
target_compile_definitions(citra_core PUBLIC -DENABLE_SCRIPTING)
|
endif()
|
||||||
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()
|
endif()
|
||||||
|
|
||||||
if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE)
|
if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE)
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <boost/serialization/array.hpp>
|
#include <boost/serialization/array.hpp>
|
||||||
@ -14,8 +16,6 @@
|
|||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
#include "core/arm/exclusive_monitor.h"
|
#include "core/arm/exclusive_monitor.h"
|
||||||
#include "core/hle/service/cam/cam.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)
|
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
|
||||||
#include "core/arm/dynarmic/arm_dynarmic.h"
|
#include "core/arm/dynarmic/arm_dynarmic.h"
|
||||||
#endif
|
#endif
|
||||||
@ -35,8 +35,10 @@
|
|||||||
#include "core/hle/service/cam/cam.h"
|
#include "core/hle/service/cam/cam.h"
|
||||||
#include "core/hle/service/fs/archive.h"
|
#include "core/hle/service/fs/archive.h"
|
||||||
#include "core/hle/service/gsp/gsp.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/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/plgldr/plgldr.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
@ -45,10 +47,7 @@
|
|||||||
#include "core/hw/lcd.h"
|
#include "core/hw/lcd.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#ifdef ENABLE_SCRIPTING
|
#include "core/rpc/rpc_server.h"
|
||||||
#include "core/rpc/server.h"
|
|
||||||
#endif
|
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "video_core/custom_textures/custom_tex_manager.h"
|
#include "video_core/custom_textures/custom_tex_manager.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
@ -73,8 +72,6 @@ Core::Timing& Global() {
|
|||||||
return System::GetInstance().CoreTiming();
|
return System::GetInstance().CoreTiming();
|
||||||
}
|
}
|
||||||
|
|
||||||
System::System() : movie{*this} {}
|
|
||||||
|
|
||||||
System::~System() = default;
|
System::~System() = default;
|
||||||
|
|
||||||
System::ResultStatus System::RunLoop(bool tight_loop) {
|
System::ResultStatus System::RunLoop(bool tight_loop) {
|
||||||
@ -88,7 +85,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
|
|||||||
if (thread && running_core) {
|
if (thread && running_core) {
|
||||||
running_core->SaveContext(thread->context);
|
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
|
// 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.
|
// 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);
|
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
||||||
return ResultStatus::ErrorGetLoader;
|
return ResultStatus::ErrorGetLoader;
|
||||||
}
|
}
|
||||||
|
std::pair<std::optional<u32>, Loader::ResultStatus> system_mode =
|
||||||
|
app_loader->LoadKernelSystemMode();
|
||||||
|
|
||||||
auto memory_mode = app_loader->LoadKernelMemoryMode();
|
if (system_mode.second != Loader::ResultStatus::Success) {
|
||||||
if (memory_mode.second != Loader::ResultStatus::Success) {
|
|
||||||
LOG_CRITICAL(Core, "Failed to determine system mode (Error {})!",
|
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:
|
case Loader::ResultStatus::ErrorEncrypted:
|
||||||
return ResultStatus::ErrorLoader_ErrorEncrypted;
|
return ResultStatus::ErrorLoader_ErrorEncrypted;
|
||||||
case Loader::ResultStatus::ErrorInvalidFormat:
|
case Loader::ResultStatus::ErrorInvalidFormat:
|
||||||
@ -280,15 +278,15 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(memory_mode.first);
|
ASSERT(system_mode.first);
|
||||||
auto n3ds_hw_caps = app_loader->LoadNew3dsHwCapabilities();
|
auto n3ds_mode = app_loader->LoadKernelN3dsMode();
|
||||||
ASSERT(n3ds_hw_caps.first);
|
ASSERT(n3ds_mode.first);
|
||||||
u32 num_cores = 2;
|
u32 num_cores = 2;
|
||||||
if (Settings::values.is_new_3ds) {
|
if (Settings::values.is_new_3ds) {
|
||||||
num_cores = 4;
|
num_cores = 4;
|
||||||
}
|
}
|
||||||
ResultStatus init_result{
|
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) {
|
if (init_result != ResultStatus::Success) {
|
||||||
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
|
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
|
||||||
static_cast<u32>(init_result));
|
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);
|
cheat_engine = std::make_unique<Cheats::CheatEngine>(title_id, *this);
|
||||||
perf_stats = std::make_unique<PerfStats>(title_id);
|
perf_stats = std::make_unique<PerfStats>(title_id);
|
||||||
|
|
||||||
if (Settings::values.dump_textures) {
|
|
||||||
custom_tex_manager->PrepareDumping(title_id);
|
|
||||||
}
|
|
||||||
if (Settings::values.custom_textures) {
|
if (Settings::values.custom_textures) {
|
||||||
custom_tex_manager->FindCustomTextures();
|
custom_tex_manager->FindCustomTextures();
|
||||||
}
|
}
|
||||||
|
if (Settings::values.dump_textures) {
|
||||||
|
custom_tex_manager->WriteConfig();
|
||||||
|
}
|
||||||
|
|
||||||
status = ResultStatus::Success;
|
status = ResultStatus::Success;
|
||||||
m_emu_window = &emu_window;
|
m_emu_window = &emu_window;
|
||||||
@ -365,18 +363,16 @@ void System::Reschedule() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
|
System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
|
||||||
Frontend::EmuWindow* secondary_window,
|
Frontend::EmuWindow* secondary_window, u32 system_mode,
|
||||||
Kernel::MemoryMode memory_mode,
|
u8 n3ds_mode, u32 num_cores) {
|
||||||
const Kernel::New3dsHwCapabilities& n3ds_hw_caps, u32 num_cores) {
|
|
||||||
LOG_DEBUG(HW_Memory, "initialized OK");
|
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());
|
timing = std::make_unique<Timing>(num_cores, Settings::values.cpu_clock_percentage.GetValue());
|
||||||
|
|
||||||
kernel = std::make_unique<Kernel::KernelSystem>(
|
kernel = std::make_unique<Kernel::KernelSystem>(
|
||||||
*memory, *timing, [this] { PrepareReschedule(); }, memory_mode, num_cores, n3ds_hw_caps,
|
*memory, *timing, [this] { PrepareReschedule(); }, system_mode, num_cores, n3ds_mode);
|
||||||
movie.GetOverrideInitTime());
|
|
||||||
|
|
||||||
exclusive_monitor = MakeExclusiveMonitor(*memory, num_cores);
|
exclusive_monitor = MakeExclusiveMonitor(*memory, num_cores);
|
||||||
cpu_cores.reserve(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>();
|
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
||||||
|
|
||||||
#ifdef ENABLE_SCRIPTING
|
rpc_server = std::make_unique<RPC::RPCServer>();
|
||||||
rpc_server = std::make_unique<RPC::Server>(*this);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
service_manager = std::make_unique<Service::SM::ServiceManager>(*this);
|
service_manager = std::make_unique<Service::SM::ServiceManager>(*this);
|
||||||
archive_manager = std::make_unique<Service::FS::ArchiveManager>(*this);
|
archive_manager = std::make_unique<Service::FS::ArchiveManager>(*this);
|
||||||
@ -514,14 +508,6 @@ const VideoCore::CustomTexManager& System::CustomTexManager() const {
|
|||||||
return *custom_tex_manager;
|
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) {
|
void System::RegisterMiiSelector(std::shared_ptr<Frontend::MiiSelector> mii_selector) {
|
||||||
registered_mii_selector = std::move(mii_selector);
|
registered_mii_selector = std::move(mii_selector);
|
||||||
}
|
}
|
||||||
@ -559,9 +545,7 @@ void System::Shutdown(bool is_deserializing) {
|
|||||||
}
|
}
|
||||||
custom_tex_manager.reset();
|
custom_tex_manager.reset();
|
||||||
telemetry_session.reset();
|
telemetry_session.reset();
|
||||||
#ifdef ENABLE_SCRIPTING
|
|
||||||
rpc_server.reset();
|
rpc_server.reset();
|
||||||
#endif
|
|
||||||
archive_manager.reset();
|
archive_manager.reset();
|
||||||
service_manager.reset();
|
service_manager.reset();
|
||||||
dsp_core.reset();
|
dsp_core.reset();
|
||||||
@ -633,14 +617,16 @@ void System::ApplySettings() {
|
|||||||
if (VideoCore::g_renderer) {
|
if (VideoCore::g_renderer) {
|
||||||
auto& settings = VideoCore::g_renderer->Settings();
|
auto& settings = VideoCore::g_renderer->Settings();
|
||||||
settings.bg_color_update_requested = true;
|
settings.bg_color_update_requested = true;
|
||||||
|
settings.sampler_update_requested = true;
|
||||||
settings.shader_update_requested = true;
|
settings.shader_update_requested = true;
|
||||||
|
settings.texture_filter_update_requested = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsPoweredOn()) {
|
if (IsPoweredOn()) {
|
||||||
CoreTiming().UpdateClockSpeed(Settings::values.cpu_clock_percentage.GetValue());
|
CoreTiming().UpdateClockSpeed(Settings::values.cpu_clock_percentage.GetValue());
|
||||||
dsp_core->SetSink(Settings::values.output_type.GetValue(),
|
Core::DSP().SetSink(Settings::values.output_type.GetValue(),
|
||||||
Settings::values.output_device.GetValue());
|
Settings::values.output_device.GetValue());
|
||||||
dsp_core->EnableStretching(Settings::values.enable_audio_stretching.GetValue());
|
Core::DSP().EnableStretching(Settings::values.enable_audio_stretching.GetValue());
|
||||||
|
|
||||||
auto hid = Service::HID::GetModule(*this);
|
auto hid = Service::HID::GetModule(*this);
|
||||||
if (hid) {
|
if (hid) {
|
||||||
@ -687,10 +673,10 @@ void System::serialize(Archive& ar, const unsigned int file_version) {
|
|||||||
Shutdown(true);
|
Shutdown(true);
|
||||||
|
|
||||||
// Re-initialize everything like it was before
|
// Re-initialize everything like it was before
|
||||||
auto memory_mode = this->app_loader->LoadKernelMemoryMode();
|
auto system_mode = this->app_loader->LoadKernelSystemMode();
|
||||||
auto n3ds_hw_caps = this->app_loader->LoadNew3dsHwCapabilities();
|
auto n3ds_mode = this->app_loader->LoadKernelN3dsMode();
|
||||||
[[maybe_unused]] const System::ResultStatus result = Init(
|
[[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
|
// 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();
|
ar&* kernel.get();
|
||||||
VideoCore::serialize(ar, file_version);
|
VideoCore::serialize(ar, file_version);
|
||||||
if (file_version >= 1) {
|
if (file_version >= 1) {
|
||||||
ar& movie;
|
ar& Movie::GetInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This needs to be set from somewhere - might as well be here!
|
// This needs to be set from somewhere - might as well be here!
|
||||||
|
@ -10,17 +10,18 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/serialization/version.hpp>
|
#include <boost/serialization/version.hpp>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/frontend/applets/mii_selector.h"
|
||||||
#include "core/movie.h"
|
#include "core/frontend/applets/swkbd.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
|
#include "core/memory.h"
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
|
#include "core/telemetry_session.h"
|
||||||
|
|
||||||
class ARM_Interface;
|
class ARM_Interface;
|
||||||
|
|
||||||
namespace Frontend {
|
namespace Frontend {
|
||||||
class EmuWindow;
|
class EmuWindow;
|
||||||
class ImageInterface;
|
class ImageInterface;
|
||||||
class MiiSelector;
|
|
||||||
class SoftwareKeyboard;
|
|
||||||
} // namespace Frontend
|
} // namespace Frontend
|
||||||
|
|
||||||
namespace Memory {
|
namespace Memory {
|
||||||
@ -31,8 +32,8 @@ namespace AudioCore {
|
|||||||
class DspInterface;
|
class DspInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Core::RPC {
|
namespace RPC {
|
||||||
class Server;
|
class RPCServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Service {
|
namespace Service {
|
||||||
@ -46,9 +47,7 @@ class ArchiveManager;
|
|||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class KernelSystem;
|
class KernelSystem;
|
||||||
struct New3dsHwCapabilities;
|
}
|
||||||
enum class MemoryMode : u8;
|
|
||||||
} // namespace Kernel
|
|
||||||
|
|
||||||
namespace Cheats {
|
namespace Cheats {
|
||||||
class CheatEngine;
|
class CheatEngine;
|
||||||
@ -63,13 +62,8 @@ class CustomTexManager;
|
|||||||
class RendererBase;
|
class RendererBase;
|
||||||
} // namespace VideoCore
|
} // namespace VideoCore
|
||||||
|
|
||||||
namespace Loader {
|
|
||||||
class AppLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
class TelemetrySession;
|
|
||||||
class ExclusiveMonitor;
|
class ExclusiveMonitor;
|
||||||
class Timing;
|
class Timing;
|
||||||
|
|
||||||
@ -101,7 +95,6 @@ public:
|
|||||||
ErrorUnknown ///< Any other error
|
ErrorUnknown ///< Any other error
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit System();
|
|
||||||
~System();
|
~System();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,10 +187,6 @@ public:
|
|||||||
return *cpu_cores[core_id];
|
return *cpu_cores[core_id];
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] const ARM_Interface& GetCore(u32 core_id) const {
|
|
||||||
return *cpu_cores[core_id];
|
|
||||||
};
|
|
||||||
|
|
||||||
[[nodiscard]] u32 GetNumCores() const {
|
[[nodiscard]] u32 GetNumCores() const {
|
||||||
return static_cast<u32>(cpu_cores.size());
|
return static_cast<u32>(cpu_cores.size());
|
||||||
}
|
}
|
||||||
@ -269,12 +258,6 @@ public:
|
|||||||
/// Gets a const reference to the custom texture cache system
|
/// Gets a const reference to the custom texture cache system
|
||||||
[[nodiscard]] const VideoCore::CustomTexManager& CustomTexManager() const;
|
[[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
|
/// Video Dumper interface
|
||||||
|
|
||||||
void RegisterVideoDumper(std::shared_ptr<VideoDumper::Backend> video_dumper);
|
void RegisterVideoDumper(std::shared_ptr<VideoDumper::Backend> video_dumper);
|
||||||
@ -359,10 +342,8 @@ private:
|
|||||||
* @return ResultStatus code, indicating if the operation succeeded.
|
* @return ResultStatus code, indicating if the operation succeeded.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] ResultStatus Init(Frontend::EmuWindow& emu_window,
|
[[nodiscard]] ResultStatus Init(Frontend::EmuWindow& emu_window,
|
||||||
Frontend::EmuWindow* secondary_window,
|
Frontend::EmuWindow* secondary_window, u32 system_mode,
|
||||||
Kernel::MemoryMode memory_mode,
|
u8 n3ds_mode, u32 num_cores);
|
||||||
const Kernel::New3dsHwCapabilities& n3ds_hw_caps,
|
|
||||||
u32 num_cores);
|
|
||||||
|
|
||||||
/// Reschedule the core emulation
|
/// Reschedule the core emulation
|
||||||
void Reschedule();
|
void Reschedule();
|
||||||
@ -390,9 +371,6 @@ private:
|
|||||||
std::shared_ptr<Frontend::MiiSelector> registered_mii_selector;
|
std::shared_ptr<Frontend::MiiSelector> registered_mii_selector;
|
||||||
std::shared_ptr<Frontend::SoftwareKeyboard> registered_swkbd;
|
std::shared_ptr<Frontend::SoftwareKeyboard> registered_swkbd;
|
||||||
|
|
||||||
/// Movie recorder
|
|
||||||
Core::Movie movie;
|
|
||||||
|
|
||||||
/// Cheats manager
|
/// Cheats manager
|
||||||
std::unique_ptr<Cheats::CheatEngine> cheat_engine;
|
std::unique_ptr<Cheats::CheatEngine> cheat_engine;
|
||||||
|
|
||||||
@ -405,10 +383,8 @@ private:
|
|||||||
/// Image interface
|
/// Image interface
|
||||||
std::shared_ptr<Frontend::ImageInterface> registered_image_interface;
|
std::shared_ptr<Frontend::ImageInterface> registered_image_interface;
|
||||||
|
|
||||||
#ifdef ENABLE_SCRIPTING
|
|
||||||
/// RPC Server for scripting support
|
/// RPC Server for scripting support
|
||||||
std::unique_ptr<RPC::Server> rpc_server;
|
std::unique_ptr<RPC::RPCServer> rpc_server;
|
||||||
#endif
|
|
||||||
|
|
||||||
std::unique_ptr<Service::FS::ArchiveManager> archive_manager;
|
std::unique_ptr<Service::FS::ArchiveManager> archive_manager;
|
||||||
|
|
||||||
@ -457,6 +433,10 @@ private:
|
|||||||
return System::GetInstance().GetNumCores();
|
return System::GetInstance().GetNumCores();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline AudioCore::DspInterface& DSP() {
|
||||||
|
return System::GetInstance().DSP();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
BOOST_CLASS_VERSION(Core::System, 1)
|
BOOST_CLASS_VERSION(Core::System, 1)
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/file_sys/romfs_reader.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 };
|
enum NCSDContentIndex { Main = 0, Manual = 1, DLP = 2, New3DSUpdate = 6, Update = 7 };
|
||||||
|
|
||||||
@ -165,11 +165,7 @@ struct ExHeader_StorageInfo {
|
|||||||
struct ExHeader_ARM11_SystemLocalCaps {
|
struct ExHeader_ARM11_SystemLocalCaps {
|
||||||
u64_le program_id;
|
u64_le program_id;
|
||||||
u32_le core_version;
|
u32_le core_version;
|
||||||
union {
|
u8 reserved_flag;
|
||||||
u8 n3ds_cpu_flags;
|
|
||||||
BitField<0, 1, u8> enable_l2_cache;
|
|
||||||
BitField<1, 1, u8> enable_804MHz_cpu;
|
|
||||||
};
|
|
||||||
u8 n3ds_mode;
|
u8 n3ds_mode;
|
||||||
union {
|
union {
|
||||||
u8 flags0;
|
u8 flags0;
|
||||||
|
@ -181,12 +181,6 @@ std::array<u8, 16> TitleMetadata::GetContentCTRByIndex(std::size_t index) const
|
|||||||
return ctr;
|
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) {
|
void TitleMetadata::SetTitleID(u64 title_id) {
|
||||||
tmd_body.title_id = title_id;
|
tmd_body.title_id = title_id;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,6 @@ public:
|
|||||||
u16 GetContentTypeByIndex(std::size_t index) const;
|
u16 GetContentTypeByIndex(std::size_t index) const;
|
||||||
u64 GetContentSizeByIndex(std::size_t index) const;
|
u64 GetContentSizeByIndex(std::size_t index) const;
|
||||||
std::array<u8, 16> GetContentCTRByIndex(std::size_t index) const;
|
std::array<u8, 16> GetContentCTRByIndex(std::size_t index) const;
|
||||||
bool HasEncryptedContent() const;
|
|
||||||
|
|
||||||
void SetTitleID(u64 title_id);
|
void SetTitleID(u64 title_id);
|
||||||
void SetTitleType(u32 type);
|
void SetTitleType(u32 type);
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
|
|
||||||
namespace Frontend {
|
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};
|
data = {return_code, mii};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Mii::MiiData> LoadMiis() {
|
std::vector<HLE::Applets::MiiData> LoadMiis() {
|
||||||
std::vector<Mii::MiiData> miis;
|
std::vector<HLE::Applets::MiiData> miis;
|
||||||
|
|
||||||
std::string nand_directory{FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)};
|
std::string nand_directory{FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)};
|
||||||
FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true);
|
FileSys::ArchiveFactory_ExtSaveData extdata_archive_factory(nand_directory, true);
|
||||||
@ -36,7 +36,7 @@ std::vector<Mii::MiiData> LoadMiis() {
|
|||||||
u32 saved_miis_offset = 0x8;
|
u32 saved_miis_offset = 0x8;
|
||||||
// The Mii Maker has a 100 Mii limit on the 3ds
|
// The Mii Maker has a 100 Mii limit on the 3ds
|
||||||
for (int i = 0; i < 100; ++i) {
|
for (int i = 0; i < 100; ++i) {
|
||||||
Mii::MiiData mii;
|
HLE::Applets::MiiData mii;
|
||||||
std::array<u8, sizeof(mii)> mii_raw;
|
std::array<u8, sizeof(mii)> mii_raw;
|
||||||
file->Read(saved_miis_offset, sizeof(mii), mii_raw.data());
|
file->Read(saved_miis_offset, sizeof(mii), mii_raw.data());
|
||||||
std::memcpy(&mii, mii_raw.data(), sizeof(mii));
|
std::memcpy(&mii, mii_raw.data(), sizeof(mii));
|
||||||
|
@ -25,7 +25,7 @@ struct MiiSelectorConfig {
|
|||||||
|
|
||||||
struct MiiSelectorData {
|
struct MiiSelectorData {
|
||||||
u32 return_code;
|
u32 return_code;
|
||||||
Mii::MiiData mii;
|
HLE::Applets::MiiData mii;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MiiSelector {
|
class MiiSelector {
|
||||||
@ -43,14 +43,14 @@ public:
|
|||||||
* Stores the data so that the HLE applet in core can
|
* Stores the data so that the HLE applet in core can
|
||||||
* send this to the calling application
|
* send this to the calling application
|
||||||
*/
|
*/
|
||||||
void Finalize(u32 return_code, Mii::MiiData mii);
|
void Finalize(u32 return_code, HLE::Applets::MiiData mii);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MiiSelectorConfig config;
|
MiiSelectorConfig config;
|
||||||
MiiSelectorData data;
|
MiiSelectorData data;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Mii::MiiData> LoadMiis();
|
std::vector<HLE::Applets::MiiData> LoadMiis();
|
||||||
|
|
||||||
class DefaultMiiSelector final : public MiiSelector {
|
class DefaultMiiSelector final : public MiiSelector {
|
||||||
public:
|
public:
|
||||||
|
@ -55,17 +55,15 @@ EmuWindow::EmuWindow(bool is_secondary_) : is_secondary{is_secondary_} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EmuWindow::~EmuWindow() = default;
|
EmuWindow::~EmuWindow() = default;
|
||||||
|
/**
|
||||||
bool EmuWindow::IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x,
|
* Check if the given x/y coordinates are within the touchpad specified by the framebuffer layout
|
||||||
unsigned framebuffer_y) {
|
* @param layout FramebufferLayout object describing the framebuffer size and screen positions
|
||||||
#ifndef ANDROID
|
* @param framebuffer_x Framebuffer x-coordinate to check
|
||||||
// If separate windows and the touch is in the primary (top) screen, ignore it.
|
* @param framebuffer_y Framebuffer y-coordinate to check
|
||||||
if (Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows &&
|
* @return True if the coordinates are within the touchpad, otherwise false
|
||||||
!is_secondary && !Settings::values.swap_screen.GetValue()) {
|
*/
|
||||||
return false;
|
static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x,
|
||||||
}
|
unsigned framebuffer_y) {
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) {
|
||||||
return (framebuffer_y >= layout.bottom_screen.top &&
|
return (framebuffer_y >= layout.bottom_screen.top &&
|
||||||
framebuffer_y < layout.bottom_screen.bottom &&
|
framebuffer_y < layout.bottom_screen.bottom &&
|
||||||
|
@ -288,17 +288,6 @@ private:
|
|||||||
|
|
||||||
void CreateTouchState();
|
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
|
Layout::FramebufferLayout framebuffer_layout; ///< Current framebuffer layout
|
||||||
|
|
||||||
WindowConfig config{}; ///< Internal configuration (changes pending for being applied in
|
WindowConfig config{}; ///< Internal configuration (changes pending for being applied in
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "core/gdbstub/gdbstub.h"
|
#include "core/gdbstub/gdbstub.h"
|
||||||
#include "core/gdbstub/hio.h"
|
#include "core/gdbstub/hio.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
namespace GDBStub {
|
namespace GDBStub {
|
||||||
@ -1034,7 +1035,7 @@ static void RemoveBreakpoint() {
|
|||||||
SendReply("OK");
|
SendReply("OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandlePacket(Core::System& system) {
|
void HandlePacket() {
|
||||||
if (!IsConnected()) {
|
if (!IsConnected()) {
|
||||||
if (defer_start) {
|
if (defer_start) {
|
||||||
ToggleServer(true);
|
ToggleServer(true);
|
||||||
@ -1075,7 +1076,7 @@ void HandlePacket(Core::System& system) {
|
|||||||
Continue();
|
Continue();
|
||||||
return;
|
return;
|
||||||
case 'F':
|
case 'F':
|
||||||
HandleHioReply(system, command_buffer, command_length);
|
HandleHioReply(command_buffer, command_length);
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
ReadRegisters();
|
ReadRegisters();
|
||||||
|
@ -10,10 +10,6 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/kernel/thread.h"
|
#include "core/hle/kernel/thread.h"
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace GDBStub {
|
namespace GDBStub {
|
||||||
|
|
||||||
/// Breakpoint Method
|
/// Breakpoint Method
|
||||||
@ -74,7 +70,7 @@ void Break(bool is_memory_break = false);
|
|||||||
bool IsMemoryBreak();
|
bool IsMemoryBreak();
|
||||||
|
|
||||||
/// Read and handle packet from gdb client.
|
/// 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.
|
* Get the nearest breakpoint of the specified type at the given address.
|
||||||
|
@ -54,7 +54,7 @@ static void SendErrorReply(int error_code, int retval = -1) {
|
|||||||
SendReply(packet.data());
|
SendReply(packet.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetHioRequest(Core::System& system, const VAddr addr) {
|
void SetHioRequest(const VAddr addr) {
|
||||||
if (!IsServerEnabled()) {
|
if (!IsServerEnabled()) {
|
||||||
LOG_WARNING(Debug_GDBStub, "HIO requested but GDB stub is not running");
|
LOG_WARNING(Debug_GDBStub, "HIO requested but GDB stub is not running");
|
||||||
return;
|
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");
|
LOG_INFO(Debug_GDBStub, "overwriting existing HIO request that was not sent yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& memory = system.Memory();
|
auto& memory = Core::System::GetInstance().Memory();
|
||||||
const auto process = system.Kernel().GetCurrentProcess();
|
const auto process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
|
|
||||||
if (!memory.IsValidVirtualAddress(*process, addr)) {
|
if (!memory.IsValidVirtualAddress(*process, addr)) {
|
||||||
LOG_WARNING(Debug_GDBStub, "Invalid address for HIO request");
|
LOG_WARNING(Debug_GDBStub, "Invalid address for HIO request");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory.ReadBlock(addr, ¤t_hio_request, sizeof(PackedGdbHioRequest));
|
memory.ReadBlock(*process, addr, ¤t_hio_request, sizeof(PackedGdbHioRequest));
|
||||||
|
|
||||||
if (current_hio_request.magic != std::array{'G', 'D', 'B', '\0'}) {
|
if (current_hio_request.magic != std::array{'G', 'D', 'B', '\0'}) {
|
||||||
std::string_view bad_magic{
|
std::string_view bad_magic{
|
||||||
@ -105,11 +105,10 @@ void SetHioRequest(Core::System& system, const VAddr addr) {
|
|||||||
Break();
|
Break();
|
||||||
SetCpuHaltFlag(true);
|
SetCpuHaltFlag(true);
|
||||||
SetCpuStepFlag(false);
|
SetCpuStepFlag(false);
|
||||||
system.GetRunningCore().ClearInstructionCache();
|
Core::GetRunningCore().ClearInstructionCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleHioReply(Core::System& system, const u8* const command_buffer,
|
void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
|
||||||
const u32 command_length) {
|
|
||||||
if (!IsWaitingForHioReply()) {
|
if (!IsWaitingForHioReply()) {
|
||||||
LOG_WARNING(Debug_GDBStub, "Got HIO reply but never sent a request");
|
LOG_WARNING(Debug_GDBStub, "Got HIO reply but never sent a request");
|
||||||
return;
|
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.retval, current_hio_request.gdb_errno,
|
||||||
current_hio_request.ctrl_c);
|
current_hio_request.ctrl_c);
|
||||||
|
|
||||||
const auto process = system.Kernel().GetCurrentProcess();
|
const auto process = Core::System::GetInstance().Kernel().GetCurrentProcess();
|
||||||
auto& memory = system.Memory();
|
auto& memory = Core::System::GetInstance().Memory();
|
||||||
|
|
||||||
// should have been checked when we first initialized the request,
|
// should have been checked when we first initialized the request,
|
||||||
// but just double check again before we write to memory
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory.WriteBlock(current_hio_request_addr, ¤t_hio_request, sizeof(PackedGdbHioRequest));
|
memory.WriteBlock(*process, current_hio_request_addr, ¤t_hio_request,
|
||||||
|
sizeof(PackedGdbHioRequest));
|
||||||
|
|
||||||
current_hio_request = {};
|
current_hio_request = {};
|
||||||
current_hio_request_addr = 0;
|
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
|
// Restore state from before the request came in
|
||||||
SetCpuStepFlag(was_stepping);
|
SetCpuStepFlag(was_stepping);
|
||||||
SetCpuHaltFlag(was_halted);
|
SetCpuHaltFlag(was_halted);
|
||||||
system.GetRunningCore().ClearInstructionCache();
|
Core::GetRunningCore().ClearInstructionCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HandlePendingHioRequestPacket() {
|
bool HandlePendingHioRequestPacket() {
|
||||||
|
@ -6,10 +6,6 @@
|
|||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace GDBStub {
|
namespace GDBStub {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +47,7 @@ static_assert(sizeof(PackedGdbHioRequest) == 152,
|
|||||||
*
|
*
|
||||||
* @param address The memory address of the \ref PackedGdbHioRequest.
|
* @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.
|
* 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.
|
* 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
|
} // namespace GDBStub
|
||||||
|
@ -71,6 +71,9 @@ void MiiSelector::Update() {
|
|||||||
const MiiSelectorData& data = frontend_applet->ReceiveData();
|
const MiiSelectorData& data = frontend_applet->ReceiveData();
|
||||||
result.return_code = data.return_code;
|
result.return_code = data.return_code;
|
||||||
result.selected_mii_data = data.mii;
|
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;
|
result.selected_guest_mii_index = 0xFFFFFFFF;
|
||||||
|
|
||||||
// TODO(Subv): We're finalizing the applet immediately after it's started,
|
// 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
|
// 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
|
// 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
|
// to the members of the MiiResult struct
|
||||||
Mii::MiiData mii_data;
|
MiiData mii_data;
|
||||||
mii_data.magic = 0x03;
|
mii_data.mii_id = 0x03001030;
|
||||||
mii_data.mii_options.raw = 0x00;
|
|
||||||
mii_data.mii_pos.raw = 0x10;
|
|
||||||
mii_data.console_identity.raw = 0x30;
|
|
||||||
mii_data.system_id = 0xD285B6B300C8850A;
|
mii_data.system_id = 0xD285B6B300C8850A;
|
||||||
mii_data.mii_id = 0x98391EE4;
|
mii_data.specialness_and_creation_date = 0x98391EE4;
|
||||||
mii_data.mac = {0x40, 0xF4, 0x07, 0xB7, 0x37, 0x10};
|
mii_data.creator_mac = {0x40, 0xF4, 0x07, 0xB7, 0x37, 0x10};
|
||||||
mii_data.pad = 0x0000;
|
mii_data.padding = 0x0;
|
||||||
mii_data.mii_details.raw = 0xA600;
|
mii_data.mii_information = 0xA600;
|
||||||
mii_data.mii_name = {'C', 'i', 't', 'r', 'a', 0x0, 0x0, 0x0, 0x0, 0x0};
|
mii_data.mii_name = {'C', 'i', 't', 'r', 'a', 0x0, 0x0, 0x0, 0x0, 0x0};
|
||||||
mii_data.height = 0x40;
|
mii_data.width_height = 0x4040;
|
||||||
mii_data.width = 0x40;
|
mii_data.appearance_bits1.raw = 0x0;
|
||||||
mii_data.face_style.raw = 0x00;
|
mii_data.appearance_bits2.raw = 0x0;
|
||||||
mii_data.face_details.raw = 0x00;
|
|
||||||
mii_data.hair_style = 0x21;
|
mii_data.hair_style = 0x21;
|
||||||
mii_data.hair_details.raw = 0x01;
|
mii_data.appearance_bits3.hair_color.Assign(0x1);
|
||||||
mii_data.eye_details.raw = 0x02684418;
|
mii_data.appearance_bits3.flip_hair.Assign(0x0);
|
||||||
mii_data.eyebrow_details.raw = 0x26344614;
|
mii_data.unknown1 = 0x02684418;
|
||||||
mii_data.nose_details.raw = 0x8112;
|
mii_data.appearance_bits4.eyebrow_style.Assign(0x6);
|
||||||
mii_data.mouth_details.raw = 0x1768;
|
mii_data.appearance_bits4.eyebrow_color.Assign(0x1);
|
||||||
mii_data.mustache_details.raw = 0x0D00;
|
mii_data.appearance_bits5.eyebrow_scale.Assign(0x4);
|
||||||
mii_data.beard_details.raw = 0x0029;
|
mii_data.appearance_bits5.eyebrow_yscale.Assign(0x3);
|
||||||
mii_data.glasses_details.raw = 0x0052;
|
mii_data.appearance_bits6 = 0x4614;
|
||||||
mii_data.mole_details.raw = 0x4850;
|
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};
|
mii_data.author_name = {'f', 'l', 'T', 'o', 'b', 'i', 0x0, 0x0, 0x0, 0x0};
|
||||||
|
|
||||||
MiiResult result;
|
MiiResult result;
|
||||||
@ -121,6 +122,8 @@ MiiResult MiiSelector::GetStandardMiiResult() {
|
|||||||
result.is_guest_mii_selected = 0x0;
|
result.is_guest_mii_selected = 0x0;
|
||||||
result.selected_guest_mii_index = 0xFFFFFFFF;
|
result.selected_guest_mii_index = 0xFFFFFFFF;
|
||||||
result.selected_mii_data = mii_data;
|
result.selected_mii_data = mii_data;
|
||||||
|
result.unknown1 = 0x0;
|
||||||
|
result.mii_data_checksum = 0x056C;
|
||||||
result.guest_mii_name.fill(0x0);
|
result.guest_mii_name.fill(0x0);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user