Skip to content
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

Possible to add more systems #6

Closed
ethanaobrien opened this issue Oct 7, 2021 · 35 comments
Closed

Possible to add more systems #6

ethanaobrien opened this issue Oct 7, 2021 · 35 comments
Labels
discussion discussion

Comments

@ethanaobrien
Copy link

Is it possible that we could add more systems such as the wii / gamecube (dolphin emulator)

@BinBashBanana
Copy link
Owner

That core requires waaaay too much power for the browser to run, sorry. For more cores, see #5

@ethanaobrien
Copy link
Author

@BinBashBanana
Understandable. There is one thing I'd like to mention (although I dont think it requires opening another issue)

Do you think It would be possible to reverse engineer the wasm and asm.js files found in this emulator. This could solve all sorts of UI problems (and add support for nintendo DS)

@BinBashBanana
Copy link
Owner

Ohh no wonder your name looked familiar. About emulatorjs, it appears to just be retroarch ported through emscripten, but not open source, and seemingly no way to contact the site owner. Unfortunately, it is impossible to decompile the code into anything readable.

Emulatorjs tries to hide the fact that it uses retroarch, or even emscripten for that matter, by deleting Module and other objects (or effectively deleting) after it finishes loading. The Module object is accessible for around 3 seconds while the emulator is loading.

Capture
Dead giveaway, these are the default exported functions in retroarch. I was also able to locate the retroarch.cfg file in the filesystem.

This emulator has a lot of nice support and features, and I hate to see it wasted on a closed-source project. :(

@ethanaobrien
Copy link
Author

@BinBashBanana I just noticed, do you think there would be a performance difference if we compiled to asmjs instead of wasm. Looking at emulatorjs they have no wasm to n64, only asmjs

@BinBashBanana
Copy link
Owner

There would most likely be a negative difference, wasm is usually faster than asm.js.

@ethanaobrien
Copy link
Author

ethanaobrien commented Oct 12, 2021

@BinBashBanana Ahh, I see.

Would you like to try to help me reverse engineer emulatorjs?

I managed to hijack the wasm data before it is run and after it is decoded and I was able to somewhat decode the ds wasm. It's really messy (and I'm a complete noob at C so it's complete chaos.) as suggested by here we could start to try to wrap the wasm, rather than decoding it. What do you think?

this zip file contains

  • the decoded ds wasm (title: ds-in.wasm)
  • The somewhat decoded to C ds wasm file (title: ds-out.c)
  • The retroarch javascript module the emulator uses (title: retroarch.js, I ran the file through a javascript cleanifier to make it easier to read). It seems as if all the data is hidden somewhere. It evals the code to hide where it gets it and there is no present fetch function in the network logs. In the end, I have the file.
  • The retroarch .mem file (title: retroarch.js.mem)

The variable that stores this info is set to null right after it is used.

To view logs from retroarch, add the line EJS_DEBUG_XX = true to the example script (or just in a script in general)

The module element used to run the wasm

window.Module = {
    'TOTAL_MEMORY': 0x10000000,
    'noInitialRun': !0x0,
    'arguments': [],
    'preRun': [],
    'postRun': [],
    'canvas': _0xb2be2a, // The HTML canvas element
    'print': function(_0x4a8983) {
        'undefined' != typeof EJS_DEBUG_XX && !0x0 === EJS_DEBUG_XX && console.log(_0x4a8983);
    },
    'printErr': function(_0x367bee) {
        'undefined' != typeof EJS_DEBUG_XX && !0x0 === EJS_DEBUG_XX && console.log(_0x367bee);
    },
    'totalDependencies': 0x0,
    'monitorRunDependencies': function(_0x5d4b07) {},
    'locateFile': function(_0x3fe7ca) {
        var _0x3787ba = null;
        if (_0x3fe7ca.includes('.worker.js')) {
            Object['keys'](_0x4d7024['coreFileData']).includes(_0x3fe7ca) && (_0x3787ba = _0x4d7024['coreFileData'][_0x3fe7ca]);
            var _0x2c1832 = new Blob([''], {
                'type': 'application/javascript'
            });
            return window.URL.createObjectURL(_0x2c1832);
        } // Instead of fetching the retroarch.js.mem, it seems to push a buffer, which is how it hides it from the network logs
        return _0x3fe7ca.includes('.js.mem') && (Object.keys(_0x4d7024['coreFileData']).includes(_0x3fe7ca) && (_0x3787ba = _0x4d7024['coreFileData'][_0x3fe7ca]), _0x3787ba) ? (_0x4d7024.memData = null, _0x3787ba.buffer) : _0x3fe7ca;
    },
    'readAsync': function(_0x20d016, _0x9d2de4, _0x1425ee) {
        if (_0x20d016 instanceof ArrayBuffer) {
            setTimeout(function() {
                _0x9d2de4(_0x20d016);
            }, 0x1f4)
        } else {
            var _0x164012 = new XMLHttpRequest();
            _0x164012.open('GET', _0x20d016, !0x0), _0x164012.responseType = 'arraybuffer', _0x164012.onload = function() {
                0xc8 == _0x164012.status || 0x0 == _0x164012.status && _0x164012.response ? _0x9d2de4(_0x164012.response) : _0x1425ee();
            }, _0x164012.onerror = _0x1425ee, _0x164012.send(null);
        }
    }
};

to find this in the emulatorjs file, just search _0x20d016, _0x9d2de4, _0x1425ee

I haven't managed to decode any asm.js cores yet.

Please let me know if you would like to help reverse it or if you would like me to keep you updated on my findings

Edit: I used another wasm decompiler and the results were much more readable. Zip uploaded below
zip.zip
(Both zips are different)

@BinBashBanana
Copy link
Owner

I tried looking through the decompiled files, I couldn't find anything of use. I also tried using wasmdec, but I had the same results. (Here is the file anyway)
wasmdec-nds.zip

I think it is probably a waste of time trying to decompile the cores, but the EJS_DEBUG_XX you found might prove to be useful. I will look into GLupeN64, and try to compile it.

@ethanaobrien
Copy link
Author

@BinBashBanana Do you think we could try to translate ppsspp? It looks like it has a libretro build target

@BinBashBanana
Copy link
Owner

Possibly... Again there is the GLES problem, and I'm not even sure if the browser can handle psp emulation.

@ethanaobrien
Copy link
Author

I think some computers could handle it, as my chromebook could run windows vista in a virtual machine in the browser (https://copy.sh/v86/). And there is one current (typescript) psp emulator. I think it would be really cool to see it run but yeah, the GLES problem is kinda tricky.

@BinBashBanana
Copy link
Owner

Ok, I will look into it. Also I didn't know copy.sh had windows vista, that's cool

@ethanaobrien
Copy link
Author

Thank you for looking into it.

Windows vista works issue - copy/v86#404

@BinBashBanana
Copy link
Owner

I think this issue is better than the other one, reopening

@BinBashBanana BinBashBanana reopened this Oct 19, 2021
@ethanaobrien
Copy link
Author

@BinBashBanana
Copy link
Owner

Those look cool, I will look into those too, though I'm not completely sure they can help.

@ethanaobrien
Copy link
Author

ethanaobrien commented Nov 24, 2021

@BinBashBanana
I have made a simple program that will decrypt the files from the emulator.js website and restore them to a .7z file
html file (zipped): decrypt.zip

output: n64-asmjs.zip

@ethanaobrien
Copy link
Author

@BinBashBanana

I built a more stable version that includes encryption and decryption. You can edit the files and encrypt a 7z file with the edited files and then place it in place of the old core
decrypt tool

@ethanaobrien
Copy link
Author

@BinBashBanana

I found this. it seems to run much better than this one. Do you think it would help? There are a lot less graphical problems as far as I can tell.

Repository owner deleted a comment from hello-smile6 Jul 30, 2022
@BinBashBanana
Copy link
Owner

@ethanaobrien v6.5 has finally released! I don't think we should continue any efforts to decompile/reverse-engineer anything, future discussion should happen in #9. Can I close this issue now?

@ethanaobrien
Copy link
Author

yeah I gave up on reverse engineering a long time ago, I started working on my own cores, “beta” cores, and they currently use about 1/10th of the cpu of the original emulatorjs cores.

One question before you close this

I saw you increased the stack size of the emscripten compiler, does that have any affect on any systems other than Nintendo 64? Did you use the larger stack size to compile all the systems? I’m wondering if it has a better (or worse) affect on the system. Also, where’d you change this setting/ what flag/edit did you use to compile it, could you send me the link, I’d love to take a look at it

But so you rewrote the entire renderer? That’s awesome! Is all the code in this repository? I’d love to look at it and see if I could use it to improve the beta cores (or make a beta core for Nintendo 64.)

@BinBashBanana
Copy link
Owner

Stack memory is only increased for Mupen64Plus-Next (see here) because it needs to be (see #4). Increasing it shouldn't have any effect on performance for any core. That option goes through into the makefile and adds this to LDFLAGS: -s TOTAL_STACK=268435456. The heap memory (TOTAL_MEMORY) also needs to be increased to 536870912 in order for it to compile with the raised stack memory.

And no, I didn't rewrite the renderer lol. I just had to change some things in GLideN64 to get it to work on emscripten GLES3, and also patch emscripten's webgl library (both pretty simple). I did have to do a lot more work for Beetle PSX though.

You can see how to apply the patches I made here: Building from source

@ethanaobrien
Copy link
Author

Ok, thanks for the info. I’m going to look into all this, thanks!

I’ll close this now

@ethanaobrien
Copy link
Author

I took a look at the building from source readme, so basically you just compile normally but apply the patches first?

you’ve put in a crazy amount of work for this project, thank you!

@BinBashBanana
Copy link
Owner

That is correct. Thank you too

@ethanaobrien
Copy link
Author

Thank you so much for your help! I was able to compile n64 to a beta core!

@BinBashBanana
Copy link
Owner

Nice!

@ethanaobrien
Copy link
Author

Hey @BinBashBanana quick question, have you experienced the bug mentioned here- https://github.com/ethanaobrien/emulatorjs/discussions/305

the Nintendo 64 load state seems to be broken, is this specifically me or have you experienced this too?

@BinBashBanana
Copy link
Owner

@ethanaobrien N64 save states are quite large, so you could be running into storage problems if you're using localStorage. I used to use localStorage but I switched over to indexedDB which has more capacity (5 MB --> 50+ MB)

@ethanaobrien
Copy link
Author

ethanaobrien commented Aug 5, 2022

Actually it doesn’t even work when you download and re-upload the state. This is probably just me then, thank you!

(and yeah I agree, indexeddb is much better)

@ethanaobrien
Copy link
Author

Hey @BinBashBanana i have some advice. I saw in one of the most recently opened issues that a user is complaining because of the time it takes to save the state. I have a solution for that and looked in your patch file and I don’t think I saw it in there.

Assuming you write the save files to the disk (I actually read the save states straight from ram) retroarch by default crazily limits the read/save chunk speed. This doesn’t affect us since everything is kept in memory.

here is a link to the line I changed that drastically changed the save/load state speed

https://github.com/ethanaobrien/RetroArch/blob/1f6ca062ae972747af6c2a8c7b5737f6e14d1f4b/tasks/task_save.c#L69

As I said, I just read my save states from memory and I’d be happy to help you implement that if you’d like. I’d recommend it, it’s much faster (but compression is unavailable, but when you actually get used to it I think it’d be better to have no compression then have a 1 minute to save state)

If there’s anything you need help with I’d be happy to help you!

(I would’ve commented in that issue, but I’ve had a really bad relationship with that user)

@BinBashBanana
Copy link
Owner

Thank you, I will increase the write chunk size in the next update, but I won't be getting rid of compression. I'll try some other optimizations such as autovectorization which should make it at least a little bit faster.

@BinBashBanana BinBashBanana added the discussion discussion label Aug 13, 2022
@ethanaobrien
Copy link
Author

Sounds good! If you have any other questions or need help with something I'd be glad to try to help

@ethanaobrien
Copy link
Author

ethanaobrien commented Sep 14, 2022

Hey @BinBashBanana Theres something I found that might be interesting to you (and I need help on)

I was digging though ppsspps code and found out that there is a libretro folder with a make file like every other project. I tried to compile for emscripten (it failed) but I made a few changes (see the patch file). Theyre very loose changes (I was just trying to get the linker file built) and I managed to do it! (I also uploaded that file below), but when trying to link with retroarch I get several type conflict errors. I've seen this before on cores you managed to compile and was wondering if you could get this core to build too! Thanks for all the work you've done!

Please note - when compiling ppsspp to the .bc linker file the command would look something like this

/path/to/emscripten/emar rcs  ../ext/vma/vk_mem_alloc.o ../ext/snappy/snappy-c.o ....

for some reason it doesnt up the bc file name in there (As you can see, there are 2 spaces). To get around this I just coppied the command and changed it and then ran the changed code

/path/to/emscripten/emar rcs ppsspp_libretro_emscripten.bc ../ext/vma/vk_mem_alloc.o ../ext/snappy/snappy-c.o ....

Note - the ppsspp linker file can take up to 1 hour to build

I think psp emulation may be possible (with enough memory), but I may also be entirely wrong. Can you look at this? Have you looked at this before?

Thanks for your help!

zip file with both the linker file and the patch file: ppsspp.zip

@ethanaobrien
Copy link
Author

ethanaobrien commented Sep 24, 2022

@BinBashBanana
EDIT: I have cleaned up some of the changes and updated it so it would have the ability to merge on the latest ppsspp commit. I also fixed the ppsspp linking bug, so you will not need to fix anything on the emar step

Here is the new zip file with the updated linker file and patch file: ppsspp.zip

Also, it looks like it actually compiles with retroarch with this new patch file, it just calls abort when you try to start it, maybe you could trace this down.
Thanks!

@BinBashBanana
Copy link
Owner

Looks good, I'll see if I can do anything.

@ethanaobrien ethanaobrien mentioned this issue Sep 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion discussion
Projects
None yet
Development

No branches or pull requests

2 participants