Skip to content

Commit 6fe6008

Browse files
committed
games/NXDoom: RGB565 support, loadable-module conversion, and crash fixes
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. Branches on pinfo.bpp: 16bpp uses RGBTO16(), 32bpp keeps the existing ARGBTO32() path, and 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). Builds as a standalone loadable module (MODULE = m) unconditionally so it can be installed/launched via nxpkg/nxstore. Fix three 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 write (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, checks against the true array bound (SCREENHEIGHT), and skips the draw instead of touching memory or aborting. Also converts visplanes/openings/drawsegs/vissprites from static arrays to heap allocation (freed via i_at_exit so cleanup also runs on the i_error() fatal path) to relieve DRAM pressure once a full application is linked into the same image. - myargv was under-allocated: sized for argc pointers, but this codebase's own argument handling assumes argv is NULL-terminated at argv[argc] (standard C/exec convention). Root-caused via a real crash dump and symbol resolution against the built ELF; now allocates argc + 1 pointers and explicitly NULL-terminates. Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
1 parent 1d15c81 commit 6fe6008

13 files changed

Lines changed: 194 additions & 32 deletions

File tree

games/NXDoom/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ include $(APPDIR)/Make.defs
22

33
# Program options
44

5-
MODULE = $(CONFIG_GAMES_NXDOOM)
5+
MODULE = m
66
PRIORITY = $(CONFIG_GAMES_NXDOOM_PRIORITY)
77
STACKSIZE = $(CONFIG_GAMES_NXDOOM_STACKSIZE)
88
PROGNAME = nxdoom

games/NXDoom/src/d_iwad.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,18 @@ static void buld_iwad_dir_list(void)
271271

272272
add_iwad_dir(m_dir_name(myargv[0]));
273273

274+
/* Add the board's configured DOOM data directory. Kconfig documents
275+
* CONFIG_GAMES_NXDOOM_PREFDIR as "Directory where DOOM WAD files are
276+
* stored", but until now it was only used for the config/save file
277+
* location -- nothing actually searched it for IWADs, forcing every
278+
* launch to rely on the current directory or DOOMWADDIR/DOOMWADPATH
279+
* being set by hand first.
280+
*/
281+
282+
#ifdef CONFIG_GAMES_NXDOOM_PREFDIR
283+
add_iwad_dir(CONFIG_GAMES_NXDOOM_PREFDIR);
284+
#endif
285+
274286
/* Add DOOMWADDIR if it is in the environment */
275287

276288
env = getenv("DOOMWADDIR");

games/NXDoom/src/doom/r_bsp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ line_t *linedef;
7878
sector_t *frontsector;
7979
sector_t *backsector;
8080

81-
drawseg_t drawsegs[CONFIG_GAMES_NXDOOM_MAXDRAWSEGS];
81+
drawseg_t *drawsegs;
8282
drawseg_t *ds_p;
8383

8484
/* newend is one past the last valid seg */

games/NXDoom/src/doom/r_bsp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ extern boolean markceiling;
5252

5353
extern boolean skymap;
5454

55-
extern drawseg_t drawsegs[CONFIG_GAMES_NXDOOM_MAXDRAWSEGS];
55+
extern drawseg_t *drawsegs;
5656
extern drawseg_t *ds_p;
5757

5858
extern lighttable_t **hscalelight;

games/NXDoom/src/doom/r_main.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,24 @@ fixed_t r_scale_from_global_angle(angle_t visangle)
685685

686686
void r_set_view_size(int blocks, int detail)
687687
{
688+
/* screenblocks is only ever meant to hold 3..11 (set that way by the
689+
* options menu and by the config default of 9). The renderer's view
690+
* geometry math divides by values derived from it - notably
691+
* pspriteiscale = FRACUNIT * SCREENWIDTH / viewwidth in
692+
* r_execute_set_view_size() - so a 0 or otherwise out-of-range value
693+
* turns into a divide-by-zero hardware exception (EXCCAUSE=6), which on
694+
* this flat-memory build takes the whole board down rather than just
695+
* this task. Clamp defensively so a bad/missing config value degrades
696+
* to the default screen size instead of a system crash.
697+
*/
698+
699+
if (blocks < 3 || blocks > 11)
700+
{
701+
printf("r_set_view_size: screenblocks=%d out of range, using 10\n",
702+
blocks);
703+
blocks = 10;
704+
}
705+
688706
setsizeneeded = true;
689707
setblocks = blocks;
690708
setdetail = detail;

games/NXDoom/src/doom/r_plane.c

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ planefunction_t ceilingfunc;
5757

5858
/* Here comes the obnoxious "visplane". */
5959

60-
visplane_t visplanes[CONFIG_GAMES_NXDOOM_MAXVISPLANES];
60+
visplane_t *visplanes;
6161
visplane_t *lastvisplane;
6262
visplane_t *floorplane;
6363
visplane_t *ceilingplane;
6464

65-
short openings[MAXOPENINGS];
65+
short *openings;
6666
short *lastopening;
6767

6868
/* Clip values are the solid pixel bounding the range. floorclip starts out
@@ -114,12 +114,23 @@ static void r_map_plane(int y, int x1, int x2)
114114
fixed_t length;
115115
unsigned index;
116116

117-
#ifdef CONFIG_GAMES_NXDOOM_RANGECHECK
118-
if (x2 < x1 || x1 < 0 || x2 >= viewwidth || y > viewheight)
117+
/* y indexes cachedheight[]/cacheddistance[]/cachedxstep[]/cachedystep[]
118+
* below, all sized SCREENHEIGHT - a y outside that range (observed on
119+
* this port: y=255 against a 200-entry array, well past even
120+
* viewheight) is an out-of-bounds array write, not just a "debug
121+
* assertion". This used to be gated behind CONFIG_GAMES_NXDOOM_
122+
* RANGECHECK and fatal (i_error(), which tears down the whole process
123+
* on what vanilla Doom would just render as one glitched span) - both
124+
* wrong: the memory-safety check must not be optional, and killing the
125+
* entire game over one bad plane span is worse than just not drawing
126+
* it. Skip the draw instead of touching memory or the process outside
127+
* the buffers' real bounds.
128+
*/
129+
130+
if (x2 < x1 || x1 < 0 || x2 >= viewwidth || y < 0 || y >= SCREENHEIGHT)
119131
{
120-
i_error("R_MapPlane: %i, %i at %i", x1, x2, y);
132+
return;
121133
}
122-
#endif
123134

124135
if (planeheight != cachedheight[y])
125136
{
@@ -195,7 +206,48 @@ static void r_make_spans(int x, int t1, int b1, int t2, int b2)
195206

196207
void r_init_planes(void)
197208
{
198-
/* Doh! */
209+
/* These renderer scratch buffers are sized for a comfortable margin
210+
* above vanilla DOOM's original limits and would blow the platform's
211+
* internal DRAM budget as static arrays, so they're heap-allocated
212+
* instead (comes out of the PSRAM-backed user heap on this target).
213+
*/
214+
215+
visplanes = malloc(sizeof(visplane_t) * CONFIG_GAMES_NXDOOM_MAXVISPLANES);
216+
openings = malloc(sizeof(short) * MAXOPENINGS);
217+
drawsegs = malloc(sizeof(drawseg_t) * CONFIG_GAMES_NXDOOM_MAXDRAWSEGS);
218+
vissprites = malloc(sizeof(vissprite_t) *
219+
CONFIG_GAMES_NXDOOM_MAXVISSPRITES);
220+
221+
if (visplanes == NULL || openings == NULL || drawsegs == NULL ||
222+
vissprites == NULL)
223+
{
224+
i_error("r_init_planes: failed to allocate renderer buffers");
225+
}
226+
227+
/* i_quit() can be followed by another r_init_planes() call within the
228+
* same boot (relaunching the game via nxpkg on this flat, single
229+
* address-space build), so these heap buffers must be freed on exit
230+
* or every relaunch leaks the previous allocation permanently.
231+
*/
232+
233+
i_at_exit(r_shutdown_planes, true);
234+
}
235+
236+
/* r_shutdown_planes
237+
* Frees the renderer scratch buffers allocated by r_init_planes.
238+
*/
239+
240+
void r_shutdown_planes(void)
241+
{
242+
free(visplanes);
243+
free(openings);
244+
free(drawsegs);
245+
free(vissprites);
246+
247+
visplanes = NULL;
248+
openings = NULL;
249+
drawsegs = NULL;
250+
vissprites = NULL;
199251
}
200252

201253
/* r_clear_planes

games/NXDoom/src/doom/r_plane.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ extern fixed_t distscale[SCREENWIDTH];
5858
****************************************************************************/
5959

6060
void r_init_planes(void);
61+
void r_shutdown_planes(void);
6162
void r_clear_planes(void);
6263

6364
void r_draw_planes(void);

games/NXDoom/src/doom/r_things.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ spriteframe_t sprtemp[29];
9393
int maxframe;
9494
const char *spritename;
9595

96-
vissprite_t vissprites[CONFIG_GAMES_NXDOOM_MAXVISSPRITES];
96+
vissprite_t *vissprites;
9797
vissprite_t *vissprite_p;
9898
int newvissprite;
9999

games/NXDoom/src/doom/r_things.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* Public Data
2929
****************************************************************************/
3030

31-
extern vissprite_t vissprites[CONFIG_GAMES_NXDOOM_MAXVISSPRITES];
31+
extern vissprite_t *vissprites;
3232
extern vissprite_t *vissprite_p;
3333
extern vissprite_t vsprsortedhead;
3434

games/NXDoom/src/doom/statdump.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
* Pre-processor Definitions
4040
****************************************************************************/
4141

42-
#define MAX_CAPTURES 32
42+
#define MAX_CAPTURES 4
4343

4444
/****************************************************************************
4545
* Private Data

0 commit comments

Comments
 (0)