feat: WASM based web simulator (#7164)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Raphael Coeffic
2026-05-08 12:40:56 +10:00
committed by GitHub
co-authored by Claude Opus 4.6
parent a2aeab9234
commit b2fb79d9f4
29 changed files with 12305 additions and 0 deletions
+1
View File
@@ -54,6 +54,7 @@ enum SwitchContext
int getFirstAvailable(int min, int max, IsValueAvailable isValueAvailable);
bool isChannelUsed(int channel);
int getChannelsUsed();
bool checkSourceAvailable(int source, uint32_t sourceTypes);
bool checkSwitchAvailable(int swtch, uint32_t swtchTypes);
bool isInputAvailable(int input);
+16
View File
@@ -27,6 +27,10 @@
#include "hal/abnormal_reboot.h"
#if defined(SIMU)
extern bool simuCreateDefaultSettings;
#endif
#if defined(COLORLCD)
#include "layout.h"
#include "theme_manager.h"
@@ -211,6 +215,18 @@ void storageReadAll()
g_eeGeneral.modelCustomScriptsDisabled = true;
if (loadRadioSettings() != nullptr) {
#if defined(SIMU)
if (simuCreateDefaultSettings) {
// Web simulator first run: silently create defaults without
// STORAGE WARNING alert or calibration screen.
simuCreateDefaultSettings = false;
storageFormat();
g_eeGeneral.chkSum = evalChkSum();
storageDirty(EE_GENERAL);
storageDirty(EE_MODEL);
storageCheck(true);
} else
#endif
storageEraseAll(true);
}
#if !defined(STORAGE_MODELSLIST)
+23
View File
@@ -33,6 +33,8 @@
#include "debug.h"
#include "switches.h"
#include "input_mapping.h"
#include "gui/gui_common.h"
#include "mixes.h"
#if defined(GVARS)
#include "gvars.h"
#endif
@@ -54,6 +56,7 @@ char * main_thread_error = nullptr;
bool simu_shutdown = false;
bool simu_running = false;
bool simuCreateDefaultSettings = false;
volatile rotenc_t rotencValue = 0;
@@ -115,6 +118,11 @@ static void* bootloaderThread(void*)
}
#endif
void simuCreateDefaults()
{
simuCreateDefaultSettings = true;
}
void simuStart(bool tests)
{
if (simu_running)
@@ -759,6 +767,21 @@ uint8_t simuCopyMixOutputs(int16_t* buf, uint8_t maxCount)
return n;
}
bool simuIsChannelUsed(uint8_t channel)
{
return isChannelUsed(channel);
}
int simuGetChannelsUsed()
{
return getChannelsUsed();
}
uint8_t simuGetMixCount()
{
return getMixCount();
}
uint8_t simuGetNumLogicalSwitches()
{
return MAX_LOGICAL_SWITCHES;
+13
View File
@@ -123,6 +123,11 @@ uint8_t WASM_EXPORT(simuGetNumChannels)();
uint8_t WASM_EXPORT(simuCopyChannelOutputs)(int16_t* buf, uint8_t maxCount);
uint8_t WASM_EXPORT(simuCopyMixOutputs)(int16_t* buf, uint8_t maxCount);
// Channel/mixer queries.
bool WASM_EXPORT(simuIsChannelUsed)(uint8_t channel);
int WASM_EXPORT(simuGetChannelsUsed)();
uint8_t WASM_EXPORT(simuGetMixCount)();
// Bulk copy logical switch states into buf (uint8_t[], 0 or 1). Returns count.
uint8_t WASM_EXPORT(simuGetNumLogicalSwitches)();
uint8_t WASM_EXPORT(simuCopyLogicalSwitches)(uint8_t* buf, uint8_t maxCount);
@@ -162,6 +167,14 @@ void WASM_IMPORT(simuTrace)(const char* text);
// listener so the frame can be rendered without polling.
void WASM_IMPORT(simuLcdNotify)();
// First-run helper: request default radio.yml + model creation if
// no settings file exists. Call before simuStart(). The actual file
// I/O runs inside storageReadAll() on a worker thread.
void WASM_EXPORT(simuCreateDefaults)();
// Flag checked by storageReadAll() to silently create defaults.
extern bool simuCreateDefaultSettings;
// Aux serial bridge (firmware -> host). port_nr is 0 for AUX1, 1 for AUX2.
// encoding values match SimulatorSerialEncoding (0=8N1, 1=8E2, 2=PXX1_PWM)
// and ETX_Encoding_* — they share the same numeric values. Called when the