Compare commits
202 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 82fa9f8d56 | |||
| 51cddcb8b8 | |||
| 2ddd83cdfe | |||
| 8b95bf041d | |||
| 93cb783853 | |||
| d5e0923e3d | |||
| d46ca5a015 | |||
| 46183294b2 | |||
| f9653a4417 | |||
| 54ea3c47c8 | |||
| 5836786246 | |||
| 51a7681957 | |||
| d6d1a8e02c | |||
| 89df483567 | |||
| a5750f437d | |||
| ccb439efb0 | |||
| 0b47f7a46b | |||
| 79316be18c | |||
| ec100ca4db | |||
| 5d29d2111c | |||
| ac3b4f918f | |||
| 9b023a56a3 | |||
| f3db273753 | |||
| 2e1b998d5e | |||
| 37bec068c2 | |||
| df6427d30b | |||
| c96930fd9d | |||
| 292dd642ce | |||
| 761206cf81 | |||
| 1c773c0869 | |||
| 69b46dd607 | |||
| c918c6480f | |||
| 37194dd4e9 | |||
| 4de079b256 | |||
| 8941cdb7d2 | |||
| dfee6321cd | |||
| 0195038c07 | |||
| ac3ec5ed13 | |||
| cdb36aef9e | |||
| 5e9b77129f | |||
| 2d47a5fd41 | |||
| 3802474483 | |||
| d1a2b3fb18 | |||
| b1657b8c6b | |||
| ec8548b414 | |||
| 4e94d0d53a | |||
| bab9cae71f | |||
| 6d6115475b | |||
| b06d6e3646 | |||
| 5fe55b16a1 | |||
| 5329834376 | |||
| 52f13f2339 | |||
| e94dd7e2c4 | |||
| ce5fcb6bb2 | |||
| 20aad9e01a | |||
| 6f41763061 | |||
| 05a703e15d | |||
| 0e54aa17e6 | |||
| 2de124e223 | |||
| aeb100cffe | |||
| f1d633cca7 | |||
| 6057dc46e5 | |||
| deff708cbe | |||
| a9cfe06aaf | |||
| 009bdb3558 | |||
| a44ff5ed31 | |||
| 00c6254129 | |||
| e15039372e | |||
| 0eb6c6cd83 | |||
| 51e6f8271a | |||
| 6b7320add4 | |||
| 215cfbb757 | |||
| 97dd67ad1c | |||
| 607bb8d14b | |||
| b57ba7bfb6 | |||
| 3415890dd5 | |||
| 4bd74ed4c7 | |||
| f782aecf4d | |||
| 09fa1d6a73 | |||
| 45c5b084fd | |||
| edcbd47800 | |||
| 5cd051eced | |||
| 12f3b13995 | |||
| 3ef35207c1 | |||
| 5d2f18fbcd | |||
| 3954f14c6d | |||
| 9ae6224f12 | |||
| a58d57a60d | |||
| 24cabf5e2f | |||
| 7234f436aa | |||
| 4c5f5c9bf3 | |||
| 8a00a0ade6 | |||
| 43f0b42088 | |||
| 23aabe85e6 | |||
| 69af6ada2f | |||
| 9e7a1f1351 | |||
| ce0712bf95 | |||
| bcc5c4403a | |||
| 2dce2be138 | |||
| 0791082b43 | |||
| 5933667cb8 | |||
| e31cb50405 | |||
| 3373149fdc | |||
| 0e122c13ad | |||
| eea5122d1b | |||
| b8fbf6969c | |||
| feac654ba0 | |||
| 5cb1a343d1 | |||
| 0dc234c5ea | |||
| 716ae72aac | |||
| d637114c17 | |||
| 7e5f595b31 | |||
| 88959b0047 | |||
| dd05c7ec79 | |||
| 53a04d6b5d | |||
| c67c25db05 | |||
| a6e6cd5788 | |||
| 9dc69fa07c | |||
| a1e7360273 | |||
| f95602f152 | |||
| c277d7d171 | |||
| f6d4a289d5 | |||
| f2f346e110 | |||
| 414a87a4f4 | |||
| e6a896c4bd | |||
| 63419e144f | |||
| 2c375013dd | |||
| b126267442 | |||
| 2a928d7492 | |||
| 7fbeb489d3 | |||
| 37d672bf08 | |||
| 1c8de85045 | |||
| 94af77aa7c | |||
| 677a8b208d | |||
| c2f83c04cb | |||
| fad38ec6e8 | |||
| defa826c53 | |||
| 69aaad9b96 | |||
| edd8208779 | |||
| 7cf34c3637 | |||
| 843ef8f2ec | |||
| cf9767c608 | |||
| 424bffcd3f | |||
| 16aadcc354 | |||
| 395997178b | |||
| 5842a767a9 | |||
| 774d7eab64 | |||
| 88089c8754 | |||
| 1ea6bdef05 | |||
| 9abb23cd27 | |||
| 25f650e075 | |||
| d39dfdf45c | |||
| ece0ae2bfb | |||
| 7b4a213603 | |||
| 44f7067cab | |||
| 756225c8ff | |||
| 7bc3e80399 | |||
| 63b3b25715 | |||
| 4b9e1b6586 | |||
| b7ef581c6e | |||
| 24cae76d16 | |||
| c2ad1243ba | |||
| 63fd1bb503 | |||
| c0870315fd | |||
| 9705f651b2 | |||
| 9423347c1b | |||
| c042a89113 | |||
| 7b642c7781 | |||
| 6750b4d3af | |||
| 6314ed5de0 | |||
| 4eb7327559 | |||
| 312a8bd4b4 | |||
| e0d30fc920 | |||
| d7019d8307 | |||
| d9b729bbfd | |||
| 1fde40b2c7 | |||
| fca87cfa3e | |||
| 32f3b6b865 | |||
| 3dc310bd52 | |||
| 1dbe39f7a2 | |||
| 5bc4eabe36 | |||
| f397edff0e | |||
| 073e07ae2d | |||
| ee5e77fbf9 | |||
| 3898d8f0d7 | |||
| 1a954b2a59 | |||
| ab315011fb | |||
| 4681e1ea9e | |||
| 2ccf85a910 | |||
| 9d3d0ae999 | |||
| 322349e8cc | |||
| e46f0e084c | |||
| ebcee03b0c | |||
| 2c2b586d86 | |||
| 630823e363 | |||
| b70751ccb9 | |||
| e48e9a406c | |||
| 0e15c68f54 | |||
| 6f70e1b1ff | |||
| e8b2fd21d8 | |||
| ab25d1fe9a | |||
| 994f497781 |
@@ -5,7 +5,7 @@ cd /yuzu
|
||||
ccache -s
|
||||
|
||||
mkdir build || true && cd build
|
||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DYUZU_USE_BUNDLED_UNICORN=ON -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON
|
||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON
|
||||
|
||||
ninja
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ cd /yuzu
|
||||
ccache -s
|
||||
|
||||
mkdir build || true && cd build
|
||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DYUZU_USE_BUNDLED_UNICORN=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON
|
||||
cmake .. -G Ninja -DDISPLAY_VERSION=$1 -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON
|
||||
ninja
|
||||
|
||||
ccache -s
|
||||
|
||||
@@ -8,7 +8,7 @@ steps:
|
||||
displayName: 'Install vulkan-sdk'
|
||||
- script: python -m pip install --upgrade pip conan
|
||||
displayName: 'Install conan'
|
||||
- script: refreshenv && mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 --config Release -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_UNICORN=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cd ..
|
||||
- script: refreshenv && mkdir build && cd build && cmake -G "Visual Studio 16 2019" -A x64 --config Release -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DUSE_DISCORD_PRESENCE=ON -DDISPLAY_VERSION=${{ parameters['version'] }} .. && cd ..
|
||||
displayName: 'Configure CMake'
|
||||
- task: MSBuild@1
|
||||
displayName: 'Build'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
mkdir -p "$HOME/.ccache"
|
||||
docker run -e ENABLE_COMPATIBILITY_REPORTING --env-file .travis/common/travis-ci.env -v $(pwd):/yuzu -v "$HOME/.ccache":/root/.ccache yuzuemu/build-environments:linux-fresh /bin/bash /yuzu/.travis/linux/docker.sh
|
||||
docker run -e ENABLE_COMPATIBILITY_REPORTING --env-file .travis/common/travis-ci.env -v $(pwd):/yuzu -v "$HOME/.ccache":/home/yuzu/.ccache yuzuemu/build-environments:linux-fresh /bin/bash /yuzu/.travis/linux/docker.sh
|
||||
|
||||
+30
-1
@@ -113,6 +113,9 @@ if (NOT DEFINED ARCHITECTURE)
|
||||
endif()
|
||||
message(STATUS "Target architecture: ${ARCHITECTURE}")
|
||||
|
||||
if (UNIX)
|
||||
add_definitions(-DYUZU_UNIX=1)
|
||||
endif()
|
||||
|
||||
# Configure C++ standard
|
||||
# ===========================
|
||||
@@ -157,7 +160,6 @@ macro(yuzu_find_packages)
|
||||
# Capitalization matters here. We need the naming to match the generated paths from Conan
|
||||
set(REQUIRED_LIBS
|
||||
# Cmake Pkg Prefix Version Conan Pkg
|
||||
"Boost 1.73 boost/1.73.0"
|
||||
"Catch2 2.13 catch2/2.13.0"
|
||||
"fmt 7.1 fmt/7.1.2"
|
||||
# can't use until https://github.com/bincrafters/community/issues/1173
|
||||
@@ -192,6 +194,22 @@ macro(yuzu_find_packages)
|
||||
unset(FN_FORCE_REQUIRED)
|
||||
endmacro()
|
||||
|
||||
find_package(Boost 1.73.0 COMPONENTS context headers QUIET)
|
||||
if (Boost_FOUND)
|
||||
set(Boost_LIBRARIES Boost::boost)
|
||||
# Conditionally add Boost::context only if the active version of the Conan or system Boost package provides it
|
||||
# The old version is missing Boost::context, so we want to avoid adding in that case
|
||||
# The new version requires adding Boost::context to prevent linking issues
|
||||
#
|
||||
# This one is used by Conan on subsequent CMake configures, not the first configure.
|
||||
if (TARGET Boost::context)
|
||||
list(APPEND Boost_LIBRARIES Boost::context)
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Boost 1.73.0 or newer not found, falling back to Conan")
|
||||
list(APPEND CONAN_REQUIRED_LIBS "boost/1.73.0")
|
||||
endif()
|
||||
|
||||
# Attempt to locate any packages that are required and report the missing ones in CONAN_REQUIRED_LIBS
|
||||
yuzu_find_packages()
|
||||
|
||||
@@ -296,6 +314,17 @@ if (CONAN_REQUIRED_LIBS)
|
||||
# this time with required, so we bail if its not found.
|
||||
yuzu_find_packages(FORCE_REQUIRED)
|
||||
|
||||
if (NOT Boost_FOUND)
|
||||
find_package(Boost 1.73.0 REQUIRED COMPONENTS context headers)
|
||||
set(Boost_LIBRARIES Boost::boost)
|
||||
# Conditionally add Boost::context only if the active version of the Conan Boost package provides it
|
||||
# The old version is missing Boost::context, so we want to avoid adding in that case
|
||||
# The new version requires adding Boost::context to prevent linking issues
|
||||
if (TARGET Boost::context)
|
||||
list(APPEND Boost_LIBRARIES Boost::context)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Due to issues with variable scopes in functions, we need to also find_package(qt5) outside of the function
|
||||
if(ENABLE_QT)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CONAN_QT_ROOT_RELEASE}")
|
||||
|
||||
Vendored
+1
-1
Submodule externals/cubeb updated: 616d773441...1d66483ad2
@@ -66,6 +66,7 @@ else()
|
||||
-Wextra
|
||||
-Wmissing-declarations
|
||||
-Wno-attributes
|
||||
-Wno-invalid-offsetof
|
||||
-Wno-unused-parameter
|
||||
)
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ if (NOT MSVC)
|
||||
-Werror=implicit-fallthrough
|
||||
-Werror=reorder
|
||||
-Werror=sign-compare
|
||||
-Werror=shadow
|
||||
-Werror=unused-parameter
|
||||
-Werror=unused-variable
|
||||
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
|
||||
|
||||
@@ -31,8 +31,8 @@ Filter Filter::LowPass(double cutoff, double Q) {
|
||||
|
||||
Filter::Filter() : Filter(1.0, 0.0, 0.0, 1.0, 0.0, 0.0) {}
|
||||
|
||||
Filter::Filter(double a0, double a1, double a2, double b0, double b1, double b2)
|
||||
: a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {}
|
||||
Filter::Filter(double a0_, double a1_, double a2_, double b0_, double b1_, double b2_)
|
||||
: a1(a1_ / a0_), a2(a2_ / a0_), b0(b0_ / a0_), b1(b1_ / a0_), b2(b2_ / a0_) {}
|
||||
|
||||
void Filter::Process(std::vector<s16>& signal) {
|
||||
const std::size_t num_frames = signal.size() / 2;
|
||||
@@ -69,7 +69,7 @@ CascadingFilter CascadingFilter::LowPass(double cutoff, std::size_t cascade_size
|
||||
}
|
||||
|
||||
CascadingFilter::CascadingFilter() = default;
|
||||
CascadingFilter::CascadingFilter(std::vector<Filter> filters) : filters(std::move(filters)) {}
|
||||
CascadingFilter::CascadingFilter(std::vector<Filter> filters_) : filters(std::move(filters_)) {}
|
||||
|
||||
void CascadingFilter::Process(std::vector<s16>& signal) {
|
||||
for (auto& filter : filters) {
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
/// Passthrough filter.
|
||||
Filter();
|
||||
|
||||
Filter(double a0, double a1, double a2, double b0, double b1, double b2);
|
||||
Filter(double a0_, double a1_, double a2_, double b0_, double b1_, double b2_);
|
||||
|
||||
void Process(std::vector<s16>& signal);
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
/// Passthrough.
|
||||
CascadingFilter();
|
||||
|
||||
explicit CascadingFilter(std::vector<Filter> filters);
|
||||
explicit CascadingFilter(std::vector<Filter> filters_);
|
||||
|
||||
void Process(std::vector<s16>& signal);
|
||||
|
||||
|
||||
@@ -71,16 +71,15 @@ namespace {
|
||||
namespace AudioCore {
|
||||
AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
|
||||
AudioCommon::AudioRendererParameter params,
|
||||
std::shared_ptr<Kernel::WritableEvent> buffer_event,
|
||||
std::shared_ptr<Kernel::WritableEvent> buffer_event_,
|
||||
std::size_t instance_number)
|
||||
: worker_params{params}, buffer_event{buffer_event},
|
||||
: worker_params{params}, buffer_event{buffer_event_},
|
||||
memory_pool_info(params.effect_count + params.voice_count * 4),
|
||||
voice_context(params.voice_count), effect_context(params.effect_count), mix_context(),
|
||||
sink_context(params.sink_count), splitter_context(),
|
||||
voices(params.voice_count), memory{memory_},
|
||||
command_generator(worker_params, voice_context, mix_context, splitter_context, effect_context,
|
||||
memory),
|
||||
temp_mix_buffer(AudioCommon::TOTAL_TEMP_MIX_SIZE) {
|
||||
memory) {
|
||||
behavior_info.SetUserRevision(params.revision);
|
||||
splitter_context.Initialize(behavior_info, params.splitter_count,
|
||||
params.num_splitter_send_channels);
|
||||
@@ -89,7 +88,7 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory
|
||||
stream =
|
||||
audio_out->OpenStream(core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS,
|
||||
fmt::format("AudioRenderer-Instance{}", instance_number),
|
||||
[=]() { buffer_event->Signal(); });
|
||||
[=]() { buffer_event_->Signal(); });
|
||||
audio_out->StartStream(stream);
|
||||
|
||||
QueueMixedBuffer(0);
|
||||
|
||||
@@ -44,7 +44,8 @@ class AudioRenderer {
|
||||
public:
|
||||
AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
|
||||
AudioCommon::AudioRendererParameter params,
|
||||
std::shared_ptr<Kernel::WritableEvent> buffer_event, std::size_t instance_number);
|
||||
std::shared_ptr<Kernel::WritableEvent> buffer_event_,
|
||||
std::size_t instance_number);
|
||||
~AudioRenderer();
|
||||
|
||||
[[nodiscard]] ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params,
|
||||
@@ -73,7 +74,6 @@ private:
|
||||
Core::Memory::Memory& memory;
|
||||
CommandGenerator command_generator;
|
||||
std::size_t elapsed_frame_count{};
|
||||
std::vector<s32> temp_mix_buffer{};
|
||||
};
|
||||
|
||||
} // namespace AudioCore
|
||||
|
||||
@@ -18,7 +18,7 @@ class Buffer {
|
||||
public:
|
||||
using Tag = u64;
|
||||
|
||||
Buffer(Tag tag, std::vector<s16>&& samples) : tag{tag}, samples{std::move(samples)} {}
|
||||
Buffer(Tag tag_, std::vector<s16>&& samples_) : tag{tag_}, samples{std::move(samples_)} {}
|
||||
|
||||
/// Returns the raw audio data for the buffer
|
||||
std::vector<s16>& GetSamples() {
|
||||
|
||||
@@ -67,12 +67,12 @@ s32 ApplyMixDepop(s32* output, s32 first_sample, s32 delta, s32 sample_count) {
|
||||
|
||||
} // namespace
|
||||
|
||||
CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params,
|
||||
VoiceContext& voice_context, MixContext& mix_context,
|
||||
SplitterContext& splitter_context, EffectContext& effect_context,
|
||||
Core::Memory::Memory& memory)
|
||||
: worker_params(worker_params), voice_context(voice_context), mix_context(mix_context),
|
||||
splitter_context(splitter_context), effect_context(effect_context), memory(memory),
|
||||
CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_,
|
||||
VoiceContext& voice_context_, MixContext& mix_context_,
|
||||
SplitterContext& splitter_context_,
|
||||
EffectContext& effect_context_, Core::Memory::Memory& memory_)
|
||||
: worker_params(worker_params_), voice_context(voice_context_), mix_context(mix_context_),
|
||||
splitter_context(splitter_context_), effect_context(effect_context_), memory(memory_),
|
||||
mix_buffer((worker_params.mix_buffer_count + AudioCommon::MAX_CHANNEL_COUNT) *
|
||||
worker_params.sample_count),
|
||||
sample_buffer(MIX_BUFFER_SIZE),
|
||||
@@ -255,7 +255,8 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo
|
||||
|
||||
void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info,
|
||||
VoiceState& dsp_state,
|
||||
s32 mix_buffer_count, s32 channel) {
|
||||
[[maybe_unused]] s32 mix_buffer_count,
|
||||
[[maybe_unused]] s32 channel) {
|
||||
for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) {
|
||||
const auto& in_params = voice_info.GetInParams();
|
||||
auto& biquad_filter = in_params.biquad_filter[i];
|
||||
@@ -278,9 +279,12 @@ void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voic
|
||||
}
|
||||
}
|
||||
|
||||
void AudioCore::CommandGenerator::GenerateBiquadFilterCommand(
|
||||
s32 mix_buffer, const BiquadFilterParameter& params, std::array<s64, 2>& state,
|
||||
std::size_t input_offset, std::size_t output_offset, s32 sample_count, s32 node_id) {
|
||||
void CommandGenerator::GenerateBiquadFilterCommand([[maybe_unused]] s32 mix_buffer_id,
|
||||
const BiquadFilterParameter& params,
|
||||
std::array<s64, 2>& state,
|
||||
std::size_t input_offset,
|
||||
std::size_t output_offset, s32 sample_count,
|
||||
s32 node_id) {
|
||||
if (dumping_frame) {
|
||||
LOG_DEBUG(Audio,
|
||||
"(DSP_TRACE) GenerateBiquadFilterCommand node_id={}, "
|
||||
@@ -714,7 +718,8 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s
|
||||
}
|
||||
|
||||
s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
|
||||
s32 sample_count, s32 channel, std::size_t mix_offset) {
|
||||
s32 sample_count, [[maybe_unused]] s32 channel,
|
||||
std::size_t mix_offset) {
|
||||
const auto& in_params = voice_info.GetInParams();
|
||||
const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
|
||||
if (wave_buffer.buffer_address == 0) {
|
||||
|
||||
@@ -25,10 +25,10 @@ using MixVolumeBuffer = std::array<float, AudioCommon::MAX_MIX_BUFFERS>;
|
||||
|
||||
class CommandGenerator {
|
||||
public:
|
||||
explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params,
|
||||
VoiceContext& voice_context, MixContext& mix_context,
|
||||
SplitterContext& splitter_context, EffectContext& effect_context,
|
||||
Core::Memory::Memory& memory);
|
||||
explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_,
|
||||
VoiceContext& voice_context_, MixContext& mix_context_,
|
||||
SplitterContext& splitter_context_, EffectContext& effect_context_,
|
||||
Core::Memory::Memory& memory_);
|
||||
~CommandGenerator();
|
||||
|
||||
void ClearMixBuffers();
|
||||
|
||||
@@ -21,15 +21,16 @@ namespace AudioCore {
|
||||
|
||||
class CubebSinkStream final : public SinkStream {
|
||||
public:
|
||||
CubebSinkStream(cubeb* ctx, u32 sample_rate, u32 num_channels_, cubeb_devid output_device,
|
||||
CubebSinkStream(cubeb* ctx_, u32 sample_rate, u32 num_channels_, cubeb_devid output_device,
|
||||
const std::string& name)
|
||||
: ctx{ctx}, num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate,
|
||||
num_channels} {
|
||||
: ctx{ctx_}, num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate,
|
||||
num_channels} {
|
||||
|
||||
cubeb_stream_params params{};
|
||||
params.rate = sample_rate;
|
||||
params.channels = num_channels;
|
||||
params.format = CUBEB_SAMPLE_S16NE;
|
||||
params.prefs = CUBEB_STREAM_PREF_PERSIST;
|
||||
switch (num_channels) {
|
||||
case 1:
|
||||
params.layout = CUBEB_LAYOUT_MONO;
|
||||
@@ -192,8 +193,9 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels,
|
||||
return *sink_streams.back();
|
||||
}
|
||||
|
||||
long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
|
||||
void* output_buffer, long num_frames) {
|
||||
long CubebSinkStream::DataCallback([[maybe_unused]] cubeb_stream* stream, void* user_data,
|
||||
[[maybe_unused]] const void* input_buffer, void* output_buffer,
|
||||
long num_frames) {
|
||||
auto* impl = static_cast<CubebSinkStream*>(user_data);
|
||||
auto* buffer = static_cast<u8*>(output_buffer);
|
||||
|
||||
@@ -236,7 +238,9 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const
|
||||
return num_frames;
|
||||
}
|
||||
|
||||
void CubebSinkStream::StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state) {}
|
||||
void CubebSinkStream::StateCallback([[maybe_unused]] cubeb_stream* stream,
|
||||
[[maybe_unused]] void* user_data,
|
||||
[[maybe_unused]] cubeb_state state) {}
|
||||
|
||||
std::vector<std::string> ListCubebSinkDevices() {
|
||||
std::vector<std::string> device_list;
|
||||
|
||||
@@ -12,7 +12,7 @@ bool ValidChannelCountForEffect(s32 channel_count) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
EffectContext::EffectContext(std::size_t effect_count) : effect_count(effect_count) {
|
||||
EffectContext::EffectContext(std::size_t effect_count_) : effect_count(effect_count_) {
|
||||
effects.reserve(effect_count);
|
||||
std::generate_n(std::back_inserter(effects), effect_count,
|
||||
[] { return std::make_unique<EffectStubbed>(); });
|
||||
@@ -61,13 +61,13 @@ const EffectBase* EffectContext::GetInfo(std::size_t i) const {
|
||||
return effects.at(i).get();
|
||||
}
|
||||
|
||||
EffectStubbed::EffectStubbed() : EffectBase::EffectBase(EffectType::Invalid) {}
|
||||
EffectStubbed::EffectStubbed() : EffectBase(EffectType::Invalid) {}
|
||||
EffectStubbed::~EffectStubbed() = default;
|
||||
|
||||
void EffectStubbed::Update(EffectInfo::InParams& in_params) {}
|
||||
void EffectStubbed::Update([[maybe_unused]] EffectInfo::InParams& in_params) {}
|
||||
void EffectStubbed::UpdateForCommandGeneration() {}
|
||||
|
||||
EffectBase::EffectBase(EffectType effect_type) : effect_type(effect_type) {}
|
||||
EffectBase::EffectBase(EffectType effect_type_) : effect_type(effect_type_) {}
|
||||
EffectBase::~EffectBase() = default;
|
||||
|
||||
UsageState EffectBase::GetUsage() const {
|
||||
@@ -90,32 +90,32 @@ s32 EffectBase::GetProcessingOrder() const {
|
||||
return processing_order;
|
||||
}
|
||||
|
||||
EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric::EffectGeneric(EffectType::I3dl2Reverb) {}
|
||||
EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric(EffectType::I3dl2Reverb) {}
|
||||
EffectI3dl2Reverb::~EffectI3dl2Reverb() = default;
|
||||
|
||||
void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) {
|
||||
auto& internal_params = GetParams();
|
||||
auto& params = GetParams();
|
||||
const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data());
|
||||
if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
|
||||
UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto last_status = internal_params.status;
|
||||
const auto last_status = params.status;
|
||||
mix_id = in_params.mix_id;
|
||||
processing_order = in_params.processing_order;
|
||||
internal_params = *reverb_params;
|
||||
params = *reverb_params;
|
||||
if (!ValidChannelCountForEffect(reverb_params->channel_count)) {
|
||||
internal_params.channel_count = internal_params.max_channels;
|
||||
params.channel_count = params.max_channels;
|
||||
}
|
||||
enabled = in_params.is_enabled;
|
||||
if (last_status != ParameterStatus::Updated) {
|
||||
internal_params.status = last_status;
|
||||
params.status = last_status;
|
||||
}
|
||||
|
||||
if (in_params.is_new || skipped) {
|
||||
usage = UsageState::Initialized;
|
||||
internal_params.status = ParameterStatus::Initialized;
|
||||
params.status = ParameterStatus::Initialized;
|
||||
skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
|
||||
}
|
||||
}
|
||||
@@ -129,15 +129,15 @@ void EffectI3dl2Reverb::UpdateForCommandGeneration() {
|
||||
GetParams().status = ParameterStatus::Updated;
|
||||
}
|
||||
|
||||
EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric::EffectGeneric(EffectType::BiquadFilter) {}
|
||||
EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric(EffectType::BiquadFilter) {}
|
||||
EffectBiquadFilter::~EffectBiquadFilter() = default;
|
||||
|
||||
void EffectBiquadFilter::Update(EffectInfo::InParams& in_params) {
|
||||
auto& internal_params = GetParams();
|
||||
auto& params = GetParams();
|
||||
const auto* biquad_params = reinterpret_cast<BiquadFilterParams*>(in_params.raw.data());
|
||||
mix_id = in_params.mix_id;
|
||||
processing_order = in_params.processing_order;
|
||||
internal_params = *biquad_params;
|
||||
params = *biquad_params;
|
||||
enabled = in_params.is_enabled;
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ void EffectBiquadFilter::UpdateForCommandGeneration() {
|
||||
GetParams().status = ParameterStatus::Updated;
|
||||
}
|
||||
|
||||
EffectAuxInfo::EffectAuxInfo() : EffectGeneric::EffectGeneric(EffectType::Aux) {}
|
||||
EffectAuxInfo::EffectAuxInfo() : EffectGeneric(EffectType::Aux) {}
|
||||
EffectAuxInfo::~EffectAuxInfo() = default;
|
||||
|
||||
void EffectAuxInfo::Update(EffectInfo::InParams& in_params) {
|
||||
@@ -200,32 +200,32 @@ VAddr EffectAuxInfo::GetRecvBuffer() const {
|
||||
return recv_buffer;
|
||||
}
|
||||
|
||||
EffectDelay::EffectDelay() : EffectGeneric::EffectGeneric(EffectType::Delay) {}
|
||||
EffectDelay::EffectDelay() : EffectGeneric(EffectType::Delay) {}
|
||||
EffectDelay::~EffectDelay() = default;
|
||||
|
||||
void EffectDelay::Update(EffectInfo::InParams& in_params) {
|
||||
const auto* delay_params = reinterpret_cast<DelayParams*>(in_params.raw.data());
|
||||
auto& internal_params = GetParams();
|
||||
auto& params = GetParams();
|
||||
if (!ValidChannelCountForEffect(delay_params->max_channels)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto last_status = internal_params.status;
|
||||
const auto last_status = params.status;
|
||||
mix_id = in_params.mix_id;
|
||||
processing_order = in_params.processing_order;
|
||||
internal_params = *delay_params;
|
||||
params = *delay_params;
|
||||
if (!ValidChannelCountForEffect(delay_params->channels)) {
|
||||
internal_params.channels = internal_params.max_channels;
|
||||
params.channels = params.max_channels;
|
||||
}
|
||||
enabled = in_params.is_enabled;
|
||||
|
||||
if (last_status != ParameterStatus::Updated) {
|
||||
internal_params.status = last_status;
|
||||
params.status = last_status;
|
||||
}
|
||||
|
||||
if (in_params.is_new || skipped) {
|
||||
usage = UsageState::Initialized;
|
||||
internal_params.status = ParameterStatus::Initialized;
|
||||
params.status = ParameterStatus::Initialized;
|
||||
skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
|
||||
}
|
||||
}
|
||||
@@ -239,7 +239,7 @@ void EffectDelay::UpdateForCommandGeneration() {
|
||||
GetParams().status = ParameterStatus::Updated;
|
||||
}
|
||||
|
||||
EffectBufferMixer::EffectBufferMixer() : EffectGeneric::EffectGeneric(EffectType::BufferMixer) {}
|
||||
EffectBufferMixer::EffectBufferMixer() : EffectGeneric(EffectType::BufferMixer) {}
|
||||
EffectBufferMixer::~EffectBufferMixer() = default;
|
||||
|
||||
void EffectBufferMixer::Update(EffectInfo::InParams& in_params) {
|
||||
@@ -257,32 +257,32 @@ void EffectBufferMixer::UpdateForCommandGeneration() {
|
||||
}
|
||||
}
|
||||
|
||||
EffectReverb::EffectReverb() : EffectGeneric::EffectGeneric(EffectType::Reverb) {}
|
||||
EffectReverb::EffectReverb() : EffectGeneric(EffectType::Reverb) {}
|
||||
EffectReverb::~EffectReverb() = default;
|
||||
|
||||
void EffectReverb::Update(EffectInfo::InParams& in_params) {
|
||||
const auto* reverb_params = reinterpret_cast<ReverbParams*>(in_params.raw.data());
|
||||
auto& internal_params = GetParams();
|
||||
auto& params = GetParams();
|
||||
if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto last_status = internal_params.status;
|
||||
const auto last_status = params.status;
|
||||
mix_id = in_params.mix_id;
|
||||
processing_order = in_params.processing_order;
|
||||
internal_params = *reverb_params;
|
||||
params = *reverb_params;
|
||||
if (!ValidChannelCountForEffect(reverb_params->channels)) {
|
||||
internal_params.channels = internal_params.max_channels;
|
||||
params.channels = params.max_channels;
|
||||
}
|
||||
enabled = in_params.is_enabled;
|
||||
|
||||
if (last_status != ParameterStatus::Updated) {
|
||||
internal_params.status = last_status;
|
||||
params.status = last_status;
|
||||
}
|
||||
|
||||
if (in_params.is_new || skipped) {
|
||||
usage = UsageState::Initialized;
|
||||
internal_params.status = ParameterStatus::Initialized;
|
||||
params.status = ParameterStatus::Initialized;
|
||||
skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ struct AuxAddress {
|
||||
|
||||
class EffectBase {
|
||||
public:
|
||||
explicit EffectBase(EffectType effect_type);
|
||||
explicit EffectBase(EffectType effect_type_);
|
||||
virtual ~EffectBase();
|
||||
|
||||
virtual void Update(EffectInfo::InParams& in_params) = 0;
|
||||
@@ -206,7 +206,7 @@ protected:
|
||||
template <typename T>
|
||||
class EffectGeneric : public EffectBase {
|
||||
public:
|
||||
explicit EffectGeneric(EffectType effect_type) : EffectBase(effect_type) {}
|
||||
explicit EffectGeneric(EffectType effect_type_) : EffectBase(effect_type_) {}
|
||||
|
||||
T& GetParams() {
|
||||
return internal_params;
|
||||
@@ -306,7 +306,7 @@ private:
|
||||
|
||||
class EffectContext {
|
||||
public:
|
||||
explicit EffectContext(std::size_t effect_count);
|
||||
explicit EffectContext(std::size_t effect_count_);
|
||||
~EffectContext();
|
||||
|
||||
[[nodiscard]] std::size_t GetCount() const;
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
InfoUpdater::InfoUpdater(const std::vector<u8>& in_params, std::vector<u8>& out_params,
|
||||
BehaviorInfo& behavior_info)
|
||||
: in_params(in_params), out_params(out_params), behavior_info(behavior_info) {
|
||||
InfoUpdater::InfoUpdater(const std::vector<u8>& in_params_, std::vector<u8>& out_params_,
|
||||
BehaviorInfo& behavior_info_)
|
||||
: in_params(in_params_), out_params(out_params_), behavior_info(behavior_info_) {
|
||||
ASSERT(
|
||||
AudioCommon::CanConsumeBuffer(in_params.size(), 0, sizeof(AudioCommon::UpdateDataHeader)));
|
||||
std::memcpy(&input_header, in_params.data(), sizeof(AudioCommon::UpdateDataHeader));
|
||||
@@ -135,8 +135,8 @@ bool InfoUpdater::UpdateVoiceChannelResources(VoiceContext& voice_context) {
|
||||
}
|
||||
|
||||
bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||
std::vector<ServerMemoryPoolInfo>& memory_pool_info,
|
||||
VAddr audio_codec_dsp_addr) {
|
||||
[[maybe_unused]] std::vector<ServerMemoryPoolInfo>& memory_pool_info,
|
||||
[[maybe_unused]] VAddr audio_codec_dsp_addr) {
|
||||
const auto voice_count = voice_context.GetVoiceCount();
|
||||
std::vector<VoiceInfo::InParams> voice_in(voice_count);
|
||||
std::vector<VoiceInfo::OutParams> voice_out(voice_count);
|
||||
@@ -165,28 +165,28 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||
|
||||
// Update our voices
|
||||
for (std::size_t i = 0; i < voice_count; i++) {
|
||||
auto& in_params = voice_in[i];
|
||||
const auto channel_count = static_cast<std::size_t>(in_params.channel_count);
|
||||
auto& voice_in_params = voice_in[i];
|
||||
const auto channel_count = static_cast<std::size_t>(voice_in_params.channel_count);
|
||||
// Skip if it's not currently in use
|
||||
if (!in_params.is_in_use) {
|
||||
if (!voice_in_params.is_in_use) {
|
||||
continue;
|
||||
}
|
||||
// Voice states for each channel
|
||||
std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{};
|
||||
ASSERT(static_cast<std::size_t>(in_params.id) < voice_count);
|
||||
ASSERT(static_cast<std::size_t>(voice_in_params.id) < voice_count);
|
||||
|
||||
// Grab our current voice info
|
||||
auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id));
|
||||
auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(voice_in_params.id));
|
||||
|
||||
ASSERT(channel_count <= AudioCommon::MAX_CHANNEL_COUNT);
|
||||
|
||||
// Get all our channel voice states
|
||||
for (std::size_t channel = 0; channel < channel_count; channel++) {
|
||||
voice_states[channel] =
|
||||
&voice_context.GetState(in_params.voice_channel_resource_ids[channel]);
|
||||
&voice_context.GetState(voice_in_params.voice_channel_resource_ids[channel]);
|
||||
}
|
||||
|
||||
if (in_params.is_new) {
|
||||
if (voice_in_params.is_new) {
|
||||
// Default our values for our voice
|
||||
voice_info.Initialize();
|
||||
if (channel_count == 0 || channel_count > AudioCommon::MAX_CHANNEL_COUNT) {
|
||||
@@ -200,12 +200,12 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context,
|
||||
}
|
||||
|
||||
// Update our voice
|
||||
voice_info.UpdateParameters(in_params, behavior_info);
|
||||
voice_info.UpdateParameters(voice_in_params, behavior_info);
|
||||
// TODO(ogniK): Handle mapping errors with behavior info based on in params response
|
||||
|
||||
// Update our wave buffers
|
||||
voice_info.UpdateWaveBuffers(in_params, voice_states, behavior_info);
|
||||
voice_info.WriteOutStatus(voice_out[i], in_params, voice_states);
|
||||
voice_info.UpdateWaveBuffers(voice_in_params, voice_states, behavior_info);
|
||||
voice_info.WriteOutStatus(voice_out[i], voice_in_params, voice_states);
|
||||
}
|
||||
|
||||
if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, voice_out_size)) {
|
||||
@@ -445,7 +445,7 @@ bool InfoUpdater::UpdatePerformanceBuffer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InfoUpdater::UpdateErrorInfo(BehaviorInfo& in_behavior_info) {
|
||||
bool InfoUpdater::UpdateErrorInfo([[maybe_unused]] BehaviorInfo& in_behavior_info) {
|
||||
const auto total_beahvior_info_out = sizeof(BehaviorInfo::OutParams);
|
||||
|
||||
if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, total_beahvior_info_out)) {
|
||||
|
||||
@@ -21,8 +21,8 @@ class SplitterContext;
|
||||
class InfoUpdater {
|
||||
public:
|
||||
// TODO(ogniK): Pass process handle when we support it
|
||||
InfoUpdater(const std::vector<u8>& in_params, std::vector<u8>& out_params,
|
||||
BehaviorInfo& behavior_info);
|
||||
InfoUpdater(const std::vector<u8>& in_params_, std::vector<u8>& out_params_,
|
||||
BehaviorInfo& behavior_info_);
|
||||
~InfoUpdater();
|
||||
|
||||
bool UpdateBehaviorInfo(BehaviorInfo& in_behavior_info);
|
||||
|
||||
@@ -10,11 +10,10 @@ namespace AudioCore {
|
||||
|
||||
ServerMemoryPoolInfo::ServerMemoryPoolInfo() = default;
|
||||
ServerMemoryPoolInfo::~ServerMemoryPoolInfo() = default;
|
||||
bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_params,
|
||||
ServerMemoryPoolInfo::OutParams& out_params) {
|
||||
|
||||
bool ServerMemoryPoolInfo::Update(const InParams& in_params, OutParams& out_params) {
|
||||
// Our state does not need to be changed
|
||||
if (in_params.state != ServerMemoryPoolInfo::State::RequestAttach &&
|
||||
in_params.state != ServerMemoryPoolInfo::State::RequestDetach) {
|
||||
if (in_params.state != State::RequestAttach && in_params.state != State::RequestDetach) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -32,11 +31,11 @@ bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_param
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in_params.state == ServerMemoryPoolInfo::State::RequestAttach) {
|
||||
if (in_params.state == State::RequestAttach) {
|
||||
cpu_address = in_params.address;
|
||||
size = in_params.size;
|
||||
used = true;
|
||||
out_params.state = ServerMemoryPoolInfo::State::Attached;
|
||||
out_params.state = State::Attached;
|
||||
} else {
|
||||
// Unexpected address
|
||||
if (cpu_address != in_params.address) {
|
||||
@@ -54,7 +53,7 @@ bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_param
|
||||
cpu_address = 0;
|
||||
size = 0;
|
||||
used = false;
|
||||
out_params.state = ServerMemoryPoolInfo::State::Detached;
|
||||
out_params.state = State::Detached;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -28,19 +28,18 @@ public:
|
||||
struct InParams {
|
||||
u64_le address{};
|
||||
u64_le size{};
|
||||
ServerMemoryPoolInfo::State state{};
|
||||
State state{};
|
||||
INSERT_PADDING_WORDS(3);
|
||||
};
|
||||
static_assert(sizeof(ServerMemoryPoolInfo::InParams) == 0x20, "InParams are an invalid size");
|
||||
static_assert(sizeof(InParams) == 0x20, "InParams are an invalid size");
|
||||
|
||||
struct OutParams {
|
||||
ServerMemoryPoolInfo::State state{};
|
||||
State state{};
|
||||
INSERT_PADDING_WORDS(3);
|
||||
};
|
||||
static_assert(sizeof(ServerMemoryPoolInfo::OutParams) == 0x10, "OutParams are an invalid size");
|
||||
static_assert(sizeof(OutParams) == 0x10, "OutParams are an invalid size");
|
||||
|
||||
bool Update(const ServerMemoryPoolInfo::InParams& in_params,
|
||||
ServerMemoryPoolInfo::OutParams& out_params);
|
||||
bool Update(const InParams& in_params, OutParams& out_params);
|
||||
|
||||
private:
|
||||
// There's another entry here which is the DSP address, however since we're not talking to the
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "audio_core/sink_context.h"
|
||||
|
||||
namespace AudioCore {
|
||||
SinkContext::SinkContext(std::size_t sink_count) : sink_count(sink_count) {}
|
||||
SinkContext::SinkContext(std::size_t sink_count_) : sink_count{sink_count_} {}
|
||||
SinkContext::~SinkContext() = default;
|
||||
|
||||
std::size_t SinkContext::GetCount() const {
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
bool in_use;
|
||||
INSERT_UNION_PADDING_BYTES(5);
|
||||
};
|
||||
static_assert(sizeof(SinkInfo::CircularBufferIn) == 0x28,
|
||||
static_assert(sizeof(CircularBufferIn) == 0x28,
|
||||
"SinkInfo::CircularBufferIn is in invalid size");
|
||||
|
||||
struct DeviceIn {
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
bool down_matrix_enabled;
|
||||
DownmixCoefficients down_matrix_coef;
|
||||
};
|
||||
static_assert(sizeof(SinkInfo::DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size");
|
||||
static_assert(sizeof(DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size");
|
||||
|
||||
struct InParams {
|
||||
SinkTypes type{};
|
||||
@@ -64,16 +64,16 @@ public:
|
||||
INSERT_PADDING_WORDS(6);
|
||||
union {
|
||||
// std::array<u8, 0x120> raw{};
|
||||
SinkInfo::DeviceIn device;
|
||||
SinkInfo::CircularBufferIn circular_buffer;
|
||||
DeviceIn device;
|
||||
CircularBufferIn circular_buffer;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(SinkInfo::InParams) == 0x140, "SinkInfo::InParams are an invalid size!");
|
||||
static_assert(sizeof(InParams) == 0x140, "SinkInfo::InParams are an invalid size!");
|
||||
};
|
||||
|
||||
class SinkContext {
|
||||
public:
|
||||
explicit SinkContext(std::size_t sink_count);
|
||||
explicit SinkContext(std::size_t sink_count_);
|
||||
~SinkContext();
|
||||
|
||||
[[nodiscard]] std::size_t GetCount() const;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
ServerSplitterDestinationData::ServerSplitterDestinationData(s32 id) : id(id) {}
|
||||
ServerSplitterDestinationData::ServerSplitterDestinationData(s32 id_) : id{id_} {}
|
||||
ServerSplitterDestinationData::~ServerSplitterDestinationData() = default;
|
||||
|
||||
void ServerSplitterDestinationData::Update(SplitterInfo::InDestinationParams& header) {
|
||||
@@ -87,7 +87,7 @@ void ServerSplitterDestinationData::UpdateInternalState() {
|
||||
needs_update = false;
|
||||
}
|
||||
|
||||
ServerSplitterInfo::ServerSplitterInfo(s32 id) : id(id) {}
|
||||
ServerSplitterInfo::ServerSplitterInfo(s32 id_) : id(id_) {}
|
||||
ServerSplitterInfo::~ServerSplitterInfo() = default;
|
||||
|
||||
void ServerSplitterInfo::InitializeInfos() {
|
||||
@@ -121,7 +121,7 @@ const ServerSplitterDestinationData* ServerSplitterInfo::GetHead() const {
|
||||
}
|
||||
|
||||
ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) {
|
||||
auto current_head = head;
|
||||
auto* current_head = head;
|
||||
for (std::size_t i = 0; i < depth; i++) {
|
||||
if (current_head == nullptr) {
|
||||
return nullptr;
|
||||
@@ -132,7 +132,7 @@ ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) {
|
||||
}
|
||||
|
||||
const ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) const {
|
||||
auto current_head = head;
|
||||
auto* current_head = head;
|
||||
for (std::size_t i = 0; i < depth; i++) {
|
||||
if (current_head == nullptr) {
|
||||
return nullptr;
|
||||
@@ -245,7 +245,7 @@ ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t i
|
||||
const ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t info,
|
||||
std::size_t data) const {
|
||||
ASSERT(info < info_count);
|
||||
auto& cur_info = GetInfo(info);
|
||||
const auto& cur_info = GetInfo(info);
|
||||
return cur_info.GetData(data);
|
||||
}
|
||||
|
||||
@@ -267,11 +267,11 @@ std::size_t SplitterContext::GetDataCount() const {
|
||||
return data_count;
|
||||
}
|
||||
|
||||
void SplitterContext::Setup(std::size_t _info_count, std::size_t _data_count,
|
||||
void SplitterContext::Setup(std::size_t info_count_, std::size_t data_count_,
|
||||
bool is_splitter_bug_fixed) {
|
||||
|
||||
info_count = _info_count;
|
||||
data_count = _data_count;
|
||||
info_count = info_count_;
|
||||
data_count = data_count_;
|
||||
|
||||
for (std::size_t i = 0; i < info_count; i++) {
|
||||
auto& splitter = infos.emplace_back(static_cast<s32>(i));
|
||||
@@ -364,7 +364,7 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info,
|
||||
// Clear our current destinations
|
||||
auto* current_head = info.GetHead();
|
||||
while (current_head != nullptr) {
|
||||
auto next_head = current_head->GetNextDestination();
|
||||
auto* next_head = current_head->GetNextDestination();
|
||||
current_head->SetNextDestination(nullptr);
|
||||
current_head = next_head;
|
||||
}
|
||||
@@ -471,8 +471,8 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto node_count = edge_matrix.GetNodeCount();
|
||||
for (s32 j = 0; j < static_cast<s32>(node_count); j++) {
|
||||
const auto edge_node_count = edge_matrix.GetNodeCount();
|
||||
for (s32 j = 0; j < static_cast<s32>(edge_node_count); j++) {
|
||||
// Check if our node is connected to our edge matrix
|
||||
if (!edge_matrix.Connected(current_stack_index, j)) {
|
||||
continue;
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
NodeStates();
|
||||
~NodeStates();
|
||||
|
||||
void Initialize(std::size_t _node_count);
|
||||
void Initialize(std::size_t node_count_);
|
||||
bool Tsort(EdgeMatrix& edge_matrix);
|
||||
std::size_t GetIndexPos() const;
|
||||
const std::vector<s32>& GetIndexList() const;
|
||||
@@ -72,15 +72,15 @@ private:
|
||||
void PushTsortResult(s32 index);
|
||||
bool DepthFirstSearch(EdgeMatrix& edge_matrix);
|
||||
void ResetState();
|
||||
void UpdateState(NodeStates::State state, std::size_t i);
|
||||
NodeStates::State GetState(std::size_t i);
|
||||
void UpdateState(State state, std::size_t i);
|
||||
State GetState(std::size_t i);
|
||||
|
||||
std::size_t node_count{};
|
||||
std::vector<bool> was_node_found{};
|
||||
std::vector<bool> was_node_completed{};
|
||||
std::size_t index_pos{};
|
||||
std::vector<s32> index_list{};
|
||||
NodeStates::Stack index_stack{};
|
||||
Stack index_stack{};
|
||||
};
|
||||
|
||||
enum class SplitterMagic : u32_le {
|
||||
@@ -97,8 +97,7 @@ public:
|
||||
s32_le data_count{};
|
||||
INSERT_PADDING_WORDS(5);
|
||||
};
|
||||
static_assert(sizeof(SplitterInfo::InHeader) == 0x20,
|
||||
"SplitterInfo::InHeader is an invalid size");
|
||||
static_assert(sizeof(InHeader) == 0x20, "SplitterInfo::InHeader is an invalid size");
|
||||
|
||||
struct InInfoPrams {
|
||||
SplitterMagic magic{};
|
||||
@@ -107,8 +106,7 @@ public:
|
||||
s32_le length{};
|
||||
s32_le resource_id_base{};
|
||||
};
|
||||
static_assert(sizeof(SplitterInfo::InInfoPrams) == 0x14,
|
||||
"SplitterInfo::InInfoPrams is an invalid size");
|
||||
static_assert(sizeof(InInfoPrams) == 0x14, "SplitterInfo::InInfoPrams is an invalid size");
|
||||
|
||||
struct InDestinationParams {
|
||||
SplitterMagic magic{};
|
||||
@@ -118,13 +116,13 @@ public:
|
||||
bool in_use{};
|
||||
INSERT_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(SplitterInfo::InDestinationParams) == 0x70,
|
||||
static_assert(sizeof(InDestinationParams) == 0x70,
|
||||
"SplitterInfo::InDestinationParams is an invalid size");
|
||||
};
|
||||
|
||||
class ServerSplitterDestinationData {
|
||||
public:
|
||||
explicit ServerSplitterDestinationData(s32 id);
|
||||
explicit ServerSplitterDestinationData(s32 id_);
|
||||
~ServerSplitterDestinationData();
|
||||
|
||||
void Update(SplitterInfo::InDestinationParams& header);
|
||||
@@ -153,7 +151,7 @@ private:
|
||||
|
||||
class ServerSplitterInfo {
|
||||
public:
|
||||
explicit ServerSplitterInfo(s32 id);
|
||||
explicit ServerSplitterInfo(s32 id_);
|
||||
~ServerSplitterInfo();
|
||||
|
||||
void InitializeInfos();
|
||||
|
||||
@@ -31,10 +31,10 @@ u32 Stream::GetNumChannels() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format format,
|
||||
ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_)
|
||||
: sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
|
||||
sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} {
|
||||
Stream::Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_,
|
||||
ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_)
|
||||
: sample_rate{sample_rate_}, format{format_}, release_callback{std::move(release_callback_)},
|
||||
sink_stream{sink_stream_}, core_timing{core_timing_}, name{std::move(name_)} {
|
||||
release_event =
|
||||
Core::Timing::CreateEvent(name, [this](std::uintptr_t, std::chrono::nanoseconds ns_late) {
|
||||
ReleaseActiveBuffer(ns_late);
|
||||
@@ -122,7 +122,7 @@ bool Stream::QueueBuffer(BufferPtr&& buffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Stream::ContainsBuffer(Buffer::Tag tag) const {
|
||||
bool Stream::ContainsBuffer([[maybe_unused]] Buffer::Tag tag) const {
|
||||
UNIMPLEMENTED();
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ public:
|
||||
/// Callback function type, used to change guest state on a buffer being released
|
||||
using ReleaseCallback = std::function<void()>;
|
||||
|
||||
Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format format,
|
||||
ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_);
|
||||
Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_,
|
||||
ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_);
|
||||
|
||||
/// Plays the audio stream
|
||||
void Play();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
ServerVoiceChannelResource::ServerVoiceChannelResource(s32 id) : id(id) {}
|
||||
ServerVoiceChannelResource::ServerVoiceChannelResource(s32 id_) : id(id_) {}
|
||||
ServerVoiceChannelResource::~ServerVoiceChannelResource() = default;
|
||||
|
||||
bool ServerVoiceChannelResource::InUse() const {
|
||||
@@ -209,7 +209,8 @@ void ServerVoiceInfo::UpdateWaveBuffers(
|
||||
|
||||
void ServerVoiceInfo::UpdateWaveBuffer(ServerWaveBuffer& out_wavebuffer,
|
||||
const WaveBuffer& in_wave_buffer, SampleFormat sample_format,
|
||||
bool is_buffer_valid, BehaviorInfo& behavior_info) {
|
||||
bool is_buffer_valid,
|
||||
[[maybe_unused]] BehaviorInfo& behavior_info) {
|
||||
if (!is_buffer_valid && out_wavebuffer.sent_to_dsp) {
|
||||
out_wavebuffer.buffer_address = 0;
|
||||
out_wavebuffer.buffer_size = 0;
|
||||
@@ -400,7 +401,7 @@ bool ServerVoiceInfo::HasValidWaveBuffer(const VoiceState* state) const {
|
||||
return std::find(valid_wb.begin(), valid_wb.end(), true) != valid_wb.end();
|
||||
}
|
||||
|
||||
VoiceContext::VoiceContext(std::size_t voice_count) : voice_count(voice_count) {
|
||||
VoiceContext::VoiceContext(std::size_t voice_count_) : voice_count{voice_count_} {
|
||||
for (std::size_t i = 0; i < voice_count; i++) {
|
||||
voice_channel_resources.emplace_back(static_cast<s32>(i));
|
||||
sorted_voice_info.push_back(&voice_info.emplace_back());
|
||||
|
||||
@@ -118,12 +118,12 @@ public:
|
||||
bool in_use{};
|
||||
INSERT_PADDING_BYTES(11);
|
||||
};
|
||||
static_assert(sizeof(VoiceChannelResource::InParams) == 0x70, "InParams is an invalid size");
|
||||
static_assert(sizeof(InParams) == 0x70, "InParams is an invalid size");
|
||||
};
|
||||
|
||||
class ServerVoiceChannelResource {
|
||||
public:
|
||||
explicit ServerVoiceChannelResource(s32 id);
|
||||
explicit ServerVoiceChannelResource(s32 id_);
|
||||
~ServerVoiceChannelResource();
|
||||
|
||||
bool InUse() const;
|
||||
@@ -174,7 +174,7 @@ public:
|
||||
BehaviorFlags behavior_flags{};
|
||||
INSERT_PADDING_BYTES(16);
|
||||
};
|
||||
static_assert(sizeof(VoiceInfo::InParams) == 0x170, "InParams is an invalid size");
|
||||
static_assert(sizeof(InParams) == 0x170, "InParams is an invalid size");
|
||||
|
||||
struct OutParams {
|
||||
u64_le played_sample_count{};
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
u8 voice_dropped{};
|
||||
INSERT_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(VoiceInfo::OutParams) == 0x10, "OutParams is an invalid size");
|
||||
static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size");
|
||||
};
|
||||
|
||||
class ServerVoiceInfo {
|
||||
@@ -263,7 +263,7 @@ private:
|
||||
|
||||
class VoiceContext {
|
||||
public:
|
||||
VoiceContext(std::size_t voice_count);
|
||||
explicit VoiceContext(std::size_t voice_count_);
|
||||
~VoiceContext();
|
||||
|
||||
std::size_t GetVoiceCount() const;
|
||||
|
||||
@@ -112,6 +112,7 @@ add_library(common STATIC
|
||||
common_paths.h
|
||||
common_types.h
|
||||
concepts.h
|
||||
div_ceil.h
|
||||
dynamic_library.cpp
|
||||
dynamic_library.h
|
||||
fiber.cpp
|
||||
@@ -208,7 +209,6 @@ else()
|
||||
endif()
|
||||
|
||||
create_target_directory_groups(common)
|
||||
find_package(Boost 1.71 COMPONENTS context headers REQUIRED)
|
||||
|
||||
target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile)
|
||||
target_link_libraries(common PRIVATE lz4::lz4 xbyak)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright 2020 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Common {
|
||||
|
||||
/// Ceiled integer division.
|
||||
template <typename N, typename D>
|
||||
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeil(
|
||||
N number, D divisor) {
|
||||
return (static_cast<D>(number) + divisor - 1) / divisor;
|
||||
}
|
||||
|
||||
/// Ceiled integer division with logarithmic divisor in base 2
|
||||
template <typename N, typename D>
|
||||
requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr auto DivCeilLog2(
|
||||
N value, D alignment_log2) {
|
||||
return (static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2;
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
+11
-106
@@ -5,18 +5,20 @@
|
||||
#include "common/assert.h"
|
||||
#include "common/fiber.h"
|
||||
#include "common/spin_lock.h"
|
||||
#include "common/virtual_buffer.h"
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <boost/context/detail/fcontext.hpp>
|
||||
#endif
|
||||
|
||||
namespace Common {
|
||||
|
||||
constexpr std::size_t default_stack_size = 256 * 1024; // 256kb
|
||||
constexpr std::size_t default_stack_size = 256 * 1024;
|
||||
|
||||
struct Fiber::FiberImpl {
|
||||
FiberImpl() : stack{default_stack_size}, rewind_stack{default_stack_size} {}
|
||||
|
||||
VirtualBuffer<u8> stack;
|
||||
VirtualBuffer<u8> rewind_stack;
|
||||
|
||||
SpinLock guard{};
|
||||
std::function<void(void*)> entry_point;
|
||||
std::function<void(void*)> rewind_point;
|
||||
@@ -26,17 +28,10 @@ struct Fiber::FiberImpl {
|
||||
bool is_thread_fiber{};
|
||||
bool released{};
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
LPVOID handle = nullptr;
|
||||
LPVOID rewind_handle = nullptr;
|
||||
#else
|
||||
alignas(64) std::array<u8, default_stack_size> stack;
|
||||
alignas(64) std::array<u8, default_stack_size> rewind_stack;
|
||||
u8* stack_limit;
|
||||
u8* rewind_stack_limit;
|
||||
boost::context::detail::fcontext_t context;
|
||||
boost::context::detail::fcontext_t rewind_context;
|
||||
#endif
|
||||
u8* stack_limit{};
|
||||
u8* rewind_stack_limit{};
|
||||
boost::context::detail::fcontext_t context{};
|
||||
boost::context::detail::fcontext_t rewind_context{};
|
||||
};
|
||||
|
||||
void Fiber::SetStartParameter(void* new_parameter) {
|
||||
@@ -48,95 +43,6 @@ void Fiber::SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewin
|
||||
impl->rewind_parameter = rewind_param;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
|
||||
void Fiber::Start() {
|
||||
ASSERT(impl->previous_fiber != nullptr);
|
||||
impl->previous_fiber->impl->guard.unlock();
|
||||
impl->previous_fiber.reset();
|
||||
impl->entry_point(impl->start_parameter);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void Fiber::OnRewind() {
|
||||
ASSERT(impl->handle != nullptr);
|
||||
DeleteFiber(impl->handle);
|
||||
impl->handle = impl->rewind_handle;
|
||||
impl->rewind_handle = nullptr;
|
||||
impl->rewind_point(impl->rewind_parameter);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void Fiber::FiberStartFunc(void* fiber_parameter) {
|
||||
auto* fiber = static_cast<Fiber*>(fiber_parameter);
|
||||
fiber->Start();
|
||||
}
|
||||
|
||||
void Fiber::RewindStartFunc(void* fiber_parameter) {
|
||||
auto* fiber = static_cast<Fiber*>(fiber_parameter);
|
||||
fiber->OnRewind();
|
||||
}
|
||||
|
||||
Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_parameter)
|
||||
: impl{std::make_unique<FiberImpl>()} {
|
||||
impl->entry_point = std::move(entry_point_func);
|
||||
impl->start_parameter = start_parameter;
|
||||
impl->handle = CreateFiber(default_stack_size, &FiberStartFunc, this);
|
||||
}
|
||||
|
||||
Fiber::Fiber() : impl{std::make_unique<FiberImpl>()} {}
|
||||
|
||||
Fiber::~Fiber() {
|
||||
if (impl->released) {
|
||||
return;
|
||||
}
|
||||
// Make sure the Fiber is not being used
|
||||
const bool locked = impl->guard.try_lock();
|
||||
ASSERT_MSG(locked, "Destroying a fiber that's still running");
|
||||
if (locked) {
|
||||
impl->guard.unlock();
|
||||
}
|
||||
DeleteFiber(impl->handle);
|
||||
}
|
||||
|
||||
void Fiber::Exit() {
|
||||
ASSERT_MSG(impl->is_thread_fiber, "Exitting non main thread fiber");
|
||||
if (!impl->is_thread_fiber) {
|
||||
return;
|
||||
}
|
||||
ConvertFiberToThread();
|
||||
impl->guard.unlock();
|
||||
impl->released = true;
|
||||
}
|
||||
|
||||
void Fiber::Rewind() {
|
||||
ASSERT(impl->rewind_point);
|
||||
ASSERT(impl->rewind_handle == nullptr);
|
||||
impl->rewind_handle = CreateFiber(default_stack_size, &RewindStartFunc, this);
|
||||
SwitchToFiber(impl->rewind_handle);
|
||||
}
|
||||
|
||||
void Fiber::YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to) {
|
||||
ASSERT_MSG(from != nullptr, "Yielding fiber is null!");
|
||||
ASSERT_MSG(to != nullptr, "Next fiber is null!");
|
||||
to->impl->guard.lock();
|
||||
to->impl->previous_fiber = from;
|
||||
SwitchToFiber(to->impl->handle);
|
||||
ASSERT(from->impl->previous_fiber != nullptr);
|
||||
from->impl->previous_fiber->impl->guard.unlock();
|
||||
from->impl->previous_fiber.reset();
|
||||
}
|
||||
|
||||
std::shared_ptr<Fiber> Fiber::ThreadToFiber() {
|
||||
std::shared_ptr<Fiber> fiber = std::shared_ptr<Fiber>{new Fiber()};
|
||||
fiber->impl->guard.lock();
|
||||
fiber->impl->handle = ConvertThreadToFiber(nullptr);
|
||||
fiber->impl->is_thread_fiber = true;
|
||||
return fiber;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void Fiber::Start(boost::context::detail::transfer_t& transfer) {
|
||||
ASSERT(impl->previous_fiber != nullptr);
|
||||
impl->previous_fiber->impl->context = transfer.fctx;
|
||||
@@ -229,5 +135,4 @@ std::shared_ptr<Fiber> Fiber::ThreadToFiber() {
|
||||
return fiber;
|
||||
}
|
||||
|
||||
#endif
|
||||
} // namespace Common
|
||||
|
||||
@@ -7,11 +7,9 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#if !defined(_WIN32) && !defined(WIN32)
|
||||
namespace boost::context::detail {
|
||||
struct transfer_t;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace Common {
|
||||
|
||||
@@ -59,17 +57,10 @@ public:
|
||||
private:
|
||||
Fiber();
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
void OnRewind();
|
||||
void Start();
|
||||
static void FiberStartFunc(void* fiber_parameter);
|
||||
static void RewindStartFunc(void* fiber_parameter);
|
||||
#else
|
||||
void OnRewind(boost::context::detail::transfer_t& transfer);
|
||||
void Start(boost::context::detail::transfer_t& transfer);
|
||||
static void FiberStartFunc(boost::context::detail::transfer_t transfer);
|
||||
static void RewindStartFunc(boost::context::detail::transfer_t transfer);
|
||||
#endif
|
||||
|
||||
struct FiberImpl;
|
||||
std::unique_ptr<FiberImpl> impl;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace detail {
|
||||
template <typename Func>
|
||||
struct ScopeExitHelper {
|
||||
explicit ScopeExitHelper(Func&& func) : func(std::move(func)) {}
|
||||
explicit ScopeExitHelper(Func&& func_) : func(std::move(func_)) {}
|
||||
~ScopeExitHelper() {
|
||||
if (active) {
|
||||
func();
|
||||
|
||||
@@ -52,8 +52,8 @@ public:
|
||||
template <typename T>
|
||||
class Field : public FieldInterface {
|
||||
public:
|
||||
Field(FieldType type, std::string name, T value)
|
||||
: name(std::move(name)), type(type), value(std::move(value)) {}
|
||||
Field(FieldType type_, std::string name_, T value_)
|
||||
: name(std::move(name_)), type(type_), value(std::move(value_)) {}
|
||||
|
||||
Field(const Field&) = default;
|
||||
Field& operator=(const Field&) = default;
|
||||
|
||||
@@ -17,8 +17,8 @@ using base_time_point = std::chrono::time_point<base_timer>;
|
||||
|
||||
class StandardWallClock final : public WallClock {
|
||||
public:
|
||||
StandardWallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency)
|
||||
: WallClock(emulated_cpu_frequency, emulated_clock_frequency, false) {
|
||||
explicit StandardWallClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_)
|
||||
: WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, false) {
|
||||
start_time = base_timer::now();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
WallClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, bool is_native)
|
||||
: emulated_cpu_frequency{emulated_cpu_frequency},
|
||||
emulated_clock_frequency{emulated_clock_frequency}, is_native{is_native} {}
|
||||
explicit WallClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_, bool is_native_)
|
||||
: emulated_cpu_frequency{emulated_cpu_frequency_},
|
||||
emulated_clock_frequency{emulated_clock_frequency_}, is_native{is_native_} {}
|
||||
|
||||
u64 emulated_cpu_frequency;
|
||||
u64 emulated_clock_frequency;
|
||||
|
||||
@@ -43,10 +43,10 @@ u64 EstimateRDTSCFrequency() {
|
||||
}
|
||||
|
||||
namespace X64 {
|
||||
NativeClock::NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency,
|
||||
u64 rtsc_frequency)
|
||||
: WallClock(emulated_cpu_frequency, emulated_clock_frequency, true), rtsc_frequency{
|
||||
rtsc_frequency} {
|
||||
NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_,
|
||||
u64 rtsc_frequency_)
|
||||
: WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{
|
||||
rtsc_frequency_} {
|
||||
_mm_mfence();
|
||||
last_measure = __rdtsc();
|
||||
accumulated_ticks = 0U;
|
||||
|
||||
@@ -14,7 +14,8 @@ namespace Common {
|
||||
namespace X64 {
|
||||
class NativeClock final : public WallClock {
|
||||
public:
|
||||
NativeClock(u64 emulated_cpu_frequency, u64 emulated_clock_frequency, u64 rtsc_frequency);
|
||||
explicit NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequency_,
|
||||
u64 rtsc_frequency_);
|
||||
|
||||
std::chrono::nanoseconds GetTimeNS() override;
|
||||
|
||||
|
||||
+10
-10
@@ -11,25 +11,25 @@
|
||||
|
||||
namespace Common::X64 {
|
||||
|
||||
constexpr std::size_t RegToIndex(const Xbyak::Reg& reg) {
|
||||
constexpr size_t RegToIndex(const Xbyak::Reg& reg) {
|
||||
using Kind = Xbyak::Reg::Kind;
|
||||
ASSERT_MSG((reg.getKind() & (Kind::REG | Kind::XMM)) != 0,
|
||||
"RegSet only support GPRs and XMM registers.");
|
||||
ASSERT_MSG(reg.getIdx() < 16, "RegSet only supports XXM0-15.");
|
||||
return reg.getIdx() + (reg.getKind() == Kind::REG ? 0 : 16);
|
||||
return static_cast<size_t>(reg.getIdx()) + (reg.getKind() == Kind::REG ? 0 : 16);
|
||||
}
|
||||
|
||||
constexpr Xbyak::Reg64 IndexToReg64(std::size_t reg_index) {
|
||||
constexpr Xbyak::Reg64 IndexToReg64(size_t reg_index) {
|
||||
ASSERT(reg_index < 16);
|
||||
return Xbyak::Reg64(static_cast<int>(reg_index));
|
||||
}
|
||||
|
||||
constexpr Xbyak::Xmm IndexToXmm(std::size_t reg_index) {
|
||||
constexpr Xbyak::Xmm IndexToXmm(size_t reg_index) {
|
||||
ASSERT(reg_index >= 16 && reg_index < 32);
|
||||
return Xbyak::Xmm(static_cast<int>(reg_index - 16));
|
||||
}
|
||||
|
||||
constexpr Xbyak::Reg IndexToReg(std::size_t reg_index) {
|
||||
constexpr Xbyak::Reg IndexToReg(size_t reg_index) {
|
||||
if (reg_index < 16) {
|
||||
return IndexToReg64(reg_index);
|
||||
} else {
|
||||
@@ -182,7 +182,7 @@ inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::b
|
||||
size_t rsp_alignment, size_t needed_frame_size = 0) {
|
||||
auto frame_info = ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size);
|
||||
|
||||
for (std::size_t i = 0; i < regs.size(); ++i) {
|
||||
for (size_t i = 0; i < regs.size(); ++i) {
|
||||
if (regs[i] && ABI_ALL_GPRS[i]) {
|
||||
code.push(IndexToReg64(i));
|
||||
}
|
||||
@@ -192,7 +192,7 @@ inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::b
|
||||
code.sub(code.rsp, frame_info.subtraction);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < regs.size(); ++i) {
|
||||
for (size_t i = 0; i < regs.size(); ++i) {
|
||||
if (regs[i] && ABI_ALL_XMMS[i]) {
|
||||
code.movaps(code.xword[code.rsp + frame_info.xmm_offset], IndexToXmm(i));
|
||||
frame_info.xmm_offset += 0x10;
|
||||
@@ -206,7 +206,7 @@ inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bits
|
||||
size_t rsp_alignment, size_t needed_frame_size = 0) {
|
||||
auto frame_info = ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size);
|
||||
|
||||
for (std::size_t i = 0; i < regs.size(); ++i) {
|
||||
for (size_t i = 0; i < regs.size(); ++i) {
|
||||
if (regs[i] && ABI_ALL_XMMS[i]) {
|
||||
code.movaps(IndexToXmm(i), code.xword[code.rsp + frame_info.xmm_offset]);
|
||||
frame_info.xmm_offset += 0x10;
|
||||
@@ -218,8 +218,8 @@ inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, std::bits
|
||||
}
|
||||
|
||||
// GPRs need to be popped in reverse order
|
||||
for (std::size_t j = 0; j < regs.size(); ++j) {
|
||||
const std::size_t i = regs.size() - j - 1;
|
||||
for (size_t j = 0; j < regs.size(); ++j) {
|
||||
const size_t i = regs.size() - j - 1;
|
||||
if (regs[i] && ABI_ALL_GPRS[i]) {
|
||||
code.pop(IndexToReg64(i));
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ add_library(core STATIC
|
||||
file_sys/bis_factory.h
|
||||
file_sys/card_image.cpp
|
||||
file_sys/card_image.h
|
||||
file_sys/common_funcs.h
|
||||
file_sys/content_archive.cpp
|
||||
file_sys/content_archive.h
|
||||
file_sys/control_metadata.cpp
|
||||
@@ -134,9 +135,9 @@ add_library(core STATIC
|
||||
frontend/emu_window.h
|
||||
frontend/framebuffer_layout.cpp
|
||||
frontend/framebuffer_layout.h
|
||||
frontend/input_interpreter.cpp
|
||||
frontend/input_interpreter.h
|
||||
frontend/input.h
|
||||
gdbstub/gdbstub.cpp
|
||||
gdbstub/gdbstub.h
|
||||
hardware_interrupt_manager.cpp
|
||||
hardware_interrupt_manager.h
|
||||
hle/ipc.h
|
||||
|
||||
@@ -64,15 +64,25 @@ public:
|
||||
/// Step CPU by one instruction
|
||||
virtual void Step() = 0;
|
||||
|
||||
/// Exits execution from a callback, the callback must rewind the stack
|
||||
virtual void ExceptionalExit() = 0;
|
||||
|
||||
/// Clear all instruction cache
|
||||
virtual void ClearInstructionCache() = 0;
|
||||
|
||||
/// Notifies CPU emulation that the current page table has changed.
|
||||
///
|
||||
/// @param new_page_table The new page table.
|
||||
/// @param new_address_space_size_in_bits The new usable size of the address space in bits.
|
||||
/// This can be either 32, 36, or 39 on official software.
|
||||
///
|
||||
/**
|
||||
* Clear instruction cache range
|
||||
* @param addr Start address of the cache range to clear
|
||||
* @param size Size of the cache range to clear, starting at addr
|
||||
*/
|
||||
virtual void InvalidateCacheRange(VAddr addr, std::size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Notifies CPU emulation that the current page table has changed.
|
||||
* @param new_page_table The new page table.
|
||||
* @param new_address_space_size_in_bits The new usable size of the address space in bits.
|
||||
* This can be either 32, 36, or 39 on official software.
|
||||
*/
|
||||
virtual void PageTableChanged(Common::PageTable& new_page_table,
|
||||
std::size_t new_address_space_size_in_bits) = 0;
|
||||
|
||||
|
||||
@@ -189,6 +189,10 @@ void ARM_Dynarmic_32::Run() {
|
||||
jit->Run();
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::ExceptionalExit() {
|
||||
jit->ExceptionalExit();
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::Step() {
|
||||
jit->Step();
|
||||
}
|
||||
@@ -282,6 +286,13 @@ void ARM_Dynarmic_32::ClearInstructionCache() {
|
||||
jit->ClearCache();
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::InvalidateCacheRange(VAddr addr, std::size_t size) {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
jit->InvalidateCacheRange(static_cast<u32>(addr), size);
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_32::ClearExclusiveState() {
|
||||
jit->ClearExclusiveState();
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
u32 GetPSTATE() const override;
|
||||
void SetPSTATE(u32 pstate) override;
|
||||
void Run() override;
|
||||
void ExceptionalExit() override;
|
||||
void Step() override;
|
||||
VAddr GetTlsAddress() const override;
|
||||
void SetTlsAddress(VAddr address) override;
|
||||
@@ -58,6 +59,7 @@ public:
|
||||
void ClearExclusiveState() override;
|
||||
|
||||
void ClearInstructionCache() override;
|
||||
void InvalidateCacheRange(VAddr addr, std::size_t size) override;
|
||||
void PageTableChanged(Common::PageTable& new_page_table,
|
||||
std::size_t new_address_space_size_in_bits) override;
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/hardware_properties.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/kernel/scheduler.h"
|
||||
@@ -96,16 +95,6 @@ public:
|
||||
case Dynarmic::A64::Exception::Yield:
|
||||
return;
|
||||
case Dynarmic::A64::Exception::Breakpoint:
|
||||
if (GDBStub::IsServerEnabled()) {
|
||||
parent.jit->HaltExecution();
|
||||
parent.SetPC(pc);
|
||||
Kernel::Thread* const thread = parent.system.CurrentScheduler().GetCurrentThread();
|
||||
parent.SaveContext(thread->GetContext64());
|
||||
GDBStub::Break();
|
||||
GDBStub::SendTrap(thread, 5);
|
||||
return;
|
||||
}
|
||||
[[fallthrough]];
|
||||
default:
|
||||
ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})",
|
||||
static_cast<std::size_t>(exception), pc, MemoryReadCode(pc));
|
||||
@@ -231,6 +220,10 @@ void ARM_Dynarmic_64::Run() {
|
||||
jit->Run();
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::ExceptionalExit() {
|
||||
jit->ExceptionalExit();
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::Step() {
|
||||
cb->InterpreterFallback(jit->GetPC(), 1);
|
||||
}
|
||||
@@ -329,6 +322,13 @@ void ARM_Dynarmic_64::ClearInstructionCache() {
|
||||
jit->ClearCache();
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::InvalidateCacheRange(VAddr addr, std::size_t size) {
|
||||
if (!jit) {
|
||||
return;
|
||||
}
|
||||
jit->InvalidateCacheRange(addr, size);
|
||||
}
|
||||
|
||||
void ARM_Dynarmic_64::ClearExclusiveState() {
|
||||
jit->ClearExclusiveState();
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
void SetPSTATE(u32 pstate) override;
|
||||
void Run() override;
|
||||
void Step() override;
|
||||
void ExceptionalExit() override;
|
||||
VAddr GetTlsAddress() const override;
|
||||
void SetTlsAddress(VAddr address) override;
|
||||
void SetTPIDR_EL0(u64 value) override;
|
||||
@@ -55,6 +56,7 @@ public:
|
||||
void ClearExclusiveState() override;
|
||||
|
||||
void ClearInstructionCache() override;
|
||||
void InvalidateCacheRange(VAddr addr, std::size_t size) override;
|
||||
void PageTableChanged(Common::PageTable& new_page_table,
|
||||
std::size_t new_address_space_size_in_bits) override;
|
||||
|
||||
|
||||
+34
-29
@@ -25,7 +25,6 @@
|
||||
#include "core/file_sys/sdmc_factory.h"
|
||||
#include "core/file_sys/vfs_concat.h"
|
||||
#include "core/file_sys/vfs_real.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/hardware_interrupt_manager.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
@@ -92,33 +91,43 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
||||
std::string dir_name;
|
||||
std::string filename;
|
||||
Common::SplitPath(path, &dir_name, &filename, nullptr);
|
||||
|
||||
if (filename == "00") {
|
||||
const auto dir = vfs->OpenDirectory(dir_name, FileSys::Mode::Read);
|
||||
std::vector<FileSys::VirtualFile> concat;
|
||||
for (u8 i = 0; i < 0x10; ++i) {
|
||||
auto next = dir->GetFile(fmt::format("{:02X}", i));
|
||||
if (next != nullptr)
|
||||
|
||||
for (u32 i = 0; i < 0x10; ++i) {
|
||||
const auto file_name = fmt::format("{:02X}", i);
|
||||
auto next = dir->GetFile(file_name);
|
||||
|
||||
if (next != nullptr) {
|
||||
concat.push_back(std::move(next));
|
||||
else {
|
||||
next = dir->GetFile(fmt::format("{:02x}", i));
|
||||
if (next != nullptr)
|
||||
concat.push_back(std::move(next));
|
||||
else
|
||||
} else {
|
||||
next = dir->GetFile(file_name);
|
||||
|
||||
if (next == nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
concat.push_back(std::move(next));
|
||||
}
|
||||
}
|
||||
|
||||
if (concat.empty())
|
||||
if (concat.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return FileSys::ConcatenatedVfsFile::MakeConcatenatedFile(concat, dir->GetName());
|
||||
return FileSys::ConcatenatedVfsFile::MakeConcatenatedFile(std::move(concat),
|
||||
dir->GetName());
|
||||
}
|
||||
|
||||
if (Common::FS::IsDirectory(path))
|
||||
return vfs->OpenFile(path + "/" + "main", FileSys::Mode::Read);
|
||||
if (Common::FS::IsDirectory(path)) {
|
||||
return vfs->OpenFile(path + "/main", FileSys::Mode::Read);
|
||||
}
|
||||
|
||||
return vfs->OpenFile(path, FileSys::Mode::Read);
|
||||
}
|
||||
|
||||
struct System::Impl {
|
||||
explicit Impl(System& system)
|
||||
: kernel{system}, fs_controller{system}, memory{system},
|
||||
@@ -186,11 +195,8 @@ struct System::Impl {
|
||||
}
|
||||
|
||||
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
|
||||
|
||||
services = std::make_unique<Service::Services>(service_manager, system);
|
||||
GDBStub::DeferStart();
|
||||
|
||||
interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system);
|
||||
interrupt_manager = std::make_unique<Hardware::InterruptManager>(system);
|
||||
|
||||
// Initialize time manager, which must happen after kernel is created
|
||||
time_manager.Initialize();
|
||||
@@ -231,7 +237,7 @@ struct System::Impl {
|
||||
Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland);
|
||||
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
|
||||
if (load_result != Loader::ResultStatus::Success) {
|
||||
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result));
|
||||
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
|
||||
Shutdown();
|
||||
|
||||
return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) +
|
||||
@@ -239,6 +245,7 @@ struct System::Impl {
|
||||
}
|
||||
AddGlueRegistrationForProcess(*app_loader, *main_process);
|
||||
kernel.MakeCurrentProcess(main_process.get());
|
||||
kernel.InitializeCores();
|
||||
|
||||
// Initialize cheat engine
|
||||
if (cheat_engine) {
|
||||
@@ -260,8 +267,7 @@ struct System::Impl {
|
||||
|
||||
u64 title_id{0};
|
||||
if (app_loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) {
|
||||
LOG_ERROR(Core, "Failed to find title id for ROM (Error {})",
|
||||
static_cast<u32>(load_result));
|
||||
LOG_ERROR(Core, "Failed to find title id for ROM (Error {})", load_result);
|
||||
}
|
||||
perf_stats = std::make_unique<PerfStats>(title_id);
|
||||
// Reset counters and set time origin to current frame
|
||||
@@ -297,7 +303,6 @@ struct System::Impl {
|
||||
}
|
||||
|
||||
// Shutdown emulation session
|
||||
GDBStub::Shutdown();
|
||||
services.reset();
|
||||
service_manager.reset();
|
||||
cheat_engine.reset();
|
||||
@@ -451,6 +456,10 @@ void System::InvalidateCpuInstructionCaches() {
|
||||
impl->kernel.InvalidateAllInstructionCaches();
|
||||
}
|
||||
|
||||
void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) {
|
||||
impl->kernel.InvalidateCpuInstructionCacheRange(addr, size);
|
||||
}
|
||||
|
||||
void System::Shutdown() {
|
||||
impl->Shutdown();
|
||||
}
|
||||
@@ -485,11 +494,11 @@ const TelemetrySession& System::TelemetrySession() const {
|
||||
}
|
||||
|
||||
ARM_Interface& System::CurrentArmInterface() {
|
||||
return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface();
|
||||
return impl->kernel.CurrentPhysicalCore().ArmInterface();
|
||||
}
|
||||
|
||||
const ARM_Interface& System::CurrentArmInterface() const {
|
||||
return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface();
|
||||
return impl->kernel.CurrentPhysicalCore().ArmInterface();
|
||||
}
|
||||
|
||||
std::size_t System::CurrentCoreIndex() const {
|
||||
@@ -549,15 +558,11 @@ const Kernel::Process* System::CurrentProcess() const {
|
||||
}
|
||||
|
||||
ARM_Interface& System::ArmInterface(std::size_t core_index) {
|
||||
auto* thread = impl->kernel.Scheduler(core_index).GetCurrentThread();
|
||||
ASSERT(thread && !thread->IsHLEThread());
|
||||
return thread->ArmInterface();
|
||||
return impl->kernel.PhysicalCore(core_index).ArmInterface();
|
||||
}
|
||||
|
||||
const ARM_Interface& System::ArmInterface(std::size_t core_index) const {
|
||||
auto* thread = impl->kernel.Scheduler(core_index).GetCurrentThread();
|
||||
ASSERT(thread && !thread->IsHLEThread());
|
||||
return thread->ArmInterface();
|
||||
return impl->kernel.PhysicalCore(core_index).ArmInterface();
|
||||
}
|
||||
|
||||
ExclusiveMonitor& System::Monitor() {
|
||||
|
||||
@@ -166,6 +166,8 @@ public:
|
||||
*/
|
||||
void InvalidateCpuInstructionCaches();
|
||||
|
||||
void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
|
||||
|
||||
/// Shutdown the emulated system.
|
||||
void Shutdown();
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ using TimedCallback =
|
||||
|
||||
/// Contains the characteristics of a particular event.
|
||||
struct EventType {
|
||||
EventType(TimedCallback&& callback, std::string&& name)
|
||||
: callback{std::move(callback)}, name{std::move(name)} {}
|
||||
explicit EventType(TimedCallback&& callback_, std::string&& name_)
|
||||
: callback{std::move(callback_)}, name{std::move(name_)} {}
|
||||
|
||||
/// The event's callback function.
|
||||
TimedCallback callback;
|
||||
@@ -67,8 +67,8 @@ public:
|
||||
void Shutdown();
|
||||
|
||||
/// Sets if emulation is multicore or single core, must be set before Initialize
|
||||
void SetMulticore(bool is_multicore) {
|
||||
this->is_multicore = is_multicore;
|
||||
void SetMulticore(bool is_multicore_) {
|
||||
is_multicore = is_multicore_;
|
||||
}
|
||||
|
||||
/// Check if it's using host timing.
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/cpu_manager.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/physical_core.h"
|
||||
#include "core/hle/kernel/scheduler.h"
|
||||
@@ -114,22 +113,23 @@ void CpuManager::MultiCoreRunGuestThread() {
|
||||
auto& sched = kernel.CurrentScheduler();
|
||||
sched.OnThreadStart();
|
||||
}
|
||||
auto* thread = kernel.CurrentScheduler().GetCurrentThread();
|
||||
auto& host_context = thread->GetHostContext();
|
||||
host_context->SetRewindPoint(GuestRewindFunction, this);
|
||||
MultiCoreRunGuestLoop();
|
||||
}
|
||||
|
||||
void CpuManager::MultiCoreRunGuestLoop() {
|
||||
auto& kernel = system.Kernel();
|
||||
auto* thread = kernel.CurrentScheduler().GetCurrentThread();
|
||||
|
||||
while (true) {
|
||||
auto* physical_core = &kernel.CurrentPhysicalCore();
|
||||
auto& arm_interface = thread->ArmInterface();
|
||||
system.EnterDynarmicProfile();
|
||||
while (!physical_core->IsInterrupted()) {
|
||||
arm_interface.Run();
|
||||
physical_core->Run();
|
||||
physical_core = &kernel.CurrentPhysicalCore();
|
||||
}
|
||||
system.ExitDynarmicProfile();
|
||||
arm_interface.ClearExclusiveState();
|
||||
auto& scheduler = kernel.CurrentScheduler();
|
||||
scheduler.TryDoContextSwitch();
|
||||
}
|
||||
@@ -210,6 +210,9 @@ void CpuManager::SingleCoreRunGuestThread() {
|
||||
auto& sched = kernel.CurrentScheduler();
|
||||
sched.OnThreadStart();
|
||||
}
|
||||
auto* thread = kernel.CurrentScheduler().GetCurrentThread();
|
||||
auto& host_context = thread->GetHostContext();
|
||||
host_context->SetRewindPoint(GuestRewindFunction, this);
|
||||
SingleCoreRunGuestLoop();
|
||||
}
|
||||
|
||||
@@ -218,17 +221,15 @@ void CpuManager::SingleCoreRunGuestLoop() {
|
||||
auto* thread = kernel.CurrentScheduler().GetCurrentThread();
|
||||
while (true) {
|
||||
auto* physical_core = &kernel.CurrentPhysicalCore();
|
||||
auto& arm_interface = thread->ArmInterface();
|
||||
system.EnterDynarmicProfile();
|
||||
if (!physical_core->IsInterrupted()) {
|
||||
arm_interface.Run();
|
||||
physical_core->Run();
|
||||
physical_core = &kernel.CurrentPhysicalCore();
|
||||
}
|
||||
system.ExitDynarmicProfile();
|
||||
thread->SetPhantomMode(true);
|
||||
system.CoreTiming().Advance();
|
||||
thread->SetPhantomMode(false);
|
||||
arm_interface.ClearExclusiveState();
|
||||
PreemptSingleCore();
|
||||
auto& scheduler = kernel.Scheduler(current_core);
|
||||
scheduler.TryDoContextSwitch();
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
constexpr u64 AOC_TITLE_ID_MASK = 0x7FF;
|
||||
constexpr u64 AOC_TITLE_ID_OFFSET = 0x1000;
|
||||
constexpr u64 BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
|
||||
|
||||
/**
|
||||
* Gets the base title ID from a given title ID.
|
||||
*
|
||||
* @param title_id The title ID.
|
||||
* @returns The base title ID.
|
||||
*/
|
||||
[[nodiscard]] constexpr u64 GetBaseTitleID(u64 title_id) {
|
||||
return title_id & BASE_TITLE_ID_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base title ID with a program index offset from a given title ID.
|
||||
*
|
||||
* @param title_id The title ID.
|
||||
* @param program_index The program index.
|
||||
* @returns The base title ID with a program index offset.
|
||||
*/
|
||||
[[nodiscard]] constexpr u64 GetBaseTitleIDWithProgramIndex(u64 title_id, u64 program_index) {
|
||||
return GetBaseTitleID(title_id) + program_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the AOC (Add-On Content) base title ID from a given title ID.
|
||||
*
|
||||
* @param title_id The title ID.
|
||||
* @returns The AOC base title ID.
|
||||
*/
|
||||
[[nodiscard]] constexpr u64 GetAOCBaseTitleID(u64 title_id) {
|
||||
return GetBaseTitleID(title_id) + AOC_TITLE_ID_OFFSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the AOC (Add-On Content) ID from a given AOC title ID.
|
||||
*
|
||||
* @param aoc_title_id The AOC title ID.
|
||||
* @returns The AOC ID.
|
||||
*/
|
||||
[[nodiscard]] constexpr u64 GetAOCID(u64 aoc_title_id) {
|
||||
return aoc_title_id & AOC_TITLE_ID_MASK;
|
||||
}
|
||||
|
||||
} // namespace FileSys
|
||||
@@ -410,8 +410,9 @@ u8 NCA::GetCryptoRevision() const {
|
||||
std::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type) const {
|
||||
const auto master_key_id = GetCryptoRevision();
|
||||
|
||||
if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index))
|
||||
return {};
|
||||
if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<u8> key_area(header.key_area.begin(), header.key_area.end());
|
||||
Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(
|
||||
@@ -420,15 +421,17 @@ std::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type
|
||||
cipher.Transcode(key_area.data(), key_area.size(), key_area.data(), Core::Crypto::Op::Decrypt);
|
||||
|
||||
Core::Crypto::Key128 out;
|
||||
if (type == NCASectionCryptoType::XTS)
|
||||
if (type == NCASectionCryptoType::XTS) {
|
||||
std::copy(key_area.begin(), key_area.begin() + 0x10, out.begin());
|
||||
else if (type == NCASectionCryptoType::CTR || type == NCASectionCryptoType::BKTR)
|
||||
} else if (type == NCASectionCryptoType::CTR || type == NCASectionCryptoType::BKTR) {
|
||||
std::copy(key_area.begin() + 0x20, key_area.begin() + 0x30, out.begin());
|
||||
else
|
||||
} else {
|
||||
LOG_CRITICAL(Crypto, "Called GetKeyAreaKey on invalid NCASectionCryptoType type={:02X}",
|
||||
static_cast<u8>(type));
|
||||
type);
|
||||
}
|
||||
|
||||
u128 out_128{};
|
||||
memcpy(out_128.data(), out.data(), 16);
|
||||
std::memcpy(out_128.data(), out.data(), sizeof(u128));
|
||||
LOG_TRACE(Crypto, "called with crypto_rev={:02X}, kak_index={:02X}, key={:016X}{:016X}",
|
||||
master_key_id, header.key_index, out_128[1], out_128[0]);
|
||||
|
||||
@@ -507,7 +510,7 @@ VirtualFile NCA::Decrypt(const NCASectionHeader& s_header, VirtualFile in, u64 s
|
||||
// TODO(DarkLordZach): Find a test case for XTS-encrypted NCAs
|
||||
default:
|
||||
LOG_ERROR(Crypto, "called with unhandled crypto type={:02X}",
|
||||
static_cast<u8>(s_header.raw.header.crypto_type));
|
||||
s_header.raw.header.crypto_type);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -516,15 +519,17 @@ Loader::ResultStatus NCA::GetStatus() const {
|
||||
return status;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VfsFile>> NCA::GetFiles() const {
|
||||
if (status != Loader::ResultStatus::Success)
|
||||
std::vector<VirtualFile> NCA::GetFiles() const {
|
||||
if (status != Loader::ResultStatus::Success) {
|
||||
return {};
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VfsDirectory>> NCA::GetSubdirectories() const {
|
||||
if (status != Loader::ResultStatus::Success)
|
||||
std::vector<VirtualDir> NCA::GetSubdirectories() const {
|
||||
if (status != Loader::ResultStatus::Success) {
|
||||
return {};
|
||||
}
|
||||
return dirs;
|
||||
}
|
||||
|
||||
@@ -532,7 +537,7 @@ std::string NCA::GetName() const {
|
||||
return file->GetName();
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> NCA::GetParentDirectory() const {
|
||||
VirtualDir NCA::GetParentDirectory() const {
|
||||
return file->GetContainingDirectory();
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ struct NCAHeader {
|
||||
};
|
||||
static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size.");
|
||||
|
||||
inline bool IsDirectoryExeFS(const std::shared_ptr<VfsDirectory>& pfs) {
|
||||
inline bool IsDirectoryExeFS(const VirtualDir& pfs) {
|
||||
// According to switchbrew, an exefs must only contain these two files:
|
||||
return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr;
|
||||
}
|
||||
@@ -104,10 +104,10 @@ public:
|
||||
|
||||
Loader::ResultStatus GetStatus() const;
|
||||
|
||||
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
|
||||
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
|
||||
std::vector<VirtualFile> GetFiles() const override;
|
||||
std::vector<VirtualDir> GetSubdirectories() const override;
|
||||
std::string GetName() const override;
|
||||
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
|
||||
VirtualDir GetParentDirectory() const override;
|
||||
|
||||
NCAContentType GetType() const;
|
||||
u64 GetTitleId() const;
|
||||
|
||||
@@ -191,7 +191,7 @@ bool BKTR::Resize(std::size_t new_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> BKTR::GetContainingDirectory() const {
|
||||
VirtualDir BKTR::GetContainingDirectory() const {
|
||||
return base_romfs->GetContainingDirectory();
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ public:
|
||||
|
||||
bool Resize(std::size_t new_size) override;
|
||||
|
||||
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
|
||||
VirtualDir GetContainingDirectory() const override;
|
||||
|
||||
bool IsWritable() const override;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/common_funcs.h"
|
||||
#include "core/file_sys/content_archive.h"
|
||||
#include "core/file_sys/control_metadata.h"
|
||||
#include "core/file_sys/ips_layer.h"
|
||||
@@ -30,7 +31,6 @@ namespace FileSys {
|
||||
namespace {
|
||||
|
||||
constexpr u32 SINGLE_BYTE_MODULUS = 0x100;
|
||||
constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000;
|
||||
|
||||
constexpr std::array<const char*, 14> EXEFS_FILE_NAMES{
|
||||
"main", "main.npdm", "rtld", "sdk", "subsdk0", "subsdk1", "subsdk2",
|
||||
@@ -532,7 +532,7 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||
dlc_match.reserve(dlc_entries.size());
|
||||
std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match),
|
||||
[this](const ContentProviderEntry& entry) {
|
||||
return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == title_id &&
|
||||
return GetBaseTitleID(entry.title_id) == title_id &&
|
||||
content_provider.GetEntry(entry)->GetStatus() ==
|
||||
Loader::ResultStatus::Success;
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/file_sys/card_image.h"
|
||||
#include "core/file_sys/common_funcs.h"
|
||||
#include "core/file_sys/content_archive.h"
|
||||
#include "core/file_sys/nca_metadata.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
@@ -47,6 +48,27 @@ ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess(u64 current_process_titl
|
||||
patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw));
|
||||
}
|
||||
|
||||
ResultVal<VirtualFile> RomFSFactory::OpenPatchedRomFS(u64 title_id, ContentRecordType type) const {
|
||||
auto nca = content_provider.GetEntry(title_id, type);
|
||||
|
||||
if (nca == nullptr) {
|
||||
// TODO: Find the right error code to use here
|
||||
return RESULT_UNKNOWN;
|
||||
}
|
||||
|
||||
const PatchManager patch_manager{title_id, filesystem_controller, content_provider};
|
||||
|
||||
return MakeResult<VirtualFile>(
|
||||
patch_manager.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), type));
|
||||
}
|
||||
|
||||
ResultVal<VirtualFile> RomFSFactory::OpenPatchedRomFSWithProgramIndex(
|
||||
u64 title_id, u8 program_index, ContentRecordType type) const {
|
||||
const auto res_title_id = GetBaseTitleIDWithProgramIndex(title_id, program_index);
|
||||
|
||||
return OpenPatchedRomFS(res_title_id, type);
|
||||
}
|
||||
|
||||
ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage,
|
||||
ContentRecordType type) const {
|
||||
const std::shared_ptr<NCA> res = GetEntry(title_id, storage, type);
|
||||
|
||||
@@ -42,6 +42,10 @@ public:
|
||||
|
||||
void SetPackedUpdate(VirtualFile update_raw);
|
||||
[[nodiscard]] ResultVal<VirtualFile> OpenCurrentProcess(u64 current_process_title_id) const;
|
||||
[[nodiscard]] ResultVal<VirtualFile> OpenPatchedRomFS(u64 title_id,
|
||||
ContentRecordType type) const;
|
||||
[[nodiscard]] ResultVal<VirtualFile> OpenPatchedRomFSWithProgramIndex(
|
||||
u64 title_id, u8 program_index, ContentRecordType type) const;
|
||||
[[nodiscard]] ResultVal<VirtualFile> Open(u64 title_id, StorageId storage,
|
||||
ContentRecordType type) const;
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@ std::string SaveDataAttribute::DebugInfo() const {
|
||||
static_cast<u8>(rank), index);
|
||||
}
|
||||
|
||||
SaveDataFactory::SaveDataFactory(VirtualDir save_directory) : dir(std::move(save_directory)) {
|
||||
SaveDataFactory::SaveDataFactory(Core::System& system_, VirtualDir save_directory_)
|
||||
: dir{std::move(save_directory_)}, system{system_} {
|
||||
// Delete all temporary storages
|
||||
// On hardware, it is expected that temporary storage be empty at first use.
|
||||
dir->DeleteSubdirectoryRecursive("temp");
|
||||
@@ -83,7 +84,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space,
|
||||
PrintSaveDataAttributeWarnings(meta);
|
||||
|
||||
const auto save_directory =
|
||||
GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id);
|
||||
GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
|
||||
|
||||
auto out = dir->CreateDirectoryRelative(save_directory);
|
||||
|
||||
@@ -100,7 +101,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
|
||||
const SaveDataAttribute& meta) const {
|
||||
|
||||
const auto save_directory =
|
||||
GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id);
|
||||
GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
|
||||
|
||||
auto out = dir->GetDirectoryRelative(save_directory);
|
||||
|
||||
@@ -135,13 +136,14 @@ std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id,
|
||||
u128 user_id, u64 save_id) {
|
||||
std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId space,
|
||||
SaveDataType type, u64 title_id, u128 user_id,
|
||||
u64 save_id) {
|
||||
// According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
|
||||
// be interpreted as the title id of the current process.
|
||||
if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
|
||||
if (title_id == 0) {
|
||||
title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
|
||||
title_id = system.CurrentProcess()->GetTitleID();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +169,7 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ
|
||||
|
||||
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
|
||||
u128 user_id) const {
|
||||
const auto path = GetFullPath(SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
|
||||
const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
|
||||
const auto dir = GetOrCreateDirectoryRelative(this->dir, path);
|
||||
|
||||
const auto size_file = dir->GetFile(SAVE_DATA_SIZE_FILENAME);
|
||||
@@ -182,7 +184,7 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
|
||||
|
||||
void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
|
||||
SaveDataSize new_value) const {
|
||||
const auto path = GetFullPath(SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
|
||||
const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
|
||||
const auto dir = GetOrCreateDirectoryRelative(this->dir, path);
|
||||
|
||||
const auto size_file = dir->CreateFile(SAVE_DATA_SIZE_FILENAME);
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include "core/file_sys/vfs.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
enum class SaveDataSpaceId : u8 {
|
||||
@@ -84,7 +88,7 @@ struct SaveDataSize {
|
||||
/// File system interface to the SaveData archive
|
||||
class SaveDataFactory {
|
||||
public:
|
||||
explicit SaveDataFactory(VirtualDir dir);
|
||||
explicit SaveDataFactory(Core::System& system_, VirtualDir save_directory_);
|
||||
~SaveDataFactory();
|
||||
|
||||
ResultVal<VirtualDir> Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const;
|
||||
@@ -93,8 +97,8 @@ public:
|
||||
VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const;
|
||||
|
||||
static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space);
|
||||
static std::string GetFullPath(SaveDataSpaceId space, SaveDataType type, u64 title_id,
|
||||
u128 user_id, u64 save_id);
|
||||
static std::string GetFullPath(Core::System& system, SaveDataSpaceId space, SaveDataType type,
|
||||
u64 title_id, u128 user_id, u64 save_id);
|
||||
|
||||
SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const;
|
||||
void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
|
||||
@@ -102,6 +106,7 @@ public:
|
||||
|
||||
private:
|
||||
VirtualDir dir;
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
} // namespace FileSys
|
||||
|
||||
@@ -6,191 +6,384 @@
|
||||
|
||||
namespace FileSys::SystemArchive::SharedFontData {
|
||||
|
||||
const std::array<unsigned char, 2932> FONT_NINTENDO_EXTENDED{{
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x80, 0x00, 0x03, 0x00, 0x70, 0x44, 0x53, 0x49, 0x47,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0b, 0x6c, 0x00, 0x00, 0x00, 0x08, 0x4f, 0x53, 0x2f, 0x32,
|
||||
0x33, 0x86, 0x1d, 0x9b, 0x00, 0x00, 0x01, 0x78, 0x00, 0x00, 0x00, 0x60, 0x63, 0x6d, 0x61, 0x70,
|
||||
0xc2, 0x06, 0x20, 0xde, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x63, 0x76, 0x74, 0x20,
|
||||
0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x04, 0x2c, 0x00, 0x00, 0x00, 0x06, 0x66, 0x70, 0x67, 0x6d,
|
||||
0x06, 0x59, 0x9c, 0x37, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x01, 0x73, 0x67, 0x61, 0x73, 0x70,
|
||||
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0b, 0x64, 0x00, 0x00, 0x00, 0x08, 0x67, 0x6c, 0x79, 0x66,
|
||||
0x10, 0x31, 0x88, 0x00, 0x00, 0x00, 0x04, 0x34, 0x00, 0x00, 0x04, 0x64, 0x68, 0x65, 0x61, 0x64,
|
||||
0x15, 0x9d, 0xef, 0x91, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61,
|
||||
0x09, 0x60, 0x03, 0x71, 0x00, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78,
|
||||
0x0d, 0x2e, 0x03, 0xa7, 0x00, 0x00, 0x01, 0xd8, 0x00, 0x00, 0x00, 0x26, 0x6c, 0x6f, 0x63, 0x61,
|
||||
0x05, 0xc0, 0x04, 0x6c, 0x00, 0x00, 0x08, 0x98, 0x00, 0x00, 0x00, 0x1e, 0x6d, 0x61, 0x78, 0x70,
|
||||
0x02, 0x1c, 0x00, 0x5f, 0x00, 0x00, 0x01, 0x58, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x7c, 0xe0, 0x84, 0x5c, 0x00, 0x00, 0x08, 0xb8, 0x00, 0x00, 0x02, 0x09, 0x70, 0x6f, 0x73, 0x74,
|
||||
0x47, 0x4e, 0x74, 0x19, 0x00, 0x00, 0x0a, 0xc4, 0x00, 0x00, 0x00, 0x9e, 0x70, 0x72, 0x65, 0x70,
|
||||
0x1c, 0xfc, 0x7d, 0x9c, 0x00, 0x00, 0x04, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x7c, 0xc7, 0xb1, 0x63, 0x5f, 0x0f, 0x3c, 0xf5, 0x00, 0x1b, 0x03, 0xe8,
|
||||
0x00, 0x00, 0x00, 0x00, 0xd9, 0x44, 0x2f, 0x5d, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x45, 0x7b, 0x69,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0xe6, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x84, 0xff, 0x83, 0x01, 0xf4, 0x03, 0xe8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0xe6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x5e,
|
||||
0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x74, 0x01, 0x90, 0x00, 0x05,
|
||||
0x00, 0x04, 0x00, 0xcd, 0x00, 0xcd, 0x00, 0x00, 0x01, 0x1f, 0x00, 0xcd, 0x00, 0xcd, 0x00, 0x00,
|
||||
0x03, 0xc3, 0x00, 0x66, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
const std::array<unsigned char, 6024> FONT_NINTENDO_EXTENDED{{
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x80, 0x00, 0x03, 0x00, 0x60, 0x4F, 0x53, 0x2F, 0x32,
|
||||
0x34, 0x00, 0x1E, 0x26, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x00, 0x60, 0x63, 0x6D, 0x61, 0x70,
|
||||
0xC1, 0xE7, 0xC8, 0xF3, 0x00, 0x00, 0x02, 0x0C, 0x00, 0x00, 0x01, 0x72, 0x63, 0x76, 0x74, 0x20,
|
||||
0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x66, 0x70, 0x67, 0x6D,
|
||||
0x06, 0x59, 0x9C, 0x37, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x01, 0x73, 0x67, 0x61, 0x73, 0x70,
|
||||
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x17, 0x80, 0x00, 0x00, 0x00, 0x08, 0x67, 0x6C, 0x79, 0x66,
|
||||
0x50, 0x0B, 0xEA, 0xFA, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x0F, 0x04, 0x68, 0x65, 0x61, 0x64,
|
||||
0x18, 0x65, 0x81, 0x09, 0x00, 0x00, 0x00, 0xEC, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61,
|
||||
0x09, 0x88, 0x03, 0x86, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6D, 0x74, 0x78,
|
||||
0x0A, 0xF0, 0x01, 0x94, 0x00, 0x00, 0x01, 0xC8, 0x00, 0x00, 0x00, 0x42, 0x6C, 0x6F, 0x63, 0x61,
|
||||
0x34, 0x80, 0x30, 0x6E, 0x00, 0x00, 0x05, 0x14, 0x00, 0x00, 0x00, 0x3A, 0x6D, 0x61, 0x78, 0x70,
|
||||
0x02, 0x2C, 0x00, 0x72, 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x00, 0x20, 0x6E, 0x61, 0x6D, 0x65,
|
||||
0xDB, 0xC5, 0x42, 0x4D, 0x00, 0x00, 0x14, 0x54, 0x00, 0x00, 0x01, 0xFE, 0x70, 0x6F, 0x73, 0x74,
|
||||
0xF4, 0xB4, 0xAC, 0xAB, 0x00, 0x00, 0x16, 0x54, 0x00, 0x00, 0x01, 0x2A, 0x70, 0x72, 0x65, 0x70,
|
||||
0x1C, 0xFC, 0x7D, 0x9C, 0x00, 0x00, 0x04, 0xF4, 0x00, 0x00, 0x00, 0x16, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0xC9, 0x16, 0x5B, 0x71, 0x5F, 0x0F, 0x3C, 0xF5, 0x00, 0x0B, 0x04, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xD9, 0x44, 0x2F, 0x5D, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x02, 0x0D, 0xA7,
|
||||
0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x9A, 0xFF, 0x80, 0x02, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0xEC, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x71,
|
||||
0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0xC4, 0x01, 0x90, 0x00, 0x05,
|
||||
0x00, 0x04, 0x00, 0xD2, 0x00, 0xD2, 0x00, 0x00, 0x01, 0x26, 0x00, 0xD2, 0x00, 0xD2, 0x00, 0x00,
|
||||
0x03, 0xDA, 0x00, 0x68, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0xc0, 0x00, 0x00, 0xe0, 0xe9, 0x03, 0x84, 0xff, 0x83,
|
||||
0x01, 0xf4, 0x02, 0xee, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8,
|
||||
0x02, 0xbc, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xfa, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x03, 0xe8, 0x00, 0xeb, 0x01, 0x21, 0x00, 0xff,
|
||||
0x00, 0xff, 0x01, 0x3d, 0x01, 0x17, 0x00, 0x42, 0x00, 0x1c, 0x00, 0x3e, 0x00, 0x17, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x68, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x1c, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x06, 0x00, 0x4c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x00, 0xC0, 0x00, 0x0D, 0xE0, 0xF0, 0x03, 0x9A, 0xFF, 0x80,
|
||||
0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
|
||||
0x02, 0xCD, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x04, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14,
|
||||
0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14,
|
||||
0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14,
|
||||
0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C,
|
||||
0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x50, 0x00, 0x00, 0x00, 0x10,
|
||||
0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x20, 0xE0, 0xA9, 0xE0, 0xB4,
|
||||
0xE0, 0xE9, 0xE0, 0xF0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x20, 0xE0, 0xA0,
|
||||
0xE0, 0xB3, 0xE0, 0xE0, 0xE0, 0xEF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF5, 0xFF, 0xE3, 0x1F, 0x64,
|
||||
0x1F, 0x5B, 0x1F, 0x30, 0x1F, 0x2B, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a,
|
||||
0x00, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x20, 0xe0, 0xe9, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x20, 0xe0, 0xe0, 0xff, 0xff, 0x00, 0x01, 0xff, 0xf5,
|
||||
0xff, 0xe3, 0x1f, 0x24, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xb8, 0x00, 0x00, 0x2c, 0x4b, 0xb8, 0x00, 0x09, 0x50, 0x58, 0xb1, 0x01, 0x01, 0x8e, 0x59, 0xb8,
|
||||
0x01, 0xff, 0x85, 0xb8, 0x00, 0x44, 0x1d, 0xb9, 0x00, 0x09, 0x00, 0x03, 0x5f, 0x5e, 0x2d, 0xb8,
|
||||
0x00, 0x01, 0x2c, 0x20, 0x20, 0x45, 0x69, 0x44, 0xb0, 0x01, 0x60, 0x2d, 0xb8, 0x00, 0x02, 0x2c,
|
||||
0xb8, 0x00, 0x01, 0x2a, 0x21, 0x2d, 0xb8, 0x00, 0x03, 0x2c, 0x20, 0x46, 0xb0, 0x03, 0x25, 0x46,
|
||||
0x52, 0x58, 0x23, 0x59, 0x20, 0x8a, 0x20, 0x8a, 0x49, 0x64, 0x8a, 0x20, 0x46, 0x20, 0x68, 0x61,
|
||||
0x64, 0xb0, 0x04, 0x25, 0x46, 0x20, 0x68, 0x61, 0x64, 0x52, 0x58, 0x23, 0x65, 0x8a, 0x59, 0x2f,
|
||||
0x20, 0xb0, 0x00, 0x53, 0x58, 0x69, 0x20, 0xb0, 0x00, 0x54, 0x58, 0x21, 0xb0, 0x40, 0x59, 0x1b,
|
||||
0x69, 0x20, 0xb0, 0x00, 0x54, 0x58, 0x21, 0xb0, 0x40, 0x65, 0x59, 0x59, 0x3a, 0x2d, 0xb8, 0x00,
|
||||
0x04, 0x2c, 0x20, 0x46, 0xb0, 0x04, 0x25, 0x46, 0x52, 0x58, 0x23, 0x8a, 0x59, 0x20, 0x46, 0x20,
|
||||
0x6a, 0x61, 0x64, 0xb0, 0x04, 0x25, 0x46, 0x20, 0x6a, 0x61, 0x64, 0x52, 0x58, 0x23, 0x8a, 0x59,
|
||||
0x2f, 0xfd, 0x2d, 0xb8, 0x00, 0x05, 0x2c, 0x4b, 0x20, 0xb0, 0x03, 0x26, 0x50, 0x58, 0x51, 0x58,
|
||||
0xb0, 0x80, 0x44, 0x1b, 0xb0, 0x40, 0x44, 0x59, 0x1b, 0x21, 0x21, 0x20, 0x45, 0xb0, 0xc0, 0x50,
|
||||
0x58, 0xb0, 0xc0, 0x44, 0x1b, 0x21, 0x59, 0x59, 0x2d, 0xb8, 0x00, 0x06, 0x2c, 0x20, 0x20, 0x45,
|
||||
0x69, 0x44, 0xb0, 0x01, 0x60, 0x20, 0x20, 0x45, 0x7d, 0x69, 0x18, 0x44, 0xb0, 0x01, 0x60, 0x2d,
|
||||
0xb8, 0x00, 0x07, 0x2c, 0xb8, 0x00, 0x06, 0x2a, 0x2d, 0xb8, 0x00, 0x08, 0x2c, 0x4b, 0x20, 0xb0,
|
||||
0x03, 0x26, 0x53, 0x58, 0xb0, 0x40, 0x1b, 0xb0, 0x00, 0x59, 0x8a, 0x8a, 0x20, 0xb0, 0x03, 0x26,
|
||||
0x53, 0x58, 0x23, 0x21, 0xb0, 0x80, 0x8a, 0x8a, 0x1b, 0x8a, 0x23, 0x59, 0x20, 0xb0, 0x03, 0x26,
|
||||
0x53, 0x58, 0x23, 0x21, 0xb8, 0x00, 0xc0, 0x8a, 0x8a, 0x1b, 0x8a, 0x23, 0x59, 0x20, 0xb0, 0x03,
|
||||
0x26, 0x53, 0x58, 0x23, 0x21, 0xb8, 0x01, 0x00, 0x8a, 0x8a, 0x1b, 0x8a, 0x23, 0x59, 0x20, 0xb0,
|
||||
0x03, 0x26, 0x53, 0x58, 0x23, 0x21, 0xb8, 0x01, 0x40, 0x8a, 0x8a, 0x1b, 0x8a, 0x23, 0x59, 0x20,
|
||||
0xb8, 0x00, 0x03, 0x26, 0x53, 0x58, 0xb0, 0x03, 0x25, 0x45, 0xb8, 0x01, 0x80, 0x50, 0x58, 0x23,
|
||||
0x21, 0xb8, 0x01, 0x80, 0x23, 0x21, 0x1b, 0xb0, 0x03, 0x25, 0x45, 0x23, 0x21, 0x23, 0x21, 0x59,
|
||||
0x1b, 0x21, 0x59, 0x44, 0x2d, 0xb8, 0x00, 0x09, 0x2c, 0x4b, 0x53, 0x58, 0x45, 0x44, 0x1b, 0x21,
|
||||
0x21, 0x59, 0x2d, 0x00, 0xb8, 0x00, 0x00, 0x2b, 0x00, 0xba, 0x00, 0x01, 0x00, 0x01, 0x00, 0x07,
|
||||
0x2b, 0xb8, 0x00, 0x00, 0x20, 0x45, 0x7d, 0x69, 0x18, 0x44, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x03, 0xe6, 0x03, 0xe8, 0x00, 0x06,
|
||||
0x00, 0x00, 0x35, 0x01, 0x33, 0x15, 0x01, 0x23, 0x35, 0x03, 0x52, 0x94, 0xfc, 0xa6, 0x8c, 0x90,
|
||||
0x03, 0x58, 0x86, 0xfc, 0xa0, 0x8e, 0x00, 0x00, 0x00, 0x02, 0x00, 0xeb, 0x00, 0xcc, 0x02, 0xfb,
|
||||
0x03, 0x1e, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x33, 0x13, 0x23, 0x27, 0x23, 0x07, 0x23,
|
||||
0x13, 0x17, 0x07, 0x06, 0x15, 0x33, 0x27, 0x07, 0x01, 0xbc, 0x6d, 0xd2, 0x7c, 0x26, 0xcc, 0x26,
|
||||
0x7c, 0xd1, 0x35, 0x40, 0x02, 0x89, 0x45, 0x02, 0x03, 0x1e, 0xfd, 0xae, 0x77, 0x77, 0x02, 0x52,
|
||||
0x9b, 0xcc, 0x08, 0x04, 0xda, 0x02, 0x00, 0x00, 0x00, 0x03, 0x01, 0x21, 0x00, 0xcc, 0x02, 0xc5,
|
||||
0x03, 0x1e, 0x00, 0x15, 0x00, 0x1f, 0x00, 0x2b, 0x00, 0x00, 0x25, 0x11, 0x33, 0x32, 0x1e, 0x02,
|
||||
0x15, 0x14, 0x0e, 0x02, 0x07, 0x1e, 0x01, 0x15, 0x14, 0x0e, 0x02, 0x2b, 0x01, 0x13, 0x33, 0x32,
|
||||
0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x1d, 0x01, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x2b,
|
||||
0x01, 0x15, 0x01, 0x21, 0xea, 0x25, 0x3f, 0x2e, 0x1a, 0x0e, 0x15, 0x1b, 0x0e, 0x2d, 0x2d, 0x1a,
|
||||
0x2e, 0x3f, 0x25, 0xf8, 0x76, 0x62, 0x20, 0x2a, 0x28, 0x22, 0x62, 0x76, 0x10, 0x18, 0x11, 0x09,
|
||||
0x22, 0x22, 0x74, 0xcc, 0x02, 0x52, 0x18, 0x2b, 0x3c, 0x24, 0x1d, 0x1f, 0x17, 0x17, 0x14, 0x0f,
|
||||
0x48, 0x2f, 0x24, 0x3f, 0x2e, 0x1a, 0x01, 0x5b, 0x29, 0x20, 0x20, 0x2b, 0x94, 0xf8, 0x0e, 0x16,
|
||||
0x1c, 0x0e, 0x1f, 0x31, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0x00, 0xcc, 0x02, 0xe7,
|
||||
0x03, 0x1e, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x33, 0x17, 0x37, 0x33, 0x03, 0x13, 0x23, 0x27, 0x07,
|
||||
0x23, 0x13, 0x03, 0x01, 0x04, 0x86, 0x69, 0x69, 0x86, 0xa3, 0xa8, 0x88, 0x6c, 0x6c, 0x88, 0xa8,
|
||||
0xa3, 0x03, 0x1e, 0xcb, 0xcb, 0xfe, 0xda, 0xfe, 0xd4, 0xcf, 0xcf, 0x01, 0x2c, 0x01, 0x26, 0x00,
|
||||
0x00, 0x01, 0x00, 0xff, 0x00, 0xcc, 0x02, 0xe7, 0x03, 0x1e, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x03,
|
||||
0x33, 0x17, 0x32, 0x15, 0x1e, 0x01, 0x15, 0x1b, 0x01, 0x33, 0x03, 0x15, 0x23, 0x35, 0x01, 0xb8,
|
||||
0xb9, 0x7e, 0x01, 0x01, 0x01, 0x03, 0x70, 0x75, 0x7f, 0xb9, 0x76, 0x01, 0xa3, 0x01, 0x7b, 0x01,
|
||||
0x01, 0x01, 0x05, 0x02, 0xff, 0x00, 0x01, 0x0a, 0xfe, 0x85, 0xd7, 0xd7, 0x00, 0x01, 0x01, 0x3d,
|
||||
0x00, 0xcc, 0x02, 0xa9, 0x03, 0x1e, 0x00, 0x06, 0x00, 0x00, 0x25, 0x11, 0x33, 0x11, 0x33, 0x15,
|
||||
0x21, 0x01, 0x3d, 0x75, 0xf7, 0xfe, 0x94, 0xcc, 0x02, 0x52, 0xfe, 0x10, 0x62, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x01, 0x17, 0x00, 0xbc, 0x02, 0xcf, 0x03, 0x0e, 0x00, 0x15, 0x00, 0x21, 0x00, 0x00,
|
||||
0x25, 0x11, 0x33, 0x32, 0x1e, 0x02, 0x1d, 0x01, 0x0e, 0x03, 0x1d, 0x01, 0x17, 0x15, 0x23, 0x27,
|
||||
0x23, 0x15, 0x23, 0x13, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x15, 0x01, 0x17,
|
||||
0xf4, 0x27, 0x40, 0x2e, 0x19, 0x01, 0x1f, 0x24, 0x1e, 0x78, 0x7d, 0x6a, 0x5c, 0x75, 0x76, 0x72,
|
||||
0x12, 0x19, 0x11, 0x08, 0x26, 0x26, 0x6a, 0xbc, 0x02, 0x52, 0x1d, 0x31, 0x42, 0x25, 0x16, 0x18,
|
||||
0x32, 0x2a, 0x1b, 0x02, 0x01, 0xef, 0x06, 0xd7, 0xd7, 0x01, 0x3f, 0x10, 0x1a, 0x1e, 0x0f, 0x23,
|
||||
0x36, 0xb0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x00, 0xbc, 0x03, 0xa4, 0x03, 0x0e, 0x00, 0x0a,
|
||||
0x00, 0x11, 0x00, 0x00, 0x13, 0x35, 0x21, 0x15, 0x01, 0x21, 0x15, 0x21, 0x35, 0x01, 0x21, 0x01,
|
||||
0x11, 0x33, 0x11, 0x33, 0x15, 0x21, 0x42, 0x01, 0xa7, 0xfe, 0xeb, 0x01, 0x1b, 0xfe, 0x53, 0x01,
|
||||
0x15, 0xfe, 0xeb, 0x01, 0xf7, 0x75, 0xf6, 0xfe, 0x95, 0x02, 0xac, 0x62, 0x45, 0xfe, 0x55, 0x62,
|
||||
0x47, 0x01, 0xa9, 0xfe, 0x10, 0x02, 0x52, 0xfe, 0x10, 0x62, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1c,
|
||||
0x00, 0xbc, 0x03, 0xca, 0x03, 0x0e, 0x00, 0x0a, 0x00, 0x21, 0x00, 0x2f, 0x00, 0x00, 0x13, 0x35,
|
||||
0x21, 0x15, 0x01, 0x21, 0x15, 0x21, 0x35, 0x01, 0x21, 0x01, 0x11, 0x33, 0x32, 0x1e, 0x02, 0x15,
|
||||
0x14, 0x06, 0x07, 0x0e, 0x03, 0x15, 0x17, 0x15, 0x23, 0x27, 0x23, 0x15, 0x23, 0x13, 0x33, 0x32,
|
||||
0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x2b, 0x01, 0x15, 0x1c, 0x01, 0xa7, 0xfe, 0xeb, 0x01, 0x1b,
|
||||
0xfe, 0x53, 0x01, 0x15, 0xfe, 0xeb, 0x01, 0xf7, 0xf3, 0x27, 0x41, 0x2d, 0x19, 0x1c, 0x20, 0x01,
|
||||
0x0d, 0x0e, 0x0a, 0x78, 0x7d, 0x69, 0x5c, 0x75, 0x76, 0x71, 0x11, 0x1a, 0x12, 0x09, 0x0a, 0x14,
|
||||
0x1d, 0x13, 0x69, 0x02, 0xac, 0x62, 0x45, 0xfe, 0x55, 0x62, 0x47, 0x01, 0xa9, 0xfe, 0x10, 0x02,
|
||||
0x52, 0x1d, 0x31, 0x42, 0x25, 0x2b, 0x44, 0x1d, 0x01, 0x08, 0x09, 0x07, 0x01, 0xf1, 0x06, 0xd7,
|
||||
0xd7, 0x01, 0x3f, 0x11, 0x19, 0x1f, 0x0e, 0x11, 0x20, 0x19, 0x0f, 0xb0, 0x00, 0x02, 0x00, 0x3e,
|
||||
0x00, 0xb3, 0x03, 0xa8, 0x03, 0x17, 0x00, 0x3a, 0x00, 0x41, 0x00, 0x00, 0x13, 0x34, 0x3e, 0x02,
|
||||
0x33, 0x32, 0x1e, 0x02, 0x15, 0x23, 0x27, 0x34, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x0e, 0x02, 0x15,
|
||||
0x14, 0x16, 0x15, 0x1e, 0x05, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x33, 0x1e,
|
||||
0x01, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x04, 0x35, 0x01, 0x11, 0x33, 0x11, 0x33, 0x15,
|
||||
0x21, 0x50, 0x24, 0x3b, 0x4a, 0x27, 0x28, 0x4b, 0x39, 0x22, 0x73, 0x01, 0x01, 0x08, 0x2b, 0x29,
|
||||
0x10, 0x20, 0x19, 0x0f, 0x01, 0x0b, 0x35, 0x41, 0x46, 0x3b, 0x25, 0x23, 0x3a, 0x4b, 0x27, 0x2b,
|
||||
0x50, 0x3f, 0x26, 0x74, 0x05, 0x34, 0x33, 0x10, 0x20, 0x1a, 0x11, 0x2c, 0x42, 0x4d, 0x42, 0x2c,
|
||||
0x01, 0xef, 0x73, 0xf6, 0xfe, 0x97, 0x02, 0x70, 0x2a, 0x3f, 0x2a, 0x14, 0x18, 0x2e, 0x44, 0x2c,
|
||||
0x02, 0x03, 0x01, 0x27, 0x27, 0x07, 0x10, 0x1a, 0x12, 0x02, 0x0b, 0x02, 0x1f, 0x22, 0x19, 0x17,
|
||||
0x27, 0x3f, 0x34, 0x2c, 0x3e, 0x28, 0x13, 0x1a, 0x32, 0x48, 0x2e, 0x30, 0x30, 0x06, 0x0f, 0x1a,
|
||||
0x13, 0x21, 0x27, 0x1e, 0x1b, 0x29, 0x3e, 0x31, 0xfe, 0x4c, 0x02, 0x53, 0xfe, 0x10, 0x63, 0x00,
|
||||
0x00, 0x03, 0x00, 0x17, 0x00, 0xb3, 0x03, 0xce, 0x03, 0x17, 0x00, 0x38, 0x00, 0x4f, 0x00, 0x5d,
|
||||
0x00, 0x00, 0x13, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x23, 0x27, 0x34, 0x23, 0x2e,
|
||||
0x01, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x04, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e,
|
||||
0x02, 0x35, 0x33, 0x1e, 0x01, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x26, 0x27, 0x2e, 0x03, 0x35,
|
||||
0x01, 0x11, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x06, 0x07, 0x30, 0x0e, 0x02, 0x31, 0x17, 0x15,
|
||||
0x23, 0x27, 0x23, 0x15, 0x23, 0x13, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x2b, 0x01,
|
||||
0x15, 0x2a, 0x24, 0x3a, 0x4a, 0x26, 0x29, 0x4b, 0x39, 0x23, 0x73, 0x01, 0x01, 0x08, 0x2a, 0x2a,
|
||||
0x10, 0x1f, 0x1a, 0x10, 0x2c, 0x42, 0x4d, 0x42, 0x2c, 0x23, 0x39, 0x4b, 0x27, 0x2b, 0x51, 0x3f,
|
||||
0x27, 0x75, 0x05, 0x34, 0x33, 0x10, 0x20, 0x1a, 0x10, 0x1f, 0x1c, 0x25, 0x53, 0x47, 0x2e, 0x01,
|
||||
0xed, 0xf3, 0x27, 0x41, 0x2d, 0x19, 0x1c, 0x20, 0x0c, 0x0e, 0x0c, 0x78, 0x7d, 0x68, 0x5d, 0x75,
|
||||
0x76, 0x71, 0x11, 0x1a, 0x12, 0x09, 0x0a, 0x14, 0x1d, 0x13, 0x69, 0x02, 0x71, 0x2a, 0x3e, 0x2a,
|
||||
0x14, 0x18, 0x2e, 0x44, 0x2c, 0x02, 0x02, 0x27, 0x29, 0x07, 0x11, 0x1a, 0x12, 0x1d, 0x24, 0x1c,
|
||||
0x1d, 0x2b, 0x40, 0x32, 0x2c, 0x3f, 0x29, 0x13, 0x1a, 0x31, 0x49, 0x2e, 0x30, 0x30, 0x06, 0x0f,
|
||||
0x19, 0x13, 0x1e, 0x22, 0x0b, 0x0e, 0x20, 0x2f, 0x43, 0x30, 0xfe, 0x4b, 0x02, 0x52, 0x1d, 0x32,
|
||||
0x42, 0x25, 0x2c, 0x42, 0x1d, 0x08, 0x0a, 0x08, 0xf1, 0x06, 0xd7, 0xd7, 0x01, 0x3f, 0x11, 0x19,
|
||||
0x1f, 0x0e, 0x11, 0x20, 0x19, 0x0f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12,
|
||||
0x00, 0x12, 0x00, 0x32, 0x00, 0x72, 0x00, 0x8e, 0x00, 0xac, 0x00, 0xbe, 0x00, 0xf0, 0x01, 0x14,
|
||||
0x01, 0x5c, 0x01, 0xb6, 0x02, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0xa2, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x00, 0x07, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x2f,
|
||||
0x00, 0x17, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x46, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x58, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x06, 0x00, 0x12, 0x00, 0x65, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x20,
|
||||
0x00, 0x77, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x97, 0x00, 0x03,
|
||||
0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x5e, 0x00, 0xa5, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
|
||||
0x00, 0x04, 0x00, 0x24, 0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x1a,
|
||||
0x01, 0x27, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x24, 0x01, 0x41, 0x00, 0x03,
|
||||
0x00, 0x01, 0x04, 0x09, 0x00, 0x11, 0x00, 0x02, 0x01, 0x65, 0x59, 0x75, 0x7a, 0x75, 0x4f, 0x53,
|
||||
0x53, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61,
|
||||
0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x30, 0x3b, 0x3b,
|
||||
0x59, 0x75, 0x7a, 0x75, 0x4f, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x2d, 0x52, 0x3b, 0x32, 0x30, 0x31, 0x39, 0x3b, 0x46, 0x4c, 0x56, 0x49, 0x2d, 0x36, 0x31, 0x34,
|
||||
0x59, 0x75, 0x7a, 0x75, 0x4f, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x20, 0x52, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x30, 0x59,
|
||||
0x75, 0x7a, 0x75, 0x4f, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2d,
|
||||
0x52, 0x00, 0x59, 0x00, 0x75, 0x00, 0x7a, 0x00, 0x75, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x53, 0x00,
|
||||
0x45, 0x00, 0x78, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00,
|
||||
0x6e, 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, 0x00,
|
||||
0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00,
|
||||
0x31, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x59, 0x00,
|
||||
0x75, 0x00, 0x7a, 0x00, 0x75, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x53, 0x00, 0x45, 0x00, 0x78, 0x00,
|
||||
0x74, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x2d, 0x00,
|
||||
0x52, 0x00, 0x3b, 0x00, 0x32, 0x00, 0x30, 0x00, 0x31, 0x00, 0x39, 0x00, 0x3b, 0x00, 0x46, 0x00,
|
||||
0x4c, 0x00, 0x56, 0x00, 0x49, 0x00, 0x2d, 0x00, 0x36, 0x00, 0x31, 0x00, 0x34, 0x00, 0x59, 0x00,
|
||||
0x75, 0x00, 0x7a, 0x00, 0x75, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x53, 0x00, 0x45, 0x00, 0x78, 0x00,
|
||||
0x74, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00,
|
||||
0x52, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00,
|
||||
0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x59, 0x00, 0x75, 0x00,
|
||||
0x7a, 0x00, 0x75, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x53, 0x00, 0x45, 0x00, 0x78, 0x00, 0x74, 0x00,
|
||||
0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x2d, 0x00, 0x52, 0x00,
|
||||
0x52, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x9c, 0x00, 0x32,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x02, 0x01, 0x03, 0x00, 0x03, 0x01, 0x04,
|
||||
0x01, 0x05, 0x01, 0x06, 0x01, 0x07, 0x01, 0x08, 0x01, 0x09, 0x01, 0x0a, 0x01, 0x0b, 0x01, 0x0c,
|
||||
0x01, 0x0d, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x30, 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x30,
|
||||
0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, 0x45, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30,
|
||||
0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, 0x45, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30,
|
||||
0x45, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30,
|
||||
0x45, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, 0x45, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30,
|
||||
0x45, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30, 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x45, 0x30,
|
||||
0x45, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xB8, 0x00, 0x00, 0x2C, 0x4B, 0xB8, 0x00, 0x09, 0x50, 0x58, 0xB1, 0x01, 0x01, 0x8E, 0x59, 0xB8,
|
||||
0x01, 0xFF, 0x85, 0xB8, 0x00, 0x44, 0x1D, 0xB9, 0x00, 0x09, 0x00, 0x03, 0x5F, 0x5E, 0x2D, 0xB8,
|
||||
0x00, 0x01, 0x2C, 0x20, 0x20, 0x45, 0x69, 0x44, 0xB0, 0x01, 0x60, 0x2D, 0xB8, 0x00, 0x02, 0x2C,
|
||||
0xB8, 0x00, 0x01, 0x2A, 0x21, 0x2D, 0xB8, 0x00, 0x03, 0x2C, 0x20, 0x46, 0xB0, 0x03, 0x25, 0x46,
|
||||
0x52, 0x58, 0x23, 0x59, 0x20, 0x8A, 0x20, 0x8A, 0x49, 0x64, 0x8A, 0x20, 0x46, 0x20, 0x68, 0x61,
|
||||
0x64, 0xB0, 0x04, 0x25, 0x46, 0x20, 0x68, 0x61, 0x64, 0x52, 0x58, 0x23, 0x65, 0x8A, 0x59, 0x2F,
|
||||
0x20, 0xB0, 0x00, 0x53, 0x58, 0x69, 0x20, 0xB0, 0x00, 0x54, 0x58, 0x21, 0xB0, 0x40, 0x59, 0x1B,
|
||||
0x69, 0x20, 0xB0, 0x00, 0x54, 0x58, 0x21, 0xB0, 0x40, 0x65, 0x59, 0x59, 0x3A, 0x2D, 0xB8, 0x00,
|
||||
0x04, 0x2C, 0x20, 0x46, 0xB0, 0x04, 0x25, 0x46, 0x52, 0x58, 0x23, 0x8A, 0x59, 0x20, 0x46, 0x20,
|
||||
0x6A, 0x61, 0x64, 0xB0, 0x04, 0x25, 0x46, 0x20, 0x6A, 0x61, 0x64, 0x52, 0x58, 0x23, 0x8A, 0x59,
|
||||
0x2F, 0xFD, 0x2D, 0xB8, 0x00, 0x05, 0x2C, 0x4B, 0x20, 0xB0, 0x03, 0x26, 0x50, 0x58, 0x51, 0x58,
|
||||
0xB0, 0x80, 0x44, 0x1B, 0xB0, 0x40, 0x44, 0x59, 0x1B, 0x21, 0x21, 0x20, 0x45, 0xB0, 0xC0, 0x50,
|
||||
0x58, 0xB0, 0xC0, 0x44, 0x1B, 0x21, 0x59, 0x59, 0x2D, 0xB8, 0x00, 0x06, 0x2C, 0x20, 0x20, 0x45,
|
||||
0x69, 0x44, 0xB0, 0x01, 0x60, 0x20, 0x20, 0x45, 0x7D, 0x69, 0x18, 0x44, 0xB0, 0x01, 0x60, 0x2D,
|
||||
0xB8, 0x00, 0x07, 0x2C, 0xB8, 0x00, 0x06, 0x2A, 0x2D, 0xB8, 0x00, 0x08, 0x2C, 0x4B, 0x20, 0xB0,
|
||||
0x03, 0x26, 0x53, 0x58, 0xB0, 0x40, 0x1B, 0xB0, 0x00, 0x59, 0x8A, 0x8A, 0x20, 0xB0, 0x03, 0x26,
|
||||
0x53, 0x58, 0x23, 0x21, 0xB0, 0x80, 0x8A, 0x8A, 0x1B, 0x8A, 0x23, 0x59, 0x20, 0xB0, 0x03, 0x26,
|
||||
0x53, 0x58, 0x23, 0x21, 0xB8, 0x00, 0xC0, 0x8A, 0x8A, 0x1B, 0x8A, 0x23, 0x59, 0x20, 0xB0, 0x03,
|
||||
0x26, 0x53, 0x58, 0x23, 0x21, 0xB8, 0x01, 0x00, 0x8A, 0x8A, 0x1B, 0x8A, 0x23, 0x59, 0x20, 0xB0,
|
||||
0x03, 0x26, 0x53, 0x58, 0x23, 0x21, 0xB8, 0x01, 0x40, 0x8A, 0x8A, 0x1B, 0x8A, 0x23, 0x59, 0x20,
|
||||
0xB8, 0x00, 0x03, 0x26, 0x53, 0x58, 0xB0, 0x03, 0x25, 0x45, 0xB8, 0x01, 0x80, 0x50, 0x58, 0x23,
|
||||
0x21, 0xB8, 0x01, 0x80, 0x23, 0x21, 0x1B, 0xB0, 0x03, 0x25, 0x45, 0x23, 0x21, 0x23, 0x21, 0x59,
|
||||
0x1B, 0x21, 0x59, 0x44, 0x2D, 0xB8, 0x00, 0x09, 0x2C, 0x4B, 0x53, 0x58, 0x45, 0x44, 0x1B, 0x21,
|
||||
0x21, 0x59, 0x2D, 0x00, 0xB8, 0x00, 0x00, 0x2B, 0x00, 0xBA, 0x00, 0x01, 0x00, 0x01, 0x00, 0x07,
|
||||
0x2B, 0xB8, 0x00, 0x00, 0x20, 0x45, 0x7D, 0x69, 0x18, 0x44, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x70,
|
||||
0x00, 0xDC, 0x01, 0x34, 0x01, 0x7C, 0x01, 0xA2, 0x01, 0xF4, 0x02, 0x3C, 0x02, 0xA8, 0x03, 0x4C,
|
||||
0x03, 0xE2, 0x04, 0x20, 0x04, 0x58, 0x04, 0x9A, 0x04, 0xEE, 0x05, 0x32, 0x05, 0x64, 0x05, 0x80,
|
||||
0x05, 0xC6, 0x05, 0xF6, 0x06, 0x54, 0x06, 0xB2, 0x07, 0x38, 0x07, 0x60, 0x07, 0x82, 0x00, 0x00,
|
||||
0x00, 0x02, 0x00, 0xA4, 0xFF, 0xFF, 0x03, 0x5C, 0x03, 0x09, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00,
|
||||
0x13, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x21, 0xCD, 0x02, 0x66, 0xFD, 0x71, 0x02, 0xB8, 0xFD,
|
||||
0x48, 0x02, 0xE0, 0xFD, 0x48, 0x02, 0xB8, 0x29, 0xFC, 0xF6, 0x00, 0x00, 0x00, 0x04, 0x00, 0x14,
|
||||
0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x0F, 0x00, 0x1F, 0x00, 0x2F, 0x00, 0x39, 0x00, 0x00,
|
||||
0x00, 0x22, 0x0E, 0x02, 0x14, 0x1E, 0x02, 0x32, 0x3E, 0x02, 0x34, 0x2E, 0x01, 0x24, 0x32, 0x1E,
|
||||
0x02, 0x14, 0x0E, 0x02, 0x22, 0x2E, 0x02, 0x34, 0x3E, 0x01, 0x13, 0x12, 0x37, 0x33, 0x13, 0x12,
|
||||
0x15, 0x16, 0x23, 0x2F, 0x01, 0x23, 0x07, 0x23, 0x22, 0x26, 0x25, 0x30, 0x27, 0x26, 0x2F, 0x01,
|
||||
0x06, 0x07, 0x06, 0x32, 0x02, 0x5A, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77,
|
||||
0x46, 0x46, 0x77, 0xFE, 0x9E, 0xC8, 0xB7, 0x83, 0x4E, 0x4E, 0x83, 0xB7, 0xC8, 0xB7, 0x83, 0x4E,
|
||||
0x4E, 0x83, 0x23, 0x6C, 0x5E, 0x6D, 0x68, 0x68, 0x01, 0x39, 0x38, 0x2E, 0xD1, 0x2B, 0x37, 0x33,
|
||||
0x04, 0x01, 0x48, 0x1D, 0x1C, 0x0A, 0x05, 0x01, 0x45, 0x01, 0x89, 0x03, 0x3F, 0x46, 0x77, 0xA4,
|
||||
0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x77, 0x4E, 0x83, 0xB7, 0xC8, 0xB7,
|
||||
0x83, 0x4E, 0x4E, 0x83, 0xB7, 0xC8, 0xB7, 0x83, 0xFD, 0x64, 0x01, 0x1A, 0xEB, 0xFE, 0xFE, 0xFE,
|
||||
0xFD, 0x03, 0x01, 0x01, 0x77, 0x78, 0x01, 0xCF, 0x4C, 0x4C, 0x1C, 0x0C, 0x02, 0xBE, 0x02, 0x00,
|
||||
0x00, 0x05, 0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x0F, 0x00, 0x1B, 0x00, 0x2F,
|
||||
0x00, 0x3A, 0x00, 0x44, 0x00, 0x00, 0x12, 0x14, 0x1E, 0x02, 0x32, 0x3E, 0x02, 0x34, 0x2E, 0x02,
|
||||
0x22, 0x0E, 0x01, 0x02, 0x10, 0x3E, 0x01, 0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x26, 0x01,
|
||||
0x16, 0x17, 0x14, 0x06, 0x07, 0x06, 0x2B, 0x01, 0x19, 0x01, 0x17, 0x32, 0x17, 0x16, 0x17, 0x16,
|
||||
0x07, 0x06, 0x0F, 0x01, 0x36, 0x37, 0x34, 0x2E, 0x01, 0x27, 0x23, 0x15, 0x33, 0x32, 0x27, 0x32,
|
||||
0x37, 0x36, 0x26, 0x27, 0x26, 0x2B, 0x01, 0x15, 0x45, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x46,
|
||||
0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x77, 0x84, 0xE2, 0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2, 0xFE,
|
||||
0xF4, 0xE2, 0x01, 0xF7, 0x61, 0x01, 0x4E, 0x3E, 0x29, 0xAF, 0x4E, 0x81, 0x8B, 0x1D, 0x3C, 0x1F,
|
||||
0x19, 0x04, 0x06, 0x39, 0x57, 0x44, 0x01, 0x1B, 0x2D, 0x51, 0x46, 0x46, 0x47, 0x66, 0x70, 0x16,
|
||||
0x1F, 0x01, 0x2C, 0x08, 0x4B, 0x4C, 0x01, 0xDE, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xA4, 0xB4,
|
||||
0xA4, 0x77, 0x46, 0x46, 0x77, 0xFE, 0x7C, 0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2, 0xFE, 0xF4, 0xE2,
|
||||
0x84, 0x84, 0x01, 0x6D, 0x21, 0x5B, 0x40, 0x50, 0x05, 0x03, 0x01, 0x03, 0x01, 0x05, 0x01, 0x05,
|
||||
0x09, 0x30, 0x25, 0x29, 0x40, 0x21, 0xC2, 0x06, 0x3E, 0x1A, 0x21, 0x0B, 0x01, 0x8C, 0xE1, 0x0A,
|
||||
0x0E, 0x54, 0x0B, 0x02, 0x79, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC,
|
||||
0x03, 0x70, 0x00, 0x0F, 0x00, 0x1B, 0x00, 0x38, 0x00, 0x00, 0x12, 0x14, 0x1E, 0x02, 0x32, 0x3E,
|
||||
0x02, 0x34, 0x2E, 0x02, 0x22, 0x0E, 0x01, 0x02, 0x10, 0x3E, 0x01, 0x20, 0x1E, 0x01, 0x10, 0x0E,
|
||||
0x01, 0x20, 0x26, 0x36, 0x34, 0x3F, 0x01, 0x27, 0x26, 0x27, 0x33, 0x17, 0x16, 0x33, 0x36, 0x3F,
|
||||
0x02, 0x32, 0x14, 0x06, 0x16, 0x12, 0x14, 0x2B, 0x01, 0x27, 0x26, 0x06, 0x0F, 0x01, 0x23, 0x45,
|
||||
0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x77, 0x84, 0xE2,
|
||||
0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x7B, 0x58, 0x58, 0x4D, 0x4F, 0x05, 0x7A,
|
||||
0x34, 0x34, 0x02, 0x01, 0x33, 0x32, 0x3C, 0x3C, 0xA1, 0x01, 0xB0, 0x3E, 0x3F, 0x39, 0x3B, 0x02,
|
||||
0x3A, 0x38, 0x3F, 0x01, 0xDE, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x46,
|
||||
0x46, 0x77, 0xFE, 0x7C, 0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0x60,
|
||||
0x02, 0x87, 0x88, 0x79, 0x7A, 0x06, 0x54, 0x54, 0x01, 0x53, 0x53, 0x01, 0x01, 0xFB, 0x04, 0xFE,
|
||||
0xF8, 0x02, 0x5B, 0x5A, 0x03, 0x59, 0x59, 0x00, 0x00, 0x03, 0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC,
|
||||
0x03, 0x70, 0x00, 0x0F, 0x00, 0x1B, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x22, 0x0E, 0x02, 0x14, 0x1E,
|
||||
0x02, 0x32, 0x3E, 0x02, 0x34, 0x2E, 0x01, 0x24, 0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x2E,
|
||||
0x01, 0x10, 0x36, 0x01, 0x35, 0x27, 0x26, 0x34, 0x3B, 0x01, 0x17, 0x16, 0x36, 0x3F, 0x01, 0x33,
|
||||
0x03, 0x15, 0x23, 0x02, 0x5A, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x46,
|
||||
0x46, 0x77, 0xFE, 0x7C, 0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0x01,
|
||||
0x36, 0x5E, 0x5F, 0x3C, 0x3D, 0x3D, 0x3D, 0x03, 0x3B, 0x3B, 0x77, 0xBE, 0x68, 0x03, 0x3F, 0x46,
|
||||
0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x77, 0x84, 0xE2, 0xFE,
|
||||
0xF4, 0xE2, 0x84, 0x84, 0xE2, 0x01, 0x0C, 0xE2, 0xFD, 0xF9, 0x6E, 0x96, 0x95, 0x01, 0x67, 0x67,
|
||||
0x03, 0x66, 0x65, 0xFE, 0xD3, 0xDA, 0x00, 0x00, 0x00, 0x03, 0x00, 0x14, 0xFF, 0xBD, 0x03, 0xEC,
|
||||
0x03, 0x4B, 0x00, 0x06, 0x00, 0x0C, 0x00, 0x12, 0x00, 0x00, 0x01, 0x21, 0x22, 0x15, 0x30, 0x11,
|
||||
0x21, 0x17, 0x21, 0x11, 0x10, 0x25, 0x21, 0x01, 0x11, 0x33, 0x11, 0x21, 0x15, 0x03, 0xBB, 0xFD,
|
||||
0x77, 0xED, 0x03, 0x76, 0x31, 0xFC, 0x28, 0x01, 0x1E, 0x02, 0xBA, 0xFD, 0x5C, 0x68, 0x01, 0x08,
|
||||
0x03, 0x1A, 0xEE, 0xFD, 0xC2, 0x31, 0x02, 0x6F, 0x01, 0x1E, 0x01, 0xFD, 0x36, 0x02, 0x07, 0xFE,
|
||||
0x50, 0x57, 0x00, 0x00, 0x00, 0x04, 0x00, 0x14, 0xFF, 0xBD, 0x03, 0xEC, 0x03, 0x4B, 0x00, 0x06,
|
||||
0x00, 0x0C, 0x00, 0x27, 0x00, 0x32, 0x00, 0x00, 0x05, 0x11, 0x34, 0x27, 0x30, 0x21, 0x11, 0x07,
|
||||
0x11, 0x21, 0x20, 0x19, 0x01, 0x25, 0x11, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x07,
|
||||
0x06, 0x07, 0x06, 0x07, 0x1E, 0x02, 0x15, 0x07, 0x23, 0x27, 0x2E, 0x01, 0x2F, 0x01, 0x15, 0x13,
|
||||
0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x23, 0x15, 0x33, 0x36, 0x03, 0xBB, 0xED, 0xFD, 0x77, 0x31,
|
||||
0x02, 0xBA, 0x01, 0x1E, 0xFD, 0x2A, 0x77, 0x76, 0x15, 0x49, 0x20, 0x35, 0x08, 0x04, 0x06, 0x13,
|
||||
0x66, 0x0C, 0x01, 0x1F, 0x2E, 0x65, 0x3D, 0x3D, 0x2A, 0x56, 0x28, 0x2E, 0x19, 0x99, 0x3C, 0x20,
|
||||
0x10, 0x56, 0x4F, 0x46, 0x47, 0x12, 0x02, 0x3E, 0xED, 0x01, 0xFC, 0xD4, 0x31, 0x03, 0x8E, 0xFE,
|
||||
0xE1, 0xFD, 0x91, 0xC4, 0x02, 0x07, 0x01, 0x04, 0x13, 0x21, 0x44, 0x1D, 0x19, 0x58, 0x15, 0x02,
|
||||
0x01, 0x13, 0x2D, 0xA2, 0x01, 0x01, 0x3D, 0x81, 0x1A, 0x01, 0x01, 0xDA, 0x01, 0x2D, 0x08, 0x3A,
|
||||
0x29, 0x0F, 0x08, 0x01, 0x85, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x14, 0xFF, 0xF5, 0x03, 0xEC,
|
||||
0x03, 0x13, 0x00, 0x09, 0x00, 0x11, 0x00, 0x26, 0x00, 0x32, 0x00, 0x00, 0x37, 0x21, 0x34, 0x10,
|
||||
0x35, 0x34, 0x27, 0x21, 0x04, 0x11, 0x23, 0x10, 0x25, 0x21, 0x16, 0x15, 0x11, 0x21, 0x37, 0x35,
|
||||
0x37, 0x36, 0x22, 0x2B, 0x01, 0x3D, 0x01, 0x3B, 0x01, 0x1D, 0x01, 0x0F, 0x01, 0x3B, 0x01, 0x1D,
|
||||
0x01, 0x2B, 0x01, 0x25, 0x35, 0x3B, 0x01, 0x1D, 0x01, 0x3B, 0x01, 0x1D, 0x01, 0x2B, 0x01, 0x45,
|
||||
0x03, 0x76, 0x45, 0xFE, 0x2D, 0xFE, 0xA2, 0x31, 0x01, 0x8F, 0x01, 0xD3, 0x76, 0xFC, 0x28, 0xA7,
|
||||
0x68, 0x68, 0x01, 0x5B, 0x5D, 0x90, 0x91, 0x6C, 0x6D, 0x71, 0x70, 0xA0, 0xA0, 0x01, 0x75, 0x27,
|
||||
0x28, 0x63, 0x63, 0x8B, 0x8A, 0x27, 0x69, 0x01, 0xA4, 0x69, 0x44, 0x01, 0x02, 0xFE, 0xA4, 0x01,
|
||||
0x8C, 0x03, 0x01, 0x75, 0xFD, 0x58, 0xBB, 0x24, 0x80, 0x80, 0x21, 0x21, 0x1F, 0x1E, 0x85, 0x86,
|
||||
0x20, 0x22, 0xC3, 0xC3, 0xA1, 0xA3, 0x20, 0x22, 0x00, 0x05, 0x00, 0x14, 0xFF, 0xF5, 0x03, 0xEC,
|
||||
0x03, 0x13, 0x00, 0x08, 0x00, 0x10, 0x00, 0x2B, 0x00, 0x37, 0x00, 0x44, 0x00, 0x00, 0x37, 0x21,
|
||||
0x11, 0x10, 0x25, 0x30, 0x21, 0x06, 0x15, 0x03, 0x11, 0x34, 0x37, 0x21, 0x04, 0x19, 0x01, 0x01,
|
||||
0x35, 0x17, 0x32, 0x17, 0x16, 0x17, 0x16, 0x07, 0x06, 0x07, 0x06, 0x17, 0x16, 0x17, 0x16, 0x17,
|
||||
0x16, 0x23, 0x2F, 0x01, 0x2E, 0x01, 0x2F, 0x01, 0x15, 0x23, 0x37, 0x32, 0x36, 0x37, 0x36, 0x35,
|
||||
0x26, 0x27, 0x26, 0x2B, 0x01, 0x15, 0x05, 0x35, 0x37, 0x36, 0x26, 0x2B, 0x01, 0x35, 0x21, 0x15,
|
||||
0x03, 0x17, 0x15, 0x45, 0x03, 0x76, 0xFE, 0xA2, 0xFE, 0x2D, 0x45, 0x31, 0x76, 0x01, 0xD3, 0x01,
|
||||
0x8F, 0xFE, 0x1E, 0x65, 0x6F, 0x15, 0x46, 0x10, 0x05, 0x04, 0x0D, 0x4F, 0x09, 0x09, 0x1F, 0x1D,
|
||||
0x3A, 0x06, 0x01, 0x30, 0x2F, 0x22, 0x37, 0x1E, 0x29, 0x14, 0x4E, 0x82, 0x34, 0x19, 0x0E, 0x13,
|
||||
0x0A, 0x22, 0x07, 0x38, 0x37, 0xFE, 0x3E, 0x68, 0x68, 0x01, 0x5C, 0x5C, 0x01, 0x20, 0xD8, 0xE1,
|
||||
0x27, 0x01, 0x5D, 0x01, 0x5B, 0x03, 0x01, 0x44, 0xFD, 0x58, 0x02, 0xA8, 0x75, 0x01, 0x03, 0xFE,
|
||||
0x74, 0xFE, 0x71, 0x01, 0x5C, 0xC5, 0x01, 0x04, 0x0C, 0x43, 0x15, 0x1D, 0x44, 0x10, 0x04, 0x06,
|
||||
0x14, 0x2B, 0x56, 0x10, 0x01, 0x01, 0x34, 0x52, 0x1C, 0x01, 0x01, 0xA5, 0xE3, 0x04, 0x06, 0x0A,
|
||||
0x20, 0x2C, 0x04, 0x01, 0x65, 0xE3, 0x47, 0x80, 0x80, 0x01, 0x42, 0x3D, 0xFE, 0xF5, 0x01, 0x41,
|
||||
0x00, 0x04, 0x00, 0x14, 0x00, 0x52, 0x03, 0xEC, 0x02, 0xB6, 0x00, 0x08, 0x00, 0x16, 0x00, 0x64,
|
||||
0x00, 0x70, 0x00, 0x00, 0x25, 0x11, 0x21, 0x22, 0x15, 0x30, 0x15, 0x14, 0x33, 0x11, 0x21, 0x32,
|
||||
0x15, 0x11, 0x14, 0x27, 0x21, 0x22, 0x26, 0x3D, 0x01, 0x34, 0x36, 0x13, 0x26, 0x27, 0x26, 0x27,
|
||||
0x26, 0x37, 0x33, 0x36, 0x37, 0x36, 0x33, 0x16, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, 0x37, 0x36,
|
||||
0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x37,
|
||||
0x36, 0x37, 0x36, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x0F, 0x01, 0x22, 0x06, 0x23,
|
||||
0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16,
|
||||
0x17, 0x16, 0x17, 0x16, 0x07, 0x06, 0x07, 0x06, 0x27, 0x37, 0x35, 0x3B, 0x01, 0x1D, 0x01, 0x3B,
|
||||
0x01, 0x1D, 0x01, 0x2B, 0x01, 0x03, 0xBB, 0xFD, 0x2A, 0xA0, 0xA0, 0x02, 0xEE, 0x19, 0x19, 0xFD,
|
||||
0x12, 0x57, 0x7A, 0x7A, 0xCA, 0x38, 0x1D, 0x16, 0x08, 0x03, 0x01, 0x02, 0x0F, 0x0C, 0x1E, 0x01,
|
||||
0x02, 0x04, 0x0C, 0x2B, 0x0F, 0x0E, 0x18, 0x0C, 0x09, 0x04, 0x15, 0x32, 0x23, 0x12, 0x1C, 0x0E,
|
||||
0x09, 0x03, 0x01, 0x01, 0x09, 0x21, 0x0F, 0x14, 0x2E, 0x2A, 0x13, 0x0F, 0x0C, 0x08, 0x0B, 0x05,
|
||||
0x02, 0x01, 0x02, 0x03, 0x36, 0x03, 0x02, 0x03, 0x08, 0x0D, 0x23, 0x16, 0x0E, 0x10, 0x01, 0x01,
|
||||
0x07, 0x0B, 0x32, 0x25, 0x13, 0x26, 0x0F, 0x09, 0x01, 0x01, 0x0F, 0x11, 0x24, 0x21, 0x2A, 0xE3,
|
||||
0x20, 0x20, 0x52, 0x50, 0x71, 0x71, 0x84, 0x02, 0x00, 0xAF, 0xA2, 0xAF, 0x02, 0x32, 0x19, 0xFD,
|
||||
0xCE, 0x19, 0x01, 0x84, 0x5C, 0xA2, 0x5C, 0x85, 0xFE, 0x29, 0x04, 0x1E, 0x18, 0x26, 0x0F, 0x01,
|
||||
0x02, 0x01, 0x03, 0x05, 0x0B, 0x29, 0x06, 0x02, 0x03, 0x04, 0x11, 0x0B, 0x0D, 0x0A, 0x06, 0x12,
|
||||
0x0D, 0x0A, 0x07, 0x0C, 0x18, 0x0D, 0x10, 0x06, 0x18, 0x05, 0x27, 0x14, 0x09, 0x03, 0x0A, 0x0D,
|
||||
0x06, 0x09, 0x09, 0x0D, 0x0F, 0x14, 0x0C, 0x06, 0x03, 0x02, 0x04, 0x10, 0x0A, 0x11, 0x08, 0x09,
|
||||
0x0E, 0x0C, 0x07, 0x0C, 0x0C, 0x0A, 0x07, 0x0F, 0x20, 0x11, 0x18, 0x1E, 0x1A, 0x1E, 0x0C, 0x0B,
|
||||
0x03, 0xAA, 0xA5, 0x89, 0x8A, 0x1C, 0x1B, 0x00, 0x00, 0x05, 0x00, 0x14, 0x00, 0x53, 0x03, 0xEC,
|
||||
0x02, 0xB6, 0x00, 0x08, 0x00, 0x16, 0x00, 0x2E, 0x00, 0x38, 0x00, 0x65, 0x00, 0x00, 0x01, 0x30,
|
||||
0x21, 0x11, 0x21, 0x32, 0x3D, 0x01, 0x34, 0x27, 0x32, 0x16, 0x1D, 0x01, 0x14, 0x06, 0x23, 0x21,
|
||||
0x26, 0x35, 0x11, 0x34, 0x33, 0x01, 0x11, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x07, 0x06, 0x07,
|
||||
0x17, 0x1E, 0x01, 0x1F, 0x01, 0x23, 0x2A, 0x01, 0x2E, 0x01, 0x23, 0x27, 0x15, 0x37, 0x32, 0x37,
|
||||
0x36, 0x27, 0x2E, 0x01, 0x2B, 0x01, 0x15, 0x05, 0x26, 0x27, 0x37, 0x32, 0x3F, 0x01, 0x16, 0x17,
|
||||
0x1E, 0x01, 0x37, 0x36, 0x27, 0x2E, 0x04, 0x37, 0x3E, 0x01, 0x33, 0x32, 0x17, 0x16, 0x17, 0x14,
|
||||
0x06, 0x27, 0x26, 0x27, 0x26, 0x0E, 0x01, 0x1E, 0x02, 0x17, 0x16, 0x06, 0x07, 0x06, 0x07, 0x06,
|
||||
0x03, 0x1B, 0xFD, 0x2A, 0x02, 0xD6, 0xA0, 0xA0, 0x57, 0x7A, 0x7A, 0x57, 0xFD, 0x12, 0x19, 0x19,
|
||||
0x01, 0xD3, 0x47, 0x44, 0x11, 0x3E, 0x18, 0x21, 0x0B, 0x0C, 0x43, 0x04, 0x17, 0x1C, 0x1E, 0x16,
|
||||
0x26, 0x26, 0x03, 0x4D, 0x18, 0x1E, 0x11, 0x25, 0x3A, 0x0C, 0x22, 0x08, 0x03, 0x1B, 0x3E, 0x29,
|
||||
0xFE, 0xAC, 0x0D, 0x04, 0x02, 0x02, 0x1E, 0x1D, 0x03, 0x02, 0x0C, 0x4C, 0x13, 0x20, 0x07, 0x04,
|
||||
0x1B, 0x56, 0x2D, 0x1C, 0x01, 0x02, 0x44, 0x35, 0x49, 0x1F, 0x10, 0x03, 0x41, 0x01, 0x06, 0x0A,
|
||||
0x16, 0x3C, 0x18, 0x0C, 0x16, 0x5D, 0x15, 0x33, 0x03, 0x2B, 0x1E, 0x34, 0x59, 0x02, 0x84, 0xFE,
|
||||
0x00, 0xAF, 0xA2, 0xAF, 0x32, 0x85, 0x5C, 0xA2, 0x5C, 0x84, 0x01, 0x17, 0x02, 0x32, 0x19, 0xFE,
|
||||
0x2F, 0x01, 0x45, 0x01, 0x02, 0x19, 0x22, 0x32, 0x39, 0x0B, 0x08, 0x0F, 0x27, 0x2F, 0x24, 0x75,
|
||||
0x12, 0x01, 0x88, 0xBB, 0x04, 0x09, 0x2A, 0x0F, 0x0D, 0x53, 0x8A, 0x17, 0x1E, 0x04, 0x03, 0x03,
|
||||
0x0C, 0x04, 0x26, 0x0E, 0x0C, 0x14, 0x1A, 0x0E, 0x0E, 0x16, 0x16, 0x2C, 0x1A, 0x2D, 0x2D, 0x2A,
|
||||
0x16, 0x1D, 0x06, 0x04, 0x01, 0x1A, 0x09, 0x11, 0x09, 0x17, 0x18, 0x0D, 0x17, 0x0C, 0x1B, 0x71,
|
||||
0x1B, 0x12, 0x01, 0x03, 0x00, 0x03, 0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x0F,
|
||||
0x00, 0x1B, 0x00, 0x27, 0x00, 0x00, 0x00, 0x22, 0x0E, 0x02, 0x14, 0x1E, 0x02, 0x32, 0x3E, 0x02,
|
||||
0x34, 0x2E, 0x01, 0x24, 0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x2E, 0x01, 0x10, 0x36, 0x13,
|
||||
0x33, 0x35, 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x02, 0x5A, 0xB4, 0xA4, 0x77,
|
||||
0x46, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xFE, 0x7C, 0x01, 0x0C, 0xE2, 0x84,
|
||||
0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0x7C, 0xC5, 0x4E, 0xC5, 0xC4, 0x50, 0xC4, 0x03, 0x3F,
|
||||
0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x77, 0x84, 0xE2,
|
||||
0xFE, 0xF4, 0xE2, 0x84, 0x84, 0xE2, 0x01, 0x0C, 0xE2, 0xFE, 0xC0, 0xC4, 0xC5, 0x4E, 0xC5, 0xC5,
|
||||
0x00, 0x03, 0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x0F, 0x00, 0x1B, 0x00, 0x1F,
|
||||
0x00, 0x00, 0x00, 0x22, 0x0E, 0x02, 0x14, 0x1E, 0x02, 0x32, 0x3E, 0x02, 0x34, 0x2E, 0x01, 0x24,
|
||||
0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x2E, 0x01, 0x10, 0x36, 0x13, 0x35, 0x21, 0x15, 0x02,
|
||||
0x5A, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xFE, 0x7C,
|
||||
0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0x7C, 0x01, 0xD8, 0x03, 0x3F,
|
||||
0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x46, 0x46, 0x77, 0xA4, 0xB4, 0xA4, 0x77, 0x77, 0x84, 0xE2,
|
||||
0xFE, 0xF4, 0xE2, 0x84, 0x84, 0xE2, 0x01, 0x0C, 0xE2, 0xFE, 0x71, 0x4E, 0x4E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x03, 0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x0B, 0x00, 0x1B, 0x00, 0x25,
|
||||
0x00, 0x00, 0x00, 0x20, 0x0E, 0x01, 0x10, 0x1E, 0x01, 0x20, 0x3E, 0x01, 0x10, 0x26, 0x01, 0x12,
|
||||
0x37, 0x33, 0x13, 0x12, 0x15, 0x16, 0x23, 0x2F, 0x01, 0x23, 0x07, 0x23, 0x22, 0x26, 0x25, 0x30,
|
||||
0x27, 0x26, 0x2F, 0x01, 0x06, 0x07, 0x06, 0x32, 0x02, 0x86, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0xE2,
|
||||
0x01, 0x0C, 0xE2, 0x84, 0x84, 0xFD, 0xA0, 0x6C, 0x5E, 0x6D, 0x68, 0x68, 0x01, 0x39, 0x38, 0x2E,
|
||||
0xD1, 0x2B, 0x37, 0x33, 0x04, 0x01, 0x48, 0x1D, 0x1C, 0x0A, 0x05, 0x01, 0x45, 0x01, 0x89, 0x03,
|
||||
0x70, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0xE2, 0x01, 0x0C, 0xE2, 0xFD, 0x9A, 0x01, 0x1A,
|
||||
0xEB, 0xFE, 0xFE, 0xFE, 0xFD, 0x03, 0x01, 0x01, 0x77, 0x78, 0x01, 0xCF, 0x4C, 0x4C, 0x1C, 0x0C,
|
||||
0x02, 0xBE, 0x02, 0x00, 0x00, 0x04, 0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x0B,
|
||||
0x00, 0x20, 0x00, 0x2B, 0x00, 0x35, 0x00, 0x00, 0x36, 0x10, 0x3E, 0x01, 0x20, 0x1E, 0x01, 0x10,
|
||||
0x0E, 0x01, 0x20, 0x26, 0x01, 0x30, 0x37, 0x36, 0x37, 0x36, 0x27, 0x26, 0x27, 0x26, 0x23, 0x27,
|
||||
0x19, 0x01, 0x33, 0x32, 0x37, 0x3E, 0x01, 0x35, 0x26, 0x07, 0x06, 0x2B, 0x01, 0x35, 0x33, 0x1E,
|
||||
0x02, 0x15, 0x06, 0x27, 0x23, 0x35, 0x33, 0x16, 0x17, 0x16, 0x14, 0x07, 0x06, 0x14, 0x84, 0xE2,
|
||||
0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x01, 0xF7, 0x0A, 0x3A, 0x05, 0x04, 0x19,
|
||||
0x20, 0x3B, 0x1D, 0x8B, 0x81, 0x4E, 0xAF, 0x29, 0x3E, 0x4E, 0x01, 0xAE, 0x0D, 0x47, 0x46, 0x46,
|
||||
0x52, 0x2C, 0x1B, 0x01, 0xB7, 0x27, 0x4C, 0x4C, 0x07, 0x2C, 0x1E, 0x16, 0xFE, 0x01, 0x0C, 0xE2,
|
||||
0x84, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0x01, 0x6D, 0x06, 0x21, 0x40, 0x2A, 0x24, 0x30,
|
||||
0x09, 0x05, 0x01, 0xFE, 0xFB, 0xFE, 0xFD, 0x03, 0x05, 0x4F, 0x41, 0x5B, 0x9B, 0x01, 0x8C, 0x01,
|
||||
0x0B, 0x21, 0x1A, 0x3E, 0xDA, 0x79, 0x01, 0x01, 0x0B, 0x54, 0x0E, 0x0A, 0x00, 0x02, 0x00, 0x14,
|
||||
0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x0B, 0x00, 0x29, 0x00, 0x00, 0x36, 0x10, 0x3E, 0x01,
|
||||
0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x26, 0x36, 0x14, 0x3B, 0x01, 0x37, 0x36, 0x37, 0x36,
|
||||
0x1F, 0x01, 0x33, 0x32, 0x34, 0x02, 0x26, 0x36, 0x34, 0x23, 0x0F, 0x01, 0x06, 0x07, 0x22, 0x2F,
|
||||
0x01, 0x23, 0x16, 0x1F, 0x01, 0x07, 0x14, 0x84, 0xE2, 0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2, 0xFE,
|
||||
0xF4, 0xE2, 0x7B, 0x3D, 0x3F, 0x38, 0x3A, 0x01, 0x02, 0x3A, 0x39, 0x3F, 0x3E, 0xB0, 0x01, 0xA1,
|
||||
0x3C, 0x3C, 0x32, 0x33, 0x01, 0x02, 0x34, 0x34, 0x7A, 0x05, 0x4F, 0x4D, 0x58, 0xFE, 0x01, 0x0C,
|
||||
0xE2, 0x84, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0x62, 0x02, 0x59, 0x59, 0x02, 0x01, 0x5A,
|
||||
0x5B, 0x02, 0x01, 0x08, 0x04, 0xFB, 0x01, 0x01, 0x53, 0x53, 0x01, 0x54, 0x54, 0x06, 0x7A, 0x79,
|
||||
0x88, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x0B,
|
||||
0x00, 0x1B, 0x00, 0x00, 0x00, 0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x2E, 0x01, 0x10, 0x36,
|
||||
0x01, 0x15, 0x33, 0x35, 0x13, 0x23, 0x07, 0x0E, 0x01, 0x2F, 0x01, 0x23, 0x22, 0x16, 0x1F, 0x01,
|
||||
0x01, 0x7A, 0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0x01, 0x36, 0x68,
|
||||
0xBE, 0x77, 0x3B, 0x3C, 0x02, 0x3D, 0x3D, 0x3D, 0x3D, 0x01, 0x5F, 0x5E, 0x03, 0x70, 0x84, 0xE2,
|
||||
0xFE, 0xF4, 0xE2, 0x84, 0x84, 0xE2, 0x01, 0x0C, 0xE2, 0xFD, 0xF9, 0x6D, 0xDA, 0x01, 0x2D, 0x65,
|
||||
0x66, 0x03, 0x67, 0x67, 0x01, 0x95, 0x96, 0x00, 0x00, 0x02, 0x00, 0x14, 0xFF, 0xBF, 0x03, 0xEC,
|
||||
0x03, 0x4A, 0x00, 0x05, 0x00, 0x0B, 0x00, 0x00, 0x05, 0x21, 0x11, 0x10, 0x05, 0x21, 0x01, 0x21,
|
||||
0x35, 0x21, 0x11, 0x23, 0x03, 0xEC, 0xFC, 0x28, 0x01, 0x14, 0x02, 0xC4, 0xFD, 0x5C, 0x01, 0x70,
|
||||
0xFE, 0xF8, 0x68, 0x41, 0x02, 0x77, 0x01, 0x14, 0x01, 0xFD, 0x38, 0x57, 0x01, 0xB0, 0x00, 0x00,
|
||||
0x00, 0x03, 0x00, 0x14, 0xFF, 0xBF, 0x03, 0xEC, 0x03, 0x49, 0x00, 0x05, 0x00, 0x20, 0x00, 0x2B,
|
||||
0x00, 0x00, 0x17, 0x11, 0x21, 0x20, 0x19, 0x01, 0x25, 0x33, 0x35, 0x17, 0x1E, 0x01, 0x1F, 0x01,
|
||||
0x33, 0x37, 0x2E, 0x02, 0x27, 0x34, 0x37, 0x36, 0x37, 0x36, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26,
|
||||
0x2B, 0x01, 0x05, 0x06, 0x2B, 0x01, 0x35, 0x33, 0x16, 0x17, 0x16, 0x15, 0x14, 0x14, 0x02, 0xC4,
|
||||
0x01, 0x14, 0xFD, 0x2A, 0x69, 0x19, 0x2E, 0x28, 0x56, 0x2A, 0x3D, 0x3D, 0x01, 0x65, 0x2C, 0x20,
|
||||
0x0D, 0x66, 0x13, 0x06, 0x04, 0x09, 0x34, 0x20, 0x49, 0x15, 0x76, 0x77, 0x01, 0x02, 0x0C, 0x47,
|
||||
0x46, 0x4F, 0x56, 0x10, 0x20, 0x41, 0x03, 0x8A, 0xFE, 0xED, 0xFD, 0x89, 0xC2, 0xDA, 0x01, 0x01,
|
||||
0x1A, 0x81, 0x3D, 0x01, 0x01, 0xA3, 0x2C, 0x13, 0x01, 0x02, 0x13, 0x5A, 0x1A, 0x1C, 0x44, 0x21,
|
||||
0x13, 0x04, 0x01, 0xDA, 0x02, 0x85, 0x01, 0x08, 0x0F, 0x29, 0x3A, 0x00, 0x00, 0x03, 0x00, 0x14,
|
||||
0xFF, 0xFB, 0x03, 0xEC, 0x03, 0x0E, 0x00, 0x08, 0x00, 0x15, 0x00, 0x1B, 0x00, 0x00, 0x05, 0x21,
|
||||
0x11, 0x10, 0x21, 0x30, 0x21, 0x32, 0x15, 0x01, 0x21, 0x35, 0x23, 0x13, 0x35, 0x21, 0x15, 0x33,
|
||||
0x32, 0x22, 0x0F, 0x01, 0x05, 0x21, 0x35, 0x23, 0x11, 0x23, 0x03, 0xEC, 0xFC, 0x28, 0x01, 0x8A,
|
||||
0x01, 0xEC, 0x62, 0xFC, 0xCF, 0x01, 0x40, 0xE1, 0xD9, 0xFE, 0xDF, 0x5D, 0x5C, 0x01, 0x67, 0x68,
|
||||
0x01, 0x75, 0x01, 0x15, 0xC6, 0x4F, 0x05, 0x01, 0x89, 0x01, 0x8A, 0x63, 0xFD, 0xE1, 0x42, 0x01,
|
||||
0x0B, 0x3D, 0x42, 0x80, 0x80, 0x48, 0x42, 0x01, 0x44, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x14,
|
||||
0xFF, 0xFB, 0x03, 0xEC, 0x03, 0x0E, 0x00, 0x07, 0x00, 0x22, 0x00, 0x2F, 0x00, 0x3C, 0x00, 0x00,
|
||||
0x17, 0x11, 0x34, 0x37, 0x21, 0x20, 0x19, 0x01, 0x01, 0x15, 0x33, 0x35, 0x17, 0x1E, 0x01, 0x1F,
|
||||
0x02, 0x32, 0x35, 0x26, 0x27, 0x26, 0x27, 0x26, 0x37, 0x36, 0x37, 0x36, 0x27, 0x26, 0x27, 0x26,
|
||||
0x23, 0x27, 0x17, 0x30, 0x23, 0x35, 0x33, 0x32, 0x17, 0x16, 0x17, 0x14, 0x07, 0x0E, 0x01, 0x05,
|
||||
0x21, 0x35, 0x27, 0x13, 0x35, 0x21, 0x15, 0x33, 0x32, 0x14, 0x0F, 0x01, 0x14, 0x62, 0x01, 0xEC,
|
||||
0x01, 0x8A, 0xFE, 0x1E, 0x4E, 0x14, 0x29, 0x1E, 0x37, 0x22, 0x2F, 0x2F, 0x06, 0x3A, 0x1D, 0x1F,
|
||||
0x09, 0x09, 0x4E, 0x0E, 0x04, 0x05, 0x0F, 0x47, 0x15, 0x6F, 0x65, 0x82, 0x34, 0x37, 0x38, 0x07,
|
||||
0x23, 0x09, 0x13, 0x0D, 0x1A, 0xFD, 0xD6, 0x01, 0x40, 0xE1, 0xD8, 0xFE, 0xE0, 0x5C, 0x5C, 0x67,
|
||||
0x68, 0x05, 0x02, 0xB0, 0x62, 0x01, 0xFE, 0x76, 0xFE, 0x77, 0x01, 0x56, 0xC5, 0xA5, 0x01, 0x01,
|
||||
0x1C, 0x52, 0x34, 0x01, 0x01, 0x0E, 0x58, 0x2C, 0x13, 0x06, 0x04, 0x0F, 0x45, 0x1E, 0x14, 0x42,
|
||||
0x0D, 0x04, 0x01, 0xA7, 0x65, 0x01, 0x04, 0x2C, 0x21, 0x09, 0x07, 0x03, 0xE3, 0x41, 0x01, 0x01,
|
||||
0x0B, 0x3D, 0x42, 0x01, 0x80, 0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x14, 0x00, 0x5D, 0x03, 0xEC,
|
||||
0x02, 0xAB, 0x00, 0x08, 0x00, 0x37, 0x00, 0x3D, 0x00, 0x00, 0x13, 0x30, 0x21, 0x11, 0x21, 0x22,
|
||||
0x3D, 0x01, 0x34, 0x05, 0x37, 0x34, 0x27, 0x26, 0x27, 0x26, 0x07, 0x06, 0x07, 0x0E, 0x01, 0x17,
|
||||
0x1E, 0x01, 0x17, 0x16, 0x14, 0x07, 0x06, 0x26, 0x27, 0x26, 0x27, 0x22, 0x06, 0x07, 0x22, 0x17,
|
||||
0x1E, 0x01, 0x17, 0x16, 0x37, 0x36, 0x27, 0x26, 0x27, 0x2E, 0x02, 0x37, 0x36, 0x33, 0x32, 0x1F,
|
||||
0x02, 0x33, 0x35, 0x23, 0x11, 0x23, 0xD6, 0x03, 0x16, 0xFC, 0xEA, 0xC2, 0x01, 0xC6, 0x02, 0x01,
|
||||
0x0C, 0x3A, 0x2B, 0x2D, 0x13, 0x10, 0x2B, 0x01, 0x33, 0x17, 0x55, 0x15, 0x04, 0x09, 0x14, 0x58,
|
||||
0x0C, 0x04, 0x02, 0x02, 0x26, 0x14, 0x01, 0x03, 0x08, 0x33, 0x38, 0x5F, 0x20, 0x10, 0x01, 0x03,
|
||||
0x3C, 0x12, 0x59, 0x11, 0x01, 0x02, 0x39, 0x2C, 0x09, 0x02, 0x9D, 0xE2, 0xA2, 0x40, 0x02, 0xAB,
|
||||
0xFD, 0xB2, 0xD2, 0xAA, 0xD2, 0xDC, 0x03, 0x07, 0x0B, 0x38, 0x10, 0x0C, 0x09, 0x04, 0x08, 0x19,
|
||||
0x6C, 0x17, 0x0B, 0x17, 0x11, 0x07, 0x17, 0x0A, 0x1A, 0x0A, 0x29, 0x0C, 0x04, 0x04, 0x02, 0x10,
|
||||
0x25, 0x37, 0x04, 0x06, 0x37, 0x1D, 0x1C, 0x3F, 0x19, 0x08, 0x16, 0x13, 0x0B, 0x1F, 0x2B, 0x04,
|
||||
0xE9, 0x37, 0x01, 0x13, 0x00, 0x04, 0x00, 0x14, 0x00, 0x5D, 0x03, 0xEC, 0x02, 0xAB, 0x00, 0x07,
|
||||
0x00, 0x1F, 0x00, 0x2A, 0x00, 0x58, 0x00, 0x00, 0x01, 0x32, 0x1D, 0x01, 0x14, 0x23, 0x21, 0x11,
|
||||
0x01, 0x33, 0x35, 0x17, 0x1E, 0x03, 0x3B, 0x01, 0x27, 0x2E, 0x01, 0x2F, 0x01, 0x36, 0x37, 0x36,
|
||||
0x27, 0x26, 0x27, 0x26, 0x2B, 0x01, 0x17, 0x30, 0x23, 0x35, 0x33, 0x32, 0x16, 0x17, 0x16, 0x07,
|
||||
0x06, 0x05, 0x16, 0x37, 0x36, 0x37, 0x3E, 0x01, 0x27, 0x2E, 0x03, 0x3E, 0x01, 0x17, 0x16, 0x17,
|
||||
0x30, 0x37, 0x36, 0x27, 0x26, 0x27, 0x26, 0x27, 0x22, 0x06, 0x07, 0x06, 0x1E, 0x03, 0x17, 0x16,
|
||||
0x07, 0x06, 0x26, 0x27, 0x26, 0x27, 0x07, 0x06, 0x23, 0x07, 0x16, 0x03, 0x2A, 0xC2, 0xC2, 0xFC,
|
||||
0xEA, 0x01, 0xEC, 0x41, 0x11, 0x1F, 0x17, 0x4D, 0x02, 0x27, 0x26, 0x16, 0x1E, 0x1C, 0x17, 0x04,
|
||||
0x43, 0x0C, 0x0B, 0x21, 0x18, 0x3E, 0x0F, 0x46, 0x47, 0x66, 0x25, 0x29, 0x3E, 0x1B, 0x03, 0x08,
|
||||
0x22, 0x0C, 0xFE, 0x4D, 0x22, 0x59, 0x34, 0x1E, 0x2B, 0x03, 0x33, 0x16, 0x5C, 0x16, 0x0C, 0x18,
|
||||
0x3C, 0x16, 0x0B, 0x05, 0x22, 0x21, 0x01, 0x03, 0x10, 0x1F, 0x49, 0x36, 0x43, 0x02, 0x01, 0x1C,
|
||||
0x2D, 0x56, 0x1B, 0x04, 0x07, 0x20, 0x13, 0x4B, 0x0D, 0x01, 0x04, 0x1D, 0x1E, 0x02, 0x02, 0x04,
|
||||
0x02, 0xAB, 0xD2, 0xAA, 0xD2, 0x02, 0x4E, 0xFE, 0x39, 0x89, 0x01, 0x01, 0x11, 0x75, 0x01, 0x25,
|
||||
0x2F, 0x27, 0x0F, 0x08, 0x0C, 0x38, 0x33, 0x21, 0x19, 0x02, 0x01, 0x8A, 0x53, 0x0D, 0x0F, 0x2A,
|
||||
0x09, 0x04, 0x8A, 0x3A, 0x03, 0x01, 0x12, 0x1B, 0x71, 0x1B, 0x0C, 0x17, 0x0D, 0x18, 0x17, 0x09,
|
||||
0x11, 0x09, 0x1A, 0x01, 0x01, 0x07, 0x1E, 0x15, 0x29, 0x01, 0x2D, 0x2D, 0x1A, 0x2C, 0x16, 0x16,
|
||||
0x0D, 0x0F, 0x1A, 0x14, 0x0C, 0x0D, 0x27, 0x04, 0x0C, 0x03, 0x03, 0x04, 0x1E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x00,
|
||||
0x00, 0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x2E, 0x01, 0x10, 0x36, 0x13, 0x15, 0x33, 0x15,
|
||||
0x33, 0x35, 0x33, 0x35, 0x23, 0x35, 0x23, 0x15, 0x01, 0x7A, 0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2,
|
||||
0xFE, 0xF4, 0xE2, 0x84, 0x84, 0x7C, 0xC4, 0x50, 0xC4, 0xC5, 0x4E, 0x03, 0x70, 0x84, 0xE2, 0xFE,
|
||||
0xF4, 0xE2, 0x84, 0x84, 0xE2, 0x01, 0x0C, 0xE2, 0xFE, 0xC0, 0x4F, 0xC5, 0xC5, 0x4E, 0xC5, 0xC4,
|
||||
0x00, 0x02, 0x00, 0x14, 0xFF, 0x98, 0x03, 0xEC, 0x03, 0x70, 0x00, 0x0B, 0x00, 0x0F, 0x00, 0x00,
|
||||
0x00, 0x20, 0x1E, 0x01, 0x10, 0x0E, 0x01, 0x20, 0x2E, 0x01, 0x10, 0x36, 0x13, 0x21, 0x35, 0x21,
|
||||
0x01, 0x7A, 0x01, 0x0C, 0xE2, 0x84, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0x7C, 0x01, 0xD8,
|
||||
0xFE, 0x28, 0x03, 0x70, 0x84, 0xE2, 0xFE, 0xF4, 0xE2, 0x84, 0x84, 0xE2, 0x01, 0x0C, 0xE2, 0xFE,
|
||||
0x71, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0xAE, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x15, 0x00, 0x2C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10,
|
||||
0x00, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x85, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0xAF, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x04, 0x00, 0x10, 0x00, 0xE2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0D,
|
||||
0x01, 0x0F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x01, 0x3F, 0x00, 0x03,
|
||||
0x00, 0x01, 0x04, 0x09, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
|
||||
0x00, 0x01, 0x00, 0x20, 0x00, 0x42, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0E,
|
||||
0x00, 0x75, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x20, 0x00, 0x8D, 0x00, 0x03,
|
||||
0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
|
||||
0x00, 0x05, 0x00, 0x1A, 0x00, 0xF3, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x20,
|
||||
0x01, 0x1D, 0x00, 0x59, 0x00, 0x75, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x20, 0x00, 0x45, 0x00, 0x6D,
|
||||
0x00, 0x75, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x20, 0x00, 0x50,
|
||||
0x00, 0x72, 0x00, 0x6F, 0x00, 0x6A, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x00, 0x59, 0x75,
|
||||
0x7A, 0x75, 0x20, 0x45, 0x6D, 0x75, 0x6C, 0x61, 0x74, 0x6F, 0x72, 0x20, 0x50, 0x72, 0x6F, 0x6A,
|
||||
0x65, 0x63, 0x74, 0x00, 0x00, 0x59, 0x00, 0x75, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x4F, 0x00, 0x53,
|
||||
0x00, 0x53, 0x00, 0x45, 0x00, 0x78, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x73, 0x00, 0x69,
|
||||
0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x59, 0x75, 0x7A, 0x75, 0x4F, 0x53, 0x53, 0x45, 0x78, 0x74,
|
||||
0x65, 0x6E, 0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, 0x00,
|
||||
0x6C, 0x00, 0x61, 0x00, 0x72, 0x00, 0x00, 0x52, 0x65, 0x67, 0x75, 0x6C, 0x61, 0x72, 0x00, 0x00,
|
||||
0x59, 0x00, 0x75, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x4F, 0x00, 0x53, 0x00, 0x53, 0x00, 0x45, 0x00,
|
||||
0x78, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00,
|
||||
0x00, 0x59, 0x75, 0x7A, 0x75, 0x4F, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x73, 0x69, 0x6F,
|
||||
0x6E, 0x00, 0x00, 0x59, 0x00, 0x75, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x4F, 0x00, 0x53, 0x00, 0x53,
|
||||
0x00, 0x45, 0x00, 0x78, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F,
|
||||
0x00, 0x6E, 0x00, 0x00, 0x59, 0x75, 0x7A, 0x75, 0x4F, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65, 0x6E,
|
||||
0x73, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00,
|
||||
0x6F, 0x00, 0x6E, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00,
|
||||
0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x31, 0x2E, 0x30, 0x30, 0x30, 0x00, 0x00,
|
||||
0x59, 0x00, 0x75, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x4F, 0x00, 0x53, 0x00, 0x53, 0x00, 0x45, 0x00,
|
||||
0x78, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00,
|
||||
0x00, 0x59, 0x75, 0x7A, 0x75, 0x4F, 0x53, 0x53, 0x45, 0x78, 0x74, 0x65, 0x6E, 0x73, 0x69, 0x6F,
|
||||
0x6E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xB5, 0x00, 0x32,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x01, 0x02, 0x01, 0x03, 0x00, 0x03, 0x01, 0x04,
|
||||
0x01, 0x05, 0x01, 0x06, 0x01, 0x07, 0x01, 0x08, 0x01, 0x09, 0x01, 0x0A, 0x01, 0x0B, 0x01, 0x0C,
|
||||
0x01, 0x0D, 0x01, 0x0E, 0x01, 0x0F, 0x01, 0x10, 0x01, 0x11, 0x01, 0x12, 0x01, 0x13, 0x01, 0x14,
|
||||
0x01, 0x15, 0x01, 0x16, 0x01, 0x17, 0x01, 0x18, 0x01, 0x19, 0x01, 0x1A, 0x01, 0x1B, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x30, 0x30, 0x30, 0x30, 0x07, 0x75, 0x6E, 0x69, 0x30, 0x30, 0x30, 0x44, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x41, 0x30, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x41, 0x31, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x41, 0x32, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x41, 0x33, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x41, 0x34, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x41, 0x35, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x41, 0x36, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x41, 0x37, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x41, 0x38, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x41, 0x39, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x42, 0x33, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x42, 0x34, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x45, 0x30, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x45, 0x31, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x45, 0x32, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x45, 0x33, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x45, 0x34, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x45, 0x35, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x45, 0x36, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x45, 0x37, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x45, 0x38, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x45, 0x39, 0x07, 0x75,
|
||||
0x6E, 0x69, 0x45, 0x30, 0x45, 0x46, 0x07, 0x75, 0x6E, 0x69, 0x45, 0x30, 0x46, 0x30, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x0F,
|
||||
}};
|
||||
|
||||
} // namespace FileSys::SystemArchive::SharedFontData
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
|
||||
namespace FileSys::SystemArchive::SharedFontData {
|
||||
|
||||
extern const std::array<unsigned char, 2932> FONT_NINTENDO_EXTENDED;
|
||||
extern const std::array<unsigned char, 6024> FONT_NINTENDO_EXTENDED;
|
||||
|
||||
} // namespace FileSys::SystemArchive::SharedFontData
|
||||
|
||||
@@ -12,17 +12,17 @@ namespace SystemVersionData {
|
||||
// This section should reflect the best system version to describe yuzu's HLE api.
|
||||
// TODO(DarkLordZach): Update when HLE gets better.
|
||||
|
||||
constexpr u8 VERSION_MAJOR = 10;
|
||||
constexpr u8 VERSION_MAJOR = 11;
|
||||
constexpr u8 VERSION_MINOR = 0;
|
||||
constexpr u8 VERSION_MICRO = 2;
|
||||
constexpr u8 VERSION_MICRO = 0;
|
||||
|
||||
constexpr u8 REVISION_MAJOR = 1;
|
||||
constexpr u8 REVISION_MAJOR = 5;
|
||||
constexpr u8 REVISION_MINOR = 0;
|
||||
|
||||
constexpr char PLATFORM_STRING[] = "NX";
|
||||
constexpr char VERSION_HASH[] = "f90143fa8bbc061d4f68c35f95f04f8080c0ecdc";
|
||||
constexpr char DISPLAY_VERSION[] = "10.0.2";
|
||||
constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 10.0.2-1.0";
|
||||
constexpr char VERSION_HASH[] = "34197eba8810e2edd5e9dfcfbde7b340882e856d";
|
||||
constexpr char DISPLAY_VERSION[] = "11.0.0";
|
||||
constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 11.0.0-5.0";
|
||||
|
||||
} // namespace SystemVersionData
|
||||
|
||||
|
||||
+16
-16
@@ -203,7 +203,7 @@ std::string VfsFile::GetFullPath() const {
|
||||
return GetContainingDirectory()->GetFullPath() + "/" + GetName();
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) const {
|
||||
VirtualFile VfsDirectory::GetFileRelative(std::string_view path) const {
|
||||
auto vec = Common::FS::SplitPathComponents(path);
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
|
||||
vec.end());
|
||||
@@ -231,7 +231,7 @@ std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) co
|
||||
return dir->GetFile(vec.back());
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> VfsDirectory::GetFileAbsolute(std::string_view path) const {
|
||||
VirtualFile VfsDirectory::GetFileAbsolute(std::string_view path) const {
|
||||
if (IsRoot()) {
|
||||
return GetFileRelative(path);
|
||||
}
|
||||
@@ -239,7 +239,7 @@ std::shared_ptr<VfsFile> VfsDirectory::GetFileAbsolute(std::string_view path) co
|
||||
return GetParentDirectory()->GetFileAbsolute(path);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryRelative(std::string_view path) const {
|
||||
VirtualDir VfsDirectory::GetDirectoryRelative(std::string_view path) const {
|
||||
auto vec = Common::FS::SplitPathComponents(path);
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
|
||||
vec.end());
|
||||
@@ -261,7 +261,7 @@ std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryRelative(std::string_vie
|
||||
return dir;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryAbsolute(std::string_view path) const {
|
||||
VirtualDir VfsDirectory::GetDirectoryAbsolute(std::string_view path) const {
|
||||
if (IsRoot()) {
|
||||
return GetDirectoryRelative(path);
|
||||
}
|
||||
@@ -269,14 +269,14 @@ std::shared_ptr<VfsDirectory> VfsDirectory::GetDirectoryAbsolute(std::string_vie
|
||||
return GetParentDirectory()->GetDirectoryAbsolute(path);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> VfsDirectory::GetFile(std::string_view name) const {
|
||||
VirtualFile VfsDirectory::GetFile(std::string_view name) const {
|
||||
const auto& files = GetFiles();
|
||||
const auto iter = std::find_if(files.begin(), files.end(),
|
||||
[&name](const auto& file1) { return name == file1->GetName(); });
|
||||
return iter == files.end() ? nullptr : *iter;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> VfsDirectory::GetSubdirectory(std::string_view name) const {
|
||||
VirtualDir VfsDirectory::GetSubdirectory(std::string_view name) const {
|
||||
const auto& subs = GetSubdirectories();
|
||||
const auto iter = std::find_if(subs.begin(), subs.end(),
|
||||
[&name](const auto& file1) { return name == file1->GetName(); });
|
||||
@@ -301,7 +301,7 @@ std::size_t VfsDirectory::GetSize() const {
|
||||
return file_total + subdir_total;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> VfsDirectory::CreateFileRelative(std::string_view path) {
|
||||
VirtualFile VfsDirectory::CreateFileRelative(std::string_view path) {
|
||||
auto vec = Common::FS::SplitPathComponents(path);
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
|
||||
vec.end());
|
||||
@@ -324,7 +324,7 @@ std::shared_ptr<VfsFile> VfsDirectory::CreateFileRelative(std::string_view path)
|
||||
return dir->CreateFileRelative(Common::FS::GetPathWithoutTop(path));
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> VfsDirectory::CreateFileAbsolute(std::string_view path) {
|
||||
VirtualFile VfsDirectory::CreateFileAbsolute(std::string_view path) {
|
||||
if (IsRoot()) {
|
||||
return CreateFileRelative(path);
|
||||
}
|
||||
@@ -332,7 +332,7 @@ std::shared_ptr<VfsFile> VfsDirectory::CreateFileAbsolute(std::string_view path)
|
||||
return GetParentDirectory()->CreateFileAbsolute(path);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> VfsDirectory::CreateDirectoryRelative(std::string_view path) {
|
||||
VirtualDir VfsDirectory::CreateDirectoryRelative(std::string_view path) {
|
||||
auto vec = Common::FS::SplitPathComponents(path);
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
|
||||
vec.end());
|
||||
@@ -355,7 +355,7 @@ std::shared_ptr<VfsDirectory> VfsDirectory::CreateDirectoryRelative(std::string_
|
||||
return dir->CreateDirectoryRelative(Common::FS::GetPathWithoutTop(path));
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> VfsDirectory::CreateDirectoryAbsolute(std::string_view path) {
|
||||
VirtualDir VfsDirectory::CreateDirectoryAbsolute(std::string_view path) {
|
||||
if (IsRoot()) {
|
||||
return CreateDirectoryRelative(path);
|
||||
}
|
||||
@@ -446,27 +446,27 @@ bool ReadOnlyVfsDirectory::IsReadable() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateSubdirectory(std::string_view name) {
|
||||
VirtualDir ReadOnlyVfsDirectory::CreateSubdirectory(std::string_view name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFile(std::string_view name) {
|
||||
VirtualFile ReadOnlyVfsDirectory::CreateFile(std::string_view name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileAbsolute(std::string_view path) {
|
||||
VirtualFile ReadOnlyVfsDirectory::CreateFileAbsolute(std::string_view path) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileRelative(std::string_view path) {
|
||||
VirtualFile ReadOnlyVfsDirectory::CreateFileRelative(std::string_view path) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryAbsolute(std::string_view path) {
|
||||
VirtualDir ReadOnlyVfsDirectory::CreateDirectoryAbsolute(std::string_view path) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryRelative(std::string_view path) {
|
||||
VirtualDir ReadOnlyVfsDirectory::CreateDirectoryRelative(std::string_view path) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
+22
-22
@@ -91,7 +91,7 @@ public:
|
||||
// Resizes the file to new_size. Returns whether or not the operation was successful.
|
||||
virtual bool Resize(std::size_t new_size) = 0;
|
||||
// Gets a pointer to the directory containing this file, returning nullptr if there is none.
|
||||
virtual std::shared_ptr<VfsDirectory> GetContainingDirectory() const = 0;
|
||||
virtual VirtualDir GetContainingDirectory() const = 0;
|
||||
|
||||
// Returns whether or not the file can be written to.
|
||||
virtual bool IsWritable() const = 0;
|
||||
@@ -183,27 +183,27 @@ public:
|
||||
|
||||
// Retrives the file located at path as if the current directory was root. Returns nullptr if
|
||||
// not found.
|
||||
virtual std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const;
|
||||
virtual VirtualFile GetFileRelative(std::string_view path) const;
|
||||
// Calls GetFileRelative(path) on the root of the current directory.
|
||||
virtual std::shared_ptr<VfsFile> GetFileAbsolute(std::string_view path) const;
|
||||
virtual VirtualFile GetFileAbsolute(std::string_view path) const;
|
||||
|
||||
// Retrives the directory located at path as if the current directory was root. Returns nullptr
|
||||
// if not found.
|
||||
virtual std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const;
|
||||
virtual VirtualDir GetDirectoryRelative(std::string_view path) const;
|
||||
// Calls GetDirectoryRelative(path) on the root of the current directory.
|
||||
virtual std::shared_ptr<VfsDirectory> GetDirectoryAbsolute(std::string_view path) const;
|
||||
virtual VirtualDir GetDirectoryAbsolute(std::string_view path) const;
|
||||
|
||||
// Returns a vector containing all of the files in this directory.
|
||||
virtual std::vector<std::shared_ptr<VfsFile>> GetFiles() const = 0;
|
||||
virtual std::vector<VirtualFile> GetFiles() const = 0;
|
||||
// Returns the file with filename matching name. Returns nullptr if directory dosen't have a
|
||||
// file with name.
|
||||
virtual std::shared_ptr<VfsFile> GetFile(std::string_view name) const;
|
||||
virtual VirtualFile GetFile(std::string_view name) const;
|
||||
|
||||
// Returns a vector containing all of the subdirectories in this directory.
|
||||
virtual std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const = 0;
|
||||
virtual std::vector<VirtualDir> GetSubdirectories() const = 0;
|
||||
// Returns the directory with name matching name. Returns nullptr if directory dosen't have a
|
||||
// directory with name.
|
||||
virtual std::shared_ptr<VfsDirectory> GetSubdirectory(std::string_view name) const;
|
||||
virtual VirtualDir GetSubdirectory(std::string_view name) const;
|
||||
|
||||
// Returns whether or not the directory can be written to.
|
||||
virtual bool IsWritable() const = 0;
|
||||
@@ -219,31 +219,31 @@ public:
|
||||
virtual std::size_t GetSize() const;
|
||||
// Returns the parent directory of this directory. Returns nullptr if this directory is root or
|
||||
// has no parent.
|
||||
virtual std::shared_ptr<VfsDirectory> GetParentDirectory() const = 0;
|
||||
virtual VirtualDir GetParentDirectory() const = 0;
|
||||
|
||||
// Creates a new subdirectory with name name. Returns a pointer to the new directory or nullptr
|
||||
// if the operation failed.
|
||||
virtual std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) = 0;
|
||||
virtual VirtualDir CreateSubdirectory(std::string_view name) = 0;
|
||||
// Creates a new file with name name. Returns a pointer to the new file or nullptr if the
|
||||
// operation failed.
|
||||
virtual std::shared_ptr<VfsFile> CreateFile(std::string_view name) = 0;
|
||||
virtual VirtualFile CreateFile(std::string_view name) = 0;
|
||||
|
||||
// Creates a new file at the path relative to this directory. Also creates directories if
|
||||
// they do not exist and is supported by this implementation. Returns nullptr on any failure.
|
||||
virtual std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path);
|
||||
virtual VirtualFile CreateFileRelative(std::string_view path);
|
||||
|
||||
// Creates a new file at the path relative to root of this directory. Also creates directories
|
||||
// if they do not exist and is supported by this implementation. Returns nullptr on any failure.
|
||||
virtual std::shared_ptr<VfsFile> CreateFileAbsolute(std::string_view path);
|
||||
virtual VirtualFile CreateFileAbsolute(std::string_view path);
|
||||
|
||||
// Creates a new directory at the path relative to this directory. Also creates directories if
|
||||
// they do not exist and is supported by this implementation. Returns nullptr on any failure.
|
||||
virtual std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path);
|
||||
virtual VirtualDir CreateDirectoryRelative(std::string_view path);
|
||||
|
||||
// Creates a new directory at the path relative to root of this directory. Also creates
|
||||
// directories if they do not exist and is supported by this implementation. Returns nullptr on
|
||||
// any failure.
|
||||
virtual std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path);
|
||||
virtual VirtualDir CreateDirectoryAbsolute(std::string_view path);
|
||||
|
||||
// Deletes the subdirectory with the given name and returns true on success.
|
||||
virtual bool DeleteSubdirectory(std::string_view name) = 0;
|
||||
@@ -280,12 +280,12 @@ class ReadOnlyVfsDirectory : public VfsDirectory {
|
||||
public:
|
||||
bool IsWritable() const override;
|
||||
bool IsReadable() const override;
|
||||
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
|
||||
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
|
||||
std::shared_ptr<VfsFile> CreateFileAbsolute(std::string_view path) override;
|
||||
std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override;
|
||||
std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path) override;
|
||||
std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override;
|
||||
VirtualDir CreateSubdirectory(std::string_view name) override;
|
||||
VirtualFile CreateFile(std::string_view name) override;
|
||||
VirtualFile CreateFileAbsolute(std::string_view path) override;
|
||||
VirtualFile CreateFileRelative(std::string_view path) override;
|
||||
VirtualDir CreateDirectoryAbsolute(std::string_view path) override;
|
||||
VirtualDir CreateDirectoryRelative(std::string_view path) override;
|
||||
bool DeleteSubdirectory(std::string_view name) override;
|
||||
bool DeleteSubdirectoryRecursive(std::string_view name) override;
|
||||
bool CleanSubdirectoryRecursive(std::string_view name) override;
|
||||
|
||||
@@ -46,7 +46,7 @@ VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(std::vector<VirtualFile> f
|
||||
if (files.size() == 1)
|
||||
return files[0];
|
||||
|
||||
return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), std::move(name)));
|
||||
return VirtualFile(new ConcatenatedVfsFile(std::move(files), std::move(name)));
|
||||
}
|
||||
|
||||
VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte,
|
||||
@@ -71,20 +71,23 @@ VirtualFile ConcatenatedVfsFile::MakeConcatenatedFile(u8 filler_byte,
|
||||
if (files.begin()->first != 0)
|
||||
files.emplace(0, std::make_shared<StaticVfsFile>(filler_byte, files.begin()->first));
|
||||
|
||||
return std::shared_ptr<VfsFile>(new ConcatenatedVfsFile(std::move(files), std::move(name)));
|
||||
return VirtualFile(new ConcatenatedVfsFile(std::move(files), std::move(name)));
|
||||
}
|
||||
|
||||
std::string ConcatenatedVfsFile::GetName() const {
|
||||
if (files.empty())
|
||||
if (files.empty()) {
|
||||
return "";
|
||||
if (!name.empty())
|
||||
}
|
||||
if (!name.empty()) {
|
||||
return name;
|
||||
}
|
||||
return files.begin()->second->GetName();
|
||||
}
|
||||
|
||||
std::size_t ConcatenatedVfsFile::GetSize() const {
|
||||
if (files.empty())
|
||||
if (files.empty()) {
|
||||
return 0;
|
||||
}
|
||||
return files.rbegin()->first + files.rbegin()->second->GetSize();
|
||||
}
|
||||
|
||||
@@ -92,9 +95,10 @@ bool ConcatenatedVfsFile::Resize(std::size_t new_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> ConcatenatedVfsFile::GetContainingDirectory() const {
|
||||
if (files.empty())
|
||||
VirtualDir ConcatenatedVfsFile::GetContainingDirectory() const {
|
||||
if (files.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return files.begin()->second->GetContainingDirectory();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
std::string GetName() const override;
|
||||
std::size_t GetSize() const override;
|
||||
bool Resize(std::size_t new_size) override;
|
||||
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
|
||||
VirtualDir GetContainingDirectory() const override;
|
||||
bool IsWritable() const override;
|
||||
bool IsReadable() const override;
|
||||
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
|
||||
|
||||
@@ -20,10 +20,10 @@ VirtualDir LayeredVfsDirectory::MakeLayeredDirectory(std::vector<VirtualDir> dir
|
||||
if (dirs.size() == 1)
|
||||
return dirs[0];
|
||||
|
||||
return std::shared_ptr<VfsDirectory>(new LayeredVfsDirectory(std::move(dirs), std::move(name)));
|
||||
return VirtualDir(new LayeredVfsDirectory(std::move(dirs), std::move(name)));
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> LayeredVfsDirectory::GetFileRelative(std::string_view path) const {
|
||||
VirtualFile LayeredVfsDirectory::GetFileRelative(std::string_view path) const {
|
||||
for (const auto& layer : dirs) {
|
||||
const auto file = layer->GetFileRelative(path);
|
||||
if (file != nullptr)
|
||||
@@ -33,23 +33,23 @@ std::shared_ptr<VfsFile> LayeredVfsDirectory::GetFileRelative(std::string_view p
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> LayeredVfsDirectory::GetDirectoryRelative(
|
||||
std::string_view path) const {
|
||||
VirtualDir LayeredVfsDirectory::GetDirectoryRelative(std::string_view path) const {
|
||||
std::vector<VirtualDir> out;
|
||||
for (const auto& layer : dirs) {
|
||||
auto dir = layer->GetDirectoryRelative(path);
|
||||
if (dir != nullptr)
|
||||
if (dir != nullptr) {
|
||||
out.push_back(std::move(dir));
|
||||
}
|
||||
}
|
||||
|
||||
return MakeLayeredDirectory(std::move(out));
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> LayeredVfsDirectory::GetFile(std::string_view name) const {
|
||||
VirtualFile LayeredVfsDirectory::GetFile(std::string_view name) const {
|
||||
return GetFileRelative(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> LayeredVfsDirectory::GetSubdirectory(std::string_view name) const {
|
||||
VirtualDir LayeredVfsDirectory::GetSubdirectory(std::string_view name) const {
|
||||
return GetDirectoryRelative(name);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ std::string LayeredVfsDirectory::GetFullPath() const {
|
||||
return dirs[0]->GetFullPath();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VfsFile>> LayeredVfsDirectory::GetFiles() const {
|
||||
std::vector<VirtualFile> LayeredVfsDirectory::GetFiles() const {
|
||||
std::vector<VirtualFile> out;
|
||||
for (const auto& layer : dirs) {
|
||||
for (const auto& file : layer->GetFiles()) {
|
||||
@@ -72,7 +72,7 @@ std::vector<std::shared_ptr<VfsFile>> LayeredVfsDirectory::GetFiles() const {
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VfsDirectory>> LayeredVfsDirectory::GetSubdirectories() const {
|
||||
std::vector<VirtualDir> LayeredVfsDirectory::GetSubdirectories() const {
|
||||
std::vector<std::string> names;
|
||||
for (const auto& layer : dirs) {
|
||||
for (const auto& sd : layer->GetSubdirectories()) {
|
||||
@@ -101,15 +101,15 @@ std::string LayeredVfsDirectory::GetName() const {
|
||||
return name.empty() ? dirs[0]->GetName() : name;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> LayeredVfsDirectory::GetParentDirectory() const {
|
||||
VirtualDir LayeredVfsDirectory::GetParentDirectory() const {
|
||||
return dirs[0]->GetParentDirectory();
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> LayeredVfsDirectory::CreateSubdirectory(std::string_view name) {
|
||||
VirtualDir LayeredVfsDirectory::CreateSubdirectory(std::string_view name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> LayeredVfsDirectory::CreateFile(std::string_view name) {
|
||||
VirtualFile LayeredVfsDirectory::CreateFile(std::string_view name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,20 +21,20 @@ public:
|
||||
/// Wrapper function to allow for more efficient handling of dirs.size() == 0, 1 cases.
|
||||
static VirtualDir MakeLayeredDirectory(std::vector<VirtualDir> dirs, std::string name = "");
|
||||
|
||||
std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const override;
|
||||
std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const override;
|
||||
std::shared_ptr<VfsFile> GetFile(std::string_view name) const override;
|
||||
std::shared_ptr<VfsDirectory> GetSubdirectory(std::string_view name) const override;
|
||||
VirtualFile GetFileRelative(std::string_view path) const override;
|
||||
VirtualDir GetDirectoryRelative(std::string_view path) const override;
|
||||
VirtualFile GetFile(std::string_view name) const override;
|
||||
VirtualDir GetSubdirectory(std::string_view name) const override;
|
||||
std::string GetFullPath() const override;
|
||||
|
||||
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
|
||||
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
|
||||
std::vector<VirtualFile> GetFiles() const override;
|
||||
std::vector<VirtualDir> GetSubdirectories() const override;
|
||||
bool IsWritable() const override;
|
||||
bool IsReadable() const override;
|
||||
std::string GetName() const override;
|
||||
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
|
||||
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
|
||||
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
|
||||
VirtualDir GetParentDirectory() const override;
|
||||
VirtualDir CreateSubdirectory(std::string_view name) override;
|
||||
VirtualFile CreateFile(std::string_view name) override;
|
||||
bool DeleteSubdirectory(std::string_view name) override;
|
||||
bool DeleteFile(std::string_view name) override;
|
||||
bool Rename(std::string_view name) override;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, std::size_t size_, std::size_t offset_,
|
||||
OffsetVfsFile::OffsetVfsFile(VirtualFile file_, std::size_t size_, std::size_t offset_,
|
||||
std::string name_, VirtualDir parent_)
|
||||
: file(file_), offset(offset_), size(size_), name(std::move(name_)),
|
||||
parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {}
|
||||
@@ -37,7 +37,7 @@ bool OffsetVfsFile::Resize(std::size_t new_size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> OffsetVfsFile::GetContainingDirectory() const {
|
||||
VirtualDir OffsetVfsFile::GetContainingDirectory() const {
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@ namespace FileSys {
|
||||
// the size of this wrapper.
|
||||
class OffsetVfsFile : public VfsFile {
|
||||
public:
|
||||
OffsetVfsFile(std::shared_ptr<VfsFile> file, std::size_t size, std::size_t offset = 0,
|
||||
OffsetVfsFile(VirtualFile file, std::size_t size, std::size_t offset = 0,
|
||||
std::string new_name = "", VirtualDir new_parent = nullptr);
|
||||
~OffsetVfsFile() override;
|
||||
|
||||
std::string GetName() const override;
|
||||
std::size_t GetSize() const override;
|
||||
bool Resize(std::size_t new_size) override;
|
||||
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
|
||||
VirtualDir GetContainingDirectory() const override;
|
||||
bool IsWritable() const override;
|
||||
bool IsReadable() const override;
|
||||
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
private:
|
||||
std::size_t TrimToFit(std::size_t r_size, std::size_t r_offset) const;
|
||||
|
||||
std::shared_ptr<VfsFile> file;
|
||||
VirtualFile file;
|
||||
std::size_t offset;
|
||||
std::size_t size;
|
||||
std::string name;
|
||||
|
||||
@@ -263,7 +263,7 @@ bool RealVfsFile::Resize(std::size_t new_size) {
|
||||
return backing->Resize(new_size);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> RealVfsFile::GetContainingDirectory() const {
|
||||
VirtualDir RealVfsFile::GetContainingDirectory() const {
|
||||
return base.OpenDirectory(parent_path, perms);
|
||||
}
|
||||
|
||||
@@ -352,7 +352,7 @@ RealVfsDirectory::RealVfsDirectory(RealVfsFilesystem& base_, const std::string&
|
||||
|
||||
RealVfsDirectory::~RealVfsDirectory() = default;
|
||||
|
||||
std::shared_ptr<VfsFile> RealVfsDirectory::GetFileRelative(std::string_view path) const {
|
||||
VirtualFile RealVfsDirectory::GetFileRelative(std::string_view path) const {
|
||||
const auto full_path = FS::SanitizePath(this->path + DIR_SEP + std::string(path));
|
||||
if (!FS::Exists(full_path) || FS::IsDirectory(full_path)) {
|
||||
return nullptr;
|
||||
@@ -360,7 +360,7 @@ std::shared_ptr<VfsFile> RealVfsDirectory::GetFileRelative(std::string_view path
|
||||
return base.OpenFile(full_path, perms);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> RealVfsDirectory::GetDirectoryRelative(std::string_view path) const {
|
||||
VirtualDir RealVfsDirectory::GetDirectoryRelative(std::string_view path) const {
|
||||
const auto full_path = FS::SanitizePath(this->path + DIR_SEP + std::string(path));
|
||||
if (!FS::Exists(full_path) || !FS::IsDirectory(full_path)) {
|
||||
return nullptr;
|
||||
@@ -368,20 +368,20 @@ std::shared_ptr<VfsDirectory> RealVfsDirectory::GetDirectoryRelative(std::string
|
||||
return base.OpenDirectory(full_path, perms);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> RealVfsDirectory::GetFile(std::string_view name) const {
|
||||
VirtualFile RealVfsDirectory::GetFile(std::string_view name) const {
|
||||
return GetFileRelative(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> RealVfsDirectory::GetSubdirectory(std::string_view name) const {
|
||||
VirtualDir RealVfsDirectory::GetSubdirectory(std::string_view name) const {
|
||||
return GetDirectoryRelative(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> RealVfsDirectory::CreateFileRelative(std::string_view path) {
|
||||
VirtualFile RealVfsDirectory::CreateFileRelative(std::string_view path) {
|
||||
const auto full_path = FS::SanitizePath(this->path + DIR_SEP + std::string(path));
|
||||
return base.CreateFile(full_path, perms);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> RealVfsDirectory::CreateDirectoryRelative(std::string_view path) {
|
||||
VirtualDir RealVfsDirectory::CreateDirectoryRelative(std::string_view path) {
|
||||
const auto full_path = FS::SanitizePath(this->path + DIR_SEP + std::string(path));
|
||||
return base.CreateDirectory(full_path, perms);
|
||||
}
|
||||
@@ -391,11 +391,11 @@ bool RealVfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) {
|
||||
return base.DeleteDirectory(full_path);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VfsFile>> RealVfsDirectory::GetFiles() const {
|
||||
std::vector<VirtualFile> RealVfsDirectory::GetFiles() const {
|
||||
return IterateEntries<RealVfsFile, VfsFile>();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VfsDirectory>> RealVfsDirectory::GetSubdirectories() const {
|
||||
std::vector<VirtualDir> RealVfsDirectory::GetSubdirectories() const {
|
||||
return IterateEntries<RealVfsDirectory, VfsDirectory>();
|
||||
}
|
||||
|
||||
@@ -411,7 +411,7 @@ std::string RealVfsDirectory::GetName() const {
|
||||
return path_components.back();
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> RealVfsDirectory::GetParentDirectory() const {
|
||||
VirtualDir RealVfsDirectory::GetParentDirectory() const {
|
||||
if (path_components.size() <= 1) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -419,12 +419,12 @@ std::shared_ptr<VfsDirectory> RealVfsDirectory::GetParentDirectory() const {
|
||||
return base.OpenDirectory(parent_path, perms);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> RealVfsDirectory::CreateSubdirectory(std::string_view name) {
|
||||
VirtualDir RealVfsDirectory::CreateSubdirectory(std::string_view name) {
|
||||
const std::string subdir_path = (path + DIR_SEP).append(name);
|
||||
return base.CreateDirectory(subdir_path, perms);
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> RealVfsDirectory::CreateFile(std::string_view name) {
|
||||
VirtualFile RealVfsDirectory::CreateFile(std::string_view name) {
|
||||
const std::string file_path = (path + DIR_SEP).append(name);
|
||||
return base.CreateFile(file_path, perms);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
std::string GetName() const override;
|
||||
std::size_t GetSize() const override;
|
||||
bool Resize(std::size_t new_size) override;
|
||||
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
|
||||
VirtualDir GetContainingDirectory() const override;
|
||||
bool IsWritable() const override;
|
||||
bool IsReadable() const override;
|
||||
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
|
||||
@@ -79,21 +79,21 @@ class RealVfsDirectory : public VfsDirectory {
|
||||
public:
|
||||
~RealVfsDirectory() override;
|
||||
|
||||
std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const override;
|
||||
std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const override;
|
||||
std::shared_ptr<VfsFile> GetFile(std::string_view name) const override;
|
||||
std::shared_ptr<VfsDirectory> GetSubdirectory(std::string_view name) const override;
|
||||
std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override;
|
||||
std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override;
|
||||
VirtualFile GetFileRelative(std::string_view path) const override;
|
||||
VirtualDir GetDirectoryRelative(std::string_view path) const override;
|
||||
VirtualFile GetFile(std::string_view name) const override;
|
||||
VirtualDir GetSubdirectory(std::string_view name) const override;
|
||||
VirtualFile CreateFileRelative(std::string_view path) override;
|
||||
VirtualDir CreateDirectoryRelative(std::string_view path) override;
|
||||
bool DeleteSubdirectoryRecursive(std::string_view name) override;
|
||||
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
|
||||
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
|
||||
std::vector<VirtualFile> GetFiles() const override;
|
||||
std::vector<VirtualDir> GetSubdirectories() const override;
|
||||
bool IsWritable() const override;
|
||||
bool IsReadable() const override;
|
||||
std::string GetName() const override;
|
||||
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
|
||||
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
|
||||
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
|
||||
VirtualDir GetParentDirectory() const override;
|
||||
VirtualDir CreateSubdirectory(std::string_view name) override;
|
||||
VirtualFile CreateFile(std::string_view name) override;
|
||||
bool DeleteSubdirectory(std::string_view name) override;
|
||||
bool DeleteFile(std::string_view name) override;
|
||||
bool Rename(std::string_view name) override;
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override {
|
||||
VirtualDir GetContainingDirectory() const override {
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ bool VectorVfsFile::Resize(size_t new_size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> VectorVfsFile::GetContainingDirectory() const {
|
||||
VirtualDir VectorVfsFile::GetContainingDirectory() const {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@@ -68,11 +68,11 @@ VectorVfsDirectory::VectorVfsDirectory(std::vector<VirtualFile> files_,
|
||||
|
||||
VectorVfsDirectory::~VectorVfsDirectory() = default;
|
||||
|
||||
std::vector<std::shared_ptr<VfsFile>> VectorVfsDirectory::GetFiles() const {
|
||||
std::vector<VirtualFile> VectorVfsDirectory::GetFiles() const {
|
||||
return files;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VfsDirectory>> VectorVfsDirectory::GetSubdirectories() const {
|
||||
std::vector<VirtualDir> VectorVfsDirectory::GetSubdirectories() const {
|
||||
return dirs;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ std::string VectorVfsDirectory::GetName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> VectorVfsDirectory::GetParentDirectory() const {
|
||||
VirtualDir VectorVfsDirectory::GetParentDirectory() const {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@@ -116,11 +116,11 @@ bool VectorVfsDirectory::Rename(std::string_view name_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> VectorVfsDirectory::CreateSubdirectory(std::string_view name) {
|
||||
VirtualDir VectorVfsDirectory::CreateSubdirectory(std::string_view name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsFile> VectorVfsDirectory::CreateFile(std::string_view name) {
|
||||
VirtualFile VectorVfsDirectory::CreateFile(std::string_view name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ namespace FileSys {
|
||||
template <std::size_t size>
|
||||
class ArrayVfsFile : public VfsFile {
|
||||
public:
|
||||
explicit ArrayVfsFile(const std::array<u8, size>& data, std::string name = "",
|
||||
VirtualDir parent = nullptr)
|
||||
: data(data), name(std::move(name)), parent(std::move(parent)) {}
|
||||
explicit ArrayVfsFile(const std::array<u8, size>& data_, std::string name_ = "",
|
||||
VirtualDir parent_ = nullptr)
|
||||
: data(data_), name(std::move(name_)), parent(std::move(parent_)) {}
|
||||
|
||||
std::string GetName() const override {
|
||||
return name;
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override {
|
||||
VirtualDir GetContainingDirectory() const override {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@@ -51,12 +51,12 @@ public:
|
||||
return read;
|
||||
}
|
||||
|
||||
std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override {
|
||||
std::size_t Write(const u8* data_, std::size_t length, std::size_t offset) override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Rename(std::string_view name) override {
|
||||
this->name = name;
|
||||
bool Rename(std::string_view new_name) override {
|
||||
name = new_name;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
std::string GetName() const override;
|
||||
std::size_t GetSize() const override;
|
||||
bool Resize(std::size_t new_size) override;
|
||||
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
|
||||
VirtualDir GetContainingDirectory() const override;
|
||||
bool IsWritable() const override;
|
||||
bool IsReadable() const override;
|
||||
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
|
||||
@@ -106,17 +106,17 @@ public:
|
||||
VirtualDir parent = nullptr);
|
||||
~VectorVfsDirectory() override;
|
||||
|
||||
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
|
||||
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
|
||||
std::vector<VirtualFile> GetFiles() const override;
|
||||
std::vector<VirtualDir> GetSubdirectories() const override;
|
||||
bool IsWritable() const override;
|
||||
bool IsReadable() const override;
|
||||
std::string GetName() const override;
|
||||
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
|
||||
VirtualDir GetParentDirectory() const override;
|
||||
bool DeleteSubdirectory(std::string_view name) override;
|
||||
bool DeleteFile(std::string_view name) override;
|
||||
bool Rename(std::string_view name) override;
|
||||
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
|
||||
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
|
||||
VirtualDir CreateSubdirectory(std::string_view name) override;
|
||||
VirtualFile CreateFile(std::string_view name) override;
|
||||
|
||||
virtual void AddFile(VirtualFile file);
|
||||
virtual void AddDirectory(VirtualDir dir);
|
||||
|
||||
@@ -152,11 +152,11 @@ NAXContentType NAX::GetContentType() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VfsFile>> NAX::GetFiles() const {
|
||||
std::vector<VirtualFile> NAX::GetFiles() const {
|
||||
return {dec_file};
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VfsDirectory>> NAX::GetSubdirectories() const {
|
||||
std::vector<VirtualDir> NAX::GetSubdirectories() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ std::string NAX::GetName() const {
|
||||
return file->GetName();
|
||||
}
|
||||
|
||||
std::shared_ptr<VfsDirectory> NAX::GetParentDirectory() const {
|
||||
VirtualDir NAX::GetParentDirectory() const {
|
||||
return file->GetContainingDirectory();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,13 +47,13 @@ public:
|
||||
|
||||
NAXContentType GetContentType() const;
|
||||
|
||||
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
|
||||
std::vector<VirtualFile> GetFiles() const override;
|
||||
|
||||
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
|
||||
std::vector<VirtualDir> GetSubdirectories() const override;
|
||||
|
||||
std::string GetName() const override;
|
||||
|
||||
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
|
||||
VirtualDir GetParentDirectory() const override;
|
||||
|
||||
private:
|
||||
Loader::ResultStatus Parse(std::string_view path);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/frontend/applets/error.h"
|
||||
|
||||
namespace Core::Frontend {
|
||||
@@ -10,7 +11,7 @@ ErrorApplet::~ErrorApplet() = default;
|
||||
|
||||
void DefaultErrorApplet::ShowError(ResultCode error, std::function<void()> finished) const {
|
||||
LOG_CRITICAL(Service_Fatal, "Application requested error display: {:04}-{:04} (raw={:08X})",
|
||||
static_cast<u32>(error.module.Value()), error.description.Value(), error.raw);
|
||||
error.module.Value(), error.description.Value(), error.raw);
|
||||
}
|
||||
|
||||
void DefaultErrorApplet::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time,
|
||||
@@ -18,7 +19,7 @@ void DefaultErrorApplet::ShowErrorWithTimestamp(ResultCode error, std::chrono::s
|
||||
LOG_CRITICAL(
|
||||
Service_Fatal,
|
||||
"Application requested error display: {:04X}-{:04X} (raw={:08X}) with timestamp={:016X}",
|
||||
static_cast<u32>(error.module.Value()), error.description.Value(), error.raw, time.count());
|
||||
error.module.Value(), error.description.Value(), error.raw, time.count());
|
||||
}
|
||||
|
||||
void DefaultErrorApplet::ShowCustomErrorText(ResultCode error, std::string main_text,
|
||||
@@ -26,7 +27,7 @@ void DefaultErrorApplet::ShowCustomErrorText(ResultCode error, std::string main_
|
||||
std::function<void()> finished) const {
|
||||
LOG_CRITICAL(Service_Fatal,
|
||||
"Application requested custom error with error_code={:04X}-{:04X} (raw={:08X})",
|
||||
static_cast<u32>(error.module.Value()), error.description.Value(), error.raw);
|
||||
error.module.Value(), error.description.Value(), error.raw);
|
||||
LOG_CRITICAL(Service_Fatal, " Main Text: {}", main_text);
|
||||
LOG_CRITICAL(Service_Fatal, " Detail Text: {}", detail_text);
|
||||
}
|
||||
|
||||
@@ -53,72 +53,4 @@ void DefaultPhotoViewerApplet::ShowAllPhotos(std::function<void()> finished) con
|
||||
finished();
|
||||
}
|
||||
|
||||
ECommerceApplet::~ECommerceApplet() = default;
|
||||
|
||||
DefaultECommerceApplet::~DefaultECommerceApplet() = default;
|
||||
|
||||
void DefaultECommerceApplet::ShowApplicationInformation(
|
||||
std::function<void()> finished, u64 title_id, std::optional<u128> user_id,
|
||||
std::optional<bool> full_display, std::optional<std::string> extra_parameter) {
|
||||
const auto value = user_id.value_or(u128{});
|
||||
LOG_INFO(Service_AM,
|
||||
"Application requested frontend show application information for EShop, "
|
||||
"title_id={:016X}, user_id={:016X}{:016X}, full_display={}, extra_parameter={}",
|
||||
title_id, value[1], value[0],
|
||||
full_display.has_value() ? fmt::format("{}", *full_display) : "null",
|
||||
extra_parameter.value_or("null"));
|
||||
finished();
|
||||
}
|
||||
|
||||
void DefaultECommerceApplet::ShowAddOnContentList(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id,
|
||||
std::optional<bool> full_display) {
|
||||
const auto value = user_id.value_or(u128{});
|
||||
LOG_INFO(Service_AM,
|
||||
"Application requested frontend show add on content list for EShop, "
|
||||
"title_id={:016X}, user_id={:016X}{:016X}, full_display={}",
|
||||
title_id, value[1], value[0],
|
||||
full_display.has_value() ? fmt::format("{}", *full_display) : "null");
|
||||
finished();
|
||||
}
|
||||
|
||||
void DefaultECommerceApplet::ShowSubscriptionList(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id) {
|
||||
const auto value = user_id.value_or(u128{});
|
||||
LOG_INFO(Service_AM,
|
||||
"Application requested frontend show subscription list for EShop, title_id={:016X}, "
|
||||
"user_id={:016X}{:016X}",
|
||||
title_id, value[1], value[0]);
|
||||
finished();
|
||||
}
|
||||
|
||||
void DefaultECommerceApplet::ShowConsumableItemList(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id) {
|
||||
const auto value = user_id.value_or(u128{});
|
||||
LOG_INFO(
|
||||
Service_AM,
|
||||
"Application requested frontend show consumable item list for EShop, title_id={:016X}, "
|
||||
"user_id={:016X}{:016X}",
|
||||
title_id, value[1], value[0]);
|
||||
finished();
|
||||
}
|
||||
|
||||
void DefaultECommerceApplet::ShowShopHome(std::function<void()> finished, u128 user_id,
|
||||
bool full_display) {
|
||||
LOG_INFO(Service_AM,
|
||||
"Application requested frontend show home menu for EShop, user_id={:016X}{:016X}, "
|
||||
"full_display={}",
|
||||
user_id[1], user_id[0], full_display);
|
||||
finished();
|
||||
}
|
||||
|
||||
void DefaultECommerceApplet::ShowSettings(std::function<void()> finished, u128 user_id,
|
||||
bool full_display) {
|
||||
LOG_INFO(Service_AM,
|
||||
"Application requested frontend show settings menu for EShop, user_id={:016X}{:016X}, "
|
||||
"full_display={}",
|
||||
user_id[1], user_id[0], full_display);
|
||||
finished();
|
||||
}
|
||||
|
||||
} // namespace Core::Frontend
|
||||
|
||||
@@ -58,55 +58,4 @@ public:
|
||||
void ShowAllPhotos(std::function<void()> finished) const override;
|
||||
};
|
||||
|
||||
class ECommerceApplet {
|
||||
public:
|
||||
virtual ~ECommerceApplet();
|
||||
|
||||
// Shows a page with application icons, description, name, and price.
|
||||
virtual void ShowApplicationInformation(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id = {},
|
||||
std::optional<bool> full_display = {},
|
||||
std::optional<std::string> extra_parameter = {}) = 0;
|
||||
|
||||
// Shows a page with all of the add on content available for a game, with name, description, and
|
||||
// price.
|
||||
virtual void ShowAddOnContentList(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id = {},
|
||||
std::optional<bool> full_display = {}) = 0;
|
||||
|
||||
// Shows a page with all of the subscriptions (recurring payments) for a game, with name,
|
||||
// description, price, and renewal period.
|
||||
virtual void ShowSubscriptionList(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id = {}) = 0;
|
||||
|
||||
// Shows a page with a list of any additional game related purchasable items (DLC,
|
||||
// subscriptions, etc) for a particular game, with name, description, type, and price.
|
||||
virtual void ShowConsumableItemList(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id = {}) = 0;
|
||||
|
||||
// Shows the home page of the shop.
|
||||
virtual void ShowShopHome(std::function<void()> finished, u128 user_id, bool full_display) = 0;
|
||||
|
||||
// Shows the user settings page of the shop.
|
||||
virtual void ShowSettings(std::function<void()> finished, u128 user_id, bool full_display) = 0;
|
||||
};
|
||||
|
||||
class DefaultECommerceApplet : public ECommerceApplet {
|
||||
public:
|
||||
~DefaultECommerceApplet() override;
|
||||
|
||||
void ShowApplicationInformation(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id, std::optional<bool> full_display,
|
||||
std::optional<std::string> extra_parameter) override;
|
||||
void ShowAddOnContentList(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id,
|
||||
std::optional<bool> full_display) override;
|
||||
void ShowSubscriptionList(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id) override;
|
||||
void ShowConsumableItemList(std::function<void()> finished, u64 title_id,
|
||||
std::optional<u128> user_id) override;
|
||||
void ShowShopHome(std::function<void()> finished, u128 user_id, bool full_display) override;
|
||||
void ShowSettings(std::function<void()> finished, u128 user_id, bool full_display) override;
|
||||
};
|
||||
|
||||
} // namespace Core::Frontend
|
||||
|
||||
@@ -11,14 +11,22 @@ WebBrowserApplet::~WebBrowserApplet() = default;
|
||||
|
||||
DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default;
|
||||
|
||||
void DefaultWebBrowserApplet::OpenPageLocal(std::string_view filename,
|
||||
std::function<void()> unpack_romfs_callback,
|
||||
std::function<void()> finished_callback) {
|
||||
LOG_INFO(Service_AM,
|
||||
"(STUBBED) called - No suitable web browser implementation found to open website page "
|
||||
"at '{}'!",
|
||||
filename);
|
||||
finished_callback();
|
||||
void DefaultWebBrowserApplet::OpenLocalWebPage(
|
||||
std::string_view local_url, std::function<void()> extract_romfs_callback,
|
||||
std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open local web page at {}",
|
||||
local_url);
|
||||
|
||||
callback(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost/");
|
||||
}
|
||||
|
||||
void DefaultWebBrowserApplet::OpenExternalWebPage(
|
||||
std::string_view external_url,
|
||||
std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const {
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open external web page at {}",
|
||||
external_url);
|
||||
|
||||
callback(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost/");
|
||||
}
|
||||
|
||||
} // namespace Core::Frontend
|
||||
|
||||
@@ -7,22 +7,34 @@
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
|
||||
#include "core/hle/service/am/applets/web_types.h"
|
||||
|
||||
namespace Core::Frontend {
|
||||
|
||||
class WebBrowserApplet {
|
||||
public:
|
||||
virtual ~WebBrowserApplet();
|
||||
|
||||
virtual void OpenPageLocal(std::string_view url, std::function<void()> unpack_romfs_callback,
|
||||
std::function<void()> finished_callback) = 0;
|
||||
virtual void OpenLocalWebPage(
|
||||
std::string_view local_url, std::function<void()> extract_romfs_callback,
|
||||
std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0;
|
||||
|
||||
virtual void OpenExternalWebPage(
|
||||
std::string_view external_url,
|
||||
std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0;
|
||||
};
|
||||
|
||||
class DefaultWebBrowserApplet final : public WebBrowserApplet {
|
||||
public:
|
||||
~DefaultWebBrowserApplet() override;
|
||||
|
||||
void OpenPageLocal(std::string_view url, std::function<void()> unpack_romfs_callback,
|
||||
std::function<void()> finished_callback) override;
|
||||
void OpenLocalWebPage(std::string_view local_url, std::function<void()> extract_romfs_callback,
|
||||
std::function<void(Service::AM::Applets::WebExitReason, std::string)>
|
||||
callback) const override;
|
||||
|
||||
void OpenExternalWebPage(std::string_view external_url,
|
||||
std::function<void(Service::AM::Applets::WebExitReason, std::string)>
|
||||
callback) const override;
|
||||
};
|
||||
|
||||
} // namespace Core::Frontend
|
||||
|
||||
@@ -102,8 +102,8 @@ public:
|
||||
float render_surface_scale = 1.0f;
|
||||
};
|
||||
|
||||
/// Polls window events
|
||||
virtual void PollEvents() = 0;
|
||||
/// Called from GPU thread when a frame is displayed.
|
||||
virtual void OnFrameDisplayed() {}
|
||||
|
||||
/**
|
||||
* Returns a GraphicsContext that the frontend provides to be used for rendering.
|
||||
|
||||
@@ -163,10 +163,15 @@ using MotionStatus = std::tuple<Common::Vec3<float>, Common::Vec3<float>, Common
|
||||
using MotionDevice = InputDevice<MotionStatus>;
|
||||
|
||||
/**
|
||||
* A touch device is an input device that returns a tuple of two floats and a bool. The floats are
|
||||
* A touch status is an object that returns a tuple of two floats and a bool. The floats are
|
||||
* x and y coordinates in the range 0.0 - 1.0, and the bool indicates whether it is pressed.
|
||||
*/
|
||||
using TouchDevice = InputDevice<std::tuple<float, float, bool>>;
|
||||
using TouchStatus = std::tuple<float, float, bool>;
|
||||
|
||||
/**
|
||||
* A touch device is an input device that returns a touch status object
|
||||
*/
|
||||
using TouchDevice = InputDevice<TouchStatus>;
|
||||
|
||||
/**
|
||||
* A mouse device is an input device that returns a tuple of two floats and four ints.
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/frontend/input_interpreter.h"
|
||||
#include "core/hle/service/hid/controllers/npad.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
||||
InputInterpreter::InputInterpreter(Core::System& system)
|
||||
: npad{system.ServiceManager()
|
||||
.GetService<Service::HID::Hid>("hid")
|
||||
->GetAppletResource()
|
||||
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} {}
|
||||
|
||||
InputInterpreter::~InputInterpreter() = default;
|
||||
|
||||
void InputInterpreter::PollInput() {
|
||||
const u32 button_state = npad.GetAndResetPressState();
|
||||
|
||||
previous_index = current_index;
|
||||
current_index = (current_index + 1) % button_states.size();
|
||||
|
||||
button_states[current_index] = button_state;
|
||||
}
|
||||
|
||||
bool InputInterpreter::IsButtonPressedOnce(HIDButton button) const {
|
||||
const bool current_press =
|
||||
(button_states[current_index] & (1U << static_cast<u8>(button))) != 0;
|
||||
const bool previous_press =
|
||||
(button_states[previous_index] & (1U << static_cast<u8>(button))) != 0;
|
||||
|
||||
return current_press && !previous_press;
|
||||
}
|
||||
|
||||
bool InputInterpreter::IsButtonHeld(HIDButton button) const {
|
||||
u32 held_buttons{button_states[0]};
|
||||
|
||||
for (std::size_t i = 1; i < button_states.size(); ++i) {
|
||||
held_buttons &= button_states[i];
|
||||
}
|
||||
|
||||
return (held_buttons & (1U << static_cast<u8>(button))) != 0;
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
// Copyright 2020 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::HID {
|
||||
class Controller_NPad;
|
||||
}
|
||||
|
||||
enum class HIDButton : u8 {
|
||||
A,
|
||||
B,
|
||||
X,
|
||||
Y,
|
||||
LStick,
|
||||
RStick,
|
||||
L,
|
||||
R,
|
||||
ZL,
|
||||
ZR,
|
||||
Plus,
|
||||
Minus,
|
||||
|
||||
DLeft,
|
||||
DUp,
|
||||
DRight,
|
||||
DDown,
|
||||
|
||||
LStickLeft,
|
||||
LStickUp,
|
||||
LStickRight,
|
||||
LStickDown,
|
||||
|
||||
RStickLeft,
|
||||
RStickUp,
|
||||
RStickRight,
|
||||
RStickDown,
|
||||
|
||||
LeftSL,
|
||||
LeftSR,
|
||||
|
||||
RightSL,
|
||||
RightSR,
|
||||
};
|
||||
|
||||
/**
|
||||
* The InputInterpreter class interfaces with HID to retrieve button press states.
|
||||
* Input is intended to be polled every 50ms so that a button is considered to be
|
||||
* held down after 400ms has elapsed since the initial button press and subsequent
|
||||
* repeated presses occur every 50ms.
|
||||
*/
|
||||
class InputInterpreter {
|
||||
public:
|
||||
explicit InputInterpreter(Core::System& system);
|
||||
virtual ~InputInterpreter();
|
||||
|
||||
/// Gets a button state from HID and inserts it into the array of button states.
|
||||
void PollInput();
|
||||
|
||||
/**
|
||||
* The specified button is considered to be pressed once
|
||||
* if it is currently pressed and not pressed previously.
|
||||
*
|
||||
* @param button The button to check.
|
||||
*
|
||||
* @returns True when the button is pressed once.
|
||||
*/
|
||||
[[nodiscard]] bool IsButtonPressedOnce(HIDButton button) const;
|
||||
|
||||
/**
|
||||
* Checks whether any of the buttons in the parameter list is pressed once.
|
||||
*
|
||||
* @tparam HIDButton The buttons to check.
|
||||
*
|
||||
* @returns True when at least one of the buttons is pressed once.
|
||||
*/
|
||||
template <HIDButton... T>
|
||||
[[nodiscard]] bool IsAnyButtonPressedOnce() {
|
||||
return (IsButtonPressedOnce(T) || ...);
|
||||
}
|
||||
|
||||
/**
|
||||
* The specified button is considered to be held down if it is pressed in all 9 button states.
|
||||
*
|
||||
* @param button The button to check.
|
||||
*
|
||||
* @returns True when the button is held down.
|
||||
*/
|
||||
[[nodiscard]] bool IsButtonHeld(HIDButton button) const;
|
||||
|
||||
/**
|
||||
* Checks whether any of the buttons in the parameter list is held down.
|
||||
*
|
||||
* @tparam HIDButton The buttons to check.
|
||||
*
|
||||
* @returns True when at least one of the buttons is held down.
|
||||
*/
|
||||
template <HIDButton... T>
|
||||
[[nodiscard]] bool IsAnyButtonHeld() {
|
||||
return (IsButtonHeld(T) || ...);
|
||||
}
|
||||
|
||||
private:
|
||||
Service::HID::Controller_NPad& npad;
|
||||
|
||||
/// Stores 9 consecutive button states polled from HID.
|
||||
std::array<u32, 9> button_states{};
|
||||
|
||||
std::size_t previous_index{};
|
||||
std::size_t current_index{};
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,114 +0,0 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// Originally written by Sven Peter <sven@fail0verflow.com> for anergistic.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
|
||||
namespace GDBStub {
|
||||
|
||||
/// Breakpoint Method
|
||||
enum class BreakpointType {
|
||||
None, ///< None
|
||||
Execute, ///< Execution Breakpoint
|
||||
Read, ///< Read Breakpoint
|
||||
Write, ///< Write Breakpoint
|
||||
Access ///< Access (R/W) Breakpoint
|
||||
};
|
||||
|
||||
struct BreakpointAddress {
|
||||
VAddr address;
|
||||
BreakpointType type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the port the gdbstub should use to listen for connections.
|
||||
*
|
||||
* @param port Port to listen for connection
|
||||
*/
|
||||
void SetServerPort(u16 port);
|
||||
|
||||
/**
|
||||
* Starts or stops the server if possible.
|
||||
*
|
||||
* @param status Set the server to enabled or disabled.
|
||||
*/
|
||||
void ToggleServer(bool status);
|
||||
|
||||
/// Start the gdbstub server.
|
||||
void Init();
|
||||
|
||||
/**
|
||||
* Defer initialization of the gdbstub to the first packet processing functions.
|
||||
* This avoids a case where the gdbstub thread is frozen after initialization
|
||||
* and fails to respond in time to packets.
|
||||
*/
|
||||
void DeferStart();
|
||||
|
||||
/// Stop gdbstub server.
|
||||
void Shutdown();
|
||||
|
||||
/// Checks if the gdbstub server is enabled.
|
||||
bool IsServerEnabled();
|
||||
|
||||
/// Returns true if there is an active socket connection.
|
||||
bool IsConnected();
|
||||
|
||||
/// Register module.
|
||||
void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext = true);
|
||||
|
||||
/**
|
||||
* Signal to the gdbstub server that it should halt CPU execution.
|
||||
*
|
||||
* @param is_memory_break If true, the break resulted from a memory breakpoint.
|
||||
*/
|
||||
void Break(bool is_memory_break = false);
|
||||
|
||||
/// Determine if there was a memory breakpoint.
|
||||
bool IsMemoryBreak();
|
||||
|
||||
/// Read and handle packet from gdb client.
|
||||
void HandlePacket();
|
||||
|
||||
/**
|
||||
* Get the nearest breakpoint of the specified type at the given address.
|
||||
*
|
||||
* @param addr Address to search from.
|
||||
* @param type Type of breakpoint.
|
||||
*/
|
||||
BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, GDBStub::BreakpointType type);
|
||||
|
||||
/**
|
||||
* Check if a breakpoint of the specified type exists at the given address.
|
||||
*
|
||||
* @param addr Address of breakpoint.
|
||||
* @param type Type of breakpoint.
|
||||
*/
|
||||
bool CheckBreakpoint(VAddr addr, GDBStub::BreakpointType type);
|
||||
|
||||
/// If set to true, the CPU will halt at the beginning of the next CPU loop.
|
||||
bool GetCpuHaltFlag();
|
||||
|
||||
/// If set to true and the CPU is halted, the CPU will step one instruction.
|
||||
bool GetCpuStepFlag();
|
||||
|
||||
/**
|
||||
* When set to true, the CPU will step one instruction when the CPU is halted next.
|
||||
*
|
||||
* @param is_step
|
||||
*/
|
||||
void SetCpuStepFlag(bool is_step);
|
||||
|
||||
/**
|
||||
* Send trap signal from thread back to the gdbstub server.
|
||||
*
|
||||
* @param thread Sending thread.
|
||||
* @param trap Trap no.
|
||||
*/
|
||||
void SendTrap(Kernel::Thread* thread, int trap);
|
||||
} // namespace GDBStub
|
||||
+35
-32
@@ -166,8 +166,23 @@ public:
|
||||
ValidateHeader();
|
||||
}
|
||||
|
||||
void PushImpl(s8 value);
|
||||
void PushImpl(s16 value);
|
||||
void PushImpl(s32 value);
|
||||
void PushImpl(s64 value);
|
||||
void PushImpl(u8 value);
|
||||
void PushImpl(u16 value);
|
||||
void PushImpl(u32 value);
|
||||
void PushImpl(u64 value);
|
||||
void PushImpl(float value);
|
||||
void PushImpl(double value);
|
||||
void PushImpl(bool value);
|
||||
void PushImpl(ResultCode value);
|
||||
|
||||
template <typename T>
|
||||
void Push(T value);
|
||||
void Push(T value) {
|
||||
return PushImpl(value);
|
||||
}
|
||||
|
||||
template <typename First, typename... Other>
|
||||
void Push(const First& first_value, const Other&... other_values);
|
||||
@@ -215,13 +230,11 @@ private:
|
||||
|
||||
/// Push ///
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(s32 value) {
|
||||
inline void ResponseBuilder::PushImpl(s32 value) {
|
||||
cmdbuf[index++] = static_cast<u32>(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(u32 value) {
|
||||
inline void ResponseBuilder::PushImpl(u32 value) {
|
||||
cmdbuf[index++] = value;
|
||||
}
|
||||
|
||||
@@ -233,62 +246,52 @@ void ResponseBuilder::PushRaw(const T& value) {
|
||||
index += (sizeof(T) + 3) / 4; // round up to word length
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(ResultCode value) {
|
||||
inline void ResponseBuilder::PushImpl(ResultCode value) {
|
||||
// Result codes are actually 64-bit in the IPC buffer, but only the high part is discarded.
|
||||
Push(value.raw);
|
||||
Push<u32>(0);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(s8 value) {
|
||||
inline void ResponseBuilder::PushImpl(s8 value) {
|
||||
PushRaw(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(s16 value) {
|
||||
inline void ResponseBuilder::PushImpl(s16 value) {
|
||||
PushRaw(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(s64 value) {
|
||||
Push(static_cast<u32>(value));
|
||||
Push(static_cast<u32>(value >> 32));
|
||||
inline void ResponseBuilder::PushImpl(s64 value) {
|
||||
PushImpl(static_cast<u32>(value));
|
||||
PushImpl(static_cast<u32>(value >> 32));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(u8 value) {
|
||||
inline void ResponseBuilder::PushImpl(u8 value) {
|
||||
PushRaw(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(u16 value) {
|
||||
inline void ResponseBuilder::PushImpl(u16 value) {
|
||||
PushRaw(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(u64 value) {
|
||||
Push(static_cast<u32>(value));
|
||||
Push(static_cast<u32>(value >> 32));
|
||||
inline void ResponseBuilder::PushImpl(u64 value) {
|
||||
PushImpl(static_cast<u32>(value));
|
||||
PushImpl(static_cast<u32>(value >> 32));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(float value) {
|
||||
inline void ResponseBuilder::PushImpl(float value) {
|
||||
u32 integral;
|
||||
std::memcpy(&integral, &value, sizeof(u32));
|
||||
Push(integral);
|
||||
PushImpl(integral);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(double value) {
|
||||
inline void ResponseBuilder::PushImpl(double value) {
|
||||
u64 integral;
|
||||
std::memcpy(&integral, &value, sizeof(u64));
|
||||
Push(integral);
|
||||
PushImpl(integral);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void ResponseBuilder::Push(bool value) {
|
||||
Push(static_cast<u8>(value));
|
||||
inline void ResponseBuilder::PushImpl(bool value) {
|
||||
PushImpl(static_cast<u8>(value));
|
||||
}
|
||||
|
||||
template <typename First, typename... Other>
|
||||
|
||||
@@ -275,12 +275,6 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
|
||||
return current_thread->GetSignalingResult();
|
||||
}
|
||||
|
||||
void AddressArbiter::HandleWakeupThread(std::shared_ptr<Thread> thread) {
|
||||
ASSERT(thread->GetStatus() == ThreadStatus::WaitArb);
|
||||
RemoveThread(thread);
|
||||
thread->SetArbiterWaitAddress(0);
|
||||
}
|
||||
|
||||
void AddressArbiter::InsertThread(std::shared_ptr<Thread> thread) {
|
||||
const VAddr arb_addr = thread->GetArbiterWaitAddress();
|
||||
std::list<std::shared_ptr<Thread>>& thread_list = arb_threads[arb_addr];
|
||||
|
||||
@@ -50,9 +50,6 @@ public:
|
||||
/// Waits on an address with a particular arbitration type.
|
||||
ResultCode WaitForAddress(VAddr address, ArbitrationType type, s32 value, s64 timeout_ns);
|
||||
|
||||
/// Removes a thread from the container and resets its address arbiter adress to 0
|
||||
void HandleWakeupThread(std::shared_ptr<Thread> thread);
|
||||
|
||||
private:
|
||||
/// Signals an address being waited on.
|
||||
ResultCode SignalToAddressOnly(VAddr address, s32 num_to_wake);
|
||||
|
||||
@@ -68,6 +68,12 @@ struct KernelCore::Impl {
|
||||
InitializeSuspendThreads();
|
||||
}
|
||||
|
||||
void InitializeCores() {
|
||||
for (auto& core : cores) {
|
||||
core.Initialize(current_process->Is64BitProcess());
|
||||
}
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
next_object_id = 0;
|
||||
next_kernel_process_id = Process::InitialKIPIDMin;
|
||||
@@ -116,7 +122,7 @@ struct KernelCore::Impl {
|
||||
Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES);
|
||||
for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
|
||||
schedulers[i] = std::make_unique<Kernel::Scheduler>(system, i);
|
||||
cores.emplace_back(system, i, *schedulers[i], interrupts[i]);
|
||||
cores.emplace_back(i, system, *schedulers[i], interrupts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,6 +187,7 @@ struct KernelCore::Impl {
|
||||
if (process == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const u32 core_id = GetCurrentHostThreadID();
|
||||
if (core_id < Core::Hardware::NUM_CPU_CORES) {
|
||||
system.Memory().SetCurrentPageTable(*process, core_id);
|
||||
@@ -372,6 +379,10 @@ void KernelCore::Initialize() {
|
||||
impl->Initialize(*this);
|
||||
}
|
||||
|
||||
void KernelCore::InitializeCores() {
|
||||
impl->InitializeCores();
|
||||
}
|
||||
|
||||
void KernelCore::Shutdown() {
|
||||
impl->Shutdown();
|
||||
}
|
||||
@@ -486,12 +497,17 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const {
|
||||
}
|
||||
|
||||
void KernelCore::InvalidateAllInstructionCaches() {
|
||||
auto& threads = GlobalScheduler().GetThreadList();
|
||||
for (auto& thread : threads) {
|
||||
if (!thread->IsHLEThread()) {
|
||||
auto& arm_interface = thread->ArmInterface();
|
||||
arm_interface.ClearInstructionCache();
|
||||
for (auto& physical_core : impl->cores) {
|
||||
physical_core.ArmInterface().ClearInstructionCache();
|
||||
}
|
||||
}
|
||||
|
||||
void KernelCore::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) {
|
||||
for (auto& physical_core : impl->cores) {
|
||||
if (!physical_core.IsInitialized()) {
|
||||
continue;
|
||||
}
|
||||
physical_core.ArmInterface().InvalidateCacheRange(addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,9 @@ public:
|
||||
/// Resets the kernel to a clean slate for use.
|
||||
void Initialize();
|
||||
|
||||
/// Initializes the CPU cores.
|
||||
void InitializeCores();
|
||||
|
||||
/// Clears all resources in use by the kernel instance.
|
||||
void Shutdown();
|
||||
|
||||
@@ -153,6 +156,8 @@ public:
|
||||
|
||||
void InvalidateAllInstructionCaches();
|
||||
|
||||
void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
|
||||
|
||||
/// Adds a port to the named port table
|
||||
void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port);
|
||||
|
||||
|
||||
@@ -222,9 +222,9 @@ public:
|
||||
|
||||
public:
|
||||
constexpr MemoryBlock() = default;
|
||||
constexpr MemoryBlock(VAddr addr, std::size_t num_pages, MemoryState state,
|
||||
MemoryPermission perm, MemoryAttribute attribute)
|
||||
: addr{addr}, num_pages(num_pages), state{state}, perm{perm}, attribute{attribute} {}
|
||||
constexpr MemoryBlock(VAddr addr_, std::size_t num_pages_, MemoryState state_,
|
||||
MemoryPermission perm_, MemoryAttribute attribute_)
|
||||
: addr{addr_}, num_pages(num_pages_), state{state_}, perm{perm_}, attribute{attribute_} {}
|
||||
|
||||
constexpr VAddr GetAddress() const {
|
||||
return addr;
|
||||
|
||||
@@ -57,8 +57,8 @@ public:
|
||||
private:
|
||||
void MergeAdjacent(iterator it, iterator& next_it);
|
||||
|
||||
const VAddr start_addr;
|
||||
const VAddr end_addr;
|
||||
[[maybe_unused]] const VAddr start_addr;
|
||||
[[maybe_unused]] const VAddr end_addr;
|
||||
|
||||
MemoryBlockTree memory_block_tree;
|
||||
};
|
||||
|
||||
@@ -670,6 +670,11 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
if ((prev_perm & MemoryPermission::Execute) != (perm & MemoryPermission::Execute)) {
|
||||
// Memory execution state is changing, invalidate CPU cache range
|
||||
system.InvalidateCpuInstructionCacheRange(addr, size);
|
||||
}
|
||||
|
||||
const std::size_t num_pages{size / PageSize};
|
||||
const OperationType operation{(perm & MemoryPermission::Execute) != MemoryPermission::None
|
||||
? OperationType::ChangePermissionsAndRefresh
|
||||
|
||||
@@ -4,21 +4,43 @@
|
||||
|
||||
#include "common/spin_lock.h"
|
||||
#include "core/arm/cpu_interrupt_handler.h"
|
||||
#include "core/arm/dynarmic/arm_dynarmic_32.h"
|
||||
#include "core/arm/dynarmic/arm_dynarmic_64.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/physical_core.h"
|
||||
#include "core/hle/kernel/scheduler.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler,
|
||||
Core::CPUInterruptHandler& interrupt_handler)
|
||||
: interrupt_handler{interrupt_handler},
|
||||
core_index{id}, scheduler{scheduler}, guard{std::make_unique<Common::SpinLock>()} {}
|
||||
PhysicalCore::PhysicalCore(std::size_t core_index, Core::System& system,
|
||||
Kernel::Scheduler& scheduler, Core::CPUInterrupts& interrupts)
|
||||
: core_index{core_index}, system{system}, scheduler{scheduler},
|
||||
interrupts{interrupts}, guard{std::make_unique<Common::SpinLock>()} {}
|
||||
|
||||
PhysicalCore::~PhysicalCore() = default;
|
||||
|
||||
void PhysicalCore::Initialize([[maybe_unused]] bool is_64_bit) {
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
auto& kernel = system.Kernel();
|
||||
if (is_64_bit) {
|
||||
arm_interface = std::make_unique<Core::ARM_Dynarmic_64>(
|
||||
system, interrupts, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index);
|
||||
} else {
|
||||
arm_interface = std::make_unique<Core::ARM_Dynarmic_32>(
|
||||
system, interrupts, kernel.IsMulticore(), kernel.GetExclusiveMonitor(), core_index);
|
||||
}
|
||||
#else
|
||||
#error Platform not supported yet.
|
||||
#endif
|
||||
}
|
||||
|
||||
void PhysicalCore::Run() {
|
||||
arm_interface->Run();
|
||||
}
|
||||
|
||||
void PhysicalCore::Idle() {
|
||||
interrupt_handler.AwaitInterrupt();
|
||||
interrupts[core_index].AwaitInterrupt();
|
||||
}
|
||||
|
||||
void PhysicalCore::Shutdown() {
|
||||
@@ -26,18 +48,18 @@ void PhysicalCore::Shutdown() {
|
||||
}
|
||||
|
||||
bool PhysicalCore::IsInterrupted() const {
|
||||
return interrupt_handler.IsInterrupted();
|
||||
return interrupts[core_index].IsInterrupted();
|
||||
}
|
||||
|
||||
void PhysicalCore::Interrupt() {
|
||||
guard->lock();
|
||||
interrupt_handler.SetInterrupt(true);
|
||||
interrupts[core_index].SetInterrupt(true);
|
||||
guard->unlock();
|
||||
}
|
||||
|
||||
void PhysicalCore::ClearInterrupt() {
|
||||
guard->lock();
|
||||
interrupt_handler.SetInterrupt(false);
|
||||
interrupts[core_index].SetInterrupt(false);
|
||||
guard->unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
#include "core/arm/arm_interface.h"
|
||||
|
||||
namespace Common {
|
||||
class SpinLock;
|
||||
}
|
||||
@@ -16,7 +19,6 @@ class Scheduler;
|
||||
} // namespace Kernel
|
||||
|
||||
namespace Core {
|
||||
class ARM_Interface;
|
||||
class CPUInterruptHandler;
|
||||
class ExclusiveMonitor;
|
||||
class System;
|
||||
@@ -26,17 +28,24 @@ namespace Kernel {
|
||||
|
||||
class PhysicalCore {
|
||||
public:
|
||||
PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler,
|
||||
Core::CPUInterruptHandler& interrupt_handler);
|
||||
PhysicalCore(std::size_t core_index, Core::System& system, Kernel::Scheduler& scheduler,
|
||||
Core::CPUInterrupts& interrupts);
|
||||
~PhysicalCore();
|
||||
|
||||
PhysicalCore(const PhysicalCore&) = delete;
|
||||
PhysicalCore& operator=(const PhysicalCore&) = delete;
|
||||
|
||||
PhysicalCore(PhysicalCore&&) = default;
|
||||
PhysicalCore& operator=(PhysicalCore&&) = default;
|
||||
PhysicalCore& operator=(PhysicalCore&&) = delete;
|
||||
|
||||
/// Initialize the core for the specified parameters.
|
||||
void Initialize(bool is_64_bit);
|
||||
|
||||
/// Execute current jit state
|
||||
void Run();
|
||||
|
||||
void Idle();
|
||||
|
||||
/// Interrupt this physical core.
|
||||
void Interrupt();
|
||||
|
||||
@@ -49,6 +58,18 @@ public:
|
||||
// Shutdown this physical core.
|
||||
void Shutdown();
|
||||
|
||||
bool IsInitialized() const {
|
||||
return arm_interface != nullptr;
|
||||
}
|
||||
|
||||
Core::ARM_Interface& ArmInterface() {
|
||||
return *arm_interface;
|
||||
}
|
||||
|
||||
const Core::ARM_Interface& ArmInterface() const {
|
||||
return *arm_interface;
|
||||
}
|
||||
|
||||
bool IsMainCore() const {
|
||||
return core_index == 0;
|
||||
}
|
||||
@@ -70,10 +91,12 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Core::CPUInterruptHandler& interrupt_handler;
|
||||
std::size_t core_index;
|
||||
const std::size_t core_index;
|
||||
Core::System& system;
|
||||
Kernel::Scheduler& scheduler;
|
||||
Core::CPUInterrupts& interrupts;
|
||||
std::unique_ptr<Common::SpinLock> guard;
|
||||
std::unique_ptr<Core::ARM_Interface> arm_interface;
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user