- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
A new NSO compression method was introduced in Switch 22.0.0. This is a
customized variant of zstd and is used when NSO flags have bit 7 set.
Key characteristics:
- ZSTD_MAGICNUMBER is set to 0x4349425A (b'ZBIC') instead of 0xFD2FB528
- ZSTD_LEGACY_SUPPORT is set to 0
- ZSTD_TRACE is set to 1, zstd version used is 1.5.7 (10507)
- FSE_readNCount is replaced with a BIC (Binary Interpolative Coding)
version which improves compression of entropy tables significantly
Source: https://switchbrew.org/wiki/22.0.0
Implementation:
- Detect ZBIC segments via NSO flag bit 7 (NsoFlags_UseZbicCompression)
and/or ZBIC magic scan in nso.cpp
- Fall back to LZ4 when ZBIC is not detected or returns unexpected size
- Handle segment 0 alternate offset (0x100 vs 0x108) for both ZBIC and LZ4
References:
- Atmosphère loader/strat zstd-zbic integration:
082115187a
- nxdumptool ZBIC segment compression support:
441e5c0904
- STORM_SWITCH ZBIC implementation:
1e09eb82b7
Tested with firmware 23.0.0 and ZBIC-compressed NSOs.
Co-authored-by: xbzk <xbzk@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4482
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
the general idea is to have a common procedure form whom to call
this way theres less "jumping around" for values of different sizes
additionally this **should** allow for better codegen since
most of the u8,u16,u32,u64 can be held within a u64
theoretically this means that you could deifne callbacks in suck
a way that it's essentially as costly as a `mov r64, m64`
but that's not doable due to the fact we have to do translations...
Is this a good change?
Primarily aimed for x86 and ARM to benefit, but I suppose LooooooongArch64 can benefit too.
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4158
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
This was intended to fix Dave the Diver issue, but we found a real silly hid bug, then a maybe broader applet issue:
By testing with John it was found out only the last controller connected worked, the others caused the game to freeze peacefully, no crashes, suggesting some loop or deadlock.
After seeking that lead, it was found that the freeze was caused by a malformed HID history entry when the controller applet removed P2.
Pressing P1 opens the controller applet, then Qt applet disconnects P2, which is expected.
Upon seeking callstack and hid sync path, it was found out that NPad::WriteEmptyEntry:
was using: ReadCurrentEntry().sampling_number + 1
instead of: ReadCurrentEntry().state.sampling_number + 1 (checked AtomicStorage in src\hid_core\resources\ring_lifo.h)
Fixing that fixed the freeze, but killed the sound!
Later handheld/docked was accidentally clicked and sound returned. Good lead.
Then i just had to corner which part of the toggle was causing the refresh and do something similar at the controller applet return routine (PopOutData in library_applet_accessor.cpp). This part seems harmless, but i'm not clearly sure about how proper it is, since it was like a transplant and test operation.
UPDATE:
To try Diablo 3 on my machine it was needed to stub HID function 551.
And to fix all abnormalies like multiple applet requests and crash the function PopOutData was reworked to ensurey idempotency among different applet focus conditions:
focus state changed: updates state and signals if needed
no state change, HLE application frontend: requests focus state changed notification
already pending change message: flag remains true and no duplicate pushed to queue entry
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4442
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: lizzie <lizzie@eden-emu.dev>
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
So, about Absolum's no overlay applet P2 issue:
The fallback controller applet ignored keep_controllers_connected, according comment: "This makes it easy to connect the desired controllers". Unfortunately it was not good enough. It disconnected every controller, then reconnected only the minimum player count. That disconnect interacts with some guests (absolum in this case) causing undesired behaviors.
The fix is entwined to original routine but it is a lot simple tho: preserves compatible connected controllers within the requested player range, while the existing routine configures only the remaining slots.
This may fix some games, and should not harm others. Let us give it a go.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4420
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
[dynarmic] use TST + B.NE instead of TBNZ for marked bit
Fixes qlaunch and ac3 crashes.
[am] Bruno FIX OVERLAY 2.0
Fixes incorrect load display when the overlay applet is enabled in AC3.
[android] handle empty programId in Game.settingsName
The ReShade post-processing change started calling
SettingsFile.loadCustomConfig() on every drawer open through
withPerGameConfig(), which exposed a pre-existing crash in
Game.settingsName when programId was an empty string.
[ns] use GetApplicationControlData3 for cmd23 in IReadOnlyApplicationControlDataInterface
We can use this method for now for launching games on fw23, while we don't have all the information.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4407
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
FFmpeg offers two opus decoders:
- libopus, this one is fed the same data (that affects output) as the previous libopus decoder had as well
- native opus decoder: this only takes Float32 samples, we then need to invoke swrescale to translate between s16 (what switch sends) and float32 (what FFmpeg expects), the process is computationally more expensive, but trades off neatly as the native opus decoder is very optimised
It also relegates the handling to FFmpeg, which simplifies existing code (more concretely, by using the "fill/drain" scheme for packets/frames)
Closes#2897
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4169
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
This issue was observed in MGS Master Collection Volume II, MGS4: Guns of the Patriots, Chapter 4: Shadow Moses
That title is a bundle, and that specific chapter is a program (MGS 1st stage), launched by a program (MGS4), launched by an application (main title bundle).
Upon decoding guest panic message, it was exposed that an abort was triggered after trying to create a save in nand/temp/gclvar.bak file.
Further instrumentation exposed the error on that file's path, caused from a previous deletion of that folder.
In the same session that folder had been already cleaned and created successfully, which evidences an undesired re-cleaning of the temp structure.
The issue was the fact that the MGS4 to MGS transition also calls EnsureSaveData>...>SaveDataFactory creator, and that was destroying the previous created temp structure. After that stage, the return from MSG to MSG4 was causing the same issue again.
By moving the deletion to the guest application level, the factory creation was called only once, as it should be, and the issue is gone.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4375
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: lizzie <lizzie@eden-emu.dev>
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
This is intended to fix Hades II save loading issue.
By analyzing panic dump it was found out that the error code was 0x160A. By decoding firmware it was found that error comes from 'nn::codec::InitializeHardwareOpusDecoder'.
Further decoding revealed that SDK tries to allocate multiple opus instances, up to the fw limit of 24 instances, and when it receives return error ResultOutOfOpusDecoders (385), a software fallback is gracefully used.
Implementing the limitation and the limit reached error code return makes saves load properly, multiple times in a row in both windows and android.
I still wonder why the game allocates too many parallel instances, but the current implementation is a real fw compliant solution, and whether the 24+ is real or some leak may be investigated later, or not.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4384
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reduces the page entries from 32 bytes to 8 and rewrites `VirtualBuffer` to be more efficient in memory usage and specifically for large zero regions.
The page table will now only reserve 1GiB instead of 4GiB and of this memory it should only use at most ~8MiB.
This PR has the side effect of using Eden on Windows on low memory systems much more plausible since it would previously require ~10GiB of committable memory at front (despite using ~5-6 at most, inadvertently stalling other processes) where as now it should only require around the amount that it'll actually use.
Co-authored-by: Lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4219
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
Problem: In cyrilic idioms, Absolum won't past beyond 1st area (intro miniboss).
From the user panic i`ve extracted these strings:
> GlobalState.request_next()
> save_state_to_saveGame(...)
> platform.ProcessSave()
> bin_serialize_to_file(...)
> StandaloneTypeModel.Write(SaveGame, ...)
> Write(SaveGame.AdventureSaveSlot, ...)
> Write(PlayerState, ...)
> ProtoBuf.ProtoWriter.WriteString(...) + 0xcc
> ProtoBuf.Helpers.DebugAssert(...)
> Debug.Fail(...)
By debugging ProtoBuf.ProtoWriter.WriteString(...) argument it was found that the string Отлично! (Great! expression for combos between 6 and 30 iirc) was reaching a size comparison of different values and causing an assert in guest side..
It seems the game tries to save highest combo level. I've managed to skip this bug by doing a perfect combo for entire level, so that the problematic word never was generated or attempted to be saved.
After further research, the issue chain was identified: Game maths literal string size via two ways and compare, and one of them was getting replaced by a wrong value due to Eden letting the literal string be interpreted as a real instruction.
Logic added:
const bool pair = decltype(l)::ExtractValue(raw) & 1;
const bool fixed_rt2 = decltype(rt2)::ExtractValue(raw) == 0b11111;
return pair || fixed_rt2;
- pair checks bit 21 (L & 1): register-pair instructions actually use Rt2, so they remain accepted.
- For single-register forms, require Rt2 == 31. The table word fails this check, so NCE leaves it intact.
Sources
https://www.scs.stanford.edu/~zyedidia/arm64/stxrb.htmlhttps://www.scs.stanford.edu/~zyedidia/arm64/stxp.htmlhttps://github.com/qemu/qemu/blob/master/target/arm/tcg/a64.decode#L344
Altough the solution is a case specific guard, it is data agnostic: This is a true fix to avoid a specific case in which a literal may be interpreted as a valid instruction, without interfering with other true instruction cases.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4369
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Replaces all instances of ankerl's unordered map/set with boost's
`unordered_flat_*` classes. This uses std::hash since boost::hash is
actually a lot slower.
Also adds an abstraction layer in `Common` so future changes are quicker
and easier.
Other implementation details:
- ankerl provided hash specializations for tuple and pair, so those were
ported here
- std::erase_if doesn't work on boost, so just used the ADL'd erase_if
This should be about equal or superior performance as unordered_dense for everything except iteration.
Signed-off-by: crueter <crueter@eden-emu.dev>
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4326
Reviewed-by: Lizzie and Samuel <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>