feat(LuaGame): Lua interpreter game engine with audio, 17 FPS, 4.5x ball speed
- Embed Lua 5.4.7 source to avoid missing symbols (clearerr, clock, getenv, etc) - Provide local stubs for missing libc and avoid unexported LVGL cache APIs - Fix float handling in sys.* bindings (checknumber vs checkinteger) - Move Lua init and game loop to dedicated 16K FreeRTOS task to avoid GUI 4K stack overflow - Implement sys API: clear, print (8x8 bitmap font direct FB), rect, circle, line, touch, sfx, tone - Audio via SfxEngine (SfxId mapping, playNote for tone) - Ball speed 2 -> 4.5, FPS counter (~17 FPS after direct FB text optimization) - Supports loading from /sdcard/lua/breakout.lua and embedded fallback - Verified symbols: 0 missing, builds esp32s3, installs on 192.168.68.107
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
#include "audio.h"
|
||||
#include "SfxEngine.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
static SfxEngine* g_engine = nullptr;
|
||||
|
||||
void audio_init(void) {
|
||||
if (g_engine) return;
|
||||
g_engine = new SfxEngine();
|
||||
if (!g_engine->start()) {
|
||||
printf("[Audio] SfxEngine start failed\n");
|
||||
delete g_engine;
|
||||
g_engine = nullptr;
|
||||
} else {
|
||||
printf("[Audio] SfxEngine started\n");
|
||||
}
|
||||
}
|
||||
|
||||
void audio_deinit(void) {
|
||||
if (g_engine) {
|
||||
g_engine->stop();
|
||||
delete g_engine;
|
||||
g_engine = nullptr;
|
||||
printf("[Audio] SfxEngine stopped\n");
|
||||
}
|
||||
}
|
||||
|
||||
static SfxId sfx_name_to_id(const char* name) {
|
||||
if (!name) return SfxId::Click;
|
||||
if (strcasecmp(name, "confirm")==0) return SfxId::Confirm;
|
||||
if (strcasecmp(name, "coin")==0) return SfxId::Coin;
|
||||
if (strcasecmp(name, "hurt")==0) return SfxId::Hurt;
|
||||
if (strcasecmp(name, "gameover")==0) return SfxId::GameOver;
|
||||
if (strcasecmp(name, "levelup")==0) return SfxId::LevelUp;
|
||||
if (strcasecmp(name, "powerup")==0) return SfxId::Powerup;
|
||||
if (strcasecmp(name, "brickhit")==0) return SfxId::BrickHit;
|
||||
if (strcasecmp(name, "click")==0) return SfxId::Click;
|
||||
if (strcasecmp(name, "blip")==0) return SfxId::Blip;
|
||||
if (strcasecmp(name, "jump")==0) return SfxId::Jump;
|
||||
if (strcasecmp(name, "laser")==0) return SfxId::Laser;
|
||||
if (strcasecmp(name, "explosion")==0) return SfxId::Explosion;
|
||||
if (strcasecmp(name, "pickup")==0) return SfxId::Pickup;
|
||||
if (strcasecmp(name, "alert")==0) return SfxId::Alert;
|
||||
if (strcasecmp(name, "success")==0) return SfxId::Success;
|
||||
// default mapping
|
||||
return SfxId::Click;
|
||||
}
|
||||
|
||||
void audio_play_sfx(const char* name) {
|
||||
if (!g_engine) return;
|
||||
SfxId id = sfx_name_to_id(name);
|
||||
g_engine->play(id);
|
||||
printf("[Audio] sfx %s -> %d\n", name, (int)id);
|
||||
}
|
||||
|
||||
void audio_play_tone(int note, int duration_ms, const char* waveform, float volume) {
|
||||
if (!g_engine) return;
|
||||
if (volume <=0) volume = 0.5f;
|
||||
if (duration_ms <=0) duration_ms = 80;
|
||||
// waveform string: sine, square, triangle, etc
|
||||
SfxWaveType wave = SfxWaveType::Square;
|
||||
if (waveform) {
|
||||
if (strcasecmp(waveform,"sine")==0) wave = SfxWaveType::Sine;
|
||||
else if (strcasecmp(waveform,"triangle")==0) wave = SfxWaveType::Triangle;
|
||||
else if (strcasecmp(waveform,"square")==0) wave = SfxWaveType::Square;
|
||||
else if (strcasecmp(waveform,"saw")==0 || strcasecmp(waveform,"sawtooth")==0) wave = SfxWaveType::Sawtooth;
|
||||
else if (strcasecmp(waveform,"noise")==0) wave = SfxWaveType::Noise;
|
||||
else if (strcasecmp(waveform,"pulse")==0) wave = SfxWaveType::Pulse25;
|
||||
}
|
||||
// Use voice 0 for tone, playNote API: voice, pitch, durationMs, wave, volume...
|
||||
// SfxEngine has playNote? Check header: playNote exists.
|
||||
// The signature in SfxEngine: bool playNote(uint8_t voice, uint8_t pitch, ...)
|
||||
// We'll use simplified: play note on voice 0
|
||||
g_engine->playNote(0, (uint8_t)note, (uint16_t)duration_ms, wave, volume);
|
||||
printf("[Audio] tone note=%d dur=%d wave=%s vol=%.2f\n", note, duration_ms, waveform?waveform:"-", volume);
|
||||
}
|
||||
Reference in New Issue
Block a user