Since we do not have an overlay yet, it can be confusing whether movie is being recorded or played. This makes it clear.
Status messages (e.g. system archive missing) will be overriden, but that shouldn't be too important when recording movies.
Doubled the status bar updating frequency to provide a better experience. It now updates every second.
This is completely rebuilt, in order to allow setting author, displaying movie metadata, and toggling read-only mode.
The UX is changed to more closely match other emulators' behaviour. Now you can only record/play from start/reset (In the future, we might want to introduce 'record from savestate')
Also fixed a critical bug where movie file can be corrupted when ending the recording while game is still running.
Instead of specifying it when starting playback. This is necessary as
you can end up playing the movie even if you started as Recording
(for example, loading a state in R/O mode will switch to Playing mode)
Most other emulators handle this automatically in the frontend,
booting/restarting the corresponding game instead of reporting an error.
Therefore, remove these checks and errors from the module.
These fields are included in most emulators and required by TASVideos.
`input_count` is implemented by counting the number of 'PadAndCircle' states, as this is always polled regularly and can act as a time/length indicator.
TASVideos also require the input count/frame count to be verified by the emulator before playback, which is also implemented in this commit.
The read-only mode switch affects how movies interact with savestates after you start a movie playback and load a savestate. When you are in read-only mode, the movie will resume playing from the loaded savestate. When you are in read+write mode however, your input will be recorded over the original movie ('rerecording'). If you wish to start rerecording immediately, you should switch to R+W mode, save a state and then load it.
To make this more user-friendly, I also added a unique ID to the movies, which allows each movie to have an individual set of savestate slots (plus another set for when not doing any movies). This is as recommended by staff at TASVideos.
Given this is a central class, we should flag cases where the return
value of some functions not being used is likely a bug.
Co-Authored-By: LC <712067+lioncash@users.noreply.github.com>
Previously core itself was the library containing the code to gather
common information (build info, CPU info, and OS info), however all of
this isn't core-dependent and can be moved to the common code and use
the common interfaces. We can then just call those functions from the
core instead.
This will allow replacing our CPU detection with Xbyak's which has
better detection facilities than ours. It also keeps more
architecture-dependent code in common instead of core.
Follows the video core PR. fmt doesn't require casts for enum classes
anymore, so we can remove quite a few casts.
Co-Authored-By: LC <712067+lioncash@users.noreply.github.com>
* service/apt: Add GetModule and GetAppletManager
These will be used to retrieve and set deliver args across system resets (which are currently implemented as complete restarts)
* applet_manager: Implement DeliverArg
`flags` was added to `ApplicationJumpParameters` as flags 0x2 is handled differently from 0x0.
* service/apt: Add ReceiveDeliverArg, implement GetStartupArgument
Some based on guesses.
* Address review comments
* kernel/thread: Change owner_process to std::weak_ptr
Previously this leaked almost all kernel objects. In short, Threads own Processes which own HandleTables which own maps of Objects which include Threads.
Changing this to weak_ptr at least got the camera interfaces to destruct properly. Did not really check the other objects though, and I think there are probably more leaks.
* hle/kernel: Lock certain objects while deserializing
When deserializing other kernel objects, these objects (`MemoryRegion`s and `VMManager`s) can possibly get modified. To avoid inconsistent state caused by destructor side-effects, we may as well simply lock them until loading is fully completed.
* Fix silly typo
Somehow this didn't break?!
Allows some implementations to avoid completely zeroing out the internal
buffer of the optional, and instead only set the validity byte within
the structure.
This also makes it consistent how we return empty optionals.
Co-Authored-By: LC <712067+lioncash@users.noreply.github.com>
The deep recursion has caused issues in certain games with large numbers of files, especially with MSVC builds.
Previously the recursion depth is about equal to the number of files present. With this the depth should be about equal to the maximum depth of the directory structure of the RomFS.
The general pattern is to mark mutexes as mutable when it comes to
matters of constness, given the mutex acts as a transient member of a
data structure.
Co-Authored-By: LC <lioncash@users.noreply.github.com>
The settings.h file doesn't actually need all of the definitions
on cam.h, only some of the enums. They can, therefore, be separated
into another file, which is included by settings.h instead.
The other changes are fixing files that included settings.h and
depended on indirect includes from includes of includes of cam.h
In all usages of LogSetting(), string literals are provided.
std::string_view is better suited here, as we won't churn a bunch of
string allocations every time the settings are logged out.
While we're at it, we can fold LogSetting() into LogSettings(), given
it's only ever used there.
Co-Authored-By: Mat M. <lioncash@users.noreply.github.com>
* Change "Toggle Speed Limit" to toggle between 100% and a custom value
This will change the shortcut for "Toggle Speed Limit" to make it swap between 100% and the value of "Limit Speed Percent" in the config. Old functionality is still there, but renamed to "Unthrottle".
* Complete reimplementation of the function
* Fix something that didn't get saved correctly
* Fix missing indentation
* Rewrite to keep only a single QSpinBox
* Second rewrite
* set Unthrottled to 0 in the Qspinbox
* Hotkey for Unthrottle
* minor improvements to the design
* Apply suggestions from code review
Co-authored-by: Ben <bene_thomas@web.de>
* Default slider values
* clang-format fixes
* Prevent the speed slider from changing size
...when an element in its row has variable width.
* Change "Game Speed" to "Emulation Speed"
* Apply suggestions from code review
`game_speed` to` emulation_speed`
Co-authored-by: Valentin Vanelslande <vvanelslandedev@gmail.com>
* Fix for QSliders
* Revert "Prevent the speed slider from changing size"
This reverts commit ddaca20044.
* clang-format
...doesn't seem to stick to a choice
* Fix 2 for QSliders
Co-authored-by: B3n30 <benediktthomas@gmail.com>
Co-authored-by: Ben <bene_thomas@web.de>
Co-authored-by: Valentin Vanelslande <vvanelslandedev@gmail.com>
We can adjust the API to allow std::size_t indices, which simplifies
operating with standard container types. It also prevents truncation
warnings from occurring in these cases as well.
* archive: Make use of std::pair for OpenFileFromArchive
The tuple only makes use of two elements, so we can use a pair to
simplify the number of underlying template instantiations that need to
be done, while also simplifying the surrounding code.
* archive: Simplify MakeResult calls
MakeResult can deduce the contained result type based off the type of
the variable being passed to it, so explicitly specifying it is a little
verbose.
While we're at it, we can also improve some of the allocations and
copying that would be going on in one case by preallocating and then
emplacing before modifying.
This might be caused by some packet/status delay within the enet protocol, or may be caused by our not properly handling disconnection. Anyway, this situation *can* happen, and we should not crash Citra for a non-critical error.
This change is not HW tested as I do not have 3 3DSes, but this should make sure that all the members of the network hold the same `node_info`, `nodes` and the bitmasks, etc.
Previously, when connecting, the host was using the incorrect node_id to update `node_info`.
This is an attempt to fix tywald's problem with MH, reported on Discord a while ago. I'm not sure if this would actually fix that though.
I'm not sure why we decided to have a boolean here, but apparently that wasn't the correct behaviour. According to HW tests, the Software Keyboard simply displays the default text when the button text provided is empty (**not necessarily all zero**). For example, if you set a text for one of the buttons and leave others empty, the button you set will have your text, while others will have their default texts. Removed the boolean and updated frontend code to make it correct.
Quite a few service functions are stubbed but still pop all their
arguments, which can lead to unused variable warnings.
We can mark the unused arguments with [[maybe_unused]] to silence these
warnings until a full implementation of these functions are made.
Allows implementations to allocate the object and the shared_ptr control
block in one allocation instead of needing to do two separate
allocations.
Also looks much nicer to the reader.
* swkbd: Fix a bug where clicking Cancel hangs the game
The text is validated in `Finalize`. If the validation fails, an error is returned and the applet is not actually finalized. This can result in hangs.
This is usually not a problem as the frontend is expected to validate the text passed to `Finalize`. However, when the user clicked on `Cancel`, the text is ignored and the frontend won't do any validation. Therefore, we should skip the validation here as well.
Also fixed a potential data race. All these functions should now be called on the same thread
* Address review comments
Renamed the fields
Remove close button
This class is memcpy-ed and memcpy has the requirement that data passed
to it must be trivially copyable, otherwise the behavior is undefined.
This is trivial to resolve as BitField was made trivially copyable a
while ago, so this explicit copy assignment operator isn't necessary.
This can be removed as it's not used. Even if it were however, it would
be an incorrect forward declaration, as ServiceManager exists within the
Service::SM namespace, not the top-level SM namespace.
Previously, we were returning a value that was way too big, causing an integer overflow in Fractured Souls.
According to wwylele, the biggest oberserved save size for 3DS is 1MB, so this new value should leave plenty of room, even if games use a bigger size.
Many of these functions are capable of being used within const contexts,
so we can apply the const qualifier in some cases and add const based
overloads for others, which makes the interface a little bit more
flexible and const-correct.
* core/memory: Amend unusual return value of operator=
operator= usually returns a reference to this. Given there's no comment
explaining why void was used, this can be assumed to be an oversight.
* core/memory: Make use of std::move in Entry::operator=
Same behavior, minus the need for an atomic reference count increment
and decrement (since MemoryRef contains a std::shared_ptr).
* ArmInterface: return ref instead of copy for GetTimer
* ArmInterface: add const ref GetTimer
* ArmInterface: return raw pointer instead of shared_ptr in GetTimer
* remove more unnecessary shared_ptr usage
* Fix save states
* fix unit tests
* am/am: Avoid redundant copy in GetProgramInfoFromCia()
We can just use a reference to the title metadata. Avoids copying
several data entries and std::vector instances that don't need to be
copied.
* hle/service: Avoid redundant copying of std::string
GetUserPath() returns the path as a reference, so we can make use of
said reference to avoid making copies.
By using a reference here, we avoid copying every single element in the
map, each of which contains a std::share_ptr and std::deque containing
std::vectors.
Allows interfaces to move the vector into the calls, avoiding any
reallocations.
Many existing call sites already std::move into the parameter, expecting
a move to occur. Only a few remain where this wasn't already
being done, which we can convert over.
This one is similar to the ReceiveCaptureBufferInfo function except it doesn't clear the capture buffer, according to 3dbrew.
This function is used by the Home Menu
The Home Menu uses this to determine whether it is allowed to launch an app (call StartApplication)
This is a no-op for us, we allow any and all titles to be launched. The official APT module holds a list of some forbidden titles like some versions of IronFall and Flipnote Studio 3D.
They are called by the Home Menu during initialization.
These functions will not see much use until we actually implement application jumping and system rebooting. For now we just need them to prevent some unmapped reads in the Home Menu due to the static buffers not being properly set up.
Also rewritten how GetArchiveResource works so that they all use the same interface.
We should decide what to do with these at some point.
Related to #3131 and #3110
* Kernel/Process: Notify the CPUs that a new pagetable has been set every time the process they're executing changes.
Previously the page table would only be changed when the current CPU's page table was changed, this lead to stale JIT states and the PC going to 0 when context-switching a different core inside the ThreadManager::SwitchContext function because the JIT for a new pagetable is only constructed upon receiving the change notification.
* Kernel/Process: Use the relevant CPU's last process to determine when to switch its current process.
Previously it was checking the kernel's current_process variable, which gets overwritten every time a CPU runs its slice. The rescheduling happens after all CPUs have run their slice so the code was effectively only checking the last CPU's process.
1. Ensure that register information available to gdbstub is most up-to-date.
2. There's no reason to check for current_thread == thread when emitting a trap.
Doing this results in random hangs whenever a step happens upon a thread switch.
* video_core/renderer_opengl: Move SurfaceParams into its own file
Some of its enums are needed outside of the rasterizer cache
and trying to use it caused circular dependencies.
* video_core/renderer_opengl: Overhaul the texture filter framework
This should make it less intrusive.
Now texture filtering doesn't have any mutable global state.
The texture filters now always upscale to the internal rendering resolution.
This simplifies the logic in UploadGLTexture and it simply takes the role of BlitTextures at the end of the function.
This also prevent extra blitting required when uploading to a framebuffer surface with a mismatched size.
* video_core/renderer_opengl: Use generated mipmaps for filtered textures
The filtered guest mipmaps often looked terrible.
* core/settings: Remove texture filter factor
* sdl/config: Remove texture filter factor
* qt/config: Remove texture filter factor
* vm_manager: Handle multiple areas in ChangeMemoryState
It is possible that a few areas have the same permisson and state, but with different backing pointers. Currently, this function assumes that only one continous area is found, but this is not always the case.
* service/ldr_ro: Handle multiple areas in VerifyBufferState
It is possible that the buffer passed from the game is made up of multiple areas with the same permisson and state but different backing pointers. Change the check to allow that.
The most important one being adding a mutex to protect the format_context. Apparently it wasn't thread safe (as one'd expect) but I didn't think about that.
Should fix some of the strange issues happening with MP4 muxers, etc.
The file's size is stored in FileSessionSlot and retrieved when the game calls GetSize. However, it is not updated when the file is written to, which can possibly change the file size. Therefore, this can cause GetSize to return incorrect results.
According to HW tests, this vsync event is signaled for activated cameras at about the same frequency as the frame rate. The last 5 vsync timings are recorded (in microseconds) and can be retrieved with the service function.
Also, corrected the default frame_rate to 15, according to HW test.
This should fix the missing camera images in certain games.
You can now directly place ExeFS overrides/patches inside the mod folder (instead of the exefs subfolder). This allows us to have drop-in compatibility with Luma3DS mods.
These two functions allow the frontend to get a list of encoders/formats and their specific options.
Retrieving the options is harder than it sounds due to FFmpeg's strange AVClass and AVOption system. For example, for integer and flags options, 'named constants' can be set. They are of type `AV_OPT_TYPE_CONST` and are categoried according to the `unit` field. An option can recognize all constants of the same `unit`.
Previously, we just used the native sample rate for encoding. However, some encoders like libmp3lame doesn't support it. Therefore, we now use a supported sample rate (preferring the native one if possible).
FFmpeg requires audio data to be sent in a sequence of frames, each containing the same specific number of samples. Previously, we buffered input samples in FFmpegBackend. However, as the source and destination sample rates can now be different, we should buffer resampled data instead. swresample have an internal input buffer, so we now just forward all data to it and 'gradually' receive resampled data, at most one frame_size at a time. When there is not enough resampled data to form a frame, we will record the current offset and request for less data on the next call.
Additionally, this commit also fixes a flaw. When an encoder supports variable frame sizes, its frame size is reported to be 0, which breaks our buffering system. Now we treat variable frame size encoders as having a frame size of 160 (the size of a HLE audio frame).
We previously assumed that the first preferred sample format is planar, but that may not be true for all codecs. Instead we should find a supported sample format that is planar.
While YUV420P is widely used, not all encoders accept it (e.g. Intel QSV only accepts NV12). We should use the codec's preferred pixel format instead as we need to rescale the frame anyway.
This uses the mailbox model to move pixel downloading to its own thread, eliminating Nvidia's warnings and (possibly) making use of GPU copy engine.
To achieve this, we created a new mailbox type that is different from the presentation mailbox in that it never discards a rendered frame.
Also, I tweaked the projection matrix thing so that it can just draw the frame upside down instead of having the CPU flip it.
This slider affects the number of cycles that the guest cpu emulation
reports that have passed since the last time slice. This option scales
the result returned by a percentage that the user selects. In some games
underclocking the CPU can give a major speedup. Exposing this as an
option will give users something to toy with for performance, while also
potentially enhancing games that experience lag on the real console
* Core::Timing: Add multiple timer, one for each core
* revert clang-format; work on tests for CoreTiming
* Kernel:: Add support for multiple cores, asserts in HandleSyncRequest because Thread->status == WaitIPC
* Add some TRACE_LOGs
* fix tests
* make some adjustments to qt-debugger, cheats and gdbstub(probably still broken)
* Make ARM_Interface::id private, rework ARM_Interface ctor
* ReRename TimingManager to Timing for smaler diff
* addressed review comments
* HTTP_C::Implement Context::MakeRequest
* httplib: Add add_client_cert_ASN1 and set_verify
* HTTP_C: Fix request methode strings case in MakeRequest
* HTTP_C: clang-format and cleanups
* HTTP_C: Add comment about async in BeginRequest and BeginRequestAsync
* Update httplib to contain all the changes we need; adapt http_c and web_services to the changes in httplib; addressed minor review comments
* Add android-ifaddrs
10 slots are offered along with 'Save to Oldest Slot' and 'Load from Newest Slot'.
The savestate format is similar to the movie file format. It is called CST (Citra SavesTate), and is basically a 0x100 byte header (consisting of magic, revision, creation time and title ID) followed by Zstd compressed raw savestate data.
The savestate files are saved to the `states` folder in Citra's user folder. The files are named like `<Title ID>.<Slot ID>.cst`.