Hi,
first of all I want to apologize if this is not the right group for my questions, but I didn't find a more appropriate one. Recently I started my very first steps with emscripten - which btw is almost too cool to be really existing .-)
What I intended to do is porting an interpreter for text adventures written in C (called Magnetic, available under GPL). The interpreter is written in C und uses only stdio for input and output. There is no SDL version and considering the "nature" of the tool, SDL would be a lot overhead with gaining nothing, probably.
While I managed to get the emscripten version to do its output to plain html after a while I am now completely stuck when trying to get the user input working. Before I throw everything into the garbage can, perhaps someone with better JS skills than I have (and that's not a major challenge), can take a look at the following parts and confirm my current assumption: not solvable - or better, give me some hints what can be done.
The main loop of the interpreter is as simple as this:
running = 1;
while (running) running=ms_rungame();
The interpreter core is actually some kind of very reduced 68k emulator and each call to the ms_rungame "executes" one instruction. Now, when the interpreter is running, at some point it runs to a function called ms_flush for doing the output. I was able to gain from the various samples in the emsdk a way to get the output written to plain html with something like this:
sprintf(outBuffer, "reformatAndSet('%c','textout')",buffer[j]);
emscripten_run_script(outBuffer);
in the C code and this in the JS code:
function reformatAndSet(text, target) {
text = text.replace(/&/g, "&");
text = text.replace(/</g, "<");
text = text.replace(/>/g, ">");
text = text.replace('\n', '<br>', 'g');
document.getElementById(target).innerHTML += text;
}Most probably not a nice solution, but at least it works. But then I reach my showstopper. So when contuing at some point the interpreter calls a function named ms_getchar, which does fill an internal buffer array with the user input in a loop of getchar calls and then return the chars after after the other in subsequent calls to the ms_getchar routine. In the C version this function waits for the user input. Emscripten replaces the getchar calls with window.prompt calls, which actually do work, but from the point of the user experience are no real option. So, the problem is: Is it possible to keep the ms_getchar busy or blocked until the user has done his input (without locking up the browser). I tried a lot of different approaches, but never came close to a solution and as far as I understand JS can not be blocked or kept busy with threads, so it seems I am lost here?!?.
My last try was something like this, but this didn't work, either, most probably because I got wrong what the emscripten_start_main_loop and emscripten_stop_main_loop calls do. I also found a reference to a function emcripten_push_Main_loop_blocker, but couldn't find a sample how to use it. Another thought was if it might be possible to run the interpreter loop in a web worker, but I guess I will run into problems with filling my html then?
Last try (partly reconstructed, tried such much with the source that I messed it up at some point). Please bear with me if that is pure nonsense, I am not very familiar with JS, especially not with the parts beyond simple web pages.
in the HTML:
<form onsubmit="setInternalBuffer();return false;"><input type="text" size="50" maxlength="255" id="textin"></form>
and
function setInternalBuffer() {
var userinput = document.getElementById('textin').value;
var cstyle_ptr = allocate(intArrayFromString(userinput), 'i8', ALLOC_NORMAL);
transferbuffer = Module.cwrap('transferbuffer', 'void', ['string']);
transferbuffer(cstyle_ptr);
emscripten_start_main_loop();
}
in the C code:
void transferbuffer(char * input)
{
strcpy(inbuf,input);
}
and
char ms_getchar()
{
int c=0;
emscripten_pause_main_loop();
if ((c = inbuf[inpos]) == '\n' || !c)
{
inpos = 0;
memset(inbuf,0x00,256);
c=0;
}
return (char)c;
}
I guess, the transferbuffer call in the JS function is not executed because the main loop is stopped?!?
Any chance to get this working or is it as simple as this not being suitable for JS?
Many, many thanks for listening and your help. If you want to mess around with the stuff yourself, please let me know and I'll make it available, it's open source anyway.
Stefan Meier