-
Notifications
You must be signed in to change notification settings - Fork 376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[🐧] GNU+Linux compatibility progress #1430
Comments
Issues with EmuHawkStartup issues:
Misc. issues:
CoresIssues with Mupen
Issues with TI83Hawk
Building and packagingDependencies are being recorded (so build scripts can be made) in the GitLab mirror's snippets. On multi-arch distros, target x86_64/amd64. For the record I've mostly focused on Manjaro (which I use), Nix/NixOS, Linux Mint, and Ubuntu. --yoshi
Don't know where else to leave these:
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
EmuHawk: SharpCompress implementation for Mono - TASEmulators#1430
…licks 'open firmware folder'. This mitigates the 'Folder open dialog crash' referenced in TASEmulators#1430
This comment has been minimized.
This comment has been minimized.
It's probably clearer if you follow the launch scripts starting with |
I suspect this is because we render text to the surface and then scale everything up at the end, rather than scaling up the frame then rendering text at a larger size on a larger surface. |
Yeah i already suspected something like that was happening. When i made the font/TextSize bigger the quality got better and better. |
Funny thing actually; |
SummaryA certain combination of memorysavestate and coroutines in a Lua script crashes the Gambatte core with a SIGSEGV. It does not crash the GBHawk core. Repro
Output
EmuHawkMono_laststdout.txt
EmuHawkMono_laststderr.txt
Host env.
BackgroundThe crash_gambatte.lua script is simplified from one I am working on for a TAS. The purpose of the console.log("main coroutine start")
run_until_exec(500, TITLE_SCREEN_ADDR)
console.log("title screen")
earliest_effective_frame(
function () joypad.set({Start = true}) end,
function () return run_until_exec(32, MAIN_MENU_ADDR) end
)
console.log("main menu") If you remove the final |
This isn't something Linux specific here (I can repro the crash on Windows, although it just crashes in managed code rather). The issue is you end up using savestate APIs in a memory callback. This is not allowed, it will crash various cores (if some don't, that's rather by happenstance and is not something to be relied on), as you are in the middle of the core's emulation loop, which is not expecting savestates to be used, and if any fix is done it would be to just prohibit savestate API usage (i.e. throw some exception so the lua script dies) while in a memory callback. |
@CasualPokePlayer, thanks for the information. I see now. Is there a list of which callbacks are safe with respect to making savestates? I suppose it's fine to call
If possible, I would suggest making the prohibition on savestates a function of the emulator state, not the Lua call stack. In the script I posted in #1430 (comment), the Changing |
The emulator should not be in charge at all in ensuring Lua users are not using savestates within memory callbacks, if just due to that meaning 10000 copy paste checks in places where the Lua script manager could be doing it.
This doesn't matter, the memory callback has not returned (and thus the emulator's FrameAdvance() call has not returned). Until that memory callback returns, and then eventually the FrameAdvance() call returns, will it be safe for a savestate to be made/loaded.
Most callbacks are safe, the only ones that aren't are memory callbacks (on_bus_* and the deprecated variants) and input callbacks (oninputpoll), as they occur midway in the emulator FrameAdvance() call. |
5bf9d38 should fix this. |
I think what I proposed was basically right, though perhaps not for the reason I thought. It's not so much in what coroutine the savestate operations happen, but as you say, whether the memory callback has returned. The workaround I suggested, "rounding up" to the next frame boundary, has the side effect of letting the memory callback return. Here's an example. Now that I understand the problem better, here's a much more minimal demonstration of a crash from improperly loading a savestate inside an -- log to a file to make messages visible after the emulator crashes
assert(io.output(assert(io.open("log.txt", "w"))))
function log(s)
console.log(s)
assert(io.write(s .. "\n"))
assert(io.flush())
end
local savestate_id = memorysavestate.savecorestate()
coroutine.resume(coroutine.create(function ()
log("begin main coroutine")
local event_id
event_id = event.on_bus_exec(function ()
assert(event.unregisterbyid(event_id))
log(string.format("enter on_bus_exec callback cycles %d", emu.totalexecutedcycles()))
log(string.format(" loadcorestate cycles %d (in on_bus_exec callback)", emu.totalexecutedcycles()))
memorysavestate.loadcorestate(savestate_id) -- crashes
memorysavestate.removestate(savestate_id)
log(string.format(" exit on_bus_exec callback cycles %d", emu.totalexecutedcycles()))
end, 0x00fe)
log(" end main coroutine")
end)) The output of the above script (which crashes the Gambatte core) is:
Here's a modified version that "rounds up" by waiting for an coroutine.resume(coroutine.create(function ()
log("begin main coroutine")
local co = coroutine.running()
local event_id
event_id = event.on_bus_exec(function ()
assert(event.unregisterbyid(event_id))
log(string.format("enter on_bus_exec callback cycles %d", emu.totalexecutedcycles()))
coroutine.resume(co)
log(string.format(" exit on_bus_exec callback cycles %d", emu.totalexecutedcycles()))
end, 0x00fe)
coroutine.yield() -- wait for on_bus_exec callback to yield back to us
-- now run the emulator up to a frame boundary, in order to make it safe to run loadcorestate
local event_id
event_id = event.onframestart(function ()
assert(event.unregisterbyid(event_id))
log(string.format("enter onframestart callback cycles %d", emu.totalexecutedcycles()))
coroutine.resume(co)
log(string.format(" exit onframestart callback cycles %d", emu.totalexecutedcycles()))
end)
coroutine.yield() -- wait for onframestart callback to yield back to us
log(string.format(" loadcorestate cycles %d (in main coroutine)", emu.totalexecutedcycles()))
memorysavestate.loadcorestate(savestate_id)
memorysavestate.removestate(savestate_id)
log(" end main coroutine")
end)) The output of the modified script shows that the
I'm using coroutines because I'd like to be able to write the program in a blocking async style rather than a callback-oriented style. But the modified version can also be expressed in a callback style: local memory_event_id
memory_event_id = event.on_bus_exec(function ()
assert(event.unregisterbyid(memory_event_id))
log(string.format("enter on_bus_exec callback cycles %d", emu.totalexecutedcycles()))
local frame_event_id
frame_event_id = event.onframestart(function ()
assert(event.unregisterbyid(frame_event_id))
log(string.format("enter onframestart callback cycles %d", emu.totalexecutedcycles()))
log(string.format(" loadcorestate cycles %d (in onframestart callback)", emu.totalexecutedcycles()))
memorysavestate.loadcorestate(savestate_id)
memorysavestate.removestate(savestate_id)
log(string.format(" exit onframestart callback cycles %d", emu.totalexecutedcycles()))
end)
log(string.format(" exit on_bus_exec callback cycles %d", emu.totalexecutedcycles()))
end, 0x00fe) The output of the program in the callback style is:
By my reading of 5bf9d38, it won't interfere with either of the two revised programs. |
This comment was marked as resolved.
This comment was marked as resolved.
I've never seen this. What DE do you use?
As you probably guessed, I still avoid Flakes, so this one is new to me too. And I have no idea what the cause could be; my understanding was that Flake evaluation is pure-by-default, and
Contributions welcome! What we have currently is a ~monthly CI job which runs let
bizhawkAttrs = import ./. { hawkSourceInfoDevBuild = {
# ...
}; };
patchList = [
# e.g.
{ rev = "5cb80569d97436c2e838732ead63c8251dcd8a91"; hash = "sha256-NdJ8Fw7YcrPlkjTzsHm8DbCQPixPmDXTdLNiZp6nggs="; }
];
bizhawkAssemblies = bizhawkAttrs.bizhawkAssemblies.overrideAttrs (oldAttrs: {
patches = (oldAttrs.patches or []) ++ (builtins.map
({ hash, rev }: fetchpatch { inherit hash; url = "https://github.com/TASEmulators/BizHawk/commit/${rev}.patch"; })
patchList);
});
in bizhawkAttrs.buildEmuHawkInstallableFor { inherit bizhawkAssemblies; } |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Note I have done so too for another project. Note |
Is the C implementation SIMD? I'm not sure if it's possible, but I was interested in writing a polyfill for |
C implementation gets optimized with SIMD the best the compiler can (it's really more that a C compiler is smart and can recognize SIMD'able code, while the JIT is not that smart and needs hints with On that note, |
SummaryThe Ares64 core doesn't seem the flush the SaveRAM file immediately, only when closing the ROM. I was playing Ocarina of Time in an Archipelago Randomizer and I got a crash. I saved multiple times during gameplay but after restarting the emulator my progress was lost. I then tested saving the game to see if the SaveRAM file would get written. It only gets written, when you close the ROM and not immediately after saving. This also happens in vanilla Ocarina of Time. Repro
Host env.
|
That is expected behavior across all the cores, not just Ares64. There is an AutoSaveRAM option in Config -> Customize -> Advanced available for avoiding issue with this behavior. (There's probably some issue that explains this in length, but the tl;dr is it's really hard to define when the "game is saving," it is something that can only be heuristically determined since the emulator has no understanding of a game's intent of doing things, and for many systems this is just impossible to determine due to "save memory" possibly being used as "extra ram" and not for save data) |
That is the received wisdom, though now you mention it I do wonder how bad the disk writes could possibly be if it was flushed every frame (the worst case of an unindicative dirty bit). |
The problem is that SSD will get clogged with that much traffic and create random hiccups. It's also abusive. Do the math on the GB/hr it can easily turn into. |
Sure: For a NES game with 64 KiB SaveRAM, it's ~4 MiB/s, or ~14 GiB/hr. For a DS game with 256 KiB SaveRAM, it will obviously be 4x that. I looked up a benchmark for my $40 SSD (CBB running one) and it gets ~300 MiB/s for random writes. I think it's worth experimenting with at least. |
Most cores don't bother to implement the SaveRAM dirty flag in the first place, just always returning true if SaveRAM exists. If we want to do anything it should just be enabling AutoSaveRAM by default. And if you want to avoid unneeded writes, you're better off just comparing the returned SaveRAM against the previously returned SaveRAM instead of relying on the core to figure out if SaveRAM is dirty or not. |
Bursts of random writes are not the same as a continuous never-ending spew of random writes. Random or not, recording an avi while playing should be a good approximation of what it will be like to continuously spew save data. Regardless, continually writing that much data without a user intentionally enabling it is a defect. Prepare for it to be reported as a bug. |
jump to known bugs
Overview:
DllNotFoundException
:libbizhash
when opening any rom on Linux AArch64 #3687. Contributions welcome.Dist/BuildRelease.sh
.output/EmuHawkMono.sh
.EmuHawkMono.sh
are passed through as expected. The single exception is if you pass--mono-no-redirect
as the first flag, which disables redirecting stdout/stderr toEmuHawkMono_last*.txt
(the default behaviour is to write to disk instead of the terminal).EmuHawkMono_last*.txt
, some appear in dialog boxes, some both. Most of these error dialogs will either have a "Copy" button, or will allow Ctrl+C.As of 2.9.1, the following systems can be emulated:
These systems haven't been tested or aren't finished:
These features/subsystems work:
Config
>Controllers...
andConfig
>Hotkeys...
Config
>Display...
Config
>Sound...
Config
>Paths...
Config
>Firmwares...
Config
>Autofire...
Config
>Customize...
Config
>Profiles...
Config
>Cores
)View
>Window Size
View
Tools
>RAM Watch
Tools
>Cheats
(does not crash)The text was updated successfully, but these errors were encountered: