moononournation / arduino-nofrendo

Clone from source http://www.baisoku.org/nofrendo-2.0pre1.zip
Other
81 stars 37 forks source link

Attempting to stop emulator reboots ESP32 #17

Closed and3rson closed 2 months ago

and3rson commented 2 months ago

When stopping nofrendo using input that's triggering quit event, an assertion fails which leads to this line being called:

https://github.com/moononournation/arduino-nofrendo/blob/c5ba6d39c1fff0ceed314b76f6da5145d0d99bcc/src/log.c#L143

exit does not do what's intended as opposed to other platforms (it simply reboots the ESP32), and thus it makes it impossible to gracefully exit nofrendo. Basically, this means thatnofrendo_main never returns - the only way out is a reboot.

I think a sensible solution would be to replace exit & atexit with a different mechanism, for example setjmp.

E.g.:

// nofrendo.c

jmp_buf nofrendo_exit_jmp;

int main_loop(...) {
    if (setjmp(nofrendo_exit_jmp) == 0) {
        // Proceed with current implementation of main_loop - init OSD/GUI & start the game
        // ...
        return 0;
    } else {
        shutdown_everything();
        return 1;
    }
}
// log.c

extern jmp_buf nofrendo_exit_jmp;

void nofrendo_log_assert(...) {
    // log message
    // ...
    // then, instead of exit(), call longjmp()
    longjmp(nofrendo_exit_jmp, 1);
}

We implemented a similar pattern when we integrated Lua into our ESP32 project, and it works perfectly for cases when "everything is bad, abort all operations and go back to a known path" approach is needed.

and3rson commented 2 months ago

Fixed in #18.