Compare commits

..

170 Commits

Author SHA1 Message Date
fearlessTobi
61db581c62 Port #3758 from Citra 2018-07-28 13:20:21 +02:00
bunnei
e1d66ea794 Merge pull request #842 from bunnei/audio-core
Initial implementation of Audio Core
2018-07-27 20:25:32 -07:00
bunnei
f1c519f2cb audout: Implement IAudioOut interface with AudioCore. 2018-07-27 22:55:39 -04:00
bunnei
2a742229ee core: Add AudioCore to global state. 2018-07-27 22:33:37 -04:00
bunnei
ab756fd068 audio_core: Add initial code for keeping track of audout state. 2018-07-27 22:33:31 -04:00
bunnei
abb4894188 Merge pull request #696 from DarkLordZach/romfs
RomFS Extraction
2018-07-27 19:10:05 -07:00
Zach Hilman
906d785c73 RomFS Extraction 2018-07-27 18:14:03 -04:00
bunnei
0191a1e526 Merge pull request #845 from lioncash/nfc
service: Add nfc services
2018-07-27 14:29:27 -07:00
bunnei
2128ab2d21 Merge pull request #839 from FearlessTobi/actually-port-3594
Port #3594 from Citra: "citra_qt: Add Continue/Pause & Toggle Speed Limit hotkeys"
2018-07-27 13:06:56 -07:00
bunnei
833ebbb626 Merge pull request #844 from lioncash/lbl
service: Add the lbl service
2018-07-27 13:06:11 -07:00
bunnei
d2749ef0ed Merge pull request #841 from lioncash/btdrv
service: Add the btdrv service
2018-07-27 13:05:36 -07:00
Lioncash
50dadc33e3 service/nfc: Implement Create[x]Interface functions
These simply return the respective interface.
2018-07-27 15:12:08 -04:00
Lioncash
04d144aa40 service: Add nfc services
Adds the skeleton of the nfc service based off the information provided
on Switch Brew.
2018-07-27 14:50:24 -04:00
Lioncash
ea8dd8b650 service/lbl: Implement EnableVrMode, DisableVrMode and GetVrMode
Implements these functions according to the information available on
Switch Brew.
2018-07-27 14:20:42 -04:00
Lioncash
c2c543e8f7 service: Add the lbl service
Adds the skeleton of the lbl service based off the information provided
by Switch Brew.
2018-07-27 14:20:07 -04:00
bunnei
dc4e5f9159 Merge pull request #837 from lioncash/priv
kernel/timer: Make data members private where applicable
2018-07-27 07:18:50 -07:00
bunnei
e247bd577c Merge pull request #833 from lioncash/irs
service/hid: Add missing services
2018-07-27 07:18:29 -07:00
Lioncash
f49248437e service: Add the btdrv service
Adds the skeleton for the btdrv service based off the information provided by Switch Brew
2018-07-26 18:06:17 -04:00
Lioncash
1121622dc1 service/hid: Add the hidbus, hid:dbg, hid:sys, and hid:tmp services 2018-07-26 15:05:42 -04:00
Lioncash
7550c2c866 service/hid: Add the xcd:sys service 2018-07-26 15:05:42 -04:00
Lioncash
82cb5f030d service/hid: Add irs services 2018-07-26 15:05:24 -04:00
bunnei
ec2b7cdb1d Merge pull request #836 from FearlessTobi/port-3594
Port #3665 from Citra: "frontend: Log Citra version"
2018-07-26 12:04:30 -07:00
bunnei
f1fbb476df Merge pull request #835 from FearlessTobi/port-minor-prs
Port #3641 and #3702 from Citra (Small changes to default_ini and gitignore)
2018-07-26 12:03:56 -07:00
bunnei
8440b814bc Merge pull request #834 from lioncash/grc
service: Add the grc:c service
2018-07-26 12:03:30 -07:00
bunnei
41d7b020a8 Merge pull request #832 from lioncash/nim
service: Add the nim services
2018-07-26 12:02:29 -07:00
bunnei
e4191b624c Merge pull request #831 from lioncash/ldn
service: Add ldn services
2018-07-26 11:52:42 -07:00
bunnei
40eb243f86 Merge pull request #830 from lioncash/socket
service/sockets: Add missing socket services
2018-07-26 11:51:11 -07:00
bunnei
e013fdc2b2 Merge pull request #808 from lioncash/mem-dedup
video_core/memory_manager: Avoid repeated unnecessary page slot lookups
2018-07-26 11:50:27 -07:00
bunnei
5a27f4e4cc Merge pull request #829 from Subv/r16f_rt
GPU: Allow using R16F as a render target format.
2018-07-26 11:44:37 -07:00
fearlessTobi
18c2c96927 Port #3594 from Citra 2018-07-26 16:09:52 +02:00
Lioncash
b28af1f6c9 service: Add the grc:c service
Adds the basic skeleton for the grc:c service based off the information
provided by Switch Brew.
2018-07-26 09:53:58 -04:00
Subv
f85cff0f48 GPU: Allow using R16F as a render target format. 2018-07-26 08:52:21 -05:00
Lioncash
0cd843151f kernel/timer: Make data members private where applicable
Instead, we can just expose functions that return the queryable state
instead of letting anything modify it.
2018-07-26 09:51:44 -04:00
fearlessTobi
6f05a57712 Port #3665 from Citra 2018-07-26 15:51:14 +02:00
fearlessTobi
9d2a1c6f12 Port #3702 from Citra 2018-07-26 15:35:24 +02:00
fearlessTobi
7a2acc86e6 Port #3641 from Citra 2018-07-26 15:35:10 +02:00
Lioncash
f916611e32 service: Add the nim services
Adds the skeleton for the nim services based off information from Switch
Brew.
2018-07-26 02:47:06 -04:00
Lioncash
8781beaf0d service: Add ldn services
Adds ldn services based off information provided by Switch Brew.
2018-07-26 01:48:06 -04:00
bunnei
57cd80c410 Merge pull request #827 from lioncash/log
service/lm: Minor changes
2018-07-25 22:30:43 -07:00
bunnei
31642ae2ee Merge pull request #825 from greggameplayer/R16_G16
Implement R16_G16
2018-07-25 22:30:25 -07:00
Lioncash
3f5dfc4d96 service/sockets: Add ethc:c and ethc:i services 2018-07-26 01:07:21 -04:00
Lioncash
165e7645e1 service/sockets: Add missing bsdcfg socket service 2018-07-26 01:00:15 -04:00
Sebastian Valle
1958d07d7d Merge pull request #828 from lioncash/ldr
service: Add ldr services
2018-07-25 23:44:13 -05:00
Sebastian Valle
8ac52c6b56 Merge pull request #826 from lioncash/erpt
service: Add erpt and eupld services
2018-07-25 23:43:47 -05:00
Sebastian Valle
0e05f98be2 Merge pull request #823 from lioncash/nifm
service/nifm: Deduplicate interface code
2018-07-25 23:43:03 -05:00
Lioncash
3fb124961e service: Add ldr services
Adds the skeleton for the ldr-related services based off the information
provided on Switch Brew.
2018-07-25 23:11:03 -04:00
Lioncash
91d86df920 lm: Move LM's class declaration into the cpp file
This isn't used directly outside of this translation unit, so we can
hide it from external use.
2018-07-25 22:40:16 -04:00
Lioncash
6f4d3d8163 lm: Amend names of Initialize() in Logger and Initialize() in LM
Amends these to match the information on Switch Brew.
2018-07-25 22:39:39 -04:00
Lioncash
8650be1020 lm: Add missing function entry to Logger's function table 2018-07-25 22:26:32 -04:00
Lioncash
7458e71f24 service: Add eupld services
Adds the skeleton for the eupld services based off information on Switch
Brew.
2018-07-25 22:13:43 -04:00
Lioncash
821f2c03cb service: Add the erpt services
Adds the basic skeleton of the erpt service based off information on
Switch Brew.
2018-07-25 22:13:39 -04:00
bunnei
b0adb9a3d9 Merge pull request #824 from lioncash/nvdrv
service/nvdrv: Minor changes
2018-07-25 19:02:08 -07:00
bunnei
851089b482 Merge pull request #822 from lioncash/pm
service: Add pm services
2018-07-25 19:01:28 -07:00
Unknown
4672a01cbf Implement R16_G16
correct trailing white spaces


Delete tabs


correct placement
Add RG16F & RG16UI & RG16I & RG16S PixelFormats
Return correct data according to changes done previously
correct PixelFormat declaration
correct coding style error
correct coding style error part 2
correct RG16S Declaration error
correct alignment
2018-07-26 02:01:29 +02:00
Mat M
d245610939 Merge pull request #820 from lioncash/es
service: Add the es service
2018-07-25 18:51:59 -04:00
Mat M
19b5ae5a25 Merge pull request #821 from lioncash/wait
wait_tree: Add missing switch case for WaitTreeThread::GetText()
2018-07-25 18:45:01 -04:00
bunnei
c88382517c Merge pull request #819 from Subv/srgb
GPU: Use the right texture format for sRGBA framebuffers.
2018-07-25 14:47:26 -07:00
Lioncash
f9951352f6 service/nvdrv: Take std::string in Open() by const reference
Avoids copies from being made, since the string is only ever used for
lookup, the data is never transfered anywhere.

Ideally, we'd use a std::string_view here, but devices is a
std::unordered_map, not a std::map, so we can't use heterogenous lookup
here.
2018-07-25 17:37:43 -04:00
Lioncash
a2cd07d094 service/nvdrv: Use std::move where applicable
Avoids unnecessary reference count increments and decrements.

In one case, we don't need to make a shared_ptr copy at all,
just to call a member function.
2018-07-25 17:31:08 -04:00
Lioncash
85ed42a1d2 service/nifm: Deduplicate interface code
Rather than having the same code for each nifm service variant, we can
centralize it on one class and get rid of a bit of extra code.
2018-07-25 17:18:41 -04:00
Lioncash
c664f8a257 service: Add pm services
Adds the skeleton for the process management services based off
information on Switch Brew.
2018-07-25 16:57:16 -04:00
Lioncash
2474340684 wait_tree: Add missing switch case for WaitTreeThread::GetText()
We were missing the enum entry for WaitIPC
2018-07-25 15:50:41 -04:00
Lioncash
4175712976 service: Add the es service
Adds the skeleton for the ETicket service based off the information on
Switch Brew
2018-07-25 15:36:55 -04:00
Mat M
1e4935c3a0 Merge pull request #801 from lioncash/time
time: Add the time:a service
2018-07-25 15:08:33 -04:00
Mat M
d3fd0351a7 Merge pull request #804 from lioncash/log
svc: Log parameters in SetMemoryAttribute()
2018-07-25 14:43:24 -04:00
Lioncash
3c1cb3b11e time: Add the time:a service
Given we already have time:s and time:u, we should also have time:a
2018-07-25 14:42:04 -04:00
bunnei
657bd113e3 Merge pull request #803 from MerryMage/core_timing_util
core_timing: Split off utility functions into core_timing_util
2018-07-25 11:09:31 -07:00
bunnei
52cb5dcf0f Merge pull request #802 from lioncash/unreach
wait_tree: Silence warning about all code paths not returning a value
2018-07-25 11:08:44 -07:00
bunnei
5c42cadbc9 Merge pull request #800 from lioncash/set
set_sys: Implement SetColorSetId()
2018-07-25 10:25:29 -07:00
bunnei
f445464baf Merge pull request #813 from Subv/z24_s8_tex
GPU: Allow the use of Z24S8 as a texture format.
2018-07-25 10:25:01 -07:00
Subv
c5b838aeef GPU: Use the right texture format for sRGBA framebuffers. 2018-07-25 09:52:39 -05:00
Subv
ee8123bf13 GPU: Allow the use of Z24S8 as a texture format. 2018-07-25 09:41:24 -05:00
bunnei
0686183c3e Merge pull request #816 from Subv/z32_s8
GPU: Implemented the Z32_S8_X24 depth buffer format.
2018-07-25 07:37:00 -07:00
bunnei
af787744ab Merge pull request #815 from Subv/z32f_tex
GPU: Allow using Z32 as a texture format.
2018-07-25 07:33:09 -07:00
bunnei
704824d50a Merge pull request #814 from Subv/rt_r8
GPU: Allow the usage of R8 as a render target format.
2018-07-25 07:32:18 -07:00
bunnei
184324c2f0 Merge pull request #818 from MerryMage/dynarmic
externals: Update dynarmic to 98e2380
2018-07-25 07:30:50 -07:00
MerryMage
abc5b3347d externals: Update dynarmic to 98e2380
98e2380 fuzz_with_unicorn: Disable testing of FDIV
041b7d5 block_of_code: Add ABI_PARAMS array
2a2371c A64: Implement MLA, MLS (by element), vector single/double variant
78c640a A64: Implement FMLS (vector), single/double variant
b6b6993 emit_x64_vector_floating_point: Specify NanHandler::function_type explicitly
4b9d12a emit_x64_vector_floating_point: ChooseOnFsize arguments maybe_unused
b1e3616 IR: Implement FPVectorNeg
4343612 A64: Implement FMLA (vector), single/double variant
93eeb25 IR: Implement FPVectorMulAdd
57e5c7e emit_x64_vector_floating_point: Standardize naming scheme
bcb9e41 emit_x64_floating_point: Simplify indexers
83aa585 emit_x64_vector_floating_point: Simplify EmitVectorOperation*
f4087c8 mp: rename mp.h to mp/function_info.h
1864090 emit_x64_vector: Slightly improve ArithmeticShiftRightByte
e048441 emit_x64_vector: Simplify VectorShuffleImpl
ff025e8 IR: Implement A64OrQC
6fac68d A64: Implement UQSHRN, UQRSHRN (vector)
5a8d9c3 emit_x64_vector: -0x80000000 isn't -0x80000000
759289e A64: Implement UQXTN (vector)
2a96281 emit_x64_vector: Fix non-SSE4.1 saturated narrowing reconstruction comparison
0682353 A64: Implement SQXTN (vector)
6c5229e emit_x64_vector: packusdw reqiures SSE4.1
158d9b1 A64: Implement SQSHRUN, SQRSHRUN (vector)
f886013 simd_shift_by_immediate: Simplify ShiftRight
d9b59c6 A64: Implement SQXTUN
50fe28b microinstruction: Reorganize FPSCR related instruction queries
d9d036a microinstruction: Add missing FP scalar opcodes to ReadsFromFPSCR() and WritesToFPSCR()
db96163 u128: Make Bit() a const-qualified member function
f7052ae A64: Implement FRSQRTS (vector), single/double variant
0925ef6 A64: Implement FRSQRTE (vector), single/double variant
f4cbbe3 A64: Implement FRSQRTS (scalar), single/double variant
4ef864e IR: Implement FPRSqrtStepFused
9dffeeb fp: Implement FPRSqrtStepFused
aa04556 fp: Implement FPNeg
cbde1c5 process_nan: Add two operand variant
1ec2663 A64: Implement FMAXP, FMINP, FMAXNMP and FMINNMP's scalar double/single-precision variant
027ddf9 emit_x64_floating_point: Fixup special NaN case in FMA FPMulAdd implementation
75a9f77 fp: Use a forward declaration in fused.h
1ee1630 u128: Implement comparison operators in terms of one another
3b77f48 tests: Print cpu info
bed3cc0 u128: StickyLogicalShiftRight requires special-casing for amount == 64
15d04f4 A64: Implement FMLA and FMLS (by element)'s double/single-precision scalar variant
7cfccdf A64: Implement FMUL (by element)'s scalar double/single-precision variant
7d2d62e (fpmuladd) emit_x64_floating_point: Implement accurate fallback for FPMulAdd{32,64}
a599eac fp: Implement FPMulAdd
d70b90e process_nan: Add FPProcessNaNs3
38ef0e0 block_of_code: Add SysV ABI fifth and sixth parameters
8e2ff56 u128: Add StickyLogicalShiftRight
3b337df u128: Add Multiply64To128
8219075 u128: Add u128::Bit
a574dcb u128: Add comparison operators
391d6d4 unpacked: Use ResidualErrorOnRightShift in FPRoundBase
5e0cf9c fp: Remove MantissaT
8c0a84c FPRSqrtEstimate: Improve documentation of RecipSqrtEstimate
c41d855 FPRSqrtEstimate: Deduplicate array bounds
4cf055b A64: Implement FMAXV, FMINV, FMAXNMV, and FMINNMV
bf24f0f FPRSqrtEstimate: Use forward declarations where applicable
206230e translate: Return by bool in helpers where applicable
346b725 Simplify fallback case for EmitVectorSetElement64()
2c34e1d emit_x64_floating_point: s/Esimate/Estimate/
5213fb6 simd_scalar_two_register_misc: Implement FRSQRTE, scalar variant
7ed089f IR: Implement FPRSqrtEstimate
cd2e286 simd_vector_x_indexed_element: Implement FMUL (by element), vector variant
2018-07-25 14:26:51 +01:00
bunnei
a6ea6febc9 Merge pull request #809 from lioncash/rasterizer
gl_rasterizer: Minor cleanup
2018-07-24 19:31:34 -07:00
bunnei
e0106a7d68 Merge pull request #811 from Subv/code_address_assert
GPU: Remove the assert that required the CODE_ADDRESS to be 0.
2018-07-24 19:31:09 -07:00
Subv
daf2504d31 GPU: Implemented the Z32_S8_X24 depth buffer format. 2018-07-24 20:41:40 -05:00
Subv
f747a7e35d GPU: Allow using Z32 as a texture format. 2018-07-24 19:54:23 -05:00
Subv
4f574201ea GPU: Allow the usage of R8 as a render target format. 2018-07-24 19:49:36 -05:00
bunnei
340771ccd7 Merge pull request #806 from lioncash/friend
friend: Deduplicate interfaces
2018-07-24 17:42:16 -07:00
bunnei
5d4ad999cf Merge pull request #810 from Subv/r16
GPU: Implemented the R16 and R16F texture formats.
2018-07-24 17:41:02 -07:00
bunnei
ea0bc8c002 Merge pull request #805 from lioncash/sign
svc: Resolve sign comparison warnings in WaitSynchronization()
2018-07-24 12:50:03 -07:00
bunnei
933c9ee853 Merge pull request #807 from lioncash/unused
deconstructed_rom_directory: Remove unused FindRomFS() function
2018-07-24 12:49:40 -07:00
Subv
8f2c4191ab GPU: Remove the assert that required the CODE_ADDRESS to be 0.
Games usually just leave it at 0 but nouveau sets it to something else. This already works fine, the assert is useless.
2018-07-24 13:54:12 -05:00
Subv
4cc1e180ec GPU: Implemented the R16 and R16F texture formats. 2018-07-24 13:39:16 -05:00
Lioncash
0162f8b3a7 gl_rasterizer: Replace magic number with GL_INVALID_INDEX in SetupConstBuffers()
This is just the named constant that OpenGL provides, so we can use that
instead of using a literal -1
2018-07-24 12:24:49 -04:00
Lioncash
16139ed53b gl_rasterizer: Use std::string_view instead of std::string when checking for extensions
We can avoid heap allocations here by just using a std::string_view
instead of performing unnecessary copying of the string data.
2018-07-24 12:10:37 -04:00
Lioncash
b5eb3905cd gl_rasterizer: Use in-class member initializers where applicable
We can just assign to the members directly in these cases.
2018-07-24 12:08:12 -04:00
Lioncash
bf608f125e video_core/memory_manager: Replace a loop with std::array's fill() function in PageSlot()
We already have a function that does what this code was doing, so let's
use that instead.
2018-07-24 11:56:30 -04:00
Lioncash
d71e19fd75 video_core/memory_manager: Avoid repeated unnecessary page slot lookups
We don't need to keep calling the same function over and over again in a
loop, especially when the behavior is slightly non-trivial. We can just
keep a reference to the looked up location and do all the checking and
assignments based off it instead.
2018-07-24 11:19:54 -04:00
Lioncash
4cf2185e81 deconstructed_rom_directory: Remove unused FindRomFS() function 2018-07-24 10:54:07 -04:00
Lioncash
07c2d057bd friend: Add friend:m, friend:s, and friend:v services
Given we already have friend:a and friend:u, we should add the remaining
services as well.
2018-07-24 10:26:01 -04:00
Lioncash
9539a1eadd friend/interface: Add missing CreateDaemonSuspendSessionService() to the function handler table 2018-07-24 10:24:16 -04:00
Lioncash
77daef44b0 friend: Deduplicate interfaces 2018-07-24 10:21:51 -04:00
Lioncash
c73410bf2c svc: Resolve sign comparison warnings in WaitSynchronization()
The loop's induction variable was signed, but we were comparing against
an unsigned variable.
2018-07-24 09:55:17 -04:00
Lioncash
8e8e906432 svc: Log parameters in SetMemoryAttribute()
Provides slightly more context than only logging out the address value.
2018-07-24 09:46:46 -04:00
bunnei
316c994f55 Merge pull request #798 from lioncash/const
arm_dynarmic: Make MakeJit() a const member function
2018-07-24 04:48:06 -07:00
bunnei
23e85b6b9f Merge pull request #797 from lioncash/explicit
core: Make converting constructors explicit where applicable
2018-07-24 04:47:26 -07:00
bunnei
1cbf7ac6ea Merge pull request #795 from lioncash/decl
apm/interface: Remove redundant declaration of InstallInterfaces()
2018-07-24 04:46:41 -07:00
bunnei
0f830d08f1 Merge pull request #799 from Subv/tex_r32f
GPU: Implement texture format R32F.
2018-07-24 04:46:07 -07:00
bunnei
d092ea0870 Merge pull request #794 from lioncash/ref
mutex: Pass SharedPtr to GetHighestPriorityMutexWaitingThread() by reference
2018-07-24 04:45:34 -07:00
bunnei
b70f757913 Merge pull request #796 from bunnei/gl-uint
maxwell_to_gl: Implement VertexAttribute::Type::UnsignedInt.
2018-07-24 04:44:56 -07:00
bunnei
54af9c206a Merge pull request #789 from bunnei/tex-wrap-border
maxwell_to_gl: Implement Texture::WrapMode::Border.
2018-07-24 04:44:37 -07:00
Lioncash
a61124a9e7 time: Simplify interface creation
We can use one instance of the interface instead of duplicating code.
2018-07-24 06:21:27 -04:00
MerryMage
44646e2ea0 core_timing: Split off utility functions into core_timing_util 2018-07-24 11:03:24 +01:00
MerryMage
b8459d2778 CMakeLists: Sort filenames 2018-07-24 11:02:53 +01:00
Lioncash
9d2cacdc9e wait_tree: Silence warning about all code paths not returning a value
If code execution hits this spot, something has gone very wrong, so mark
the path as unreachable. This silences a warning on MSVC.
2018-07-24 04:06:55 -04:00
Lioncash
63c605c04a set_sys: Implement SetColorSetId() 2018-07-24 00:48:16 -04:00
Lioncash
76f191ce36 ipc_helper: Add helper member function for popping enum values to RequestParser 2018-07-24 00:47:51 -04:00
bunnei
2f029577c7 Merge pull request #793 from lioncash/priv
ipc_helpers: Make member variables of ResponseBuilder private
2018-07-23 21:23:27 -07:00
bunnei
bc5b65a1b0 Merge pull request #785 from lioncash/fs
partition_filesystem: Use std::move where applicable
2018-07-23 20:36:59 -07:00
bunnei
69c45ce71c gl_rasterizer: Implement texture border color. 2018-07-23 23:34:42 -04:00
bunnei
6b3e54621f maxwell_to_gl: Implement Texture::WrapMode::Border. 2018-07-23 23:34:41 -04:00
Subv
ccc42702b5 GPU: Implement texture format R32F. 2018-07-23 22:21:31 -05:00
Lioncash
7d124ec82b arm_dynarmic: Make MakeJit() a const member function
This functions doesn't modify instance state, so it can be a made a
const member function.
2018-07-23 23:19:37 -04:00
Lioncash
1d755abce4 core: Make converting constructors explicit where applicable
Avoids unwanted implicit conversions. Thankfully, given the large amount
of cleanup in past PRs, only this tiny amount is left over to cover.
2018-07-23 23:13:22 -04:00
bunnei
1ff3bea6c7 Merge pull request #791 from bunnei/rg32f-rgba32f-bgra8
gl_rasterizer_cache: Implement formats BGRA8_UNORM/RGBA32_FLOAT/RG32_FLOAT
2018-07-23 20:13:19 -07:00
bunnei
2ff86f5765 maxwell_to_gl: Implement VertexAttribute::Type::UnsignedInt. 2018-07-23 23:12:14 -04:00
bunnei
92304181d5 Merge pull request #792 from lioncash/retval
gl_shader_decompiler: Correct return value of WriteTexsInstruction()
2018-07-23 20:06:48 -07:00
Lioncash
8b83adfed6 apm/interface: Remove redundant declaration of InstallInterfaces()
This is already declared in apm/apm.h
2018-07-23 23:01:04 -04:00
Lioncash
42b5158c96 mutex: Pass SharedPtr to GetHighestPriorityMutexWaitingThread() by reference
The pointed to thread's members are simply observed in this case, so we
don't need to copy it here.
2018-07-23 22:54:35 -04:00
bunnei
47ac369180 Merge pull request #790 from bunnei/shader-print-instr
gl_shader_decompiler: Print instruction value in shader comments.
2018-07-23 19:48:47 -07:00
bunnei
c2b4ff5d48 Merge pull request #788 from bunnei/shader-check-zero
gl_shader_decompiler: Check if SetRegister result is ZeroIndex.
2018-07-23 19:44:05 -07:00
Zach Hilman
59cb258409 VFS Regression and Accuracy Fixes (#776)
* Regression and Mode Fixes

* Review Fixes

* string_view correction

* Add operator& for FileSys::Mode

* Return std::string from SanitizePath

* Farming Simulator Fix

* Use != With mode operator&
2018-07-23 19:40:35 -07:00
Lioncash
22fd3f0026 hle_ipc: Make constructors explicit where applicable 2018-07-23 22:40:24 -04:00
Lioncash
33e2033af5 gl_shader_decompiler: Correct return value of WriteTexsInstruction()
This should be returning void, not a std::string
2018-07-23 22:31:58 -04:00
Lioncash
2a1daf8f83 ipc_helpers: Make member variables of ResponseBuilder private
These aren't used externally at all, so they can be made private.
2018-07-23 22:29:07 -04:00
bunnei
f6657bc8d7 Merge pull request #787 from bunnei/tlds
gl_shader_decompiler: Implement shader instruction TLDS.
2018-07-23 19:14:01 -07:00
bunnei
25635907a2 Merge pull request #786 from lioncash/exclusive
exclusive_monitor: Use consistent type alias for u64
2018-07-23 19:11:05 -07:00
bunnei
84cc5dd35d Merge pull request #784 from lioncash/loader
loader: Minor cleanup
2018-07-23 19:08:12 -07:00
bunnei
1ce5e04be8 Merge pull request #783 from lioncash/linker
linker: Remove unused parameter from WriteRelocations()
2018-07-23 19:07:22 -07:00
bunnei
10dd03dec5 Merge pull request #782 from lioncash/file
loader/nro: Minor changes
2018-07-23 19:06:30 -07:00
bunnei
9505283989 gl_shader_decompiler: Implement shader instruction TLDS. 2018-07-23 22:02:51 -04:00
bunnei
f6f6f3811e Merge pull request #781 from lioncash/decl
gl_shader_decompiler: Simplify GetCommonDeclarations()
2018-07-23 18:30:23 -07:00
bunnei
52ec1840f5 Merge pull request #780 from lioncash/move
vi: Minor changes
2018-07-23 18:29:11 -07:00
bunnei
e0b6771e25 Merge pull request #779 from lioncash/shared
hle: Remove unused config_mem and shared_page source files
2018-07-23 18:28:45 -07:00
bunnei
a27c0099ed gl_rasterizer_cache: Implement RenderTargetFormat RG32_FLOAT. 2018-07-23 21:22:54 -04:00
bunnei
3a19c1098d gl_rasterizer_cache: Implement RenderTargetFormat RGBA32_FLOAT. 2018-07-23 21:22:53 -04:00
bunnei
bcc184acfa gl_rasterizer_cache: Implement RenderTargetFormat BGRA8_UNORM. 2018-07-23 21:22:44 -04:00
bunnei
89db8c2171 gl_rasterizer_cache: Add missing log statements. 2018-07-23 21:20:09 -04:00
bunnei
c4322ce87e gl_shader_decompiler: Print instruction value in shader comments. 2018-07-23 21:11:05 -04:00
bunnei
81aa02424b gl_shader_decompiler: Check if SetRegister result is ZeroIndex. 2018-07-23 21:08:40 -04:00
Lioncash
e12c84d5c5 exclusive_monitor: Use consistent type alias for u64
Uses the same type aliases we use for virtual addresses, and converts
one lingering usage of std::array<uint64_t, 2> to u128 for consistency.
2018-07-23 20:54:57 -04:00
Lioncash
db48ebb9c9 partition_filesystem: Use std::move where applicable
Avoids copying a std::string instance and avoids unnecessary atomic
reference count incrementing and decrementing.
2018-07-23 20:27:11 -04:00
Lioncash
a147fa5825 loader: Remove unnecessary constructor call in IdentifyFile()
RealVfsFile inherits from VfsFile, the instance from std::make_shared is
already compatible with the function argument type, making the copy
constructor call unnecessary.
2018-07-23 17:44:58 -04:00
Lioncash
184c516182 linker: Remove unused parameter from WriteRelocations()
is_jump_relocation is never used within the function, so we can just
remove it.
2018-07-23 17:40:12 -04:00
Lioncash
1b4d0ac20e nro: Replace inclusion with a forward declaration
It's sufficient to use a forward declaration instead of a direct
inclusion here.
2018-07-23 17:29:02 -04:00
Lioncash
2b497e5830 nro: Make bracing consistent
Makes the code more uniform, and also braces cases where the body of an
unbraced conditional travels more than one line.
2018-07-23 17:24:29 -04:00
Lioncash
ac8133b9ee nro: Make constructor explicit
Makes it consistent with the other Apploader constructors, and prevents
implicit conversions.
2018-07-23 17:20:33 -04:00
Lioncash
1c16700372 nro: Remove unused forward declaration
This isn't used anywhere in the header.
2018-07-23 17:19:42 -04:00
bunnei
07e5319d55 Merge pull request #695 from DarkLordZach/nro-asset
NRO Assets and NACP File Format
2018-07-23 14:14:11 -07:00
bunnei
d787873b3b Merge pull request #778 from lioncash/log
set: Add missing log call in GetAvailableLanguageCodeCount()
2018-07-23 14:13:09 -07:00
Lioncash
3b88ce3dcb gl_shader_decompiler: Simplify GetCommonDeclarations() 2018-07-23 17:11:18 -04:00
Lioncash
1432912ae8 vi: Add std::is_trivially_copyable checks to Read and Write functions
It's undefined behavior to memcpy an object that isn't considered
trivially copyable, so put a compile-time check in to make sure this
doesn't occur.
2018-07-23 14:53:54 -04:00
Lioncash
344a0c91f2 vi: std::move std::vector in constructors where applicable
Allows avoiding unnecessary copies of the vector depending on the
calling code.

While we're at it, remove a redundant no-parameter base constructor call
2018-07-23 14:49:54 -04:00
Lioncash
cbe841c9c9 hle: Remove config_mem.h/.cpp
This is just an unused hold-over from citra, so we can get rid of this
to trim off an exposed global, among other things.
2018-07-23 12:57:34 -04:00
Lioncash
1f3889a290 hle: Remove shared_page.h/.cpp
This is a holdover from citra that's essentially unused.
2018-07-23 12:53:07 -04:00
Lioncash
e85308cd90 set: Add missing log call in GetAvailableLanguageCodeCount()
Forgot to include this in 22f448b632
2018-07-23 12:37:42 -04:00
bunnei
7138b99f21 Merge pull request #775 from lioncash/str
string_util: Minor changes
2018-07-23 09:34:41 -07:00
Zach Hilman
e8f641a52d NRO Assets and NACP file format
Cleanup

Review fixes
2018-07-23 12:34:26 -04:00
bunnei
a85366a40c Merge pull request #777 from lioncash/lang
set: Amend return value of GetAvailableLanguageCodes()
2018-07-23 09:34:08 -07:00
Lioncash
22f448b632 set: Implement GetAvailableLanguageCodeCount()
This just returns the size of the language code buffer.
2018-07-23 00:29:40 -04:00
Lioncash
37aeecd29f set: Correct return code size of value in GetAvailableLanguageCodes()
The return code should be 32-bit in size.
2018-07-23 00:29:22 -04:00
bunnei
e85a528bb9 Merge pull request #769 from bunnei/shader-mask-fixes
shader_bytecode: Implement other TEXS masks.
2018-07-22 18:03:31 -07:00
bunnei
a4b2af7382 Merge pull request #774 from Subv/atomic_signal
Kernel/SVC: Perform atomic accesses in SignalProcessWideKey as per the real kernel.
2018-07-22 12:26:03 -07:00
Subv
7841447cf0 Kernel/SVC: Perform atomic accesses in SignalProcessWideKey as per the real kernel. 2018-07-22 12:27:24 -05:00
bunnei
148a5bef7e shader_bytecode: Implement other TEXS masks. 2018-07-22 03:23:15 -04:00
147 changed files with 3612 additions and 1085 deletions

2
.gitignore vendored
View File

@@ -11,7 +11,7 @@ src/common/scm_rev.cpp
.idea/
.vs/
.vscode/
CMakeLists.txt.user
CMakeLists.txt.user*
# *nix related
# Common convention for backup or temporary files

View File

@@ -3,6 +3,7 @@ include_directories(.)
add_subdirectory(common)
add_subdirectory(core)
add_subdirectory(audio_core)
add_subdirectory(video_core)
add_subdirectory(input_common)
add_subdirectory(tests)

View File

@@ -0,0 +1,11 @@
add_library(audio_core STATIC
audio_out.cpp
audio_out.h
buffer.h
stream.cpp
stream.h
)
create_target_directory_groups(audio_core)
target_link_libraries(audio_core PUBLIC common core)

View File

@@ -0,0 +1,50 @@
// Copyright 2018 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "audio_core/audio_out.h"
#include "common/assert.h"
#include "common/logging/log.h"
namespace AudioCore {
/// Returns the stream format from the specified number of channels
static Stream::Format ChannelsToStreamFormat(int num_channels) {
switch (num_channels) {
case 1:
return Stream::Format::Mono16;
case 2:
return Stream::Format::Stereo16;
case 6:
return Stream::Format::Multi51Channel16;
}
LOG_CRITICAL(Audio, "Unimplemented num_channels={}", num_channels);
UNREACHABLE();
return {};
}
StreamPtr AudioOut::OpenStream(int sample_rate, int num_channels,
Stream::ReleaseCallback&& release_callback) {
streams.push_back(std::make_shared<Stream>(sample_rate, ChannelsToStreamFormat(num_channels),
std::move(release_callback)));
return streams.back();
}
std::vector<u64> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) {
return stream->GetTagsAndReleaseBuffers(max_count);
}
void AudioOut::StartStream(StreamPtr stream) {
stream->Play();
}
void AudioOut::StopStream(StreamPtr stream) {
stream->Stop();
}
bool AudioOut::QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<u8>&& data) {
return stream->QueueBuffer(std::make_shared<Buffer>(tag, std::move(data)));
}
} // namespace AudioCore

View File

@@ -0,0 +1,44 @@
// Copyright 2018 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <vector>
#include "audio_core/buffer.h"
#include "audio_core/stream.h"
#include "common/common_types.h"
namespace AudioCore {
using StreamPtr = std::shared_ptr<Stream>;
/**
* Represents an audio playback interface, used to open and play audio streams
*/
class AudioOut {
public:
/// Opens a new audio stream
StreamPtr OpenStream(int sample_rate, int num_channels,
Stream::ReleaseCallback&& release_callback);
/// Returns a vector of recently released buffers specified by tag for the specified stream
std::vector<u64> GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count);
/// Starts an audio stream for playback
void StartStream(StreamPtr stream);
/// Stops an audio stream that is currently playing
void StopStream(StreamPtr stream);
/// Queues a buffer into the specified audio stream, returns true on success
bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<u8>&& data);
private:
/// Active audio streams on the interface
std::vector<StreamPtr> streams;
};
} // namespace AudioCore

37
src/audio_core/buffer.h Normal file
View File

@@ -0,0 +1,37 @@
// Copyright 2018 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <vector>
#include "common/common_types.h"
namespace AudioCore {
/**
* Represents a buffer of audio samples to be played in an audio stream
*/
class Buffer {
public:
using Tag = u64;
Buffer(Tag tag, std::vector<u8>&& data) : tag{tag}, data{std::move(data)} {}
/// Returns the raw audio data for the buffer
const std::vector<u8>& GetData() const {
return data;
}
/// Returns the buffer tag, this is provided by the game to the audout service
Tag GetTag() const {
return tag;
}
private:
Tag tag;
std::vector<u8> data;
};
} // namespace AudioCore

103
src/audio_core/stream.cpp Normal file
View File

@@ -0,0 +1,103 @@
// Copyright 2018 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "audio_core/stream.h"
namespace AudioCore {
constexpr size_t MaxAudioBufferCount{32};
/// Returns the sample size for the specified audio stream format
static size_t SampleSizeFromFormat(Stream::Format format) {
switch (format) {
case Stream::Format::Mono16:
return 2;
case Stream::Format::Stereo16:
return 4;
case Stream::Format::Multi51Channel16:
return 12;
};
LOG_CRITICAL(Audio, "Unimplemented format={}", static_cast<u32>(format));
UNREACHABLE();
return {};
}
Stream::Stream(int sample_rate, Format format, ReleaseCallback&& release_callback)
: sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)} {
release_event = CoreTiming::RegisterEvent(
"Stream::Release", [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); });
}
void Stream::Play() {
state = State::Playing;
PlayNextBuffer();
}
void Stream::Stop() {
ASSERT_MSG(false, "Unimplemented");
}
s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
const size_t num_samples{buffer.GetData().size() / SampleSizeFromFormat(format)};
return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
}
void Stream::PlayNextBuffer() {
if (!IsPlaying()) {
// Ensure we are in playing state before playing the next buffer
return;
}
if (active_buffer) {
// Do not queue a new buffer if we are already playing a buffer
return;
}
if (queued_buffers.empty()) {
// No queued buffers - we are effectively paused
return;
}
active_buffer = queued_buffers.front();
queued_buffers.pop();
CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {});
}
void Stream::ReleaseActiveBuffer() {
released_buffers.push(std::move(active_buffer));
release_callback();
PlayNextBuffer();
}
bool Stream::QueueBuffer(BufferPtr&& buffer) {
if (queued_buffers.size() < MaxAudioBufferCount) {
queued_buffers.push(std::move(buffer));
PlayNextBuffer();
return true;
}
return false;
}
bool Stream::ContainsBuffer(Buffer::Tag tag) const {
ASSERT_MSG(false, "Unimplemented");
return {};
}
std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers(size_t max_count) {
std::vector<Buffer::Tag> tags;
for (size_t count = 0; count < max_count && !released_buffers.empty(); ++count) {
tags.push_back(released_buffers.front()->GetTag());
released_buffers.pop();
}
return tags;
}
} // namespace AudioCore

89
src/audio_core/stream.h Normal file
View File

@@ -0,0 +1,89 @@
// Copyright 2018 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <functional>
#include <memory>
#include <vector>
#include <queue>
#include "audio_core/buffer.h"
#include "common/assert.h"
#include "common/common_types.h"
#include "core/core_timing.h"
namespace AudioCore {
using BufferPtr = std::shared_ptr<Buffer>;
/**
* Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut
*/
class Stream {
public:
/// Audio format of the stream
enum class Format {
Mono16,
Stereo16,
Multi51Channel16,
};
/// Callback function type, used to change guest state on a buffer being released
using ReleaseCallback = std::function<void()>;
Stream(int sample_rate, Format format, ReleaseCallback&& release_callback);
/// Plays the audio stream
void Play();
/// Stops the audio stream
void Stop();
/// Queues a buffer into the audio stream, returns true on success
bool QueueBuffer(BufferPtr&& buffer);
/// Returns true if the audio stream contains a buffer with the specified tag
bool ContainsBuffer(Buffer::Tag tag) const;
/// Returns a vector of recently released buffers specified by tag
std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(size_t max_count);
/// Returns true if the stream is currently playing
bool IsPlaying() const {
return state == State::Playing;
}
/// Returns the number of queued buffers
size_t GetQueueSize() const {
return queued_buffers.size();
}
private:
/// Current state of the stream
enum class State {
Stopped,
Playing,
};
/// Plays the next queued buffer in the audio stream, starting playback if necessary
void PlayNextBuffer();
/// Releases the actively playing buffer, signalling that it has been completed
void ReleaseActiveBuffer();
/// Gets the number of core cycles when the specified buffer will be released
s64 GetBufferReleaseCycles(const Buffer& buffer) const;
int sample_rate; ///< Sample rate of the stream
Format format; ///< Format of the stream
ReleaseCallback release_callback; ///< Buffer release callback for the stream
State state{State::Stopped}; ///< Playback state of the stream
CoreTiming::EventType* release_event{}; ///< Core timing release event for the stream
BufferPtr active_buffer; ///< Actively playing buffer in the stream
std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream
std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream
};
} // namespace AudioCore

View File

@@ -826,7 +826,7 @@ std::string_view GetPathWithoutTop(std::string_view path) {
}
while (path[0] == '\\' || path[0] == '/') {
path.remove_suffix(1);
path.remove_prefix(1);
if (path.empty()) {
return path;
}
@@ -870,6 +870,15 @@ std::string_view RemoveTrailingSlash(std::string_view path) {
return path;
}
std::string SanitizePath(std::string_view path_) {
std::string path(path_);
std::replace(path.begin(), path.end(), '\\', '/');
path.erase(std::unique(path.begin(), path.end(),
[](char c1, char c2) { return c1 == '/' && c2 == '/'; }),
path.end());
return std::string(RemoveTrailingSlash(path));
}
IOFile::IOFile() {}
IOFile::IOFile(const std::string& filename, const char openmode[], int flags) {

View File

@@ -178,6 +178,9 @@ std::vector<T> SliceVector(const std::vector<T>& vector, size_t first, size_t la
return std::vector<T>(vector.begin() + first, vector.begin() + first + last);
}
// Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'.
std::string SanitizePath(std::string_view path);
// simple wrapper for cstdlib file functions to
// hopefully will make error checking easier
// and make forgetting an fclose() harder

View File

@@ -173,8 +173,11 @@ void FileBackend::Write(const Entry& entry) {
SUB(Service, Friend) \
SUB(Service, FS) \
SUB(Service, HID) \
SUB(Service, LBL) \
SUB(Service, LDN) \
SUB(Service, LM) \
SUB(Service, MM) \
SUB(Service, NFC) \
SUB(Service, NFP) \
SUB(Service, NIFM) \
SUB(Service, NS) \

View File

@@ -60,8 +60,11 @@ enum class Class : ClassType {
Service_Friend, ///< The friend service
Service_FS, ///< The FS (Filesystem) service
Service_HID, ///< The HID (Human interface device) service
Service_LBL, ///< The LBL (LCD backlight) service
Service_LDN, ///< The LDN (Local domain network) service
Service_LM, ///< The LM (Logger) service
Service_MM, ///< The MM (Multimedia) service
Service_NFC, ///< The NFC (Near-field communication) service
Service_NFP, ///< The NFP service
Service_NIFM, ///< The NIFM (Network interface) service
Service_NS, ///< The NS services

View File

@@ -5,6 +5,7 @@
#pragma once
#include <cstddef>
#include <string>
namespace Log {

View File

@@ -10,8 +10,12 @@ add_library(core STATIC
core_cpu.h
core_timing.cpp
core_timing.h
core_timing_util.cpp
core_timing_util.h
file_sys/content_archive.cpp
file_sys/content_archive.h
file_sys/control_metadata.cpp
file_sys/control_metadata.h
file_sys/directory.h
file_sys/errors.h
file_sys/mode.h
@@ -19,6 +23,8 @@ add_library(core STATIC
file_sys/partition_filesystem.h
file_sys/program_metadata.cpp
file_sys/program_metadata.h
file_sys/romfs.cpp
file_sys/romfs.h
file_sys/romfs_factory.cpp
file_sys/romfs_factory.h
file_sys/savedata_factory.cpp
@@ -31,6 +37,8 @@ add_library(core STATIC
file_sys/vfs_offset.h
file_sys/vfs_real.cpp
file_sys/vfs_real.h
file_sys/vfs_vector.cpp
file_sys/vfs_vector.h
frontend/emu_window.cpp
frontend/emu_window.h
frontend/framebuffer_layout.cpp
@@ -38,8 +46,6 @@ add_library(core STATIC
frontend/input.h
gdbstub/gdbstub.cpp
gdbstub/gdbstub.h
hle/config_mem.cpp
hle/config_mem.h
hle/ipc.h
hle/ipc_helpers.h
hle/kernel/address_arbiter.cpp
@@ -114,26 +120,34 @@ add_library(core STATIC
hle/service/apm/apm.h
hle/service/apm/interface.cpp
hle/service/apm/interface.h
hle/service/audio/audio.cpp
hle/service/audio/audio.h
hle/service/audio/audin_u.cpp
hle/service/audio/audin_u.h
hle/service/audio/audio.cpp
hle/service/audio/audio.h
hle/service/audio/audout_u.cpp
hle/service/audio/audout_u.h
hle/service/audio/audrec_u.cpp
hle/service/audio/audrec_u.h
hle/service/audio/audren_u.cpp
hle/service/audio/audren_u.h
hle/service/audio/audren_u.cpp
hle/service/audio/audren_u.h
hle/service/audio/audren_u.h
hle/service/audio/codecctl.cpp
hle/service/audio/codecctl.h
hle/service/audio/hwopus.cpp
hle/service/audio/hwopus.h
hle/service/bcat/module.cpp
hle/service/bcat/module.h
hle/service/bcat/bcat.cpp
hle/service/bcat/bcat.h
hle/service/bcat/module.cpp
hle/service/bcat/module.h
hle/service/btdrv/btdrv.cpp
hle/service/btdrv/btdrv.h
hle/service/erpt/erpt.cpp
hle/service/erpt/erpt.h
hle/service/es/es.cpp
hle/service/es/es.h
hle/service/eupld/eupld.cpp
hle/service/eupld/eupld.h
hle/service/fatal/fatal.cpp
hle/service/fatal/fatal.h
hle/service/fatal/fatal_p.cpp
@@ -146,28 +160,36 @@ add_library(core STATIC
hle/service/filesystem/fsp_srv.h
hle/service/friend/friend.cpp
hle/service/friend/friend.h
hle/service/friend/friend_a.cpp
hle/service/friend/friend_a.h
hle/service/friend/friend_u.cpp
hle/service/friend/friend_u.h
hle/service/friend/interface.cpp
hle/service/friend/interface.h
hle/service/grc/grc.cpp
hle/service/grc/grc.h
hle/service/hid/hid.cpp
hle/service/hid/hid.h
hle/service/hid/irs.cpp
hle/service/hid/irs.h
hle/service/hid/xcd.cpp
hle/service/hid/xcd.h
hle/service/lbl/lbl.cpp
hle/service/lbl/lbl.h
hle/service/ldn/ldn.cpp
hle/service/ldn/ldn.h
hle/service/ldr/ldr.cpp
hle/service/ldr/ldr.h
hle/service/lm/lm.cpp
hle/service/lm/lm.h
hle/service/mm/mm_u.cpp
hle/service/mm/mm_u.h
hle/service/nifm/nifm.cpp
hle/service/nifm/nifm.h
hle/service/nifm/nifm_a.cpp
hle/service/nifm/nifm_a.h
hle/service/nifm/nifm_s.cpp
hle/service/nifm/nifm_s.h
hle/service/nifm/nifm_u.cpp
hle/service/nifm/nifm_u.h
hle/service/nfc/nfc.cpp
hle/service/nfc/nfc.h
hle/service/nfp/nfp.cpp
hle/service/nfp/nfp.h
hle/service/nfp/nfp_user.cpp
hle/service/nfp/nfp_user.h
hle/service/nifm/nifm.cpp
hle/service/nifm/nifm.h
hle/service/nim/nim.cpp
hle/service/nim/nim.h
hle/service/ns/ns.cpp
hle/service/ns/ns.h
hle/service/ns/pl_u.cpp
@@ -201,6 +223,8 @@ add_library(core STATIC
hle/service/pctl/module.h
hle/service/pctl/pctl.cpp
hle/service/pctl/pctl.h
hle/service/pm/pm.cpp
hle/service/pm/pm.h
hle/service/prepo/prepo.cpp
hle/service/prepo/prepo.h
hle/service/service.cpp
@@ -221,6 +245,8 @@ add_library(core STATIC
hle/service/sm/sm.h
hle/service/sockets/bsd.cpp
hle/service/sockets/bsd.h
hle/service/sockets/ethc.cpp
hle/service/sockets/ethc.h
hle/service/sockets/nsd.cpp
hle/service/sockets/nsd.h
hle/service/sockets/sfdnsres.cpp
@@ -235,12 +261,10 @@ add_library(core STATIC
hle/service/spl/spl.h
hle/service/ssl/ssl.cpp
hle/service/ssl/ssl.h
hle/service/time/interface.cpp
hle/service/time/interface.h
hle/service/time/time.cpp
hle/service/time/time.h
hle/service/time/time_s.cpp
hle/service/time/time_s.h
hle/service/time/time_u.cpp
hle/service/time/time_u.h
hle/service/vi/vi.cpp
hle/service/vi/vi.h
hle/service/vi/vi_m.cpp
@@ -249,8 +273,6 @@ add_library(core STATIC
hle/service/vi/vi_s.h
hle/service/vi/vi_u.cpp
hle/service/vi/vi_u.h
hle/shared_page.cpp
hle/shared_page.h
hw/hw.cpp
hw/hw.h
hw/lcd.cpp
@@ -287,7 +309,7 @@ add_library(core STATIC
create_target_directory_groups(core)
target_link_libraries(core PUBLIC common PRIVATE video_core)
target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static unicorn)
if (ARCHITECTURE_x86_64)

View File

@@ -102,8 +102,8 @@ public:
u64 tpidr_el0 = 0;
};
std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() {
const auto page_table = Core::CurrentProcess()->vm_manager.page_table.pointers.data();
std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const {
auto** const page_table = Core::CurrentProcess()->vm_manager.page_table.pointers.data();
Dynarmic::A64::UserConfig config;
@@ -257,7 +257,7 @@ void ARM_Dynarmic::PageTableChanged() {
DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(size_t core_count) : monitor(core_count) {}
DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default;
void DynarmicExclusiveMonitor::SetExclusive(size_t core_index, u64 addr) {
void DynarmicExclusiveMonitor::SetExclusive(size_t core_index, VAddr addr) {
// Size doesn't actually matter.
monitor.Mark(core_index, addr, 16);
}
@@ -266,28 +266,27 @@ void DynarmicExclusiveMonitor::ClearExclusive() {
monitor.Clear();
}
bool DynarmicExclusiveMonitor::ExclusiveWrite8(size_t core_index, u64 vaddr, u8 value) {
bool DynarmicExclusiveMonitor::ExclusiveWrite8(size_t core_index, VAddr vaddr, u8 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 1,
[&] { Memory::Write8(vaddr, value); });
}
bool DynarmicExclusiveMonitor::ExclusiveWrite16(size_t core_index, u64 vaddr, u16 value) {
bool DynarmicExclusiveMonitor::ExclusiveWrite16(size_t core_index, VAddr vaddr, u16 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 2,
[&] { Memory::Write16(vaddr, value); });
}
bool DynarmicExclusiveMonitor::ExclusiveWrite32(size_t core_index, u64 vaddr, u32 value) {
bool DynarmicExclusiveMonitor::ExclusiveWrite32(size_t core_index, VAddr vaddr, u32 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 4,
[&] { Memory::Write32(vaddr, value); });
}
bool DynarmicExclusiveMonitor::ExclusiveWrite64(size_t core_index, u64 vaddr, u64 value) {
bool DynarmicExclusiveMonitor::ExclusiveWrite64(size_t core_index, VAddr vaddr, u64 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 8,
[&] { Memory::Write64(vaddr, value); });
}
bool DynarmicExclusiveMonitor::ExclusiveWrite128(size_t core_index, u64 vaddr,
std::array<std::uint64_t, 2> value) {
bool DynarmicExclusiveMonitor::ExclusiveWrite128(size_t core_index, VAddr vaddr, u128 value) {
return monitor.DoExclusiveOperation(core_index, vaddr, 16, [&] {
Memory::Write64(vaddr, value[0]);
Memory::Write64(vaddr, value[1]);

View File

@@ -50,7 +50,7 @@ public:
void PageTableChanged() override;
private:
std::unique_ptr<Dynarmic::A64::Jit> MakeJit();
std::unique_ptr<Dynarmic::A64::Jit> MakeJit() const;
friend class ARM_Dynarmic_Callbacks;
std::unique_ptr<ARM_Dynarmic_Callbacks> cb;
@@ -68,15 +68,14 @@ public:
explicit DynarmicExclusiveMonitor(size_t core_count);
~DynarmicExclusiveMonitor();
void SetExclusive(size_t core_index, u64 addr) override;
void SetExclusive(size_t core_index, VAddr addr) override;
void ClearExclusive() override;
bool ExclusiveWrite8(size_t core_index, u64 vaddr, u8 value) override;
bool ExclusiveWrite16(size_t core_index, u64 vaddr, u16 value) override;
bool ExclusiveWrite32(size_t core_index, u64 vaddr, u32 value) override;
bool ExclusiveWrite64(size_t core_index, u64 vaddr, u64 value) override;
bool ExclusiveWrite128(size_t core_index, u64 vaddr,
std::array<std::uint64_t, 2> value) override;
bool ExclusiveWrite8(size_t core_index, VAddr vaddr, u8 value) override;
bool ExclusiveWrite16(size_t core_index, VAddr vaddr, u16 value) override;
bool ExclusiveWrite32(size_t core_index, VAddr vaddr, u32 value) override;
bool ExclusiveWrite64(size_t core_index, VAddr vaddr, u64 value) override;
bool ExclusiveWrite128(size_t core_index, VAddr vaddr, u128 value) override;
private:
friend class ARM_Dynarmic;

View File

@@ -4,20 +4,18 @@
#pragma once
#include <array>
#include "common/common_types.h"
class ExclusiveMonitor {
public:
virtual ~ExclusiveMonitor();
virtual void SetExclusive(size_t core_index, u64 addr) = 0;
virtual void SetExclusive(size_t core_index, VAddr addr) = 0;
virtual void ClearExclusive() = 0;
virtual bool ExclusiveWrite8(size_t core_index, u64 vaddr, u8 value) = 0;
virtual bool ExclusiveWrite16(size_t core_index, u64 vaddr, u16 value) = 0;
virtual bool ExclusiveWrite32(size_t core_index, u64 vaddr, u32 value) = 0;
virtual bool ExclusiveWrite64(size_t core_index, u64 vaddr, u64 value) = 0;
virtual bool ExclusiveWrite128(size_t core_index, u64 vaddr,
std::array<std::uint64_t, 2> value) = 0;
virtual bool ExclusiveWrite8(size_t core_index, VAddr vaddr, u8 value) = 0;
virtual bool ExclusiveWrite16(size_t core_index, VAddr vaddr, u16 value) = 0;
virtual bool ExclusiveWrite32(size_t core_index, VAddr vaddr, u32 value) = 0;
virtual bool ExclusiveWrite64(size_t core_index, VAddr vaddr, u64 value) = 0;
virtual bool ExclusiveWrite128(size_t core_index, VAddr vaddr, u128 value) = 0;
};

View File

@@ -177,6 +177,7 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
}
gpu_core = std::make_unique<Tegra::GPU>();
audio_core = std::make_unique<AudioCore::AudioOut>();
telemetry_session = std::make_unique<Core::TelemetrySession>();
service_manager = std::make_shared<Service::SM::ServiceManager>();
@@ -228,6 +229,7 @@ void System::Shutdown() {
service_manager.reset();
telemetry_session.reset();
gpu_core.reset();
audio_core.reset();
// Close all CPU/threading state
cpu_barrier->NotifyEnd();

View File

@@ -8,6 +8,7 @@
#include <memory>
#include <string>
#include <thread>
#include "audio_core/audio_out.h"
#include "common/common_types.h"
#include "core/arm/exclusive_monitor.h"
#include "core/core_cpu.h"
@@ -131,6 +132,11 @@ public:
return *gpu_core;
}
/// Gets the AudioCore interface
AudioCore::AudioOut& AudioCore() {
return *audio_core;
}
/// Gets the scheduler for the CPU core that is currently running
Kernel::Scheduler& CurrentScheduler() {
return *CurrentCpuCore().Scheduler();
@@ -195,6 +201,7 @@ private:
/// AppLoader used to load the current executing application
std::unique_ptr<Loader::AppLoader> app_loader;
std::unique_ptr<Tegra::GPU> gpu_core;
std::unique_ptr<AudioCore::AudioOut> audio_core;
std::shared_ptr<Tegra::DebugContext> debug_context;
Kernel::SharedPtr<Kernel::Process> current_process;
std::shared_ptr<ExclusiveMonitor> cpu_exclusive_monitor;

View File

@@ -5,17 +5,15 @@
#include "core/core_timing.h"
#include <algorithm>
#include <cinttypes>
#include <limits>
#include <mutex>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/thread.h"
#include "common/threadsafe_queue.h"
#include "core/core_timing_util.h"
namespace CoreTiming {
@@ -59,7 +57,6 @@ static u64 event_fifo_id;
static Common::MPSCQueue<Event, false> ts_queue;
constexpr int MAX_SLICE_LENGTH = 20000;
constexpr u64 MAX_VALUE_TO_MULTIPLY = std::numeric_limits<s64>::max() / BASE_CLOCK_RATE;
static s64 idled_cycles;
@@ -72,54 +69,6 @@ static EventType* ev_lost = nullptr;
static void EmptyTimedCallback(u64 userdata, s64 cyclesLate) {}
s64 usToCycles(s64 us) {
if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) {
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
return std::numeric_limits<s64>::max();
}
if (us > MAX_VALUE_TO_MULTIPLY) {
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
return BASE_CLOCK_RATE * (us / 1000000);
}
return (BASE_CLOCK_RATE * us) / 1000000;
}
s64 usToCycles(u64 us) {
if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) {
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
return std::numeric_limits<s64>::max();
}
if (us > MAX_VALUE_TO_MULTIPLY) {
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
return BASE_CLOCK_RATE * static_cast<s64>(us / 1000000);
}
return (BASE_CLOCK_RATE * static_cast<s64>(us)) / 1000000;
}
s64 nsToCycles(s64 ns) {
if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) {
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
return std::numeric_limits<s64>::max();
}
if (ns > MAX_VALUE_TO_MULTIPLY) {
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
return BASE_CLOCK_RATE * (ns / 1000000000);
}
return (BASE_CLOCK_RATE * ns) / 1000000000;
}
s64 nsToCycles(u64 ns) {
if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) {
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
return std::numeric_limits<s64>::max();
}
if (ns > MAX_VALUE_TO_MULTIPLY) {
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
return BASE_CLOCK_RATE * (static_cast<s64>(ns) / 1000000000);
}
return (BASE_CLOCK_RATE * static_cast<s64>(ns)) / 1000000000;
}
EventType* RegisterEvent(const std::string& name, TimedCallback callback) {
// check for existing type with same name.
// we want event type names to remain unique so that we can use them for serialization.

View File

@@ -23,59 +23,6 @@
namespace CoreTiming {
// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz
// The exact value used is of course unverified.
constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch clock speed is 1020MHz un/docked
inline s64 msToCycles(int ms) {
// since ms is int there is no way to overflow
return BASE_CLOCK_RATE * static_cast<s64>(ms) / 1000;
}
inline s64 msToCycles(float ms) {
return static_cast<s64>(BASE_CLOCK_RATE * (0.001f) * ms);
}
inline s64 msToCycles(double ms) {
return static_cast<s64>(BASE_CLOCK_RATE * (0.001) * ms);
}
inline s64 usToCycles(float us) {
return static_cast<s64>(BASE_CLOCK_RATE * (0.000001f) * us);
}
inline s64 usToCycles(int us) {
return (BASE_CLOCK_RATE * static_cast<s64>(us) / 1000000);
}
s64 usToCycles(s64 us);
s64 usToCycles(u64 us);
inline s64 nsToCycles(float ns) {
return static_cast<s64>(BASE_CLOCK_RATE * (0.000000001f) * ns);
}
inline s64 nsToCycles(int ns) {
return BASE_CLOCK_RATE * static_cast<s64>(ns) / 1000000000;
}
s64 nsToCycles(s64 ns);
s64 nsToCycles(u64 ns);
inline u64 cyclesToNs(s64 cycles) {
return cycles * 1000000000 / BASE_CLOCK_RATE;
}
inline s64 cyclesToUs(s64 cycles) {
return cycles * 1000000 / BASE_CLOCK_RATE;
}
inline u64 cyclesToMs(s64 cycles) {
return cycles * 1000 / BASE_CLOCK_RATE;
}
/**
* CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is
* required to end slice -1 and start slice 0 before the first cycle of code is executed.

View File

@@ -0,0 +1,63 @@
// Copyright 2008 Dolphin Emulator Project / 2017 Citra Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "core/core_timing_util.h"
#include <cinttypes>
#include <limits>
#include "common/logging/log.h"
namespace CoreTiming {
constexpr u64 MAX_VALUE_TO_MULTIPLY = std::numeric_limits<s64>::max() / BASE_CLOCK_RATE;
s64 usToCycles(s64 us) {
if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) {
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
return std::numeric_limits<s64>::max();
}
if (us > MAX_VALUE_TO_MULTIPLY) {
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
return BASE_CLOCK_RATE * (us / 1000000);
}
return (BASE_CLOCK_RATE * us) / 1000000;
}
s64 usToCycles(u64 us) {
if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) {
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
return std::numeric_limits<s64>::max();
}
if (us > MAX_VALUE_TO_MULTIPLY) {
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
return BASE_CLOCK_RATE * static_cast<s64>(us / 1000000);
}
return (BASE_CLOCK_RATE * static_cast<s64>(us)) / 1000000;
}
s64 nsToCycles(s64 ns) {
if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) {
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
return std::numeric_limits<s64>::max();
}
if (ns > MAX_VALUE_TO_MULTIPLY) {
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
return BASE_CLOCK_RATE * (ns / 1000000000);
}
return (BASE_CLOCK_RATE * ns) / 1000000000;
}
s64 nsToCycles(u64 ns) {
if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) {
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
return std::numeric_limits<s64>::max();
}
if (ns > MAX_VALUE_TO_MULTIPLY) {
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
return BASE_CLOCK_RATE * (static_cast<s64>(ns) / 1000000000);
}
return (BASE_CLOCK_RATE * static_cast<s64>(ns)) / 1000000000;
}
} // namespace CoreTiming

View File

@@ -0,0 +1,64 @@
// Copyright 2008 Dolphin Emulator Project / 2017 Citra Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
namespace CoreTiming {
// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz
// The exact value used is of course unverified.
constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch clock speed is 1020MHz un/docked
inline s64 msToCycles(int ms) {
// since ms is int there is no way to overflow
return BASE_CLOCK_RATE * static_cast<s64>(ms) / 1000;
}
inline s64 msToCycles(float ms) {
return static_cast<s64>(BASE_CLOCK_RATE * (0.001f) * ms);
}
inline s64 msToCycles(double ms) {
return static_cast<s64>(BASE_CLOCK_RATE * (0.001) * ms);
}
inline s64 usToCycles(float us) {
return static_cast<s64>(BASE_CLOCK_RATE * (0.000001f) * us);
}
inline s64 usToCycles(int us) {
return (BASE_CLOCK_RATE * static_cast<s64>(us) / 1000000);
}
s64 usToCycles(s64 us);
s64 usToCycles(u64 us);
inline s64 nsToCycles(float ns) {
return static_cast<s64>(BASE_CLOCK_RATE * (0.000000001f) * ns);
}
inline s64 nsToCycles(int ns) {
return BASE_CLOCK_RATE * static_cast<s64>(ns) / 1000000000;
}
s64 nsToCycles(s64 ns);
s64 nsToCycles(u64 ns);
inline u64 cyclesToNs(s64 cycles) {
return cycles * 1000000000 / BASE_CLOCK_RATE;
}
inline s64 cyclesToUs(s64 cycles) {
return cycles * 1000000 / BASE_CLOCK_RATE;
}
inline u64 cyclesToMs(s64 cycles) {
return cycles * 1000 / BASE_CLOCK_RATE;
}
} // namespace CoreTiming

View File

@@ -9,6 +9,7 @@
#include "core/file_sys/content_archive.h"
#include "core/file_sys/vfs_offset.h"
#include "core/loader/loader.h"
#include "romfs.h"
namespace FileSys {
@@ -46,21 +47,9 @@ struct PFS0Superblock {
};
static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size.");
struct IVFCLevel {
u64_le offset;
u64_le size;
u32_le block_size;
u32_le reserved;
};
static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size.");
struct RomFSSuperblock {
NCASectionHeaderBlock header_block;
u32_le magic;
u32_le magic_number;
INSERT_PADDING_BYTES(8);
std::array<IVFCLevel, 6> levels;
INSERT_PADDING_BYTES(64);
IVFCHeader ivfc;
};
static_assert(sizeof(RomFSSuperblock) == 0xE8, "RomFSSuperblock has incorrect size.");
@@ -92,8 +81,8 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) {
const size_t romfs_offset =
header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER +
sb.levels[IVFC_MAX_LEVEL - 1].offset;
const size_t romfs_size = sb.levels[IVFC_MAX_LEVEL - 1].size;
sb.ivfc.levels[IVFC_MAX_LEVEL - 1].offset;
const size_t romfs_size = sb.ivfc.levels[IVFC_MAX_LEVEL - 1].size;
files.emplace_back(std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset));
romfs = files.back();
} else if (block.filesystem_type == NCASectionFilesystemType::PFS0) {

View File

@@ -0,0 +1,42 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/string_util.h"
#include "common/swap.h"
#include "core/file_sys/control_metadata.h"
namespace FileSys {
std::string LanguageEntry::GetApplicationName() const {
return Common::StringFromFixedZeroTerminatedBuffer(application_name.data(), 0x200);
}
std::string LanguageEntry::GetDeveloperName() const {
return Common::StringFromFixedZeroTerminatedBuffer(developer_name.data(), 0x100);
}
NACP::NACP(VirtualFile file_) : file(std::move(file_)), raw(std::make_unique<RawNACP>()) {
file->ReadObject(raw.get());
}
const LanguageEntry& NACP::GetLanguageEntry(Language language) const {
return raw->language_entries.at(static_cast<u8>(language));
}
std::string NACP::GetApplicationName(Language language) const {
return GetLanguageEntry(language).GetApplicationName();
}
std::string NACP::GetDeveloperName(Language language) const {
return GetLanguageEntry(language).GetDeveloperName();
}
u64 NACP::GetTitleId() const {
return raw->title_id;
}
std::string NACP::GetVersionString() const {
return Common::StringFromFixedZeroTerminatedBuffer(raw->version_string.data(), 0x10);
}
} // namespace FileSys

View File

@@ -0,0 +1,81 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <array>
#include <memory>
#include <string>
#include "common/common_funcs.h"
#include "core/file_sys/vfs.h"
namespace FileSys {
// A localized entry containing strings within the NACP.
// One for each language of type Language.
struct LanguageEntry {
std::array<char, 0x200> application_name;
std::array<char, 0x100> developer_name;
std::string GetApplicationName() const;
std::string GetDeveloperName() const;
};
static_assert(sizeof(LanguageEntry) == 0x300, "LanguageEntry has incorrect size.");
// The raw file format of a NACP file.
struct RawNACP {
std::array<LanguageEntry, 16> language_entries;
INSERT_PADDING_BYTES(0x38);
u64_le title_id;
INSERT_PADDING_BYTES(0x20);
std::array<char, 0x10> version_string;
u64_le dlc_base_title_id;
u64_le title_id_2;
INSERT_PADDING_BYTES(0x28);
u64_le product_code;
u64_le title_id_3;
std::array<u64_le, 0x7> title_id_array;
INSERT_PADDING_BYTES(0x8);
u64_le title_id_update;
std::array<u8, 0x40> bcat_passphrase;
INSERT_PADDING_BYTES(0xEC0);
};
static_assert(sizeof(RawNACP) == 0x4000, "RawNACP has incorrect size.");
// A language on the NX. These are for names and icons.
enum class Language : u8 {
AmericanEnglish = 0,
BritishEnglish = 1,
Japanese = 2,
French = 3,
German = 4,
LatinAmericanSpanish = 5,
Spanish = 6,
Italian = 7,
Dutch = 8,
CanadianFrench = 9,
Portugese = 10,
Russian = 11,
Korean = 12,
Taiwanese = 13,
Chinese = 14,
};
// A class representing the format used by NX metadata files, typically named Control.nacp.
// These store application name, dev name, title id, and other miscellaneous data.
class NACP {
public:
explicit NACP(VirtualFile file);
const LanguageEntry& GetLanguageEntry(Language language = Language::AmericanEnglish) const;
std::string GetApplicationName(Language language = Language::AmericanEnglish) const;
std::string GetDeveloperName(Language language = Language::AmericanEnglish) const;
u64 GetTitleId() const;
std::string GetVersionString() const;
private:
VirtualFile file;
std::unique_ptr<RawNACP> raw;
};
} // namespace FileSys

View File

@@ -11,7 +11,13 @@ namespace FileSys {
enum class Mode : u32 {
Read = 1,
Write = 2,
ReadWrite = 3,
Append = 4,
WriteAppend = 6,
};
inline u32 operator&(Mode lhs, Mode rhs) {
return static_cast<u32>(lhs) & static_cast<u32>(rhs);
}
} // namespace FileSys

View File

@@ -65,8 +65,8 @@ PartitionFilesystem::PartitionFilesystem(std::shared_ptr<VfsFile> file) {
std::string name(
reinterpret_cast<const char*>(&file_data[strtab_offset + entry.strtab_offset]));
pfs_files.emplace_back(
std::make_shared<OffsetVfsFile>(file, entry.size, content_offset + entry.offset, name));
pfs_files.emplace_back(std::make_shared<OffsetVfsFile>(
file, entry.size, content_offset + entry.offset, std::move(name)));
}
status = Loader::ResultStatus::Success;
@@ -109,7 +109,7 @@ bool PartitionFilesystem::ReplaceFileWithSubdirectory(VirtualFile file, VirtualD
return false;
const std::ptrdiff_t offset = std::distance(pfs_files.begin(), iter);
pfs_files[offset] = pfs_files.back();
pfs_files[offset] = std::move(pfs_files.back());
pfs_files.pop_back();
pfs_dirs.emplace_back(std::move(dir));

124
src/core/file_sys/romfs.cpp Normal file
View File

@@ -0,0 +1,124 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/common_types.h"
#include "common/swap.h"
#include "core/file_sys/romfs.h"
#include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_offset.h"
#include "core/file_sys/vfs_vector.h"
namespace FileSys {
constexpr u32 ROMFS_ENTRY_EMPTY = 0xFFFFFFFF;
struct TableLocation {
u64_le offset;
u64_le size;
};
static_assert(sizeof(TableLocation) == 0x10, "TableLocation has incorrect size.");
struct RomFSHeader {
u64_le header_size;
TableLocation directory_hash;
TableLocation directory_meta;
TableLocation file_hash;
TableLocation file_meta;
u64_le data_offset;
};
static_assert(sizeof(RomFSHeader) == 0x50, "RomFSHeader has incorrect size.");
struct DirectoryEntry {
u32_le sibling;
u32_le child_dir;
u32_le child_file;
u32_le hash;
u32_le name_length;
};
static_assert(sizeof(DirectoryEntry) == 0x14, "DirectoryEntry has incorrect size.");
struct FileEntry {
u32_le parent;
u32_le sibling;
u64_le offset;
u64_le size;
u32_le hash;
u32_le name_length;
};
static_assert(sizeof(FileEntry) == 0x20, "FileEntry has incorrect size.");
template <typename Entry>
static std::pair<Entry, std::string> GetEntry(const VirtualFile& file, size_t offset) {
Entry entry{};
if (file->ReadObject(&entry, offset) != sizeof(Entry))
return {};
std::string string(entry.name_length, '\0');
if (file->ReadArray(&string[0], string.size(), offset + sizeof(Entry)) != string.size())
return {};
return {entry, string};
}
void ProcessFile(VirtualFile file, size_t file_offset, size_t data_offset, u32 this_file_offset,
std::shared_ptr<VectorVfsDirectory> parent) {
while (true) {
auto entry = GetEntry<FileEntry>(file, file_offset + this_file_offset);
parent->AddFile(std::make_shared<OffsetVfsFile>(
file, entry.first.size, entry.first.offset + data_offset, entry.second, parent));
if (entry.first.sibling == ROMFS_ENTRY_EMPTY)
break;
this_file_offset = entry.first.sibling;
}
}
void ProcessDirectory(VirtualFile file, size_t dir_offset, size_t file_offset, size_t data_offset,
u32 this_dir_offset, std::shared_ptr<VectorVfsDirectory> parent) {
while (true) {
auto entry = GetEntry<DirectoryEntry>(file, dir_offset + this_dir_offset);
auto current = std::make_shared<VectorVfsDirectory>(
std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, parent, entry.second);
if (entry.first.child_file != ROMFS_ENTRY_EMPTY) {
ProcessFile(file, file_offset, data_offset, entry.first.child_file, current);
}
if (entry.first.child_dir != ROMFS_ENTRY_EMPTY) {
ProcessDirectory(file, dir_offset, file_offset, data_offset, entry.first.child_dir,
current);
}
parent->AddDirectory(current);
if (entry.first.sibling == ROMFS_ENTRY_EMPTY)
break;
this_dir_offset = entry.first.sibling;
}
}
VirtualDir ExtractRomFS(VirtualFile file) {
RomFSHeader header{};
if (file->ReadObject(&header) != sizeof(RomFSHeader))
return nullptr;
if (header.header_size != sizeof(RomFSHeader))
return nullptr;
const u64 file_offset = header.file_meta.offset;
const u64 dir_offset = header.directory_meta.offset + 4;
const auto root =
std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{}, std::vector<VirtualDir>{},
file->GetContainingDirectory(), file->GetName());
ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root);
VirtualDir out = std::move(root);
while (out->GetSubdirectory("") != nullptr)
out = out->GetSubdirectory("");
return out;
}
} // namespace FileSys

35
src/core/file_sys/romfs.h Normal file
View File

@@ -0,0 +1,35 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <array>
#include "common/common_funcs.h"
#include "common/swap.h"
#include "core/file_sys/vfs.h"
namespace FileSys {
struct IVFCLevel {
u64_le offset;
u64_le size;
u32_le block_size;
u32_le reserved;
};
static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size.");
struct IVFCHeader {
u32_le magic;
u32_le magic_number;
INSERT_PADDING_BYTES(8);
std::array<IVFCLevel, 6> levels;
INSERT_PADDING_BYTES(64);
};
static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size.");
// Converts a RomFS binary blob to VFS Filesystem
// Returns nullptr on failure
VirtualDir ExtractRomFS(VirtualFile file);
} // namespace FileSys

View File

@@ -46,6 +46,13 @@ size_t VfsFile::WriteBytes(const std::vector<u8>& data, size_t offset) {
return Write(data.data(), data.size(), offset);
}
std::string VfsFile::GetFullPath() const {
if (GetContainingDirectory() == nullptr)
return "/" + GetName();
return GetContainingDirectory()->GetFullPath() + "/" + GetName();
}
std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) const {
auto vec = FileUtil::SplitPathComponents(path);
vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }),
@@ -243,6 +250,13 @@ bool VfsDirectory::Copy(std::string_view src, std::string_view dest) {
return f2->WriteBytes(f1->ReadAllBytes()) == f1->GetSize();
}
std::string VfsDirectory::GetFullPath() const {
if (IsRoot())
return GetName();
return GetParentDirectory()->GetFullPath() + "/" + GetName();
}
bool ReadOnlyVfsDirectory::IsWritable() const {
return false;
}
@@ -270,4 +284,13 @@ bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) {
bool ReadOnlyVfsDirectory::Rename(std::string_view name) {
return false;
}
bool VfsRawCopy(VirtualFile src, VirtualFile dest) {
if (src == nullptr || dest == nullptr)
return false;
if (!dest->Resize(src->GetSize()))
return false;
std::vector<u8> data = src->ReadAllBytes();
return dest->WriteBytes(data, 0) == data.size();
}
} // namespace FileSys

View File

@@ -113,6 +113,9 @@ struct VfsFile : NonCopyable {
// Renames the file to name. Returns whether or not the operation was successsful.
virtual bool Rename(std::string_view name) = 0;
// Returns the full path of this file as a string, recursively
virtual std::string GetFullPath() const;
};
// A class representing a directory in an abstract filesystem.
@@ -213,6 +216,17 @@ struct VfsDirectory : NonCopyable {
return ReplaceFileWithSubdirectory(file_p, std::make_shared<Directory>(file_p));
}
bool InterpretAsDirectory(const std::function<VirtualDir(VirtualFile)>& function,
const std::string& file) {
auto file_p = GetFile(file);
if (file_p == nullptr)
return false;
return ReplaceFileWithSubdirectory(file_p, function(file_p));
}
// Returns the full path of this directory as a string, recursively
virtual std::string GetFullPath() const;
protected:
// Backend for InterpretAsDirectory.
// Removes all references to file and adds a reference to dir in the directory's implementation.
@@ -230,4 +244,10 @@ struct ReadOnlyVfsDirectory : public VfsDirectory {
bool DeleteFile(std::string_view name) override;
bool Rename(std::string_view name) override;
};
// A method that copies the raw data between two different implementations of VirtualFile. If you
// are using the same implementation, it is probably better to use the Copy method in the parent
// directory of src/dest.
bool VfsRawCopy(VirtualFile src, VirtualFile dest);
} // namespace FileSys

View File

@@ -10,8 +10,9 @@
namespace FileSys {
OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, size_t size_, size_t offset_,
std::string name_)
: file(std::move(file_)), offset(offset_), size(size_), name(std::move(name_)) {}
std::string name_, VirtualDir parent_)
: file(file_), offset(offset_), size(size_), name(std::move(name_)),
parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {}
std::string OffsetVfsFile::GetName() const {
return name.empty() ? file->GetName() : name;
@@ -35,7 +36,7 @@ bool OffsetVfsFile::Resize(size_t new_size) {
}
std::shared_ptr<VfsDirectory> OffsetVfsFile::GetContainingDirectory() const {
return file->GetContainingDirectory();
return parent;
}
bool OffsetVfsFile::IsWritable() const {

View File

@@ -17,7 +17,7 @@ namespace FileSys {
// the size of this wrapper.
struct OffsetVfsFile : public VfsFile {
OffsetVfsFile(std::shared_ptr<VfsFile> file, size_t size, size_t offset = 0,
std::string new_name = "");
std::string new_name = "", VirtualDir new_parent = nullptr);
std::string GetName() const override;
size_t GetSize() const override;
@@ -44,6 +44,7 @@ private:
size_t offset;
size_t size;
std::string name;
VirtualDir parent;
};
} // namespace FileSys

View File

@@ -13,24 +13,31 @@
namespace FileSys {
static std::string PermissionsToCharArray(Mode perms) {
std::string out;
switch (perms) {
case Mode::Read:
out += "r";
break;
case Mode::Write:
out += "r+";
break;
case Mode::Append:
out += "a";
break;
static std::string ModeFlagsToString(Mode mode) {
std::string mode_str;
// Calculate the correct open mode for the file.
if (mode & Mode::Read && mode & Mode::Write) {
if (mode & Mode::Append)
mode_str = "a+";
else
mode_str = "r+";
} else {
if (mode & Mode::Read)
mode_str = "r";
else if (mode & Mode::Append)
mode_str = "a";
else if (mode & Mode::Write)
mode_str = "w";
}
return out + "b";
mode_str += "b";
return mode_str;
}
RealVfsFile::RealVfsFile(const std::string& path_, Mode perms_)
: backing(path_, PermissionsToCharArray(perms_).c_str()), path(path_),
: backing(path_, ModeFlagsToString(perms_).c_str()), path(path_),
parent_path(FileUtil::GetParentPath(path_)),
path_components(FileUtil::SplitPathComponents(path_)),
parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)),
@@ -53,11 +60,11 @@ std::shared_ptr<VfsDirectory> RealVfsFile::GetContainingDirectory() const {
}
bool RealVfsFile::IsWritable() const {
return perms == Mode::Append || perms == Mode::Write;
return (perms & Mode::WriteAppend) != 0;
}
bool RealVfsFile::IsReadable() const {
return perms == Mode::Read || perms == Mode::Write;
return (perms & Mode::ReadWrite) != 0;
}
size_t RealVfsFile::Read(u8* data, size_t length, size_t offset) const {
@@ -79,7 +86,7 @@ bool RealVfsFile::Rename(std::string_view name) {
path = (parent_path + DIR_SEP).append(name);
path_components = parent_components;
path_components.push_back(std::move(name_str));
backing = FileUtil::IOFile(path, PermissionsToCharArray(perms).c_str());
backing = FileUtil::IOFile(path, ModeFlagsToString(perms).c_str());
return out;
}
@@ -93,7 +100,7 @@ RealVfsDirectory::RealVfsDirectory(const std::string& path_, Mode perms_)
path_components(FileUtil::SplitPathComponents(path)),
parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)),
perms(perms_) {
if (!FileUtil::Exists(path) && (perms == Mode::Write || perms == Mode::Append))
if (!FileUtil::Exists(path) && perms & Mode::WriteAppend)
FileUtil::CreateDir(path);
if (perms == Mode::Append)
@@ -120,11 +127,11 @@ std::vector<std::shared_ptr<VfsDirectory>> RealVfsDirectory::GetSubdirectories()
}
bool RealVfsDirectory::IsWritable() const {
return perms == Mode::Write || perms == Mode::Append;
return (perms & Mode::WriteAppend) != 0;
}
bool RealVfsDirectory::IsReadable() const {
return perms == Mode::Read || perms == Mode::Write;
return (perms & Mode::ReadWrite) != 0;
}
std::string RealVfsDirectory::GetName() const {
@@ -188,6 +195,12 @@ bool RealVfsDirectory::Rename(std::string_view name) {
return FileUtil::Rename(path, new_name);
}
std::string RealVfsDirectory::GetFullPath() const {
auto out = path;
std::replace(out.begin(), out.end(), '\\', '/');
return out;
}
bool RealVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
const auto iter = std::find(files.begin(), files.end(), file);
if (iter == files.end())

View File

@@ -41,7 +41,7 @@ private:
// An implementation of VfsDirectory that represents a directory on the user's computer.
struct RealVfsDirectory : public VfsDirectory {
RealVfsDirectory(const std::string& path, Mode perms);
RealVfsDirectory(const std::string& path, Mode perms = Mode::Read);
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
@@ -54,6 +54,7 @@ struct RealVfsDirectory : public VfsDirectory {
bool DeleteSubdirectory(std::string_view name) override;
bool DeleteFile(std::string_view name) override;
bool Rename(std::string_view name) override;
std::string GetFullPath() const override;
protected:
bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;

View File

@@ -0,0 +1,83 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include "core/file_sys/vfs_vector.h"
namespace FileSys {
VectorVfsDirectory::VectorVfsDirectory(std::vector<VirtualFile> files_,
std::vector<VirtualDir> dirs_, VirtualDir parent_,
std::string name_)
: files(std::move(files_)), dirs(std::move(dirs_)), parent(std::move(parent_)),
name(std::move(name_)) {}
std::vector<std::shared_ptr<VfsFile>> VectorVfsDirectory::GetFiles() const {
return files;
}
std::vector<std::shared_ptr<VfsDirectory>> VectorVfsDirectory::GetSubdirectories() const {
return dirs;
}
bool VectorVfsDirectory::IsWritable() const {
return false;
}
bool VectorVfsDirectory::IsReadable() const {
return true;
}
std::string VectorVfsDirectory::GetName() const {
return name;
}
std::shared_ptr<VfsDirectory> VectorVfsDirectory::GetParentDirectory() const {
return parent;
}
template <typename T>
static bool FindAndRemoveVectorElement(std::vector<T>& vec, std::string_view name) {
auto iter = std::find_if(vec.begin(), vec.end(), [name](T e) { return e->GetName() == name; });
if (iter == vec.end())
return false;
auto old_size = vec.size();
vec.erase(iter);
return true;
}
bool VectorVfsDirectory::DeleteSubdirectory(std::string_view name) {
return FindAndRemoveVectorElement(dirs, name);
}
bool VectorVfsDirectory::DeleteFile(std::string_view name) {
return FindAndRemoveVectorElement(files, name);
}
bool VectorVfsDirectory::Rename(std::string_view name_) {
name = name_;
return true;
}
std::shared_ptr<VfsDirectory> VectorVfsDirectory::CreateSubdirectory(std::string_view name) {
return nullptr;
}
std::shared_ptr<VfsFile> VectorVfsDirectory::CreateFile(std::string_view name) {
return nullptr;
}
void VectorVfsDirectory::AddFile(VirtualFile file) {
files.push_back(std::move(file));
}
void VectorVfsDirectory::AddDirectory(VirtualDir dir) {
dirs.push_back(std::move(dir));
}
bool VectorVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) {
if (!DeleteFile(file->GetName()))
return false;
dirs.emplace_back(dir);
return true;
}
} // namespace FileSys

View File

@@ -0,0 +1,44 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/file_sys/vfs.h"
namespace FileSys {
// An implementation of VfsDirectory that maintains two vectors for subdirectories and files.
// Vector data is supplied upon construction.
struct VectorVfsDirectory : public VfsDirectory {
explicit VectorVfsDirectory(std::vector<VirtualFile> files = {},
std::vector<VirtualDir> dirs = {}, VirtualDir parent = nullptr,
std::string name = "");
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
bool IsWritable() const override;
bool IsReadable() const override;
std::string GetName() const override;
std::shared_ptr<VfsDirectory> 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;
virtual void AddFile(VirtualFile file);
virtual void AddDirectory(VirtualDir dir);
protected:
bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
private:
std::vector<VirtualFile> files;
std::vector<VirtualDir> dirs;
VirtualDir parent;
std::string name;
};
} // namespace FileSys

View File

@@ -1,31 +0,0 @@
// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cstring>
#include "core/hle/config_mem.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace ConfigMem {
ConfigMemDef config_mem;
void Init() {
std::memset(&config_mem, 0, sizeof(config_mem));
// Values extracted from firmware 11.2.0-35E
config_mem.kernel_version_min = 0x34;
config_mem.kernel_version_maj = 0x2;
config_mem.ns_tid = 0x0004013000008002;
config_mem.sys_core_ver = 0x2;
config_mem.unit_info = 0x1; // Bit 0 set for Retail
config_mem.prev_firm = 0x1;
config_mem.ctr_sdk_ver = 0x0000F297;
config_mem.firm_version_min = 0x34;
config_mem.firm_version_maj = 0x2;
config_mem.firm_sys_core_ver = 0x2;
config_mem.firm_ctr_sdk_ver = 0x0000F297;
}
} // namespace ConfigMem

View File

@@ -1,56 +0,0 @@
// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
// Configuration memory stores various hardware/kernel configuration settings. This memory page is
// read-only for ARM11 processes. I'm guessing this would normally be written to by the firmware/
// bootrom. Because we're not emulating this, and essentially just "stubbing" the functionality, I'm
// putting this as a subset of HLE for now.
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"
#include "core/memory.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace ConfigMem {
struct ConfigMemDef {
u8 kernel_unk; // 0
u8 kernel_version_rev; // 1
u8 kernel_version_min; // 2
u8 kernel_version_maj; // 3
u32_le update_flag; // 4
u64_le ns_tid; // 8
u32_le sys_core_ver; // 10
u8 unit_info; // 14
u8 boot_firm; // 15
u8 prev_firm; // 16
INSERT_PADDING_BYTES(0x1); // 17
u32_le ctr_sdk_ver; // 18
INSERT_PADDING_BYTES(0x30 - 0x1C); // 1C
u32_le app_mem_type; // 30
INSERT_PADDING_BYTES(0x40 - 0x34); // 34
u32_le app_mem_alloc; // 40
u32_le sys_mem_alloc; // 44
u32_le base_mem_alloc; // 48
INSERT_PADDING_BYTES(0x60 - 0x4C); // 4C
u8 firm_unk; // 60
u8 firm_version_rev; // 61
u8 firm_version_min; // 62
u8 firm_version_maj; // 63
u32_le firm_sys_core_ver; // 64
u32_le firm_ctr_sdk_ver; // 68
INSERT_PADDING_BYTES(0x1000 - 0x6C); // 6C
};
static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE,
"Config Memory structure size is wrong");
extern ConfigMemDef config_mem;
void Init();
} // namespace ConfigMem

View File

@@ -25,9 +25,9 @@ protected:
ptrdiff_t index = 0;
public:
RequestHelperBase(u32* command_buffer) : cmdbuf(command_buffer) {}
explicit RequestHelperBase(u32* command_buffer) : cmdbuf(command_buffer) {}
RequestHelperBase(Kernel::HLERequestContext& context)
explicit RequestHelperBase(Kernel::HLERequestContext& context)
: context(&context), cmdbuf(context.CommandBuffer()) {}
void Skip(unsigned size_in_words, bool set_to_null) {
@@ -56,13 +56,6 @@ public:
class ResponseBuilder : public RequestHelperBase {
public:
ResponseBuilder(u32* command_buffer) : RequestHelperBase(command_buffer) {}
u32 normal_params_size{};
u32 num_handles_to_copy{};
u32 num_objects_to_move{}; ///< Domain objects or move handles, context dependent
std::ptrdiff_t datapayload_index{};
/// Flags used for customizing the behavior of ResponseBuilder
enum class Flags : u32 {
None = 0,
@@ -71,9 +64,11 @@ public:
AlwaysMoveHandles = 1,
};
ResponseBuilder(Kernel::HLERequestContext& context, u32 normal_params_size,
u32 num_handles_to_copy = 0, u32 num_objects_to_move = 0,
Flags flags = Flags::None)
explicit ResponseBuilder(u32* command_buffer) : RequestHelperBase(command_buffer) {}
explicit ResponseBuilder(Kernel::HLERequestContext& context, u32 normal_params_size,
u32 num_handles_to_copy = 0, u32 num_objects_to_move = 0,
Flags flags = Flags::None)
: RequestHelperBase(context), normal_params_size(normal_params_size),
num_handles_to_copy(num_handles_to_copy), num_objects_to_move(num_objects_to_move) {
@@ -206,6 +201,12 @@ public:
template <typename... O>
void PushCopyObjects(Kernel::SharedPtr<O>... pointers);
private:
u32 normal_params_size{};
u32 num_handles_to_copy{};
u32 num_objects_to_move{}; ///< Domain objects or move handles, context dependent
std::ptrdiff_t datapayload_index{};
};
/// Push ///
@@ -273,9 +274,9 @@ inline void ResponseBuilder::PushMoveObjects(Kernel::SharedPtr<O>... pointers) {
class RequestParser : public RequestHelperBase {
public:
RequestParser(u32* command_buffer) : RequestHelperBase(command_buffer) {}
explicit RequestParser(u32* command_buffer) : RequestHelperBase(command_buffer) {}
RequestParser(Kernel::HLERequestContext& context) : RequestHelperBase(context) {
explicit RequestParser(Kernel::HLERequestContext& context) : RequestHelperBase(context) {
ASSERT_MSG(context.GetDataPayloadOffset(), "context is incomplete");
Skip(context.GetDataPayloadOffset(), false);
// Skip the u64 command id, it's already stored in the context
@@ -285,8 +286,9 @@ public:
ResponseBuilder MakeBuilder(u32 normal_params_size, u32 num_handles_to_copy,
u32 num_handles_to_move,
ResponseBuilder::Flags flags = ResponseBuilder::Flags::None) {
return {*context, normal_params_size, num_handles_to_copy, num_handles_to_move, flags};
ResponseBuilder::Flags flags = ResponseBuilder::Flags::None) const {
return ResponseBuilder{*context, normal_params_size, num_handles_to_copy,
num_handles_to_move, flags};
}
template <typename T>
@@ -298,6 +300,14 @@ public:
template <typename First, typename... Other>
void Pop(First& first_value, Other&... other_values);
template <typename T>
T PopEnum() {
static_assert(std::is_enum_v<T>, "T must be an enum type within a PopEnum call.");
static_assert(!std::is_convertible_v<T, int>,
"enum type in PopEnum must be a strongly typed enum.");
return static_cast<T>(Pop<std::underlying_type_t<T>>());
}
/**
* @brief Reads the next normal parameters as a struct, by copying it
* @note: The output class must be correctly packed/padded to fit hardware layout.

View File

@@ -91,7 +91,7 @@ protected:
*/
class HLERequestContext {
public:
HLERequestContext(SharedPtr<Kernel::ServerSession> session);
explicit HLERequestContext(SharedPtr<ServerSession> session);
~HLERequestContext();
/// Returns a pointer to the IPC command buffer for this request.

View File

@@ -2,7 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/config_mem.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/memory.h"
@@ -11,7 +10,6 @@
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
#include "core/hle/shared_page.h"
namespace Kernel {
@@ -19,9 +17,6 @@ unsigned int Object::next_object_id;
/// Initialize the kernel
void Init(u32 system_mode) {
ConfigMem::Init();
SharedPage::Init();
Kernel::MemoryInit(system_mode);
Kernel::ResourceLimitsInit();

View File

@@ -11,11 +11,9 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/hle/config_mem.h"
#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/vm_manager.h"
#include "core/hle/result.h"
#include "core/hle/shared_page.h"
#include "core/memory.h"
#include "core/memory_setup.h"
@@ -63,14 +61,6 @@ void MemoryInit(u32 mem_type) {
// We must've allocated the entire FCRAM by the end
ASSERT(base == Memory::FCRAM_SIZE);
using ConfigMem::config_mem;
config_mem.app_mem_type = mem_type;
// app_mem_malloc does not always match the configured size for memory_region[0]: in case the
// n3DS type override is in effect it reports the size the game expects, not the real one.
config_mem.app_mem_alloc = memory_region_sizes[mem_type][0];
config_mem.sys_mem_alloc = static_cast<u32_le>(memory_regions[1].size);
config_mem.base_mem_alloc = static_cast<u32_le>(memory_regions[2].size);
}
void MemoryShutdown() {

View File

@@ -19,7 +19,7 @@ namespace Kernel {
/// Returns the number of threads that are waiting for a mutex, and the highest priority one among
/// those.
static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread(
SharedPtr<Thread> current_thread, VAddr mutex_addr) {
const SharedPtr<Thread>& current_thread, VAddr mutex_addr) {
SharedPtr<Thread> highest_priority_thread;
u32 num_waiters = 0;

View File

@@ -40,7 +40,9 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
}
static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) {
LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x{:X}", addr);
LOG_WARNING(Kernel_SVC,
"(STUBBED) called, addr=0x{:X}, size=0x{:X}, state0=0x{:X}, state1=0x{:X}", addr,
size, state0, state1);
return RESULT_SUCCESS;
}
@@ -165,11 +167,14 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
using ObjectPtr = SharedPtr<WaitObject>;
std::vector<ObjectPtr> objects(handle_count);
for (int i = 0; i < handle_count; ++i) {
Handle handle = Memory::Read32(handles_address + i * sizeof(Handle));
auto object = g_handle_table.Get<WaitObject>(handle);
if (object == nullptr)
for (u64 i = 0; i < handle_count; ++i) {
const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle));
const auto object = g_handle_table.Get<WaitObject>(handle);
if (object == nullptr) {
return ERR_INVALID_HANDLE;
}
objects[i] = object;
}
@@ -650,12 +655,27 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
ASSERT(thread->condvar_wait_address == condition_variable_addr);
// If the mutex is not yet acquired, acquire it.
u32 mutex_val = Memory::Read32(thread->mutex_wait_address);
size_t current_core = Core::System::GetInstance().CurrentCoreIndex();
auto& monitor = Core::System::GetInstance().Monitor();
// Atomically read the value of the mutex.
u32 mutex_val = 0;
do {
monitor.SetExclusive(current_core, thread->mutex_wait_address);
// If the mutex is not yet acquired, acquire it.
mutex_val = Memory::Read32(thread->mutex_wait_address);
if (mutex_val != 0) {
monitor.ClearExclusive();
break;
}
} while (!monitor.ExclusiveWrite32(current_core, thread->mutex_wait_address,
thread->wait_handle));
if (mutex_val == 0) {
// We were able to acquire the mutex, resume this thread.
Memory::Write32(thread->mutex_wait_address, thread->wait_handle);
ASSERT(thread->status == ThreadStatus::WaitMutex);
thread->ResumeFromWait();
@@ -668,7 +688,19 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
thread->condvar_wait_address = 0;
thread->wait_handle = 0;
} else {
// Couldn't acquire the mutex, block the thread.
// Atomically signal that the mutex now has a waiting thread.
do {
monitor.SetExclusive(current_core, thread->mutex_wait_address);
// Ensure that the mutex value is still what we expect.
u32 value = Memory::Read32(thread->mutex_wait_address);
// TODO(Subv): When this happens, the kernel just clears the exclusive state and
// retries the initial read for this thread.
ASSERT_MSG(mutex_val == value, "Unhandled synchronization primitive case");
} while (!monitor.ExclusiveWrite32(current_core, thread->mutex_wait_address,
mutex_val | Mutex::MutexHasWaitersFlag));
// The mutex is already owned by some other thread, make this thread wait on it.
Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask);
auto owner = g_handle_table.Get<Thread>(owner_handle);
ASSERT(owner);
@@ -676,9 +708,6 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
thread->status = ThreadStatus::WaitMutex;
thread->wakeup_callback = nullptr;
// Signal that the mutex now has a waiting thread.
Memory::Write32(thread->mutex_wait_address, mutex_val | Mutex::MutexHasWaitersFlag);
owner->AddMutexWaiter(thread);
Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule();

View File

@@ -14,6 +14,7 @@
#include "core/arm/arm_interface.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"

View File

@@ -6,6 +6,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/thread.h"

View File

@@ -32,13 +32,17 @@ public:
return HANDLE_TYPE;
}
ResetType reset_type; ///< The ResetType of this timer
ResetType GetResetType() const {
return reset_type;
}
bool signaled; ///< Whether the timer has been signaled or not
std::string name; ///< Name of timer (optional)
u64 GetInitialDelay() const {
return initial_delay;
}
u64 initial_delay; ///< The delay until the timer fires for the first time
u64 interval_delay; ///< The delay until the timer fires after the first time
u64 GetIntervalDelay() const {
return interval_delay;
}
bool ShouldWait(Thread* thread) const override;
void Acquire(Thread* thread) override;
@@ -67,6 +71,14 @@ private:
Timer();
~Timer() override;
ResetType reset_type; ///< The ResetType of this timer
u64 initial_delay; ///< The delay until the timer fires for the first time
u64 interval_delay; ///< The delay until the timer fires after the first time
bool signaled; ///< Whether the timer has been signaled or not
std::string name; ///< Name of timer (optional)
/// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
Handle callback_handle;
};

View File

@@ -5,7 +5,6 @@
#include <algorithm>
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/hle/config_mem.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/memory.h"
@@ -13,7 +12,6 @@
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
#include "core/hle/shared_page.h"
namespace Kernel {

View File

@@ -35,7 +35,7 @@ static constexpr u128 DEFAULT_USER_ID{1ull, 0ull};
class IProfile final : public ServiceFramework<IProfile> {
public:
IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) {
explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) {
static const FunctionInfo functions[] = {
{0, nullptr, "Get"},
{1, &IProfile::GetBase, "GetBase"},

View File

@@ -19,7 +19,4 @@ private:
std::shared_ptr<Module> apm;
};
/// Registers all AM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
} // namespace Service::APM

View File

@@ -5,7 +5,7 @@
#include <array>
#include <vector>
#include "common/logging/log.h"
#include "core/core_timing.h"
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/hle_ipc.h"
@@ -13,17 +13,22 @@
namespace Service::Audio {
/// Switch sample rate frequency
constexpr u32 sample_rate{48000};
/// TODO(st4rk): dynamic number of channels, as I think Switch has support
/// to more audio channels (probably when Docked I guess)
constexpr u32 audio_channels{2};
/// TODO(st4rk): find a proper value for the audio_ticks
constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 500)};
namespace ErrCodes {
enum {
ErrorUnknown = 2,
BufferCountExceeded = 8,
};
}
constexpr std::array<char, 10> DefaultDevice{{"DeviceOut"}};
constexpr int DefaultSampleRate{48000};
class IAudioOut final : public ServiceFramework<IAudioOut> {
public:
IAudioOut() : ServiceFramework("IAudioOut"), audio_out_state(AudioState::Stopped) {
IAudioOut(AudoutParams audio_params)
: ServiceFramework("IAudioOut"), audio_params(audio_params),
audio_core(Core::System::GetInstance().AudioCore()) {
static const FunctionInfo functions[] = {
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
{1, &IAudioOut::StartAudioOut, "StartAudioOut"},
@@ -31,66 +36,65 @@ public:
{3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"},
{4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"},
{5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"},
{6, nullptr, "ContainsAudioOutBuffer"},
{6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"},
{7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"},
{8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"},
{9, nullptr, "GetAudioOutBufferCount"},
{9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"},
{10, nullptr, "GetAudioOutPlayedSampleCount"},
{11, nullptr, "FlushAudioOutBuffers"},
};
RegisterHandlers(functions);
// This is the event handle used to check if the audio buffer was released
buffer_event =
Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioOutBufferReleasedEvent");
buffer_event = Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioOutBufferReleased");
// Register event callback to update the Audio Buffer
audio_event = CoreTiming::RegisterEvent(
"IAudioOut::UpdateAudioBuffersCallback", [this](u64 userdata, int cycles_late) {
UpdateAudioBuffersCallback();
CoreTiming::ScheduleEvent(audio_ticks - cycles_late, audio_event);
});
// Start the audio event
CoreTiming::ScheduleEvent(audio_ticks, audio_event);
}
~IAudioOut() {
CoreTiming::UnscheduleEvent(audio_event, 0);
stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count,
[=]() { buffer_event->Signal(); });
}
private:
struct AudioBuffer {
u64_le next;
u64_le buffer;
u64_le buffer_capacity;
u64_le buffer_size;
u64_le offset;
};
static_assert(sizeof(AudioBuffer) == 0x28, "AudioBuffer is an invalid size");
void GetAudioOutState(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u32>(audio_out_state));
rb.Push(static_cast<u32>(stream->IsPlaying() ? AudioState::Started : AudioState::Stopped));
}
void StartAudioOut(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
LOG_DEBUG(Service_Audio, "called");
// Start audio
audio_out_state = AudioState::Started;
if (stream->IsPlaying()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::ErrorUnknown));
return;
}
audio_core.StartStream(stream);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void StopAudioOut(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
LOG_DEBUG(Service_Audio, "called");
// Stop audio
audio_out_state = AudioState::Stopped;
queue_keys.clear();
audio_core.StopStream(stream);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void RegisterBufferEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
LOG_DEBUG(Service_Audio, "called");
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
@@ -98,101 +102,107 @@ private:
}
void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
LOG_DEBUG(Service_Audio, "(STUBBED) called {}", ctx.Description());
IPC::RequestParser rp{ctx};
const u64 key{rp.Pop<u64>()};
queue_keys.insert(queue_keys.begin(), key);
const auto& input_buffer{ctx.ReadBuffer()};
ASSERT_MSG(input_buffer.size() == sizeof(AudioBuffer),
"AudioBuffer input is an invalid size!");
AudioBuffer audio_buffer{};
std::memcpy(&audio_buffer, input_buffer.data(), sizeof(AudioBuffer));
const u64 tag{rp.Pop<u64>()};
std::vector<u8> data(audio_buffer.buffer_size);
Memory::ReadBlock(audio_buffer.buffer, data.data(), data.size());
if (!audio_core.QueueBuffer(stream, tag, std::move(data))) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::BufferCountExceeded));
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetReleasedAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
LOG_DEBUG(Service_Audio, "called {}", ctx.Description());
IPC::RequestParser rp{ctx};
const u64 max_count{ctx.GetWriteBufferSize() / sizeof(u64)};
const auto released_buffers{audio_core.GetTagsAndReleaseBuffers(stream, max_count)};
// TODO(st4rk): This is how libtransistor currently implements the
// GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address
// is used to know which buffer should be filled with data and send again to the service
// through AppendAudioOutBuffer. Check if this is the proper way to do it.
u64 key{0};
if (queue_keys.size()) {
key = queue_keys.back();
queue_keys.pop_back();
}
ctx.WriteBuffer(&key, sizeof(u64));
std::vector<u64> tags{released_buffers};
tags.resize(max_count);
ctx.WriteBuffer(tags);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
// TODO(st4rk): This might be the total of released buffers, needs to be verified on
// hardware
rb.Push<u32>(static_cast<u32>(queue_keys.size()));
rb.Push<u32>(static_cast<u32>(released_buffers.size()));
}
void UpdateAudioBuffersCallback() {
if (audio_out_state != AudioState::Started) {
return;
}
if (queue_keys.empty()) {
return;
}
buffer_event->Signal();
void ContainsAudioOutBuffer(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
IPC::RequestParser rp{ctx};
const u64 tag{rp.Pop<u64>()};
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(stream->ContainsBuffer(tag));
}
enum class AudioState : u32 {
Started,
Stopped,
};
void GetAudioOutBufferCount(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u32>(stream->GetQueueSize()));
}
/// This is used to trigger the audio event callback that is going to read the samples from the
/// audio_buffer list and enqueue the samples using the sink (audio_core).
CoreTiming::EventType* audio_event;
AudioCore::AudioOut& audio_core;
AudioCore::StreamPtr stream;
AudoutParams audio_params{};
/// This is the evend handle used to check if the audio buffer was released
Kernel::SharedPtr<Kernel::Event> buffer_event;
/// (st4rk): This is just a temporary workaround for the future implementation. Libtransistor
/// uses the key as an address in the App, so we need to return when the
/// GetReleasedAudioOutBuffer_1 is called, otherwise we'll run in problems, because
/// libtransistor uses the key returned as an pointer.
std::vector<u64> queue_keys;
AudioState audio_out_state;
};
void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
LOG_DEBUG(Service_Audio, "called");
IPC::RequestParser rp{ctx};
constexpr std::array<char, 15> audio_interface{{"AudioInterface"}};
ctx.WriteBuffer(audio_interface);
ctx.WriteBuffer(DefaultDevice);
IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0);
rb.Push(RESULT_SUCCESS);
// TODO(st4rk): We're currently returning only one audio interface (stringlist size). However,
// it's highly possible to have more than one interface (despite that libtransistor requires
// only one).
rb.Push<u32>(1);
rb.Push<u32>(1); // Amount of audio devices
}
void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called");
LOG_DEBUG(Service_Audio, "called");
if (!audio_out_interface) {
audio_out_interface = std::make_shared<IAudioOut>();
ctx.WriteBuffer(DefaultDevice);
IPC::RequestParser rp{ctx};
auto params{rp.PopRaw<AudoutParams>()};
if (params.channel_count <= 2) {
// Mono does not exist for audout
params.channel_count = 2;
} else {
params.channel_count = 6;
}
if (!params.sample_rate) {
params.sample_rate = DefaultSampleRate;
}
// TODO(bunnei): Support more than one IAudioOut interface. When we add this, ListAudioOutsImpl
// will likely need to be updated as well.
ASSERT_MSG(!audio_out_interface, "Unimplemented");
audio_out_interface = std::make_shared<IAudioOut>(std::move(params));
IPC::ResponseBuilder rb{ctx, 6, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(sample_rate);
rb.Push<u32>(audio_channels);
rb.Push<u32>(DefaultSampleRate);
rb.Push<u32>(params.channel_count);
rb.Push<u32>(static_cast<u32>(PcmFormat::Int16));
rb.Push<u32>(0); // This field is unknown
rb.Push<u32>(static_cast<u32>(AudioState::Stopped));
rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface);
}

View File

@@ -12,6 +12,18 @@ class HLERequestContext;
namespace Service::Audio {
struct AudoutParams {
s32_le sample_rate;
u16_le channel_count;
INSERT_PADDING_BYTES(2);
};
static_assert(sizeof(AudoutParams) == 0x8, "AudoutParams is an invalid size");
enum class AudioState : u32 {
Started,
Stopped,
};
class IAudioOut;
class AudOutU final : public ServiceFramework<AudOutU> {

View File

@@ -7,6 +7,7 @@
#include "common/alignment.h"
#include "common/logging/log.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/hle_ipc.h"

View File

@@ -0,0 +1,72 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/btdrv/btdrv.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
namespace Service::BtDrv {
class BtDrv final : public ServiceFramework<BtDrv> {
public:
explicit BtDrv() : ServiceFramework{"btdrv"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Unknown"},
{1, nullptr, "Init"},
{2, nullptr, "Enable"},
{3, nullptr, "Disable"},
{4, nullptr, "CleanupAndShutdown"},
{5, nullptr, "GetAdapterProperties"},
{6, nullptr, "GetAdapterProperty"},
{7, nullptr, "SetAdapterProperty"},
{8, nullptr, "StartDiscovery"},
{9, nullptr, "CancelDiscovery"},
{10, nullptr, "CreateBond"},
{11, nullptr, "RemoveBond"},
{12, nullptr, "CancelBond"},
{13, nullptr, "PinReply"},
{14, nullptr, "SspReply"},
{15, nullptr, "Unknown2"},
{16, nullptr, "InitInterfaces"},
{17, nullptr, "HidHostInterface_Connect"},
{18, nullptr, "HidHostInterface_Disconnect"},
{19, nullptr, "HidHostInterface_SendData"},
{20, nullptr, "HidHostInterface_SendData2"},
{21, nullptr, "HidHostInterface_SetReport"},
{22, nullptr, "HidHostInterface_GetReport"},
{23, nullptr, "HidHostInterface_WakeController"},
{24, nullptr, "HidHostInterface_AddPairedDevice"},
{25, nullptr, "HidHostInterface_GetPairedDevice"},
{26, nullptr, "HidHostInterface_CleanupAndShutdown"},
{27, nullptr, "Unknown3"},
{28, nullptr, "ExtInterface_SetTSI"},
{29, nullptr, "ExtInterface_SetBurstMode"},
{30, nullptr, "ExtInterface_SetZeroRetran"},
{31, nullptr, "ExtInterface_SetMcMode"},
{32, nullptr, "ExtInterface_StartLlrMode"},
{33, nullptr, "ExtInterface_ExitLlrMode"},
{34, nullptr, "ExtInterface_SetRadio"},
{35, nullptr, "ExtInterface_SetVisibility"},
{36, nullptr, "Unknown4"},
{37, nullptr, "Unknown5"},
{38, nullptr, "HidHostInterface_GetLatestPlr"},
{39, nullptr, "ExtInterface_GetPendingConnections"},
{40, nullptr, "HidHostInterface_GetChannelMap"},
{41, nullptr, "SetIsBluetoothBoostEnabled"},
{42, nullptr, "GetIsBluetoothBoostEnabled"},
{43, nullptr, "SetIsBluetoothAfhEnabled"},
{44, nullptr, "GetIsBluetoothAfhEnabled"},
};
// clang-format on
RegisterHandlers(functions);
}
};
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<BtDrv>()->InstallAsService(sm);
}
} // namespace Service::BtDrv

View File

@@ -0,0 +1,16 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Service::BtDrv {
/// Registers all BtDrv services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::BtDrv

View File

@@ -0,0 +1,51 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <memory>
#include "core/hle/service/erpt/erpt.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
namespace Service::ERPT {
class ErrorReportContext final : public ServiceFramework<ErrorReportContext> {
public:
explicit ErrorReportContext() : ServiceFramework{"erpt:c"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "SubmitContext"},
{1, nullptr, "CreateReport"},
{2, nullptr, "Unknown1"},
{3, nullptr, "Unknown2"},
{4, nullptr, "Unknown3"},
{5, nullptr, "Unknown4"},
{6, nullptr, "Unknown5"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class ErrorReportSession final : public ServiceFramework<ErrorReportSession> {
public:
explicit ErrorReportSession() : ServiceFramework{"erpt:r"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "OpenReport"},
{1, nullptr, "OpenManager"},
};
// clang-format on
RegisterHandlers(functions);
}
};
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<ErrorReportContext>()->InstallAsService(sm);
std::make_shared<ErrorReportSession>()->InstallAsService(sm);
}
} // namespace Service::ERPT

View File

@@ -0,0 +1,16 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Service::ERPT {
/// Registers all ERPT services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::ERPT

View File

@@ -0,0 +1,57 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/service.h"
namespace Service::ES {
class ETicket final : public ServiceFramework<ETicket> {
public:
explicit ETicket() : ServiceFramework{"es"} {
static const FunctionInfo functions[] = {
{1, nullptr, "ImportTicket"},
{2, nullptr, "ImportTicketCertificateSet"},
{3, nullptr, "DeleteTicket"},
{4, nullptr, "DeletePersonalizedTicket"},
{5, nullptr, "DeleteAllCommonTicket"},
{6, nullptr, "DeleteAllPersonalizedTicket"},
{7, nullptr, "DeleteAllPersonalizedTicketEx"},
{8, nullptr, "GetTitleKey"},
{9, nullptr, "CountCommonTicket"},
{10, nullptr, "CountPersonalizedTicket"},
{11, nullptr, "ListCommonTicket"},
{12, nullptr, "ListPersonalizedTicket"},
{13, nullptr, "ListMissingPersonalizedTicket"},
{14, nullptr, "GetCommonTicketSize"},
{15, nullptr, "GetPersonalizedTicketSize"},
{16, nullptr, "GetCommonTicketData"},
{17, nullptr, "GetPersonalizedTicketData"},
{18, nullptr, "OwnTicket"},
{19, nullptr, "GetTicketInfo"},
{20, nullptr, "ListLightTicketInfo"},
{21, nullptr, "SignData"},
{22, nullptr, "GetCommonTicketAndCertificateSize"},
{23, nullptr, "GetCommonTicketAndCertificateData"},
{24, nullptr, "ImportPrepurchaseRecord"},
{25, nullptr, "DeletePrepurchaseRecord"},
{26, nullptr, "DeleteAllPrepurchaseRecord"},
{27, nullptr, "CountPrepurchaseRecord"},
{28, nullptr, "ListPrepurchaseRecord"},
{29, nullptr, "ListPrepurchaseRecordInfo"},
{30, nullptr, "Unknown1"},
{31, nullptr, "Unknown2"},
{32, nullptr, "Unknown3"},
{33, nullptr, "Unknown4"},
{34, nullptr, "Unknown5"},
{35, nullptr, "Unknown6"},
};
RegisterHandlers(functions);
}
};
void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<ETicket>()->InstallAsService(service_manager);
}
} // namespace Service::ES

View File

@@ -0,0 +1,16 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Service::ES {
/// Registers all ES services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
} // namespace Service::ES

View File

@@ -0,0 +1,52 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <memory>
#include "core/hle/service/eupld/eupld.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
namespace Service::EUPLD {
class ErrorUploadContext final : public ServiceFramework<ErrorUploadContext> {
public:
explicit ErrorUploadContext() : ServiceFramework{"eupld:c"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "SetUrl"},
{1, nullptr, "ImportCrt"},
{2, nullptr, "ImportPki"},
{3, nullptr, "SetAutoUpload"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class ErrorUploadRequest final : public ServiceFramework<ErrorUploadRequest> {
public:
explicit ErrorUploadRequest() : ServiceFramework{"eupld:r"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Initialize"},
{1, nullptr, "UploadAll"},
{2, nullptr, "UploadSelected"},
{3, nullptr, "GetUploadStatus"},
{4, nullptr, "CancelUpload"},
{5, nullptr, "GetResult"},
};
// clang-format on
RegisterHandlers(functions);
}
};
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<ErrorUploadContext>()->InstallAsService(sm);
std::make_shared<ErrorUploadRequest>()->InstallAsService(sm);
}
} // namespace Service::EUPLD

View File

@@ -0,0 +1,16 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Service::EUPLD {
/// Registers all EUPLD services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::EUPLD

View File

@@ -24,7 +24,8 @@ namespace Service::FileSystem {
constexpr u64 EMULATED_SD_REPORTED_SIZE = 32000000000;
static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base,
std::string_view dir_name) {
std::string_view dir_name_) {
std::string dir_name(FileUtil::SanitizePath(dir_name_));
if (dir_name.empty() || dir_name == "." || dir_name == "/" || dir_name == "\\")
return base;
@@ -38,7 +39,8 @@ std::string VfsDirectoryServiceWrapper::GetName() const {
return backing->GetName();
}
ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path, u64 size) const {
ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 size) const {
std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
auto file = dir->CreateFile(FileUtil::GetFilename(path));
if (file == nullptr) {
@@ -52,7 +54,8 @@ ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path, u64 s
return RESULT_SUCCESS;
}
ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path) const {
ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) const {
std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (path == "/" || path == "\\") {
// TODO(DarkLordZach): Why do games call this and what should it do? Works as is but...
@@ -60,14 +63,15 @@ ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path) const
}
if (dir->GetFile(FileUtil::GetFilename(path)) == nullptr)
return FileSys::ERROR_PATH_NOT_FOUND;
if (!backing->DeleteFile(FileUtil::GetFilename(path))) {
if (!dir->DeleteFile(FileUtil::GetFilename(path))) {
// TODO(DarkLordZach): Find a better error code for this
return ResultCode(-1);
}
return RESULT_SUCCESS;
}
ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path) const {
ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) const {
std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (dir == nullptr && FileUtil::GetFilename(FileUtil::GetParentPath(path)).empty())
dir = backing;
@@ -79,7 +83,8 @@ ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path)
return RESULT_SUCCESS;
}
ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path) const {
ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path_) const {
std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (!dir->DeleteSubdirectory(FileUtil::GetFilename(path))) {
// TODO(DarkLordZach): Find a better error code for this
@@ -88,7 +93,8 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path)
return RESULT_SUCCESS;
}
ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::string& path) const {
ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::string& path_) const {
std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (!dir->DeleteSubdirectoryRecursive(FileUtil::GetFilename(path))) {
// TODO(DarkLordZach): Find a better error code for this
@@ -97,8 +103,10 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::str
return RESULT_SUCCESS;
}
ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path,
const std::string& dest_path) const {
ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
const std::string& dest_path_) const {
std::string src_path(FileUtil::SanitizePath(src_path_));
std::string dest_path(FileUtil::SanitizePath(dest_path_));
auto src = backing->GetFileRelative(src_path);
if (FileUtil::GetParentPath(src_path) == FileUtil::GetParentPath(dest_path)) {
// Use more-optimized vfs implementation rename.
@@ -130,8 +138,10 @@ ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path,
return RESULT_SUCCESS;
}
ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_path,
const std::string& dest_path) const {
ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_path_,
const std::string& dest_path_) const {
std::string src_path(FileUtil::SanitizePath(src_path_));
std::string dest_path(FileUtil::SanitizePath(dest_path_));
auto src = GetDirectoryRelativeWrapped(backing, src_path);
if (FileUtil::GetParentPath(src_path) == FileUtil::GetParentPath(dest_path)) {
// Use more-optimized vfs implementation rename.
@@ -154,8 +164,9 @@ ResultCode VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_pa
return ResultCode(-1);
}
ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::string& path,
ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::string& path_,
FileSys::Mode mode) const {
std::string path(FileUtil::SanitizePath(path_));
auto npath = path;
while (npath.size() > 0 && (npath[0] == '/' || npath[0] == '\\'))
npath = npath.substr(1);
@@ -171,7 +182,8 @@ ResultVal<FileSys::VirtualFile> VfsDirectoryServiceWrapper::OpenFile(const std::
return MakeResult<FileSys::VirtualFile>(file);
}
ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const std::string& path) {
ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const std::string& path_) {
std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, path);
if (dir == nullptr) {
// TODO(DarkLordZach): Find a better error code for this
@@ -188,7 +200,8 @@ u64 VfsDirectoryServiceWrapper::GetFreeSpaceSize() const {
}
ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType(
const std::string& path) const {
const std::string& path_) const {
std::string path(FileUtil::SanitizePath(path_));
auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (dir == nullptr)
return FileSys::ERROR_PATH_NOT_FOUND;
@@ -272,9 +285,9 @@ void RegisterFileSystems() {
sdmc_factory = nullptr;
auto nand_directory = std::make_shared<FileSys::RealVfsDirectory>(
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), FileSys::Mode::Write);
FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), FileSys::Mode::ReadWrite);
auto sd_directory = std::make_shared<FileSys::RealVfsDirectory>(
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), FileSys::Mode::Write);
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), FileSys::Mode::ReadWrite);
auto savedata = std::make_unique<FileSys::SaveDataFactory>(std::move(nand_directory));
save_data_factory = std::move(savedata);

View File

@@ -5,8 +5,7 @@
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/friend/friend.h"
#include "core/hle/service/friend/friend_a.h"
#include "core/hle/service/friend/friend_u.h"
#include "core/hle/service/friend/interface.h"
namespace Service::Friend {
@@ -21,8 +20,11 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
void InstallInterfaces(SM::ServiceManager& service_manager) {
auto module = std::make_shared<Module>();
std::make_shared<Friend_A>(module)->InstallAsService(service_manager);
std::make_shared<Friend_U>(module)->InstallAsService(service_manager);
std::make_shared<Friend>(module, "friend:a")->InstallAsService(service_manager);
std::make_shared<Friend>(module, "friend:m")->InstallAsService(service_manager);
std::make_shared<Friend>(module, "friend:s")->InstallAsService(service_manager);
std::make_shared<Friend>(module, "friend:u")->InstallAsService(service_manager);
std::make_shared<Friend>(module, "friend:v")->InstallAsService(service_manager);
}
} // namespace Service::Friend

View File

@@ -1,18 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/friend/friend_a.h"
namespace Service::Friend {
Friend_A::Friend_A(std::shared_ptr<Module> module)
: Module::Interface(std::move(module), "friend:a") {
static const FunctionInfo functions[] = {
{0, &Friend_A::CreateFriendService, "CreateFriendService"},
{1, nullptr, "CreateNotificationService"},
};
RegisterHandlers(functions);
}
} // namespace Service::Friend

View File

@@ -1,16 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/friend/friend.h"
namespace Service::Friend {
class Friend_A final : public Module::Interface {
public:
explicit Friend_A(std::shared_ptr<Module> module);
};
} // namespace Service::Friend

View File

@@ -2,15 +2,16 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/friend/friend_u.h"
#include "core/hle/service/friend/interface.h"
namespace Service::Friend {
Friend_U::Friend_U(std::shared_ptr<Module> module)
: Module::Interface(std::move(module), "friend:u") {
Friend::Friend(std::shared_ptr<Module> module, const char* name)
: Interface(std::move(module), name) {
static const FunctionInfo functions[] = {
{0, &Friend_U::CreateFriendService, "CreateFriendService"},
{0, &Friend::CreateFriendService, "CreateFriendService"},
{1, nullptr, "CreateNotificationService"},
{2, nullptr, "CreateDaemonSuspendSessionService"},
};
RegisterHandlers(functions);
}

View File

@@ -8,9 +8,9 @@
namespace Service::Friend {
class Friend_U final : public Module::Interface {
class Friend final : public Module::Interface {
public:
explicit Friend_U(std::shared_ptr<Module> module);
explicit Friend(std::shared_ptr<Module> module, const char* name);
};
} // namespace Service::Friend

View File

@@ -0,0 +1,31 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <memory>
#include "core/hle/service/grc/grc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
namespace Service::GRC {
class GRC final : public ServiceFramework<GRC> {
public:
explicit GRC() : ServiceFramework{"grc:c"} {
// clang-format off
static const FunctionInfo functions[] = {
{1, nullptr, "OpenContinuousRecorder"},
{2, nullptr, "OpenGameMovieTrimmer"},
};
// clang-format on
RegisterHandlers(functions);
}
};
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<GRC>()->InstallAsService(sm);
}
} // namespace Service::GRC

View File

@@ -0,0 +1,15 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Service::GRC {
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::GRC

View File

@@ -5,6 +5,7 @@
#include <atomic>
#include "common/logging/log.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "core/frontend/emu_window.h"
#include "core/frontend/input.h"
#include "core/hle/ipc_helpers.h"
@@ -13,6 +14,8 @@
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/hid/irs.h"
#include "core/hle/service/hid/xcd.h"
#include "core/hle/service/service.h"
namespace Service::HID {
@@ -554,10 +557,233 @@ private:
}
};
class HidDbg final : public ServiceFramework<HidDbg> {
public:
explicit HidDbg() : ServiceFramework{"hid:dbg"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "DeactivateDebugPad"},
{1, nullptr, "SetDebugPadAutoPilotState"},
{2, nullptr, "UnsetDebugPadAutoPilotState"},
{10, nullptr, "DeactivateTouchScreen"},
{11, nullptr, "SetTouchScreenAutoPilotState"},
{12, nullptr, "UnsetTouchScreenAutoPilotState"},
{20, nullptr, "DeactivateMouse"},
{21, nullptr, "SetMouseAutoPilotState"},
{22, nullptr, "UnsetMouseAutoPilotState"},
{30, nullptr, "DeactivateKeyboard"},
{31, nullptr, "SetKeyboardAutoPilotState"},
{32, nullptr, "UnsetKeyboardAutoPilotState"},
{50, nullptr, "DeactivateXpad"},
{51, nullptr, "SetXpadAutoPilotState"},
{52, nullptr, "UnsetXpadAutoPilotState"},
{60, nullptr, "DeactivateJoyXpad"},
{91, nullptr, "DeactivateGesture"},
{110, nullptr, "DeactivateHomeButton"},
{111, nullptr, "SetHomeButtonAutoPilotState"},
{112, nullptr, "UnsetHomeButtonAutoPilotState"},
{120, nullptr, "DeactivateSleepButton"},
{121, nullptr, "SetSleepButtonAutoPilotState"},
{122, nullptr, "UnsetSleepButtonAutoPilotState"},
{123, nullptr, "DeactivateInputDetector"},
{130, nullptr, "DeactivateCaptureButton"},
{131, nullptr, "SetCaptureButtonAutoPilotState"},
{132, nullptr, "UnsetCaptureButtonAutoPilotState"},
{133, nullptr, "SetShiftAccelerometerCalibrationValue"},
{134, nullptr, "GetShiftAccelerometerCalibrationValue"},
{135, nullptr, "SetShiftGyroscopeCalibrationValue"},
{136, nullptr, "GetShiftGyroscopeCalibrationValue"},
{140, nullptr, "DeactivateConsoleSixAxisSensor"},
{141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"},
{142, nullptr, "DeactivateSevenSixAxisSensor"},
{201, nullptr, "ActivateFirmwareUpdate"},
{202, nullptr, "DeactivateFirmwareUpdate"},
{203, nullptr, "StartFirmwareUpdate"},
{204, nullptr, "GetFirmwareUpdateStage"},
{205, nullptr, "GetFirmwareVersion"},
{206, nullptr, "GetDestinationFirmwareVersion"},
{207, nullptr, "DiscardFirmwareInfoCacheForRevert"},
{208, nullptr, "StartFirmwareUpdateForRevert"},
{209, nullptr, "GetAvailableFirmwareVersionForRevert"},
{210, nullptr, "IsFirmwareUpdatingDevice"},
{221, nullptr, "UpdateControllerColor"},
{222, nullptr, "ConnectUsbPadsAsync"},
{223, nullptr, "DisconnectUsbPadsAsync"},
{224, nullptr, "UpdateDesignInfo"},
{225, nullptr, "GetUniquePadDriverState"},
{226, nullptr, "GetSixAxisSensorDriverStates"},
{301, nullptr, "GetAbstractedPadHandles"},
{302, nullptr, "GetAbstractedPadState"},
{303, nullptr, "GetAbstractedPadsState"},
{321, nullptr, "SetAutoPilotVirtualPadState"},
{322, nullptr, "UnsetAutoPilotVirtualPadState"},
{323, nullptr, "UnsetAllAutoPilotVirtualPadState"},
{350, nullptr, "AddRegisteredDevice"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class HidSys final : public ServiceFramework<HidSys> {
public:
explicit HidSys() : ServiceFramework{"hid:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
{31, nullptr, "SendKeyboardLockKeyEvent"},
{101, nullptr, "AcquireHomeButtonEventHandle"},
{111, nullptr, "ActivateHomeButton"},
{121, nullptr, "AcquireSleepButtonEventHandle"},
{131, nullptr, "ActivateSleepButton"},
{141, nullptr, "AcquireCaptureButtonEventHandle"},
{151, nullptr, "ActivateCaptureButton"},
{210, nullptr, "AcquireNfcDeviceUpdateEventHandle"},
{211, nullptr, "GetNpadsWithNfc"},
{212, nullptr, "AcquireNfcActivateEventHandle"},
{213, nullptr, "ActivateNfc"},
{214, nullptr, "GetXcdHandleForNpadWithNfc"},
{215, nullptr, "IsNfcActivated"},
{230, nullptr, "AcquireIrSensorEventHandle"},
{231, nullptr, "ActivateIrSensor"},
{301, nullptr, "ActivateNpadSystem"},
{303, nullptr, "ApplyNpadSystemCommonPolicy"},
{304, nullptr, "EnableAssigningSingleOnSlSrPress"},
{305, nullptr, "DisableAssigningSingleOnSlSrPress"},
{306, nullptr, "GetLastActiveNpad"},
{307, nullptr, "GetNpadSystemExtStyle"},
{308, nullptr, "ApplyNpadSystemCommonPolicyFull"},
{309, nullptr, "GetNpadFullKeyGripColor"},
{311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
{321, nullptr, "GetUniquePadsFromNpad"},
{322, nullptr, "GetIrSensorState"},
{323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
{500, nullptr, "SetAppletResourceUserId"},
{501, nullptr, "RegisterAppletResourceUserId"},
{502, nullptr, "UnregisterAppletResourceUserId"},
{503, nullptr, "EnableAppletToGetInput"},
{504, nullptr, "SetAruidValidForVibration"},
{505, nullptr, "EnableAppletToGetSixAxisSensor"},
{510, nullptr, "SetVibrationMasterVolume"},
{511, nullptr, "GetVibrationMasterVolume"},
{512, nullptr, "BeginPermitVibrationSession"},
{513, nullptr, "EndPermitVibrationSession"},
{520, nullptr, "EnableHandheldHids"},
{521, nullptr, "DisableHandheldHids"},
{540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
{541, nullptr, "GetPlayReportControllerUsages"},
{542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
{543, nullptr, "GetRegisteredDevicesOld"},
{544, nullptr, "AcquireConnectionTriggerTimeoutEvent"},
{545, nullptr, "SendConnectionTrigger"},
{546, nullptr, "AcquireDeviceRegisteredEventForControllerSupport"},
{547, nullptr, "GetAllowedBluetoothLinksCount"},
{548, nullptr, "GetRegisteredDevices"},
{700, nullptr, "ActivateUniquePad"},
{702, nullptr, "AcquireUniquePadConnectionEventHandle"},
{703, nullptr, "GetUniquePadIds"},
{751, nullptr, "AcquireJoyDetachOnBluetoothOffEventHandle"},
{800, nullptr, "ListSixAxisSensorHandles"},
{801, nullptr, "IsSixAxisSensorUserCalibrationSupported"},
{802, nullptr, "ResetSixAxisSensorCalibrationValues"},
{803, nullptr, "StartSixAxisSensorUserCalibration"},
{804, nullptr, "CancelSixAxisSensorUserCalibration"},
{805, nullptr, "GetUniquePadBluetoothAddress"},
{806, nullptr, "DisconnectUniquePad"},
{807, nullptr, "GetUniquePadType"},
{808, nullptr, "GetUniquePadInterface"},
{809, nullptr, "GetUniquePadSerialNumber"},
{810, nullptr, "GetUniquePadControllerNumber"},
{811, nullptr, "GetSixAxisSensorUserCalibrationStage"},
{821, nullptr, "StartAnalogStickManualCalibration"},
{822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"},
{823, nullptr, "CancelAnalogStickManualCalibration"},
{824, nullptr, "ResetAnalogStickManualCalibration"},
{825, nullptr, "GetAnalogStickState"},
{826, nullptr, "GetAnalogStickManualCalibrationStage"},
{827, nullptr, "IsAnalogStickButtonPressed"},
{828, nullptr, "IsAnalogStickInReleasePosition"},
{829, nullptr, "IsAnalogStickInCircumference"},
{850, nullptr, "IsUsbFullKeyControllerEnabled"},
{851, nullptr, "EnableUsbFullKeyController"},
{852, nullptr, "IsUsbConnected"},
{900, nullptr, "ActivateInputDetector"},
{901, nullptr, "NotifyInputDetector"},
{1000, nullptr, "InitializeFirmwareUpdate"},
{1001, nullptr, "GetFirmwareVersion"},
{1002, nullptr, "GetAvailableFirmwareVersion"},
{1003, nullptr, "IsFirmwareUpdateAvailable"},
{1004, nullptr, "CheckFirmwareUpdateRequired"},
{1005, nullptr, "StartFirmwareUpdate"},
{1006, nullptr, "AbortFirmwareUpdate"},
{1007, nullptr, "GetFirmwareUpdateState"},
{1008, nullptr, "ActivateAudioControl"},
{1009, nullptr, "AcquireAudioControlEventHandle"},
{1010, nullptr, "GetAudioControlStates"},
{1011, nullptr, "DeactivateAudioControl"},
{1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"},
{1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"},
{1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
{1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"},
{1100, nullptr, "GetHidbusSystemServiceObject"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class HidTmp final : public ServiceFramework<HidTmp> {
public:
explicit HidTmp() : ServiceFramework{"hid:tmp"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetConsoleSixAxisSensorCalibrationValues"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class HidBus final : public ServiceFramework<HidBus> {
public:
explicit HidBus() : ServiceFramework{"hidbus"} {
// clang-format off
static const FunctionInfo functions[] = {
{1, nullptr, "GetBusHandle"},
{2, nullptr, "IsExternalDeviceConnected"},
{3, nullptr, "Initialize"},
{4, nullptr, "Finalize"},
{5, nullptr, "EnableExternalDevice"},
{6, nullptr, "GetExternalDeviceId"},
{7, nullptr, "SendCommandAsync"},
{8, nullptr, "GetSendCommandAsynceResult"},
{9, nullptr, "SetEventForSendCommandAsycResult"},
{10, nullptr, "GetSharedMemoryHandle"},
{11, nullptr, "EnableJoyPollingReceiveMode"},
{12, nullptr, "DisableJoyPollingReceiveMode"},
{13, nullptr, "GetPollingData"},
};
// clang-format on
RegisterHandlers(functions);
}
};
void ReloadInputDevices() {}
void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<Hid>()->InstallAsService(service_manager);
std::make_shared<HidBus>()->InstallAsService(service_manager);
std::make_shared<HidDbg>()->InstallAsService(service_manager);
std::make_shared<HidSys>()->InstallAsService(service_manager);
std::make_shared<HidTmp>()->InstallAsService(service_manager);
std::make_shared<IRS>()->InstallAsService(service_manager);
std::make_shared<IRS_SYS>()->InstallAsService(service_manager);
std::make_shared<XCD_SYS>()->InstallAsService(service_manager);
}
} // namespace Service::HID

View File

@@ -0,0 +1,49 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/hid/irs.h"
namespace Service::HID {
IRS::IRS() : ServiceFramework{"irs"} {
// clang-format off
static const FunctionInfo functions[] = {
{302, nullptr, "ActivateIrsensor"},
{303, nullptr, "DeactivateIrsensor"},
{304, nullptr, "GetIrsensorSharedMemoryHandle"},
{305, nullptr, "StopImageProcessor"},
{306, nullptr, "RunMomentProcessor"},
{307, nullptr, "RunClusteringProcessor"},
{308, nullptr, "RunImageTransferProcessor"},
{309, nullptr, "GetImageTransferProcessorState"},
{310, nullptr, "RunTeraPluginProcessor"},
{311, nullptr, "GetNpadIrCameraHandle"},
{312, nullptr, "RunPointingProcessor"},
{313, nullptr, "SuspendImageProcessor"},
{314, nullptr, "CheckFirmwareVersion"},
{315, nullptr, "SetFunctionLevel"},
{316, nullptr, "RunImageTransferExProcessor"},
{317, nullptr, "RunIrLedProcessor"},
{318, nullptr, "StopImageProcessorAsync"},
{319, nullptr, "ActivateIrsensorWithFunctionLevel"},
};
// clang-format on
RegisterHandlers(functions);
}
IRS_SYS::IRS_SYS() : ServiceFramework{"irs:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
{500, nullptr, "SetAppletResourceUserId"},
{501, nullptr, "RegisterAppletResourceUserId"},
{502, nullptr, "UnregisterAppletResourceUserId"},
{503, nullptr, "EnableAppletToGetInput"},
};
// clang-format on
RegisterHandlers(functions);
}
} // namespace Service::HID

View File

@@ -0,0 +1,21 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service::HID {
class IRS final : public ServiceFramework<IRS> {
public:
explicit IRS();
};
class IRS_SYS final : public ServiceFramework<IRS_SYS> {
public:
explicit IRS_SYS();
};
} // namespace Service::HID

View File

@@ -0,0 +1,37 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/hid/xcd.h"
namespace Service::HID {
XCD_SYS::XCD_SYS() : ServiceFramework{"xcd:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetDataFormat"},
{1, nullptr, "SetDataFormat"},
{2, nullptr, "GetMcuState"},
{3, nullptr, "SetMcuState"},
{4, nullptr, "GetMcuVersionForNfc"},
{5, nullptr, "CheckNfcDevicePower"},
{10, nullptr, "SetNfcEvent"},
{11, nullptr, "GetNfcInfo"},
{12, nullptr, "StartNfcDiscovery"},
{13, nullptr, "StopNfcDiscovery"},
{14, nullptr, "StartNtagRead"},
{15, nullptr, "StartNtagWrite"},
{16, nullptr, "SendNfcRawData"},
{17, nullptr, "RegisterMifareKey"},
{18, nullptr, "ClearMifareKey"},
{19, nullptr, "StartMifareRead"},
{20, nullptr, "StartMifareWrite"},
{101, nullptr, "GetAwakeTriggerReasonForLeftRail"},
{102, nullptr, "GetAwakeTriggerReasonForRightRail"},
};
// clang-format on
RegisterHandlers(functions);
}
} // namespace Service::HID

View File

@@ -0,0 +1,16 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service::HID {
class XCD_SYS final : public ServiceFramework<XCD_SYS> {
public:
explicit XCD_SYS();
};
} // namespace Service::HID

View File

@@ -0,0 +1,90 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <memory>
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/lbl/lbl.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
namespace Service::LBL {
class LBL final : public ServiceFramework<LBL> {
public:
explicit LBL() : ServiceFramework{"lbl"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Unknown1"},
{1, nullptr, "Unknown2"},
{2, nullptr, "Unknown3"},
{3, nullptr, "Unknown4"},
{4, nullptr, "Unknown5"},
{5, nullptr, "Unknown6"},
{6, nullptr, "TurnOffBacklight"},
{7, nullptr, "TurnOnBacklight"},
{8, nullptr, "GetBacklightStatus"},
{9, nullptr, "Unknown7"},
{10, nullptr, "Unknown8"},
{11, nullptr, "Unknown9"},
{12, nullptr, "Unknown10"},
{13, nullptr, "Unknown11"},
{14, nullptr, "Unknown12"},
{15, nullptr, "Unknown13"},
{16, nullptr, "ReadRawLightSensor"},
{17, nullptr, "Unknown14"},
{18, nullptr, "Unknown15"},
{19, nullptr, "Unknown16"},
{20, nullptr, "Unknown17"},
{21, nullptr, "Unknown18"},
{22, nullptr, "Unknown19"},
{23, nullptr, "Unknown20"},
{24, nullptr, "Unknown21"},
{25, nullptr, "Unknown22"},
{26, &LBL::EnableVrMode, "EnableVrMode"},
{27, &LBL::DisableVrMode, "DisableVrMode"},
{28, &LBL::GetVrMode, "GetVrMode"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void EnableVrMode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
vr_mode_enabled = true;
LOG_DEBUG(Service_LBL, "called");
}
void DisableVrMode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
vr_mode_enabled = false;
LOG_DEBUG(Service_LBL, "called");
}
void GetVrMode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(vr_mode_enabled);
LOG_DEBUG(Service_LBL, "called");
}
bool vr_mode_enabled = false;
};
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<LBL>()->InstallAsService(sm);
}
} // namespace Service::LBL

View File

@@ -0,0 +1,15 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Service::LBL {
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::LBL

View File

@@ -0,0 +1,142 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <memory>
#include "core/hle/ipc_helpers.h"
#include "core/hle/result.h"
#include "core/hle/service/ldn/ldn.h"
#include "core/hle/service/sm/sm.h"
namespace Service::LDN {
class IMonitorService final : public ServiceFramework<IMonitorService> {
public:
explicit IMonitorService() : ServiceFramework{"IMonitorService"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetStateForMonitor"},
{1, nullptr, "GetNetworkInfoForMonitor"},
{2, nullptr, "GetIpv4AddressForMonitor"},
{3, nullptr, "GetDisconnectReasonForMonitor"},
{4, nullptr, "GetSecurityParameterForMonitor"},
{5, nullptr, "GetNetworkConfigForMonitor"},
{100, nullptr, "InitializeMonitor"},
{101, nullptr, "FinalizeMonitor"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class LDNM final : public ServiceFramework<LDNM> {
public:
explicit LDNM() : ServiceFramework{"ldn:m"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &LDNM::CreateMonitorService, "CreateMonitorService"}
};
// clang-format on
RegisterHandlers(functions);
}
void CreateMonitorService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IMonitorService>();
LOG_DEBUG(Service_LDN, "called");
}
};
class ILocalCommunicationService final : public ServiceFramework<ILocalCommunicationService> {
public:
explicit ILocalCommunicationService(const char* name) : ServiceFramework{name} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetState"},
{1, nullptr, "GetNetworkInfo"},
{2, nullptr, "GetIpv4Address"},
{3, nullptr, "GetDisconnectReason"},
{4, nullptr, "GetSecurityParameter"},
{5, nullptr, "GetNetworkConfig"},
{100, nullptr, "AttachStateChangeEvent"},
{101, nullptr, "GetNetworkInfoLatestUpdate"},
{102, nullptr, "Scan"},
{103, nullptr, "ScanPrivate"},
{200, nullptr, "OpenAccessPoint"},
{201, nullptr, "CloseAccessPoint"},
{202, nullptr, "CreateNetwork"},
{203, nullptr, "CreateNetworkPrivate"},
{204, nullptr, "DestroyNetwork"},
{205, nullptr, "Reject"},
{206, nullptr, "SetAdvertiseData"},
{207, nullptr, "SetStationAcceptPolicy"},
{208, nullptr, "AddAcceptFilterEntry"},
{209, nullptr, "ClearAcceptFilter"},
{300, nullptr, "OpenStation"},
{301, nullptr, "CloseStation"},
{302, nullptr, "Connect"},
{303, nullptr, "ConnectPrivate"},
{304, nullptr, "Disconnect"},
{400, nullptr, "InitializeSystem"},
{401, nullptr, "FinalizeSystem"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class LDNS final : public ServiceFramework<LDNS> {
public:
explicit LDNS() : ServiceFramework{"ldn:s"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &LDNS::CreateSystemLocalCommunicationService, "CreateSystemLocalCommunicationService"},
};
// clang-format on
RegisterHandlers(functions);
}
void CreateSystemLocalCommunicationService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ILocalCommunicationService>("ISystemLocalCommunicationService");
LOG_DEBUG(Service_LDN, "called");
}
};
class LDNU final : public ServiceFramework<LDNU> {
public:
explicit LDNU() : ServiceFramework{"ldn:u"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &LDNU::CreateUserLocalCommunicationService, "CreateUserLocalCommunicationService"},
};
// clang-format on
RegisterHandlers(functions);
}
void CreateUserLocalCommunicationService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ILocalCommunicationService>("IUserLocalCommunicationService");
LOG_DEBUG(Service_LDN, "called");
}
};
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<LDNM>()->InstallAsService(sm);
std::make_shared<LDNS>()->InstallAsService(sm);
std::make_shared<LDNU>()->InstallAsService(sm);
}
} // namespace Service::LDN

View File

@@ -0,0 +1,16 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Service::LDN {
/// Registers all LDN services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::LDN

View File

@@ -0,0 +1,81 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <memory>
#include "core/hle/service/ldr/ldr.h"
#include "core/hle/service/service.h"
namespace Service::LDR {
class DebugMonitor final : public ServiceFramework<DebugMonitor> {
public:
explicit DebugMonitor() : ServiceFramework{"ldr:dmnt"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "AddProcessToDebugLaunchQueue"},
{1, nullptr, "ClearDebugLaunchQueue"},
{2, nullptr, "GetNsoInfos"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class ProcessManager final : public ServiceFramework<ProcessManager> {
public:
explicit ProcessManager() : ServiceFramework{"ldr:pm"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "CreateProcess"},
{1, nullptr, "GetProgramInfo"},
{2, nullptr, "RegisterTitle"},
{3, nullptr, "UnregisterTitle"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class Shell final : public ServiceFramework<Shell> {
public:
explicit Shell() : ServiceFramework{"ldr:shel"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "AddProcessToLaunchQueue"},
{1, nullptr, "ClearLaunchQueue"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class RelocatableObject final : public ServiceFramework<RelocatableObject> {
public:
explicit RelocatableObject() : ServiceFramework{"ldr:ro"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "LoadNro"},
{1, nullptr, "UnloadNro"},
{2, nullptr, "LoadNrr"},
{3, nullptr, "UnloadNrr"},
{4, nullptr, "Initialize"},
};
// clang-format on
RegisterHandlers(functions);
}
};
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<DebugMonitor>()->InstallAsService(sm);
std::make_shared<ProcessManager>()->InstallAsService(sm);
std::make_shared<Shell>()->InstallAsService(sm);
std::make_shared<RelocatableObject>()->InstallAsService(sm);
}
} // namespace Service::LDR

View File

@@ -0,0 +1,16 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Service::LDR {
/// Registers all LDR services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::LDR

View File

@@ -4,10 +4,12 @@
#include <sstream>
#include <string>
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_session.h"
#include "core/hle/service/lm/lm.h"
#include "core/hle/service/service.h"
#include "core/memory.h"
namespace Service::LM {
@@ -15,13 +17,12 @@ class Logger final : public ServiceFramework<Logger> {
public:
Logger() : ServiceFramework("Logger") {
static const FunctionInfo functions[] = {
{0x00000000, &Logger::Log, "Log"},
{0x00000000, &Logger::Initialize, "Initialize"},
{0x00000001, nullptr, "SetDestination"},
};
RegisterHandlers(functions);
}
~Logger() = default;
private:
struct MessageHeader {
enum Flags : u32_le {
@@ -66,13 +67,13 @@ private:
};
/**
* LM::Log service function
* ILogger::Initialize service function
* Inputs:
* 0: 0x00000000
* Outputs:
* 0: ResultCode
*/
void Log(Kernel::HLERequestContext& ctx) {
void Initialize(Kernel::HLERequestContext& ctx) {
// This function only succeeds - Get that out of the way
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -162,30 +163,33 @@ private:
std::ostringstream log_stream;
};
class LM final : public ServiceFramework<LM> {
public:
explicit LM() : ServiceFramework{"lm"} {
static const FunctionInfo functions[] = {
{0x00000000, &LM::OpenLogger, "OpenLogger"},
};
RegisterHandlers(functions);
}
/**
* LM::OpenLogger service function
* Inputs:
* 0: 0x00000000
* Outputs:
* 0: ResultCode
*/
void OpenLogger(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<Logger>();
LOG_DEBUG(Service_LM, "called");
}
};
void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<LM>()->InstallAsService(service_manager);
}
/**
* LM::Initialize service function
* Inputs:
* 0: 0x00000000
* Outputs:
* 0: ResultCode
*/
void LM::Initialize(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<Logger>();
LOG_DEBUG(Service_LM, "called");
}
LM::LM() : ServiceFramework("lm") {
static const FunctionInfo functions[] = {
{0x00000000, &LM::Initialize, "Initialize"},
};
RegisterHandlers(functions);
}
} // namespace Service::LM

View File

@@ -4,21 +4,12 @@
#pragma once
#include <vector>
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/service.h"
namespace Service::SM {
class ServiceManager;
}
namespace Service::LM {
class LM final : public ServiceFramework<LM> {
public:
LM();
~LM() = default;
private:
void Initialize(Kernel::HLERequestContext& ctx);
};
/// Registers all LM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);

View File

@@ -0,0 +1,222 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <memory>
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/nfc/nfc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
namespace Service::NFC {
class IAm final : public ServiceFramework<IAm> {
public:
explicit IAm() : ServiceFramework{"IAm"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Initialize"},
{1, nullptr, "Finalize"},
{2, nullptr, "NotifyForegroundApplet"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class NFC_AM final : public ServiceFramework<NFC_AM> {
public:
explicit NFC_AM() : ServiceFramework{"nfc:am"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &NFC_AM::CreateAmInterface, "CreateAmInterface"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void CreateAmInterface(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IAm>();
LOG_DEBUG(Service_NFC, "called");
}
};
class MFIUser final : public ServiceFramework<MFIUser> {
public:
explicit MFIUser() : ServiceFramework{"IUser"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Initialize"},
{1, nullptr, "Finalize"},
{2, nullptr, "ListDevices"},
{3, nullptr, "StartDetection"},
{4, nullptr, "StopDetection"},
{5, nullptr, "Read"},
{6, nullptr, "Write"},
{7, nullptr, "GetTagInfo"},
{8, nullptr, "GetActivateEventHandle"},
{9, nullptr, "GetDeactivateEventHandle"},
{10, nullptr, "GetState"},
{11, nullptr, "GetDeviceState"},
{12, nullptr, "GetNpadId"},
{13, nullptr, "GetAvailabilityChangeEventHandle"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class NFC_MF_U final : public ServiceFramework<NFC_MF_U> {
public:
explicit NFC_MF_U() : ServiceFramework{"nfc:mf:u"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &NFC_MF_U::CreateUserInterface, "CreateUserInterface"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void CreateUserInterface(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<MFIUser>();
LOG_DEBUG(Service_NFC, "called");
}
};
class IUser final : public ServiceFramework<IUser> {
public:
explicit IUser() : ServiceFramework{"IUser"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Initialize"},
{1, nullptr, "Finalize"},
{2, nullptr, "GetState"},
{3, nullptr, "IsNfcEnabled"},
{400, nullptr, "Initialize"},
{401, nullptr, "Finalize"},
{402, nullptr, "GetState"},
{403, nullptr, "IsNfcEnabled"},
{404, nullptr, "ListDevices"},
{405, nullptr, "GetDeviceState"},
{406, nullptr, "GetNpadId"},
{407, nullptr, "AttachAvailabilityChangeEvent"},
{408, nullptr, "StartDetection"},
{409, nullptr, "StopDetection"},
{410, nullptr, "GetTagInfo"},
{411, nullptr, "AttachActivateEvent"},
{412, nullptr, "AttachDeactivateEvent"},
{1000, nullptr, "ReadMifare"},
{1001, nullptr, "WriteMifare"},
{1300, nullptr, "SendCommandByPassThrough"},
{1301, nullptr, "KeepPassThroughSession"},
{1302, nullptr, "ReleasePassThroughSession"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class NFC_U final : public ServiceFramework<NFC_U> {
public:
explicit NFC_U() : ServiceFramework{"nfc:u"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &NFC_U::CreateUserInterface, "CreateUserInterface"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void CreateUserInterface(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IUser>();
LOG_DEBUG(Service_NFC, "called");
}
};
class ISystem final : public ServiceFramework<ISystem> {
public:
explicit ISystem() : ServiceFramework{"ISystem"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "Initialize"},
{1, nullptr, "Finalize"},
{2, nullptr, "GetState"},
{3, nullptr, "IsNfcEnabled"},
{100, nullptr, "SetNfcEnabled"},
{400, nullptr, "InitializeSystem"},
{401, nullptr, "FinalizeSystem"},
{402, nullptr, "GetState"},
{403, nullptr, "IsNfcEnabled"},
{404, nullptr, "ListDevices"},
{405, nullptr, "GetDeviceState"},
{406, nullptr, "GetNpadId"},
{407, nullptr, "AttachAvailabilityChangeEvent"},
{408, nullptr, "StartDetection"},
{409, nullptr, "StopDetection"},
{410, nullptr, "GetTagInfo"},
{411, nullptr, "AttachActivateEvent"},
{412, nullptr, "AttachDeactivateEvent"},
{500, nullptr, "SetNfcEnabled"},
{1000, nullptr, "ReadMifare"},
{1001, nullptr, "WriteMifare"},
{1300, nullptr, "SendCommandByPassThrough"},
{1301, nullptr, "KeepPassThroughSession"},
{1302, nullptr, "ReleasePassThroughSession"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class NFC_SYS final : public ServiceFramework<NFC_SYS> {
public:
explicit NFC_SYS() : ServiceFramework{"nfc:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &NFC_SYS::CreateSystemInterface, "CreateSystemInterface"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void CreateSystemInterface(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISystem>();
LOG_DEBUG(Service_NFC, "called");
}
};
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<NFC_AM>()->InstallAsService(sm);
std::make_shared<NFC_MF_U>()->InstallAsService(sm);
std::make_shared<NFC_U>()->InstallAsService(sm);
std::make_shared<NFC_SYS>()->InstallAsService(sm);
}
} // namespace Service::NFC

View File

@@ -0,0 +1,15 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Service::NFC {
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::NFC

View File

@@ -5,9 +5,7 @@
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/nifm/nifm_a.h"
#include "core/hle/service/nifm/nifm_s.h"
#include "core/hle/service/nifm/nifm_u.h"
#include "core/hle/service/service.h"
namespace Service::NIFM {
@@ -210,28 +208,35 @@ IGeneralService::IGeneralService() : ServiceFramework("IGeneralService") {
RegisterHandlers(functions);
}
void Module::Interface::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
class NetworkInterface final : public ServiceFramework<NetworkInterface> {
public:
explicit NetworkInterface(const char* name) : ServiceFramework{name} {
static const FunctionInfo functions[] = {
{4, &NetworkInterface::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NetworkInterface::CreateGeneralService, "CreateGeneralService"},
};
RegisterHandlers(functions);
}
void Module::Interface::CreateGeneralService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
: ServiceFramework(name), module(std::move(module)) {}
void CreateGeneralService(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IGeneralService>();
LOG_DEBUG(Service_NIFM, "called");
}
};
void InstallInterfaces(SM::ServiceManager& service_manager) {
auto module = std::make_shared<Module>();
std::make_shared<NIFM_A>(module)->InstallAsService(service_manager);
std::make_shared<NIFM_S>(module)->InstallAsService(service_manager);
std::make_shared<NIFM_U>(module)->InstallAsService(service_manager);
std::make_shared<NetworkInterface>("nifm:a")->InstallAsService(service_manager);
std::make_shared<NetworkInterface>("nifm:s")->InstallAsService(service_manager);
std::make_shared<NetworkInterface>("nifm:u")->InstallAsService(service_manager);
}
} // namespace Service::NIFM

View File

@@ -4,24 +4,13 @@
#pragma once
#include "core/hle/service/service.h"
namespace Service::SM {
class ServiceManager;
}
namespace Service::NIFM {
class Module final {
public:
class Interface : public ServiceFramework<Interface> {
public:
explicit Interface(std::shared_ptr<Module> module, const char* name);
void CreateGeneralServiceOld(Kernel::HLERequestContext& ctx);
void CreateGeneralService(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> module;
};
};
/// Registers all NIFM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
} // namespace Service::NIFM

View File

@@ -1,17 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/nifm/nifm_a.h"
namespace Service::NIFM {
NIFM_A::NIFM_A(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "nifm:a") {
static const FunctionInfo functions[] = {
{4, &NIFM_A::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NIFM_A::CreateGeneralService, "CreateGeneralService"},
};
RegisterHandlers(functions);
}
} // namespace Service::NIFM

View File

@@ -1,16 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/nifm/nifm.h"
namespace Service::NIFM {
class NIFM_A final : public Module::Interface {
public:
explicit NIFM_A(std::shared_ptr<Module> module);
};
} // namespace Service::NIFM

View File

@@ -1,17 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/nifm/nifm_s.h"
namespace Service::NIFM {
NIFM_S::NIFM_S(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "nifm:s") {
static const FunctionInfo functions[] = {
{4, &NIFM_S::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NIFM_S::CreateGeneralService, "CreateGeneralService"},
};
RegisterHandlers(functions);
}
} // namespace Service::NIFM

View File

@@ -1,16 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/nifm/nifm.h"
namespace Service::NIFM {
class NIFM_S final : public Module::Interface {
public:
explicit NIFM_S(std::shared_ptr<Module> module);
};
} // namespace Service::NIFM

View File

@@ -1,17 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/nifm/nifm_u.h"
namespace Service::NIFM {
NIFM_U::NIFM_U(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "nifm:u") {
static const FunctionInfo functions[] = {
{4, &NIFM_U::CreateGeneralServiceOld, "CreateGeneralServiceOld"},
{5, &NIFM_U::CreateGeneralService, "CreateGeneralService"},
};
RegisterHandlers(functions);
}
} // namespace Service::NIFM

View File

@@ -1,16 +0,0 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/nifm/nifm.h"
namespace Service::NIFM {
class NIFM_U final : public Module::Interface {
public:
explicit NIFM_U(std::shared_ptr<Module> module);
};
} // namespace Service::NIFM

View File

@@ -0,0 +1,124 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/nim/nim.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
namespace Service::NIM {
class NIM final : public ServiceFramework<NIM> {
public:
explicit NIM() : ServiceFramework{"nim"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "CreateSystemUpdateTask"},
{1, nullptr, "DestroySystemUpdateTask"},
{2, nullptr, "ListSystemUpdateTask"},
{3, nullptr, "RequestSystemUpdateTaskRun"},
{4, nullptr, "GetSystemUpdateTaskInfo"},
{5, nullptr, "CommitSystemUpdateTask"},
{6, nullptr, "CreateNetworkInstallTask"},
{7, nullptr, "DestroyNetworkInstallTask"},
{8, nullptr, "ListNetworkInstallTask"},
{9, nullptr, "RequestNetworkInstallTaskRun"},
{10, nullptr, "GetNetworkInstallTaskInfo"},
{11, nullptr, "CommitNetworkInstallTask"},
{12, nullptr, "RequestLatestSystemUpdateMeta"},
{14, nullptr, "ListApplicationNetworkInstallTask"},
{15, nullptr, "ListNetworkInstallTaskContentMeta"},
{16, nullptr, "RequestLatestVersion"},
{17, nullptr, "SetNetworkInstallTaskAttribute"},
{18, nullptr, "AddNetworkInstallTaskContentMeta"},
{19, nullptr, "GetDownloadedSystemDataPath"},
{20, nullptr, "CalculateNetworkInstallTaskRequiredSize"},
{21, nullptr, "IsExFatDriverIncluded"},
{22, nullptr, "GetBackgroundDownloadStressTaskInfo"},
{23, nullptr, "RequestDeviceAuthenticationToken"},
{24, nullptr, "RequestGameCardRegistrationStatus"},
{25, nullptr, "RequestRegisterGameCard"},
{26, nullptr, "RequestRegisterNotificationToken"},
{27, nullptr, "RequestDownloadTaskList"},
{28, nullptr, "RequestApplicationControl"},
{29, nullptr, "RequestLatestApplicationControl"},
{30, nullptr, "RequestVersionList"},
{31, nullptr, "CreateApplyDeltaTask"},
{32, nullptr, "DestroyApplyDeltaTask"},
{33, nullptr, "ListApplicationApplyDeltaTask"},
{34, nullptr, "RequestApplyDeltaTaskRun"},
{35, nullptr, "GetApplyDeltaTaskInfo"},
{36, nullptr, "ListApplyDeltaTask"},
{37, nullptr, "CommitApplyDeltaTask"},
{38, nullptr, "CalculateApplyDeltaTaskRequiredSize"},
{39, nullptr, "PrepareShutdown"},
{40, nullptr, "ListApplyDeltaTask"},
{41, nullptr, "ClearNotEnoughSpaceStateOfApplyDeltaTask"},
{42, nullptr, "Unknown1"},
{43, nullptr, "Unknown2"},
{44, nullptr, "Unknown3"},
{45, nullptr, "Unknown4"},
{46, nullptr, "Unknown5"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class NIM_SHP final : public ServiceFramework<NIM_SHP> {
public:
explicit NIM_SHP() : ServiceFramework{"nim:shp"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestDeviceAuthenticationToken"},
{1, nullptr, "RequestCachedDeviceAuthenticationToken"},
{100, nullptr, "RequestRegisterDeviceAccount"},
{101, nullptr, "RequestUnregisterDeviceAccount"},
{102, nullptr, "RequestDeviceAccountStatus"},
{103, nullptr, "GetDeviceAccountInfo"},
{104, nullptr, "RequestDeviceRegistrationInfo"},
{105, nullptr, "RequestTransferDeviceAccount"},
{106, nullptr, "RequestSyncRegistration"},
{107, nullptr, "IsOwnDeviceId"},
{200, nullptr, "RequestRegisterNotificationToken"},
{300, nullptr, "RequestUnlinkDevice"},
{301, nullptr, "RequestUnlinkDeviceIntegrated"},
{302, nullptr, "RequestLinkDevice"},
{303, nullptr, "HasDeviceLink"},
{304, nullptr, "RequestUnlinkDeviceAll"},
{305, nullptr, "RequestCreateVirtualAccount"},
{306, nullptr, "RequestDeviceLinkStatus"},
{400, nullptr, "GetAccountByVirtualAccount"},
{500, nullptr, "RequestSyncTicket"},
{501, nullptr, "RequestDownloadTicket"},
{502, nullptr, "RequestDownloadTicketForPrepurchasedContents"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class NTC final : public ServiceFramework<NTC> {
public:
explicit NTC() : ServiceFramework{"ntc"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "OpenEnsureNetworkClockAvailabilityService"},
{100, nullptr, "SuspendAutonomicTimeCorrection"},
{101, nullptr, "ResumeAutonomicTimeCorrection"},
};
// clang-format on
RegisterHandlers(functions);
}
};
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<NIM>()->InstallAsService(sm);
std::make_shared<NIM_SHP>()->InstallAsService(sm);
std::make_shared<NTC>()->InstallAsService(sm);
}
} // namespace Service::NIM

View File

@@ -0,0 +1,15 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
namespace Service::SM {
class ServiceManager;
}
namespace Service::NIM {
void InstallInterfaces(SM::ServiceManager& sm);
} // namespace Service::NIM

View File

@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <utility>
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
@@ -40,14 +42,14 @@ Module::Module() {
devices["/dev/nvhost-nvdec"] = std::make_shared<Devices::nvhost_nvdec>();
}
u32 Module::Open(std::string device_name) {
u32 Module::Open(const std::string& device_name) {
ASSERT_MSG(devices.find(device_name) != devices.end(), "Trying to open unknown device {}",
device_name);
auto device = devices[device_name];
u32 fd = next_fd++;
const u32 fd = next_fd++;
open_files[fd] = device;
open_files[fd] = std::move(device);
return fd;
}
@@ -56,7 +58,7 @@ u32 Module::Ioctl(u32 fd, u32_le command, const std::vector<u8>& input, std::vec
auto itr = open_files.find(fd);
ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device");
auto device = itr->second;
auto& device = itr->second;
return device->ioctl({command}, input, output);
}

View File

@@ -38,7 +38,7 @@ public:
}
/// Opens a device node and returns a file descriptor to it.
u32 Open(std::string device_name);
u32 Open(const std::string& device_name);
/// Sends an ioctl command to the specified file descriptor.
u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output);
/// Closes a device file descriptor and returns operation success.

View File

@@ -9,6 +9,7 @@
#include "common/scope_exit.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/nvflinger/buffer_queue.h"

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