I looked into adding tools and disks to the NX embedded web player

2

SP4CEBAR 2025-07-10 23:42 (Edited)

For those who didn't know, I've made an online editor site for NX (sp4cebar.com/nx-editor) using the embedded NX web player.

An essential part of NX is it's use of tool programs. To add such functionality to my editor, I've been looking through the NX source code:

core

The NX core (core/core.h) has a struct named core with data of which a pointer to the diskDrive struct in core/accessories/disk_drive.h which has data of which a pointer to the dataManager struct in core/datamanager/datamanager.h.

interpreter

The interpreter has a function for each NX command, the files interpreter (core/interpreter/cmd_files.c) handles NX file commands such as FILES at line 149 (cmd_FILES)

sdl

The sdl/main.c appears to be a main access point for running NX. It has lines like this:

44: const char *defaultDisk = "Disk.nx";

And functions with names like: getDiskFilename, saveScreenshot, runMainProgram, and runToolProgram

This is very interesting for understanding disk behavior, but it doesn't yet explain how the web player interfaces with it.

I also have not found where the "no disk" error message is defined.

web embed

The web player appears to use a pattern called "emscriptem" in a 9187-line-long-JavaScript file to run an NX web assembly file, this pattern also appears to handle graphics through "emscriptem_gl".

Despite my browsing and searching efforts, I haven't figured out how it runs web assembly.

I have figured out how it interfaces NX's user inputs and video outputs to JavaScript, as there are many functions that suggest this functionality. But I haven't figured out how they are called according to the instructions in the NX web assembly file, and how I would add functions to handle NX commands like "FILES".

Here is an index I wrote to the long JavaScript file


Timo 2025-07-11 06:18

emscriptem (https://emscripten.org/) is a compiler that creates WebAssembly from C/C++. It has built-in support for SDL.
I didn't write anything of that long JavaScript file, it's generated by emscripten.


SP4CEBAR 2025-07-11 16:49

Thanks for the details!


SP4CEBAR 2025-07-11 22:01

is SDL Simple DirectMedia Layer?


Timo 2025-07-11 22:08

Yes. Using SDL it‘s possible to build for Mac, Windows and Linux with almost the same code.


SP4CEBAR 2025-07-11 22:40 (Edited)

Cool!


SP4CEBAR 2025-07-11 23:13

By adding the line below (log FS.root after two seconds) I was able to look in emscriptem's file system

setTimeout(() => console.log(FS.root), 2000);

And I found my blob nx code!

root: Object { id: 1, name: "/", mode: 16895, … }
​​
contents: Object { tmp: {…}, home: {…}, dev: {…}, … }
​​​
"blob:http:": Object { id: 20, name: "blob:http:", mode: 16895, … }
​​​
dev: Object { id: 5, name: "dev", mode: 16895, … }
​​​
home: Object { id: 3, name: "home", mode: 16895, … }
​​​
proc: Object { id: 13, name: "proc", mode: 16895, … }
​​​
tmp: Object { id: 2, name: "tmp", mode: 16895, … }


SP4CEBAR 2025-07-11 23:58 (Edited)

This script (added to the embed's index.html) allows me to read an NX program's code from emscriptem's file system.
It appears only the last of the "arguments" parameters gets loaded as a program, it seems not to load two of them.

      const params = new URLSearchParams(window.location.search);
      const p = params.get("p");
      console.log(p);

      function readFilesFromFS {
        console.log(FS.root.contents);
        const file = FS.readFile(p.replace(/\/\//g, "/"));
        // const file = FS.readFile('/Gfx Designer 2.0.nx');
        console.log(file);
        const decoder = new TextDecoder("utf-8");
        const text = decoder.decode(file);
        console.log(text); // Output: "'TITLE:  
      }

      setTimeout(readFilesFromFS, 5000);

      var Module = {
        canvas: document.getElementById('canvas'),
        arguments: [
          // "Gfx Designer 2.0.nx",
          // "Disk.nx",
          p,
        ],
        print: function(t) {
          console.log(t);
        },
        printErr: function(t) {
          console.log(t);
        }
      };

So now I just need to figure out how to get two programs in there and make one of them take the other as its disk, either by running sdl/main.c's runToolProgram or have it detect a Disk.nx somehow


SP4CEBAR 2025-07-12 01:51 (Edited)

It now can add a Disk.nx file to the emscriptem filesystem (here is the code). However I found something in sdl/runner.c on line 125, I found the NO DISK message:

#ifdef __EMSCRIPTEN__
        overlay_message(runner->core, "NO DISK");
#else
        overlay_message(runner->core, "USING DISK.NX");
#endif

and this line after it controlling a block of code

#ifndef __EMSCRIPTEN__

In other words, if emscriptem is being used, which is likely the web environment, NX will not attempt to look for a disk.

So to add disk support to the online editor, I would need to modify a copy of NX and look into (re)compiling the NX web assembly through emscriptem


Timo 2025-07-12 12:57

Right, the current web version has disk support disabled.
I thought sometimes about using the user account to load and save disks, but I decided that it‘s not worth the effort.
If you want tools to be usable with your online editor, you need a way to run for example the Gfx Designer independently from the current editor code, and use the editor code as Disk.


Timo 2025-07-12 12:59

So the web player somehow needs a bridge to JavaScript to pass the data.
A „disk“ luckily is just a text, so you just need to pass strings between the player and JavaScript.


SP4CEBAR 2025-07-12 21:35 (Edited)

Thanks for the confirmation!
I'm not too worried about sending data back, I can use the postMessage method in the player (iframe) and use an eventlistener to listen for any "message" in the host of the embedded iframe


Log in to reply.