Skip to content

feat: port DOOM to EdgeTX for RadioMaster TX15#1

Open
kpucynski wants to merge 9 commits into
mainfrom
doom
Open

feat: port DOOM to EdgeTX for RadioMaster TX15#1
kpucynski wants to merge 9 commits into
mainfrom
doom

Conversation

@kpucynski
Copy link
Copy Markdown
Owner

@kpucynski kpucynski commented Feb 12, 2026

DOOM on EdgeTX — RadioMaster TX15

Port of the DOOM engine (chocolate-doom based) to EdgeTX, targeting the RadioMaster TX15 (STM32H750, 480×272 LCD).

Note: This port was heavily AI-assisted (GitHub Copilot / Claude).

Features

  • Full DOOM gameplay — reads DOOM1.WAD from SD card (/DOOM/DOOM1.WAD)
  • 320×200 → 480×272 nearest-neighbor scaled rendering direct to LTDC framebuffer
  • SFX: all 109 sound effects, resampled (11 kHz → 32 kHz) and mixed in real-time (up to 8 channels)
  • Music: MUS format playback via triangle/square-wave synthesis with envelope and LPF filtering
  • TX15 hardware keys mapped to DOOM controls (RTN, TELE, PAGE, ROLL, SYS, MDL)
  • Gimbals mapped to DOOM controls (left, right, fwd, back, strife)
  • All changes gated behind WITH_DOOM — zero impact on normal builds

Build

cmake --preset firmware -DPCB=TX15 -DDEFAULT_MODE=2 -DGVARS=YES -DWITH_DOOM=ON
cd build/fw && make -j$(nproc) firmware

Port the DOOM game engine from edgetx-doom to the latest EdgeTX codebase,
targeting the RadioMaster TX15 (STM32H750, 480x272 LCD).

- Add radio/src/doom/ with full DOOM engine (chocolate-doom based)
- WAD loading via FatFS from SD card (/DOOM/DOOM1.WAD)
- RGB565 framebuffer rendering with nearest-neighbor scaling (320x200 -> 480x272)
- STM32H7 D-Cache management (SCB_CleanDCache) for LTDC framebuffer
- Watchdog feeding during WAD I/O and game loop
- Build system: WITH_DOOM=ON cmake option, integrated into CMakeLists.txt
- Bypass LVGL init and color LCD layout system when WITH_DOOM is enabled
- Dedicated RTOS task for DOOM (32KB stack, mixer priority)
- Input mapping: hardware keys to DOOM controls via readKeys()
- DOOM_PATH defined in sdcard.h for SD card WAD location
Add a sound_module_t implementation for the EdgeTX DOOM port that plays
sound effects through the TX-15 integrated speaker (TAS2505 / I2S).

New files:
- doom/edgetx/sound.cpp: Full SFX pipeline — loads WAD lumps, resamples
  from 11025 Hz to 32 kHz with linear interpolation, mixes up to 8
  simultaneous channels, and feeds the EdgeTX AudioBufferFifo for DMA.
- doom/edgetx/sound.h: Header declaring sound_edgetx_module.

Restored files:
- doom/sounds.c: Restored complete S_sfx[] table with all 109 SFX
  entries matching the sfxenum_t enum (was gutted to a single dummy).
- doom/s_sound.c: Un-commented all sound functions (S_Init, S_Start,
  S_StartSound, S_UpdateSounds, etc.). Simplified S_AdjustSoundParams
  to skip stereo separation (mono speaker). Music functions remain
  stubbed for now.
- doom/i_sound.c: Registered sound_edgetx_module in sound_modules[]
  when WITH_DOOM is defined.

Other changes:
- doom/CMakeLists.txt: Added doom/edgetx/sound- doom/CMakeLists.txt: Added doom/edgetx/sound- doom/CMakeL_BUFFER_COUNT = 6 to cover
  one DOOM game frame (~28 ms at 35 fps).
Add a music_module_t implementation that parses DOOM's MUS format music
data from WAD lumps and synthesises audio using lightweight waveforms:
- Melodic channels (0-14): square waves with attack/release envelope
- Percussion channel (15): LFSR noise with fast decay
- MUS sequencer at 140 ticks/sec via fixed-point sample counting
- Per-channel volume and pitch bend (±2 semitones)

New files:
- doom/edgetx/music.cpp: MUS parser, sequencer, waveform synthesis,
  and music_module_t. Mixed into SFX buffer via music_mix_into_buffer().
- doom/edgetx/music.h: Header for music_edgetx_module and mix API.

Restored / modified:
- doom/sounds.c: Full S_music[] table (68 entries for musicenum_t).
- doom/s_sound.c: Restored S_Start() level-music selection, S_ChangeMusic,
  S_StartMusic, S_StopMusic, S_PauseSound, S_ResumeSound, S_MusicPlaying.
- doom/i_sound.c: Registered music_edgetx_module in music- doom/i_sound.c: Registered music_edgetx_module in music- doom/i_sound.c: Registered music_edgetx_module in music- doom/iusic.cpp.
Volume adjustments:
- Hardware speaker volume set to ~70% (16/23)
- SFX gain scaled to ~60% to avoid clipping
- Default sfxVolume and musicVolume raised to 15 (max)

Music synthesis improvements:
- Melodic channels: replaced pure square wave with 75% triangle /
  25% square blend for warmer tone with audible bass
- Added 1-pole low-pass filter on melodic voices (1/2 old + 1/2 new)
- Percussion: lightened LPF (1/4 old + 3/4 new) to keep snap
- Percussion decay slowed (env -= 1) for presence instead of clicks
- Master fade-in ramp over ~256 samples to eliminate startup noise
- Slower per-voice attack envelope (~20ms) to prevent note clicks

Updated DOOM_README.md with revised audio details.
Map all TX15 hardware keys to DOOM actions:
  RTN       → forward
  TELE      → backward
  PAGE<     → turn left
  PAGE>     → turn right
  ROLL push → fire / select
  SYS       → menu (Esc)
  MDL       → use (open doors)

Extended keyboardMap from 7 to 16 entries to cover the
full EnumKeys range (0-15). Unmapped indices are skipped.

Updated DOOM_README.md controls table accordingly.
Implement dual-stick control scheme for natural DOOM gameplay:
  - Left stick vertical → move forward/backward
  - Left stick horizontal → strafe left/right
  - Right stick horizontal → turn left/right (analog, inverted)

Technical implementation:
- Read calibratedAnalogs[] for ADC_MAIN_LH/LV/RH stick positions
- Apply 6.5% deadzone to eliminate drift
- 20% threshold triggers digital movement keys (forward/back/strafe)
- Right horizontal mapped to AD_RH (inverted) for smooth analog turning
- Analog inputs disabled in menus to prevent navigation conflicts
- Physical buttons (RTN, TELE, PAGE, etc.) continue to work

Updated DOOM_README.md with:
- Gimbal controls table showing dual-stick layout
- Input system technical details section
- Updated feature description highlighting analog controls
1. Key remapping for better ergonomics:
   - MDL → Fire (easier to reach for primary action)
   - ROLL → Use (doors/switches in-game)
   - ROLL auto-converts to ENTER in menus for selection

2. Smooth percussion hi-hats:
   - Reduced amplitude: ±12000 → ±8000 (33% quieter)
   - Heavier low-pass filter: 1/4+3/4 → 1/2+1/2
   - Eliminates crackly/annoying sound on hi-hats

Updated DOOM_README.md:
- Button mapping table reflects new key assignments
- Added note about ROLL dual-function behavior
- Updated percussion waveform description with filtering details
Normalize table separator rows for Gimbals, Buttons, and File/Change tables; add missing blank line after 'Note:'; minor markdown/whitespace cleanup in DOOM_README.md.
Change stick layout for more intuitive control:
  - Left stick vertical → move forward/backward (unchanged)
  - Left stick horizontal → turn left/right (analog, inverted)
  - Right stick horizontal → strafe left/right

This layout better matches traditional FPS dual-stick controls
where the left stick primarily handles movement + turning, and
the right stick handles strafing.

Updated DOOM_README.md to reflect new gimbal mapping.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant