This makes cpu_core and memory being completely independent components inside the system, having a simpler and more understandable initialization process
The thread which casues page table changes in memory will be responsible to notify the cpu_core too
* CMakeLists: Move compilation flags into the src directory
We generally shouldn't be hijacking CMAKE_CXX_FLAGS, etc as a means to
append flags to the targets, since this adds the compilation flags to
everything, including our externals, which can result in weird issues
and makes the build hierarchy fragile.
Instead, we want to just apply these compilation flags to our targets,
and let those managing external libraries to properly specify their
compilation flags.
This also results in us not getting as many warnings, as we don't raise
the warning level on every external target.
* CMakeLists: Move off of modifying CMAKE_*-related flags
Modifying CMAKE_* related flags directly applies those changes to every
single CMake target. This includes even the targets we have in the
externals directory.
So, if we ever increased our warning levels, or enabled particular ones,
or enabled any other compilation setting, then this would apply to
externals as well, which is often not desirable.
This makes our compilation flag setup less error prone by only applying
our settings to our targets and leaving the externals alone entirely.
This also means we don't end up clobbering any provided flags on the
command line either, allowing users to specifically use the flags they
want.
Makes the dependency explicit in the TelemetrySession's interface
instead of making it a hidden dependency.
This also revealed a hidden issue with the way the telemetry session was
being initialized. It was attempting to retrieve the app loader and log
out title-specific information. However, this isn't always guaranteed to
be possible.
During the initialization phase, everything is being constructed. It
doesn't mean an actual title has been selected. This is what the Load()
function is for. This potentially results in dead code paths involving
the app loader. Instead, we explicitly add this information when we know
the app loader instance is available.
A checkbox is able to be tri-state, giving it three possible activity
types, so in the connect call here, it would actually be truncating an
int into a bool.
Instead, we can just listen on the toggled() signal, which passes along
a bool, not an int.
* common/file_util: Make IOFile's WriteString take a std::string_view
We don't need to force the usage of a std::string here, and can instead
use a std::string_view, which allows writing out other forms of strings
(e.g. C-style strings) without any unnecessary heap allocations.
* common/file_util: Remove unnecessary c_str() calls
The file stream open functions have supported std::string overloads
since C++11, so we don't need to use c_str() here. Same behavior, less
code.
* common/file_util: Make ReadFileToString and WriteStringToFile consistent
Makes the parameter ordering consistent, and also makes the filename
parameter a std::string. A std::string would be constructed anyways with
the previous code, as IOFile's only constructor with a filepath is one
taking a std::string.
We can also make WriteStringToFile's string parameter utilize a
std::string_view for the string, making use of our previous changes to
IOFile.
* common/file_util: Remove duplicated documentation comments
These are already present within the header, so they don't need to be
repeated in the cpp file.
* common/file_util: Make GetCurrentDir() return a std::optional
nullptr was being returned in the error case, which, at a glance may
seem perfectly OK... until you realize that std::string has the
invariant that it may not be constructed from a null pointer. This
means that if this error case was ever hit, then the application would
most likely crash from a thrown exception in std::string's constructor.
Instead, we can change the function to return an optional value,
indicating if a failure occurred.
* common/file_util: Remove unnecessary return at end of void StripTailDirSlashes()
While we're at it, also invert the conditional into a guard clause.
critical() is intended for critical/fatal errors that threaten the
overall stability of an application. A user entering a conflicting key
sequence is neither of those.
Allows for things such as:
auto rect = Common::Rectangle{0, 0, 0, 0};
as opposed to being required to explicitly write out the underlying
type, such as:
auto rect = Common::Rectangle<int>{0, 0, 0, 0};
The only requirement for the deduction is that all constructor arguments
be the same type.
The previous code was all "smushed" together wasn't really grouped
together that well.
This spaces things out and separates them by relation to one another,
making it easier to visually parse the individual sections of code that
make up the constructor.
Without passing in a parent, this can result in focus being stolen from
the dialog in certain cases.
Example:
On Windows, if the logging window is left open, the logging Window will
potentially get focus over the hotkey dialog itself, since it brings all
open windows for the application into view. By specifying a parent, we
only bring windows for the parent into view (of which there are none,
aside from the hotkey dialog).
Avoids dumping all of the core settings machinery into whatever files
include this header. Nothing inside the header itself actually made use
of anything in settings.h anyways.
* common/thread: Remove unused functions
Many of these functions are carried over from Dolphin (where they aren't
used anymore). Given these have no use (and we really shouldn't be
screwing around with OS-specific thread scheduler handling from the
emulator, these can be removed.
The function for setting the thread name is left, however, since it can
have debugging utility usages.
* input_common/sdl: Use a type alias to shorten declaration of GetPollers
Just makes the definitions a little bit more tidy.
* input_common/sdl: Correct return values within implementations of GetPollers()
In both cases, we weren't actually returning anything, which is
undefined behavior.
* yuzu/debugger/graphics_surface: Fill in missing surface format listings
Fills in the missing surface types that were marked as unknown. The
order corresponds with the TextureFormat enum within
video_core/texture.h.
We also don't need to all of these strings as translatable (only the
first string, as it's an English word).
* yuzu/debugger/graphics_surface: Clean up connection overload deduction
We can utilize qOverload with the signal connections to make the
function deducing a little less ugly.
* yuzu/debugger/graphics_surface: Tidy up SaveSurface
- Use QStringLiteral where applicable.
- Use const where applicable
- Remove unnecessary precondition check (we already assert the pixbuf
being non null)
* yuzu/debugger/graphics_surface: Display error messages for file I/O errors
* core: Add missing override specifiers where applicable
Applies the override specifier where applicable. In the case of
destructors that are defaulted in their definition, they can
simply be removed.
This also removes the unnecessary inclusions being done in audin_u and
audrec_u, given their close proximity.
* kernel/thread: Make parameter of GetWaitObjectIndex() const qualified
The pointed to member is never actually modified, so it can be made
const.
* kernel/thread: Avoid sign conversion within GetCommandBufferAddress()
Previously this was performing a u64 + int sign conversion. When dealing
with addresses, we should generally be keeping the arithmetic in the
same signedness type.
This also gets rid of the static lifetime of the constant, as there's no
need to make a trivial type like this potentially live for the entire
duration of the program.
* kernel/codeset: Make CodeSet's memory data member a regular std::vector
The use of a shared_ptr is an implementation detail of the VMManager
itself when mapping memory. Because of that, we shouldn't require all
users of the CodeSet to have to allocate the shared_ptr ahead of time.
It's intended that CodeSet simply pass in the required direct data, and
that the memory manager takes care of it from that point on.
This means we just do the shared pointer allocation in a single place,
when loading modules, as opposed to in each loader.
* kernel/wait_object: Make ShouldWait() take thread members by pointer-to-const
Given this is intended as a querying function, it doesn't make sense to
allow the implementer to modify the state of the given thread.
This is a compile definition introduced in Qt 4.8 for reducing the total
potential number of strings created when performing string
concatenation. This allows for less memory churn.
This can be read about here:
https://blog.qt.io/blog/2011/06/13/string-concatenation-with-qstringbuilder/
For a change that isn't source-compatible, we only had one occurrence
that actually need to have its type clarified, which is pretty good, as
far as transitioning goes.
* Set accepted EULA version to max value
CFG: write the max value of 0x7F7F to the default cfg savegame and
auto update on init
CECD: Actually read the EULA version from CFG
* HTTP_C: Implement SetClientCertContext and GetSSLError; Stubbed BeginRequest and BeginRequestAsync
* HTTP_C: Move logs to beginning of function calls
The multiplayer state object and dialogs hold a (modified) game list model, but it isn't updated when the actual game list changes. This updates the multiplayer dialogs with the new game list when it got repopulated.
Allows updating the credentials of the announce session, thus allowing credentials changes to be reflected before citra restart. To avoid race conditions and web errors (you can only update the room that you created, i.e. changing credentials halfway will make it break), now you can only use the Citra Web Services settings when not hosting a public room.
The `Register()` function can now handle error results and the error will be passed immediately to the Qt frontend, instead of being ignored silently and failing later with a "Room is not registered".
The backend is not used until we decide to submit the testcase/telemetry, and creating it early prevents users from updating the credentials properly while the games are running.
Keeps the return type consistent with the function name. While we're at
it, we can also reduce the amount of boilerplate involved with handling
these by using structured bindings.
Some objects declare their handle type as const, while others declare it
as constexpr. This makes the const ones constexpr for consistency, and
prevent unexpected compilation errors if these happen to be attempted to be
used within a constexpr context.
Uses arithmetic that can be identified more trivially by compilers for
optimizations. e.g. Rather than shifting the halves of the value and
then swapping and combining them, we can swap them in place.
e.g. for the original swap32 code on x86-64, clang 8.0 would generate:
mov ecx, edi
rol cx, 8
shl ecx, 16
shr edi, 16
rol di, 8
movzx eax, di
or eax, ecx
ret
while GCC 8.3 would generate the ideal:
mov eax, edi
bswap eax
ret
now both generate the same optimal output.
MSVC used to generate the following with the old code:
mov eax, ecx
rol cx, 8
shr eax, 16
rol ax, 8
movzx ecx, cx
movzx eax, ax
shl ecx, 16
or eax, ecx
ret 0
Now MSVC also generates a similar, but equally optimal result as clang/GCC:
bswap ecx
mov eax, ecx
ret 0
====
In the swap64 case, for the original code, clang 8.0 would generate:
mov eax, edi
bswap eax
shl rax, 32
shr rdi, 32
bswap edi
or rax, rdi
ret
(almost there, but still missing the mark)
while, again, GCC 8.3 would generate the more ideal:
mov rax, rdi
bswap rax
ret
now clang also generates the optimal sequence for this fallback as well.
This is a case where MSVC unfortunately falls short, despite the new
code, this one still generates a doozy of an output.
mov r8, rcx
mov r9, rcx
mov rax, 71776119061217280
mov rdx, r8
and r9, rax
and edx, 65280
mov rax, rcx
shr rax, 16
or r9, rax
mov rax, rcx
shr r9, 16
mov rcx, 280375465082880
and rax, rcx
mov rcx, 1095216660480
or r9, rax
mov rax, r8
and rax, rcx
shr r9, 16
or r9, rax
mov rcx, r8
mov rax, r8
shr r9, 8
shl rax, 16
and ecx, 16711680
or rdx, rax
mov eax, -16777216
and rax, r8
shl rdx, 16
or rdx, rcx
shl rdx, 16
or rax, rdx
shl rax, 8
or rax, r9
ret 0
which is pretty unfortunate.
Allows the compiler to inform when the result of a swap function is
being ignored (which is 100% a bug in all usage scenarios). We also mark
them noexcept to allow other functions using them to be able to be
marked as noexcept and play nicely with things that potentially inspect
"nothrowability".
Including every OS' own built-in byte swapping functions is kind of
undesirable, since it adds yet another build path to ensure compilation
succeeds on.
Given we only support clang, GCC, and MSVC for the time being, we can
utilize their built-in functions directly instead of going through the
OS's API functions.
This shrinks the overall code down to just
if (msvc)
use msvc's functions
else if (clang or gcc)
use clang/gcc's builtins
else
use the slow path
The template type here is actually a forwarding reference, not an rvalue
reference in this case, so it's more appropriate to use std::forward to
preserve the value category of the type being moved.
These can just be passed regularly, now that we use fmt instead of our
old logging system.
While we're at it, make the parameters to MakeFunctionString
std::string_views.
Reduces the potential amount of rebuilding necessary if any headers
change. In particular, we were including a header from the core library
when we don't even link the core library to the web_service library, so
this also gets rid of an indirect dependency.
Since C++17, the introduction of deduction guides for locking facilities
means that we no longer need to hardcode the mutex type into the locks
themselves, making it easier to switch mutex types, should it ever be
necessary in the future.
This reduces the boilerplate that services have to write out the current thread explicitly. Using current thread instead of client thread is also semantically incorrect, and will be a problem when we implement multicore (at which time there will be multiple current threads)
We really don't need to pull in several headers of boost related
machinery just to perform the erase-remove idiom (particularly with
C++20 around the corner, which adds universal container std::erase and
std::erase_if, which we can just use instead).
With this, we don't need to link in anything boost-related into common.
In these cases the system object is nearby, and in the other, the
long-form of accessing the telemetry instance is already used, so we can
get rid of the use of the global accessor.
Moves local global state into the Impl class itself and initializes it
at the creation of the instance instead of in the function.
This makes it nicer for weakly-ordered architectures, given the
CreateEntry() class won't need to have atomic loads executed for each
individual call to the CreateEntry class.
This makes the class much more flexible and doesn't make performing
copies with classes that contain a bitfield member a pain.
Given BitField instances are only intended to be used within unions, the
fact the full storage value would be copied isn't a big concern (only
sizeof(union_type) would be copied anyways).
While we're at it, provide defaulted move constructors for consistency.
This causes a reference cycle because ServerPort also holds a shared pointer to SessionRequestHandler (inherited by ServiceFrameworkBase). Given that the member port is never used in ServiceFrameworkBase, we can simply remove it. The port object is kept alive by ServiceManager|KernelSystem::named_ports -> ClientPort -> ServerPort
Services can hold kernel objects and do cleanup upon destruction, so we need to keep the kernel alive longer. The new order approximnately resembles the reverse construction order. I will revisit the ordering issue and make it less error-prone after global state cleanup
When making the initial implementation, I forgot to add the series variable to the AmiiboConfig struct.
With this PR it is added and many of the AmiiboConfig fields get their proper values now.
The loading of the Amiibo data that is added here has been hwtested.
This fixes Amiibos in Yoshis Woolly World, Smash (partially) and probably other games too.
wwylele / 白疾風Today at 6:14 PM
I doubt the performance of constructing regex everytime the function is called
Is TrimSourcePath only called by logging? if so, you can move the implementation into logging, and cache the regex object into global
This function is probably too specific to be in common anyway
Previously this check is in GetSurface (if (addr == 0)). This worked fine because GetTextureSurface directly forwarded the address value to GetSurface. However, now with mipmap support, GetTextureSurface would call GetSurface several times with different address offset, resulting some >0 but still invalid address in case the input is 0. We should error out early on invalid address instead of sending it furthor down which would cause invalid memory access
* gdbstub: fix IsMemoryBreak() returning false while connected to client
As a result, the only existing codepath for a memory watchpoint hit to break into GDB (InterpeterMainLoop, GDB_BP_CHECK, ARMul_State::RecordBreak) is finally taken,
which exposes incorrect logic* in both RecordBreak and ServeBreak.
* a blank BreakpointAddress structure is passed, which sets r15 (PC) to NULL
* gdbstub: DynCom: default-initialize two members/vars used in conditionals
* gdbstub: DynCom: don't record memory watchpoint hits via RecordBreak()
For now, instead check for GDBStub::IsMemoryBreak() in InterpreterMainLoop and ServeBreak.
Fixes PC being set to a stale/unhit breakpoint address (often zero) when a memory watchpoint (rwatch, watch, awatch) is handled in ServeBreak() and generates a GDB trap.
Reasons for removing a call to RecordBreak() for memory watchpoints:
* The``breakpoint_data`` we pass is typed Execute or None. It describes the predicted next code breakpoint hit relative to PC;
* GDBStub::IsMemoryBreak() returns true if a recent Read/Write operation hit a watchpoint. It doesn't specify which in return, nor does it trace it anywhere. Thus, the only data we could give RecordBreak() is a placeholder BreakpointAddress at offset NULL and type Access. I found the idea silly, compared to simply relying on GDBStub::IsMemoryBreak().
There is currently no measure in the code that remembers the addresses (and types) of any watchpoints that were hit by an instruction, in order to send them to GDB as "extended stop information."
I'm considering an implementation for this.
* gdbstub: Change an ASSERT to DEBUG_ASSERT
I have never seen the (Reg[15] == last_bkpt.address) assert fail in practice, even after several weeks of (locally) developping various branches around GDB. Only leave it inside Debug builds.
udp_server might not be created due to error (occupied port etc.), in which case its destructor and thread-ending call chain will not be excuted in Server::Stop. However, the ending packet still need to be send no matter udp is on or not, so move it to Server::Stop
MSVC does not seem to like using constexpr values in a lambda that were declared outside of it.
Previously on MSVC build the hotkeys to inc-/decrease the speed limit were not working correctly because in the lambda the SPEED_LIMIT_STEP had garbage values.
After googling around a bit I found: https://github.com/codeplaysoftware/computecpp-sdk/issues/95 which seems to be a similar issue.
Trying the suggested fix to make the variable static constexpr also fixes the bug here.
Makes it consistent with the regular standard containers in terms of
size representation. This also gets rid of dependence on our own
type aliases, removing the need for an include.
The necessity of this parameter is dubious at best, and in 2019 probably
offers completely negligible savings as opposed to just leaving this
enabled. This removes it and simplifies the overall interface.
video_core: shorten GetGLSLVersionString
video_core: make GLES version and extensions consistent
video_core: move some logic to LoadShader
video_core: deduplicate fragment shader precision specifier
The comment already invalidates itself: neither MMIO nor rasterizer cache belongsHLE kernel state. This mutex has a too large scope if MMIO or cache is included, which is prone to dead lock when multiple thread acquires these resource at the same time. If necessary, each MMIO component or rasterizer should have their own lock.
To eliminate System::GetInstance usage. Archive type like SelfNCCH and SaveData changes the actual reference path for different client, so archive backend interface should accept client information from the service interface. Currently we only pass the program ID as the client information.
The UI file is rewritten, to better make use of Qt's layouts (instead of depending on abstract geometry). "Add Cheat", "Save", "Delete" buttons are also added.
The UI logic should be rather easy and usable (IMO), but the code may seem a bit dirty. If anyone has a better idea regarding UI logic design or code implementation, feel free to tell me about it.
Added a few interfaces for adding/deleting/replacing/saving cheats. The cheats list is guarded by a std::shared_mutex, and would only need a exclusive lock when it's being updated.
I marked the `Execute` function as `const` to avoid accidentally changing the internal state of the cheat on execution, so that execution can be considered a "read" operation which only needs a shared lock.
Whether a cheat is enabled or not is now saved by a special comment line `*citra_enabled`.
To break a circular reference formed by process->handle_table->shared_memory->process. Since SharedMemory uses its owner process in the destructor, which is not kept alive by SharedMemory any more, we need to make sure that the lifetime of process is longer than the shared memory. To partially resolve this, Process now explicitly releases shared memory first in its destructor. This is with the assumtion that there is no inter-process reference to shared memory on exit, which is not true when we introduce more multi-process emulation. A TODO is left there for this, as more RE needs to be done on how 3DS handles this situation
This commit it automatically generated by command in zsh:
sed -i -- 's/BitField<\(.*\)_le>/BitField<\1>/g' **/*(D.)
BitField is now aware to endianness and default to little endian. It expects a value representation type without storage specification for its template parameter.
This is compromise for swap type being used in union. A union has deleted default constructor if it has at least one variant member with non-trivial default constructor, and no variant member of T has a default member initializer. In the use case of Bitfield, all variant members will be the swap type on endianness mismatch, which would all have non-trivial default constructor if default value is specified, and non of them can have member initializer
According to documentation, if the argument of std::exp is zero, one is returned.
However we want the return value to be also zero in this case so no audio is played.
The V-Sync option is fundamentally broken in Citra, so let's do the same as yuzu and remove it entirely for SDL2 and at least from the frontend for QT.
(It was also only used by 7.3% of users)
Just two minor fixes:
1. Font color is black in dark theme. It is now only black for pings.
2. If a user is called `abc`, you can ping them by `@abc_`. Now a ping only takes effect when there are spaces around it.
std::make_unique for arrays is equivalent to doing:
std::unique_ptr<T>(new typename std::remove_extent<T>::type[size]())
(note the ending () after the array size specifier). This means that the
default value within memory for the constructed types will be whatever
the default constructor for that type does. Given the built-in
type for std::uint8_t doesn't have a constructor, this is equivalent to
forcing zero-initialization, so the memory will already be zeroed out on
construction. Because of that, there's no need to zero it out again.
We can hide the direct array from external view and instead provide
functions to retrieve the necessary info. This has the benefit of
completely hiding the makeup of the SinkDetails structure from the rest
of the code.
Given that this makes the array hidden, we can also make the array
constexpr by altering the members slightly. This gets rid of several
static constructor calls related to std::vector and std::function.
Now we don't have heap allocations here that need to occur before the
program can even enter main(). It also has the benefit of saving a
little bit of heap space, but this doesn't matter too much, since the
savings in that regard are pretty tiny.
Based on the `roles` payload in the JWT, the rooms will now give mod permission to Citra Community Moderators. To notify the client of its permissions, a new response, IdJoinSuccessAsMod is added, and there's now a new RoomMember::State called Moderator.
The user would be notified if the message contains "@" followed by the user's nickname or forum username. An alert would be shown, and the icon and message in the status bar would be changed. All notification is only shown if the chat window currently does not have focus.
Also added a connected_notification icon for showing in the status bar.
The ban list is stored in a format so-called CitraRoom-BanList-1 and just first stores username ban list, one entry per line, then an empty line and then store the ip ban list.
To allow for passing moderation errors around without impacting the State, this commit also separates the previous State enum into two enums: State, and Error. The State enum now only contains generic states like disconnected or connected, and the Error enum describes the specific error happened.
citra_qt/multiplayer/{state, message} is changed accordingly.
Displayed username along with nickname (when they are not identical); Requested and displayed user's avatar; Made the dialog bigger for extended names.
Added a few functions to web_backend (GetImage, GetPlain) to support getting data in multiple content-types.
Added a no_avatar icon for users without avatars.
Added verify_backend to load user_data for members. and removed method to generate UID as this is now done server-side.
Added GetUsername function and a "token" param to room_member.
Also added a username to ChatEntry, so that the username can be shown (along with nicknames) in the chat dialog.
These slots are only ever attached to event handling mechanisms within
the class itself, they're never used externally. Because of this, we can
make the functions private.
This also removes redundant usages of the private access specifier.
The previous code could potentially be a compilation issue waiting to
occur, given we forward declare the type for a std::unique_ptr. If the
complete definition of the forward declared type isn't visible in a
translation unit that the class is used in, then it would fail to
compile.
Defaulting the destructor in a cpp file ensures the std::unique_ptr's
destructor is only invoked where its complete type is known.
Because HLE::Source is initialized as an array in the member initializer, it is hard to let it accept the reference on ctor, so it has a second init stage performed by DspHle::Impl::Impl
Hardware testing indicated that FFFFFFFC is the correct mask for all audio formats (mono and stereo PCM8, mono and stereo PCM16, and ADPCM). This fixes broken audio in Luigi's Mansion: Dark Moon and a few other games.
Allows capturing screenshot at the current internal resolution (native for software renderer), but a setting is available to capture it in other resolutions. The screenshot is saved to a single PNG in the current layout.
While admirable as a means to ensure immutability, this has the
unfortunate downside of making the class non-movable. std::move cannot
actually perform a move operation if the provided operand has const data
members (std::move acts as an operation to "slide" resources out of an
object instance). Given Barrier contains move-only types such as
std::mutex, this can lead to confusing error messages if an object ever
contained a Barrier instance and said object was attempted to be moved.
This is also unused and superceded by standard functionality. The
standard library provides std::this_thread::sleep_for(), which provides
a much more flexible interface, as different time units can be used with
it.
This is an old function that's no longer necessary. C++11 introduced
proper threading support to the language and a thread ID can be
retrieved via std::this_thread::get_id() if it's ever needed.
Both member functions assume the passed in target process will not be
null. Instead of making this assumption implicit, we can change the
functions to be references and enforce this at the type-system level.
All usage of GetPointerFromVMA is to recover the pointer that is nulled by changing page type to RasterizerCachedMemory. Our rasterizer cache only works on linear heap and vram, so we can recover the pointer directly by address computation, instead of going through VMA table. Also removed a sanity check pointer!=nullptr in RasterizerMarkRegionCached(RasterizerCachedMemory=>Memory), as now the pointer is never null. The sanity check was added in f2a5a77 (#2797), which was originally necessary during VMA unmapping process, because the function is invloked by VMA after unmapping the page, which in turn invokes back to query the memory, forming a circular dependency. Now the dependency is resolved so the check is not necessary