Skip to content

Commit a0328da

Browse files
committed
games/NXDoom: support RGB565 framebuffers and locate WADs via Kconfig dir
blit_screen() assumed a 32-bit ARGB framebuffer unconditionally - a real limitation for any RGB565 board (this target's framebuffer is FB_FMT_RGB16_565), not specific to any one board. Branch on pinfo.bpp: 16bpp uses RGBTO16(), 32bpp keeps the existing ARGBTO32() path, and anything else fails loudly via i_error() instead of reading/ writing past the intended pixel bounds silently. Also center the scaled viewport within the framebuffer (new xoffset/yoffset fields) rather than pinning it to the top-left corner, since the buffer is typically larger than SCREENWIDTH/HEIGHT * scale. buld_iwad_dir_list() never searched CONFIG_GAMES_NXDOOM_PREFDIR - that Kconfig option is documented as the directory where DOOM WAD files are stored, but was previously only used for the config/save file location, forcing every launch to rely on the current directory or DOOMWADDIR/DOOMWADPATH being set by hand. Add it to the IWAD search path. Build this as a standalone loadable module (MODULE = m) unconditionally rather than tracking CONFIG_GAMES_NXDOOM directly, so it can be installed/launched via nxpkg/nxstore rather than only ever being a firmware built-in. Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
1 parent 30830d9 commit a0328da

3 files changed

Lines changed: 82 additions & 17 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/i_video.c

Lines changed: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ struct graphics_state_s
9292

9393
uint8_t scale;
9494

95+
/* Pixel offset to center the scaled game viewport within the frame
96+
* buffer when the buffer is larger than SCREENWIDTH/HEIGHT * scale.
97+
*/
98+
99+
int xoffset;
100+
int yoffset;
101+
95102
bool inited; /* Track initialization */
96103
};
97104

@@ -262,27 +269,61 @@ static void blit_screen(void)
262269
uint8_t p_idx;
263270
void *fbptr;
264271

265-
/* TODO: It would be best to do this more efficiently/with less memory.
266-
* It also would be good if we could handle the palette translation here
267-
* such that DOOM can be played on frame buffers with differing bit depths
268-
* and pixel formats.
269-
*/
272+
/* TODO: It would be best to do this more efficiently/with less memory. */
270273

271-
fbptr = g_graphics_state.fbmem;
272-
for (unsigned y = 0; y < SCREENHEIGHT * g_graphics_state.scale; y++)
274+
fbptr = g_graphics_state.fbmem +
275+
g_graphics_state.yoffset * g_graphics_state.pinfo.stride +
276+
g_graphics_state.xoffset *
277+
(g_graphics_state.pinfo.bpp == 16 ? 2 : 4);
278+
279+
if (g_graphics_state.pinfo.bpp == 16)
273280
{
274-
for (unsigned x = 0; x < SCREENWIDTH * g_graphics_state.scale; x++)
281+
for (unsigned y = 0; y < SCREENHEIGHT * g_graphics_state.scale; y++)
275282
{
276-
p_idx = g_graphics_state
277-
.scrnbuf[(y / g_graphics_state.scale) * SCREENWIDTH +
278-
(x / g_graphics_state.scale)];
279-
280-
((uint32_t *)(fbptr))[x] =
281-
ARGBTO32(g_palette[p_idx].a, g_palette[p_idx].r,
282-
g_palette[p_idx].g, g_palette[p_idx].b);
283+
for (unsigned x = 0; x < SCREENWIDTH * g_graphics_state.scale; x++)
284+
{
285+
p_idx = g_graphics_state
286+
.scrnbuf[(y / g_graphics_state.scale) *
287+
SCREENWIDTH +
288+
(x / g_graphics_state.scale)];
289+
290+
((uint16_t *)(fbptr))[x] =
291+
RGBTO16(g_palette[p_idx].r, g_palette[p_idx].g,
292+
g_palette[p_idx].b);
293+
}
294+
295+
fbptr += g_graphics_state.pinfo.stride;
296+
}
297+
}
298+
else if (g_graphics_state.pinfo.bpp == 32)
299+
{
300+
for (unsigned y = 0; y < SCREENHEIGHT * g_graphics_state.scale; y++)
301+
{
302+
for (unsigned x = 0; x < SCREENWIDTH * g_graphics_state.scale; x++)
303+
{
304+
p_idx = g_graphics_state
305+
.scrnbuf[(y / g_graphics_state.scale) *
306+
SCREENWIDTH +
307+
(x / g_graphics_state.scale)];
308+
309+
((uint32_t *)(fbptr))[x] =
310+
ARGBTO32(g_palette[p_idx].a, g_palette[p_idx].r,
311+
g_palette[p_idx].g, g_palette[p_idx].b);
312+
}
313+
314+
fbptr += g_graphics_state.pinfo.stride;
283315
}
316+
}
317+
else
318+
{
319+
/* Neither 16bpp nor 32bpp: the xoffset/stride math above assumed
320+
* one of those two pixel sizes, so continuing would read/write
321+
* past the intended pixel bounds on the very first frame. Fail
322+
* loudly instead of silently corrupting framebuffer memory.
323+
*/
284324

285-
fbptr += g_graphics_state.pinfo.stride;
325+
i_error("Unsupported framebuffer depth: %u bpp",
326+
g_graphics_state.pinfo.bpp);
286327
}
287328
}
288329

@@ -724,6 +765,18 @@ void i_init_graphics(void)
724765
yscale = g_graphics_state.vinfo.yres / SCREENHEIGHT;
725766
g_graphics_state.scale = xscale > yscale ? yscale : xscale;
726767

768+
/* Center the scaled viewport within the frame buffer rather than
769+
* pinning it to the top-left corner, since the buffer is typically
770+
* larger than SCREENWIDTH/HEIGHT * scale.
771+
*/
772+
773+
g_graphics_state.xoffset =
774+
(g_graphics_state.vinfo.xres -
775+
SCREENWIDTH * g_graphics_state.scale) / 2;
776+
g_graphics_state.yoffset =
777+
(g_graphics_state.vinfo.yres -
778+
SCREENHEIGHT * g_graphics_state.scale) / 2;
779+
727780
/* Get frame buffer plane info */
728781

729782
if (ioctl(g_graphics_state.fd, FBIOGET_PLANEINFO,

0 commit comments

Comments
 (0)