Skip to content

games/NXDoom: Add RGB565, module support, and crash fixes. - #3644

Open
aviralgarg05 wants to merge 10 commits into
apache:masterfrom
aviralgarg05:gsoc/nxdoom-bringup-fixes-pr7
Open

games/NXDoom: Add RGB565, module support, and crash fixes.#3644
aviralgarg05 wants to merge 10 commits into
apache:masterfrom
aviralgarg05:gsoc/nxdoom-bringup-fixes-pr7

Conversation

@aviralgarg05

@aviralgarg05 aviralgarg05 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Note: Please adhere to Contributing Guidelines.

Summary

Update NXDoom for RGB565 framebuffer targets and optional loadable-module
builds, and fix crashes observed during ESP32-S3 bring-up.

The changes:

  • make CONFIG_GAMES_NXDOOM tristate and derive MODULE from it;
  • support FB_FMT_RGB16_565 while retaining FB_FMT_RGB32;
  • validate framebuffer format and depth before drawing;
  • keep renderer scratch buffers static by default, with heap allocation behind
    CONFIG_GAMES_NXDOOM_HEAP_BUFFERS;
  • parse configuration one physical line at a time, retain defaults for
    malformed integer values, and clamp screenblocks;
  • guard plane/span renderer indices and check visplane capacity before writing;
  • handle supervisor SIGTERM at a safe point in the frame loop.
  • compute the framebuffer origin after FBIOGET_PLANEINFO has filled the plane
    info, so the scaled image is actually centred instead of being drawn at the
    top-left corner;
  • report the drawn region with FBIO_UPDATE, which NXDoom was alone among the
    tree's framebuffer consumers in never doing.

Impact

  • New feature: YES. NXDoom can be built in with =y or as a loadable ELF
    with =m, and can render to RGB565.
  • User adaptation: NO for existing RGB32/static-storage configurations.
  • Build: YES. The Kconfig symbol becomes tristate and derives MODULE.
  • Hardware: YES for framebuffer compatibility; RGB565 is added without
    changing a framebuffer driver.
  • Documentation: NO user-documentation change is required for these
    compatibility and correctness fixes.
  • Security: NO known security-boundary change; the renderer and parser bounds
    fixes prevent invalid memory accesses.
  • Compatibility: Existing static renderer storage remains the default. Heap
    storage is opt-in. Unsupported framebuffer layouts now fail initialization.
  • Other: A direct-framebuffer build can reserve nxstore's supervisor strip.

Testing

Build host:

  • macOS 26.5, arm64
  • xtensa-esp-elf-gcc 14.2.0
    (esp-14.2.0_20251107)

Target:

  • Xtensa / ESP32-S3
  • Waveshare ESP32-S3-Touch-LCD-7 custom configuration
  • RGB565 framebuffer

Static verification:

  • nxstyle and git diff --check
  • all NXDoom sources cross-compiled for ESP32-S3
  • independent review of the complete diff

The exact final source head was built and flashed. NXDoom reached gameplay on
RGB565, malformed configuration input retained safe defaults, and the process
returned cleanly to nxstore after SIGTERM.

Hardware bring-up photograph from July 11 (the later signed-tree checks are
recorded below):

NXDoom rendering gameplay on the Waveshare ESP32-S3-Touch-LCD-7 RGB565 framebuffer under nxstore supervision

Testing logs after change:

Raw serial capture of a launch/play/close cycle on the target. This is the
console output as received, with only an elapsed-time prefix added by the
capture script:

  34.1s | gt911: DOWN x=120 y=146 pressure=60
  34.1s | gt911: UP x=120 y=146
  41.1s |                              NXDoom v0.0.0
  41.1s | z_init: Init zone memory allocation daemon.
  41.1s | zone memory: Using native C allocator.
  41.1s | Using /mnt/sdcard/doom/ for configuration and saves
  41.1s | v_init: allocate screens.
  41.1s | m_load_defaults: Load system defaults.
  41.1s | saving config in /mnt/sdcard/doom/default.cfg
  42.1s | W_Init: Init WADfiles.
  42.1s |  adding /mnt/sdcard/doom/doom1.wad
  42.1s | ===========================================================================
  42.1s |                             DOOM Shareware
  42.1s | ===========================================================================
  42.1s |  NXDoom is free software, covered by the GNU General Public
  42.1s |  License.  There is NO warranty; not even for MERCHANTABILITY or FITNESS
  42.1s |  FOR A PARTICULAR PURPOSE. You are welcome to change and distribute
  42.1s |  copies under certain conditions. See the source for more information.
  42.1s | ===========================================================================
  42.1s | i_init: Setting up machine state.
  43.2s | m_init: Init miscellaneous info.
  47.2s | r_init: Init DOOM refresh daemon - [                   ]...................
  47.2s | p_init: Init Playloop state.
  47.2s | d_check_net_game: Checking network game status.
  47.2s | startskill 2  deathmatch: 0  startmap: 1  startepisode: 1
  47.2s | player 1 of 1 (1 nodes)
  47.2s | Emulating the behavior of the 'Doom 1.9' executable.
  47.2s | hu_init: Setting up heads up display.
  48.2s | st_init: Init status bar.
  59.2s | gt911: DOWN x=770 y=33 pressure=57
  59.2s | gt911: UP x=770 y=33
  59.2s | nxstore: close cb fired, active=1 pid=10
  59.2s | nxstore: close SIGTERM sent to 10
  59.2s | nxdoom: quit signal seen, calling i_quit
  62.2s | nxstore: close reaped=0 gone=0 after 40 tries

The two taps are the launch and the close. NXDoom takes SIGTERM and runs
i_quit as intended.

The final line is a supervisor-side limitation rather than an NXDoom one: the
store frontend waits 2 s (40 x 50 ms) for the child before giving up, while
NXDoom's shutdown writes its configuration back to the FAT card, which takes
longer than that. A subsequent ps on the same session shows no NXDoom task,
so it does exit cleanly. That timeout belongs to the store frontend and is not
addressed here.

Malformed-configuration reproduction:

fixture: screenblocks has no value
fixture SHA-256: 8d4d67d909e257165e28478cd0ee42e18af7c0fa4c9ebb0f908fb68cb4bcf981
result: compiled default retained; gameplay started; SIGTERM close completed

The original divide-by-zero or renderer-exception log was not retained, so it
cannot be included as before-change output.

The final restored image remained stable while idle; the earlier glitch
coincided with a failed transfer whose Base64 payload was interpreted as NSH
commands, not ordinary nxpkg file writing.

Simulator evidence for the centring and update fixes (sim:vncserver)

Both fixes were isolated on the simulator by reverting one at a time and
measuring the bounding box of the non-black content in the frame a VNC client
receives. examples/fb was used as a positive control and returns the full
1,536,128-byte framebuffer in every case.

Variant Rectangles Content bounding box
origin computed before FBIOGET_PLANEINFO (previous behaviour) 9 640x400 at (0,0)
origin computed after (this PR) 9 640x400 at (80,40), centred in 800x480
without FBIO_UPDATE 0 blank, no rectangles at all
with FBIO_UPDATE (this PR) 9 full frame

(800-640)/2 = 80 and (480-400)/2 = 40, so the centred result is exact. The
blank result reproduced across three consecutive captures with the game
confirmed running, so it is a display fault rather than a startup failure.

PR verification Self-Check

  • This PR introduces one focused NXDoom bring-up/correctness change set.
  • I have updated all required description fields above.
  • I have reviewed and signed every rewritten commit.
  • I have attached the retained real-hardware evidence and imagery.
  • This PR adheres to the current contribution and coding guidelines.
  • My PR is still work in progress.
  • My PR is ready for review and can be safely merged.

@linguini1 linguini1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description needs to be revised and made more concise. It reads totally AI generated and is hard to follow, and also has some subtle mistakes (i.e. " happy to split further if any single commit above should be its own PR" when there is only one). Pretty much the entirety of this PR is just patches to NXDoom, we don't really need to know about the other module loading PRs here, just the build system change you made to load this as a module. You are expected to review the output of AI agents before submitting here, even as a draft :)
You should also use the Assisted-by: field in your commit messages, see the new updates to the contribution guide :)

Again, the testing section cannot just be a description of what you tested. Can you show the simulator playing DOOM after the changes, or your target device? Could you show some before/after output for the divide-by-zero and other issues reported here?

I don't see the need to malloc the arrays that were previously statically allocated. Using malloc on embedded devices is not a good practice and should be avoided where possible. I think those changes should be reverted.

Comment thread games/NXDoom/src/doom/r_bsp.c
Comment thread games/NXDoom/src/doom/r_bsp.h
Comment thread games/NXDoom/src/doom/r_main.c
Comment thread games/NXDoom/src/doom/r_plane.c
Comment thread games/NXDoom/src/doom/r_plane.c
Comment thread games/NXDoom/src/d_iwad.c Outdated
Comment thread games/NXDoom/src/i_main.c Outdated
Comment thread games/NXDoom/src/i_video.c Outdated
Comment thread games/NXDoom/src/m_config.c
Comment thread games/NXDoom/Makefile Outdated
@aviralgarg05

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review @linguini1 going through each point:

PR description: You're right, that was sloppy, I squashed the commits down but didn't re-read the description afterward, so it still had a line referring to multiple commits that no longer existed. Rewriting it now

Assisted-by field: Didn't know this was now expected, will add it going forward, including updating this PR's commit message.

Testing section: Fair — I have this on real hardware (ESP32-S3 board, RGB565 framebuffer) but didn't capture it for the PR. I'll get a screen recording of it running plus the crash logs from before the fixes and attach both.

malloc vs static arrays: The reason was DRAM budget, these buffers (visplanes/openings/drawsegs/vissprites) are sized generously above vanilla DOOM's limits, and as static arrays they were eating into internal SRAM budget once this actually gets linked into a full firmware image alongside everything else. Heap allocation moves them onto this target's PSRAM-backed heap instead.

But you're right that malloc-by-default isn't great practice, I'll put it behind a Kconfig option instead, so boards that don't need it keep static allocation as the default, and boards that are DRAM-constrained can opt in.

Will push an update addressing all of this plus the inline comments one by one

@linguini1

Copy link
Copy Markdown
Contributor

But you're right that malloc-by-default isn't great practice, I'll put it behind a Kconfig option instead, so boards that don't need it keep static allocation as the default, and boards that are DRAM-constrained can opt in.

Can we resolve this with FAR designators?

@aviralgarg05

Copy link
Copy Markdown
Contributor Author

Can we resolve this with FAR designators?

FAR is defined as empty on this target (Xtensa/flat 32-bit memory model). It only expands to something real on segmented 8/16-bit architectures like 8051 (__xdata) or old x86 memory models (far/_Far), where it's about pointer segment qualification, not memory placement.

The actual problem here is static/BSS footprint at link time — a large static array is always-resident regardless of what pointer qualifier you put on it, FAR included. That's a different axis from what FAR addresses, so it won't help with the DRAM budget concern. The Kconfig-gated heap allocation is still the mechanism that actually moves the buffer's footprint onto the PSRAM-backed heap instead of internal SRAM.

@aviralgarg05
aviralgarg05 force-pushed the gsoc/nxdoom-bringup-fixes-pr7 branch from 6fe6008 to 9dd0915 Compare July 17, 2026 19:48
@aviralgarg05
aviralgarg05 force-pushed the gsoc/nxdoom-bringup-fixes-pr7 branch from 9dd0915 to 1fbe5cc Compare July 24, 2026 10:01
@aviralgarg05 aviralgarg05 changed the title games/NXDoom: RGB565 support, loadable-module conversion, and crash fixes games/NXDoom: Add RGB565, module support, and crash fixes. Jul 24, 2026
@aviralgarg05

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review. I went back through the PR and addressed the
main points:

  • the description is now focused on the NXDoom changes;
  • every rewritten commit has the required sign-off and Assisted-by trailer;
  • renderer buffers remain static by default, with heap allocation behind the
    explicit Kconfig option;
  • the Testing section includes a real RGB565 target photograph, startup and
    clean SIGTERM-close output, and the malformed-configuration result; and
  • I removed the unsupported argv-sentinel change and corrected my earlier
    root-cause claim in that thread.

The original exception log was not retained, and the Testing section now says
that plainly. I have replied to each remaining inline point and resolved the
threads after checking the updated diff and evidence.

Add RGB565 framebuffer support to blit_screen() - it previously assumed
a 32-bit ARGB framebuffer unconditionally, a real limitation for any
board whose framebuffer is FB_FMT_RGB16_565. A single blit loop now
branches on pinfo.bpp only at the pixel-write step (RGBTO16() for
16bpp, the existing ARGBTO32() path for 32bpp); anything else fails
loudly via i_error() rather than reading/writing past the intended
pixel bounds silently. Also centers the scaled viewport within the
framebuffer instead of pinning it to the top-left corner, and adds
CONFIG_GAMES_NXDOOM_PREFDIR to the IWAD search path (previously only
used for the config/save file location; the Kconfig entry always has a
default, so no #ifdef guard is needed around using it).

Makes GAMES_NXDOOM tristate and lets MODULE follow it
(MODULE = $(CONFIG_GAMES_NXDOOM)) instead of hardcoding MODULE = m, so
it can still be built in as before or selected as a standalone
loadable module installable via nxpkg/nxstore, same as every other
tristate-capable app in apps/.

Fix two real hardware crashes found while bringing this up as a
loadable module:

- A truncated/corrupted config line was silently overriding a
  variable's compiled-in default with an empty/unparsable value
  instead of being skipped - this let a corrupted "screenblocks" line
  through as screenblocks=0, and the renderer's view-size math divides
  by a value derived from screenblocks, reaching a divide-by-zero
  hardware exception. Also clamps screenblocks to its own valid range
  [3, 11] as an independent second layer of defense.

- r_map_plane()'s bounds check was gated behind the debug-only
  CONFIG_GAMES_NXDOOM_RANGECHECK and, when tripped, called the fatal
  i_error() - both wrong: the check guards a real out-of-bounds array
  access (observed with values far past even viewheight), so it cannot
  be optional, and killing the whole process over one glitched plane
  span is worse than vanilla DOOM's own behavior of rendering the
  glitch. Now unconditional and clamps y into range instead of
  touching memory outside the buffers' bounds, so the span still
  renders (as one glitched row) rather than leaving a gap.

Also adds CONFIG_GAMES_NXDOOM_HEAP_BUFFERS: the renderer's
visplanes/openings/drawsegs/vissprites scratch buffers remain static
arrays by default (matching vanilla DOOM), with heap allocation
available as an opt-in for targets where their combined size threatens
the internal DRAM budget once linked into a full application image.
CONFIG_GAMES_NXDOOM_STATDUMP_MAX_CAPTURES makes statdump's diagnostic
capture-buffer size (unrelated to gameplay) a Kconfig option instead of
a hardcoded value, default unchanged from vanilla (32).

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
r_map_plane()'s existing bounds check clamped an out-of-range `y` to
SCREENHEIGHT - 1, believing that to be the array bound in need of
protection. On real hardware that clamp itself caused a crash: `y` is
stored into ds_y and later used by r_draw_span() (r_draw.c) to index
ylookup[], which r_init_buffer() only populates for [0, viewheight) -
viewheight can be smaller than SCREENHEIGHT (a sub-window within the
physical screen), so entries from viewheight up to SCREENHEIGHT are
zero-initialized (NULL) pointers. Clamping to SCREENHEIGHT - 1 traded
the original out-of-bounds write for a NULL-pointer-plus-offset
framebuffer write, confirmed on real hardware as a load/store
exception at a small virtual address. viewheight is always <=
SCREENHEIGHT, so clamping to viewheight - 1 instead is safe for
cachedheight[]/cacheddistance[]/cachedxstep[]/cachedystep[] too.
r_draw.c's own RANGECHECK-gated debug assertions are updated to match
(they previously compared against SCREENHEIGHT as well).

Separately, r_make_spans() indexes spanstart[t1]/spanstart[b1] (read)
and writes spanstart[t2]/spanstart[b2] using row indices taken
directly from a visplane's top[]/bottom[] arrays, before r_map_plane()
is ever called - so its clamp can't protect these. In valid play these
rows are either a real screen row or vanilla DOOM's 0xff (255) "no
span here" sentinel, and the surrounding while-loop guards are written
so the sentinel can never reach spanstart[] except at a plane's own
edge columns, where writing spanstart[255] is part of the normal
algorithm - already out-of-bounds on this port, since spanstart[] is
only sized SCREENHEIGHT (200). A corrupted BSP/segment can also hand
these a genuinely arbitrary value (this is what the row-255 crash
above traced back to). Guard every touch of spanstart[] directly
instead of altering t1/b1/t2/b2 themselves, so the span-tracking state
machine's comparisons - including the sentinel logic they rely on -
are completely unaffected; a row outside the array just contributes 0
as its span start instead of corrupting or reading past memory.

Also gives GAMES_NXDOOM_STATDUMP_MAX_CAPTURES an explicit range (1
1024) - this diagnostic capture-buffer size Kconfig option had no
bound at all.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
load_default_collection()'s `while (!feof(f))` loop decided whether to
keep looping off feof() rather than fscanf()'s own return value - the
classic version of this bug: on a config file whose bytes don't line
up with "%s %[^\n]\n" at all (e.g. leftover binary/corrupted content
from a previous write), fscanf() can fail a conversion without the
stream ever reaching EOF, and feof() has no way to know that. On real
hardware this hung NXDoom completely at startup with a corrupted
default.cfg on disk - no crash, no output, and no way to close the
game either, since the hang happened before the main loop (and its
SIGTERM poll point) was ever reached.

Terminate directly off EOF/error from fscanf() instead. A failed
conversion is only guaranteed to consume nothing, not to advance the
stream, so also track the file position directly and force one byte
of progress (or bail out) if a scan attempt didn't move it - corrupt/
binary content can now only ever cost one pass over the file, never
an infinite loop.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
…ors.

A supervisor process (e.g. an app-store UI that owns the framebuffer
while a launched game runs directly against /dev/fb0) has no reachable
in-game quit path to drive - no keyboard/touch input is wired up for
that - so it can only ask NXDoom to exit from the outside. The only
existing option for that was a forced task_delete() from the
supervisor's side, which was found on real hardware to hang the
entire board (not just this one task) when it landed mid framebuffer/
heap access, on this flat-memory build where a bad access in one task
isn't contained to that task.

Add i_install_quit_signal()/i_poll_quit_signal()/a SIGTERM handler
(i_system.c/i_system.h): the handler itself only sets a volatile
sig_atomic_t flag - it must not call i_quit() (or anything it does:
munmap, fclose, exit()'s atexit chain) directly, since a signal can
land at literally any point in this process's own execution,
including mid-malloc()/mid-blit, the same "unsafe mid-operation
teardown" risk as being force-killed from outside, just moved into
this process's own context. i_poll_quit_signal() defers the actual
shutdown to a call in the main per-frame loop (d_doomloop(), d_main.c)
- a point that's definitely safe (outside any framebuffer/heap access)
and reached every frame regardless of what else NXDoom is doing, which
is what's actually verified working end-to-end against a real
supervisor's SIGTERM/close path on hardware.

i_install_quit_signal() is called once from main() (i_main.c), and
also:

- Checks sigaction()'s return value and logs via syslog on failure
  instead of ignoring it silently - the game still runs either way,
  but silently leaving close non-functional with no trace of why
  would make a real close-path bug harder to diagnose than it needs
  to be.

- Resets quit_requested and exit_funcs at the start of
  i_install_quit_signal(). This board's flat, single address-space
  build normally relaunches NXDoom as a fresh loadable ELF module with
  its own zeroed .bss, but GAMES_NXDOOM is a tristate Kconfig symbol
  and can also be built in as a true built-in sharing this process's
  address space across "launches" with no fresh .bss at all - a
  leaked quit_requested flag would call i_quit() again before the game
  even starts on a second invocation, and a leaked exit_funcs chain
  would re-run every previous invocation's exit handlers a second
  time.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
Read each physical configuration line independently so malformed or truncated input cannot consume a following setting as its value. Discard overlong lines and retain defaults for incomplete entries.

Assisted-by: Codex:gpt-5
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
Move the maximum-visplane guard ahead of the new plane initialization. At full capacity, the previous ordering wrote three fields one element past the visplanes array before reporting the overflow.

Assisted-by: Codex:gpt-5
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
Check integer conversions before updating bound configuration values. This keeps compiled defaults intact for malformed non-numeric values instead of propagating an uninitialized result from sscanf().

Assisted-by: Codex:gpt-5
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
i_init_graphics() derived the centring offset from pinfo.stride and
pinfo.bpp before FBIOGET_PLANEINFO had filled them in. g_graphics_state
is zero-initialised, so origin was always 0 and the scaled image was
drawn at the top left corner of the display rather than centred on it.

Record the position in pixels where the geometry is known, and convert
it to a byte offset once the plane info has actually been read.

Assisted-by: OpenAI Codex:gpt-5.6-sol
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
blit_screen() wrote straight into the mapped frame buffer and never issued
FBIO_UPDATE, making NXDoom the only frame buffer consumer in the tree that
skips it. Drivers that do not scan the frame buffer out continuously never
learn that the pixels changed, so nothing is displayed at all.

Verified on the sim vncserver target: with the update the client receives
the full 640x400 image, and without it the client receives no rectangles
and a blank screen, while the game itself runs identically in both cases.

Assisted-by: OpenAI Codex:gpt-5.6-sol
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
@aviralgarg05
aviralgarg05 force-pushed the gsoc/nxdoom-bringup-fixes-pr7 branch from 1fbe5cc to 0899b14 Compare August 6, 2026 16:35
@aviralgarg05
aviralgarg05 marked this pull request as ready for review August 6, 2026 16:37
@linguini1

Copy link
Copy Markdown
Contributor

Testing logs do not match what real output would look like. How come?

@aviralgarg05

Copy link
Copy Markdown
Contributor Author

Testing logs do not match what real output would look like. How come?

Sorry, that wasn't a verbatim capture. I had trimmed the startup lines and mixed the build output into the same block as the serial log, which was a bad call. I've replaced it with the raw capture from the board.

Comment thread games/NXDoom/src/doom/d_main.c Outdated
Comment thread games/NXDoom/src/doom/r_main.c
Comment thread games/NXDoom/src/d_iwad.c Outdated
Comment thread games/NXDoom/src/i_main.c Outdated
Comment thread games/NXDoom/src/i_system.c Outdated
Comment thread games/NXDoom/src/doom/r_plane.c Outdated
Comment thread games/NXDoom/src/doom/r_plane.c Outdated
Comment thread games/NXDoom/src/doom/r_plane.c Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we using viewheight here? Does it get properly set?

Comment thread games/NXDoom/src/doom/r_plane.c Outdated
@linguini1

Copy link
Copy Markdown
Contributor

Sorry, that wasn't a verbatim capture.

In the future, please always provide the exact output. That is what is meant by testing logs :)

Also, when using AI to generate code, please review its comments and shorten them. This patch is full of very long comments that make reference to other applications and testing that you performed, which is not necessary information for a developer to read and understand the logic.

@aviralgarg05
aviralgarg05 force-pushed the gsoc/nxdoom-bringup-fixes-pr7 branch from 729c326 to 3a12ffa Compare August 8, 2026 10:03
@aviralgarg05

Copy link
Copy Markdown
Contributor Author

@linguini1
All the comment cleanups are done and pushed: NuttX function blocks, nxstore/nxpkg references gone everywhere, syslog swapped for printf, and the allocation failure path now goes through r_shutdown_planes() which checks each pointer.

Four things I've left as they are, since I think changing them would reintroduce bugs:

parse_int_parameter — upstream returns param without checking sscanf, so a value that doesn't parse returns an uninitialised stack variable straight into the config. That's what caused the divide-by-zero this PR fixes: a screenblocks line with no value set the view size to garbage. Returning success and writing through a pointer is the smallest way to leave the compiled default alone. Happy to reshape the signature if you'd prefer it done differently.

viewheight in r_draw.c — r_init_buffer() only fills ylookup[] for [0, height), and r_main.c passes viewheight as that height, so indexing at SCREENHEIGHT reads an entry that was never set. viewheight is set in r_execute_set_view_size() before any drawing. The old check also used > rather than >=, so it let ds_y == SCREENHEIGHT through.

Discarded characters — the line is longer than the buffer, so it can't be a valid setting; that loop drops the rest rather than parsing a truncated one.

Empty check — reachable because the strip loop above removes non-printable characters, so a value that was only a tab or a stray \r ends up empty. Added comments for both.

@aviralgarg05
aviralgarg05 force-pushed the gsoc/nxdoom-bringup-fixes-pr7 branch from 3a12ffa to b555c0d Compare August 8, 2026 10:08
Shorten the comments added by this series to what the code needs, and use
NuttX function comment blocks for the new interfaces. Drop references to
the supervisor and the package manager, which are not part of this game.

Report a failed signal handler installation through printf(), matching the
rest of the application, rather than syslog().

Free the renderer scratch buffers through r_shutdown_planes() on the
allocation failure path instead of repeating the frees, and make that
function safe to call more than once.

Assisted-by: OpenAI Codex:gpt-5.6-sol
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
@aviralgarg05
aviralgarg05 force-pushed the gsoc/nxdoom-bringup-fixes-pr7 branch from b555c0d to 8951e2a Compare August 8, 2026 10:09
@linguini1

Copy link
Copy Markdown
Contributor

Once again, stop replying to my review comments with AI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants