danoon2/Boxedwine

Is it possible to... And how?

Opened this issue · 11 comments

I had a few things I wanted to do that I am not yet sure how to do so I thought I could ask in bulk here:

  • Start apps maximized
    • Some apps do, some don't
  • Resize canvas dynamically
    • Can it be changed while running?
  • Add files dynamically
    • Can I load/add files while running?
  • Detect shutdown/closing
    • After clicking close the app just freezes
  • Use networking
    • NetSurf didn't load anything
  • Destroy/cleanup after closing
    • After deleting the canvas my app feels sluggish

Thanks for any help with any of these questions! Amazing app and if none of this got resolved I would still be happy to use it in my app as it is now.

Hi Dustin,
I worked on the JS side of things. I will try to answer your questions. I am in no way a JS developer, so the code you see is sufficient for what needs to be done, but maybe less than ideal.

  1. The app may record it has started maximised via a config file property or maybe a registry entry. If you run the app in BoxedWine desktop you may be able to capture where the window state is captured. Registry files are stored in /home/username/.wine/*.reg

  2. Not currently. I should say the JS layer is just there to run the WASM code. I took shell.html from emscripten repo and made edits.

  3. You can definitely add files to the browserFS filesystem(s). The issue is the visibility to BoxedWine. @danoon2 may have some thoughts.

  4. The JS layer was not designed as a component. The use case is to make it easy to run a game. That requires grabbing the url params, setting up the filesystem(s) and setting the BoxedWine command line params. It is single use. Gracefully handling shutdown didn't come into it. Happy to take advice on how to handle.

  5. Functionality not there. Would be nice to see it. I have heard of examples that use a WASM to WEB-RTC proxy for network communication. There might be better options.

  6. Not sure what is going on there. Probably related to 4.

Thank you very much for this response @kevodwyer!

  1. So I could add a .reg file into the file system possibly that would maximize all apps?

  2. Ok that is fine, I contain BoxedWine within a movable/resizable "window", so I was seeing if it would be possible to increase/decrease canvas size and have that reflected dynamically on a running BoxedWine instance.

  3. Ok I can experiment with BrowserFS. I actually use the same library within my app and was hoping they might be able to interact someday. But as you said, getting BoxedWine to detect/show the changes might be the tricky part.

  4. If I could figure out a way to detect somewhere that the user has ended the instance by pressing x to the main app, that is what I am hoping/looking for. My use case is automatically closing the containing element when BoxedWine has essentially been closed. Another possibility would be if BoxedWine didn't crash on close. Can I run the app + a shell so that when the app is closed the shell remains?

  5. I do see requests via websockets protocol, but I think there might be a missing proxy layer that could allow us to pass in a websockets proxy to use, similar to how is done in v86 which is another emulator I utilized which does have networking via websockets.

  6. Yes I am not clear how to find out what is keeping it slow, but after closing the BoxedWine app via [x], then closing my window/container of BoxedWine which holds the canvas, my app remains sluggish as if the entire thing is still running. I was hoping to find some things I could uninstantiate to free up whatever remains.
    I actually was not closing the app via [x] first. Doing that seems to free things up. So I may need to find a way to simulate that click or somehow .close()/.stop() the instance when I close it's container.

  1. Just keep in mind, Boxedwine will not see file system changes after it starts. For performance reasons I cache the file system entries. It will still open the file, so if you update the contents of an existing file, Boxedwine will see that. It just won't handle adding new files after Boxedwine starts.

  2. The networking code in Boxedwine is very primitive, before spending time on websockets, you should make sure it works with the desktop builds of Boxedwine. Also, as an emulator, it needs UDP access in order to do DNS lookups.

https://youtu.be/UFYsuaLav6o?t=5092

I added BoxedWine to my app this stream around that timestamp. It adds a lot, thank you again for the help @danoon2 & @kevodwyer !

@DustinBrett That is a really cool example of using Boxedwine in the browser. I've never see anything like that before where you implemented a desktop in the browser that let you open and close Boxedwine.

As for performance, I have 3 levels of CPU emulation

  1. Normal: this decodes an instruction and creates an object that represents it which contains a pointer to the next instruction. That pointer to the next instruction in an indirect function call and this leads to a lot of the slowness, especially in WASM.

  2. Normal+JIT: This will find heavily used blocks of code in the normal CPU core, then for the instructions in that block, write ASM for the device so that instead of indirect function calls, the operation for the instruction might be inlined, or at least the function that implements the instruction will become a direct function call.

  3. Binary translator: This will rewrite all x86 to the native ASM on the device. This is only supported on 64-bit systems because of how I handle memory management. I need to give each emulated process a 4GB continuous uncommitted virtual memory address block. This CPU core is multi-thread where each emulated thread gets a real thread on the host.

2 is twice as fast as 1. 3 is close to 50% of native speed.

WASM uses 1, the slowest emulation. We still haven't figured out how to create dynamic WASM code. If we do figure it out and are able to use Normal+JIT, I would expect the WASM build to be twice as fast. We've seen some small example of dynamic WASM, but our main issue is that we would need to be able to create a large number of "modules" which isn't allowed or at least figure out how to unload them at runtime to recreate them.

Thanks @danoon2 for this explanation. For my purposes right now I am happy it's working at all tbh. I actually find the speed decent but if you ever do figure out those other 2 methods they sound promising for speed. I plan/hope to have this app/website grow and evolve over my lifetime as it's a platform for my personal website/content. So maybe as BoxedWine grows I can integrate improvements over time. Maybe I need to learn more about WASM and help. :-)

Thanks either way, amazing app you got here!

I have added boxedwine-simple.html and boxedwine-shell-simple.js to /project/emscipten
They are cut-down versions of the files they replace and likely to be much easier to reason about.
Integration should be seamless if you are already using BrowserFS.

The more complicated boxedwine-shell.js file in this scenario can be seen as a collection of recipes to add additional functionality if required. Also means the need for an API is side-stepped.

Back to app window maximisation. The application you run is likely to record user settings in a config/setting file or the windows registry. The Windows registry is a Key/Value store used for configuration.

Thank you @kevodwyer for this trimmed down version. I will look into adjust the shell file I've taken based on this example. At the moment it's all working pretty well anyway, at least as a POC type of thing. :-)

This project (BoxedWine) and Dustin's (daedalOS) have the potential to save really old games over the long run, because the web platform is pretty guaranteed to maintain long-term backwards compatibility, even as CPU architectures and hardware designs radically change. I'm hoping BoxedWine starts to integrate together some of the upcoming changes currently in branches into a stable release that can make it up to daedalOS in the future. Being able to run Windows 3.x / 9.x games in the browser without any hardware dependency other than a modern browser is an incredible use of new tech to extend the lifespan of old software.

This project (BoxedWine) and Dustin's (daedalOS) have the potential to save really old games over the long run, because the web platform is pretty guaranteed to maintain long-term backwards compatibility, even as CPU architectures and hardware designs radically change. I'm hoping BoxedWine starts to integrate together some of the upcoming changes currently in branches into a stable release that can make it up to daedalOS in the future. Being able to run Windows 3.x / 9.x games in the browser without any hardware dependency other than a modern browser is an incredible use of new tech to extend the lifespan of old software.

Thanks! I am definitely interested in any new releases of BoxedWine. If an improved version comes out I'd love to integrate it into daedalOS.

I agree, the main goal of BoxedWine is game preservation.

Sometimes there are changes I need to implement on my side for each new Wine version, mainly around my winex11.drv replacement. But in Wine 6 there were major changes that required me to update the CPU emulation because Wine now uses shared memory between the client and wineserver. It was mostly working at the beginning of 2022 but then I got sick. I'm on the road to recovery now and hope to get back to finishing support for ARM and Wine 6/7 at the beginning of 2023, just in time to see what Wine 8 brings.