games/NXDoom: support RGB565 and loadable modules

Add RGB565 framebuffer output and module builds. Harden configuration parsing and renderer bounds, support supervised SIGTERM shutdown, and notify framebuffer drivers after drawing.

Assisted-by: Codex:gpt-5
Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
This commit is contained in:
aviralgarg05 2026-08-16 21:02:53 +05:30 • committed by Alan C. Assis
parent 34ca2a5ed8
commit 922cf59799
11 changed files with 711 additions and 235 deletions

View file

@ -4,7 +4,7 @@
#
config GAMES_NXDOOM
bool "NXDoom"
tristate "NXDoom"
default n
depends on ALLOW_GPL_COMPONENTS
depends on VIDEO_FB
@ -252,6 +252,13 @@ config GAMES_NXDOOM_MAXDRAWSEGS
memory, so you may reduce the number. However, too few will cause
rendering issues (overflow is checked to avoid crashes).
config GAMES_NXDOOM_STATDUMP_MAX_CAPTURES
int "Maximum statdump capture buffer entries"
default 32
range 1 1024
---help---
Number of diagnostic playtime-statistics capture slots.
config GAMES_NXDOOM_RANGECHECK
bool "Perform range checks"
default y

View file

@ -194,7 +194,10 @@ static gamemission_t identify_iwad_by_name(const char *name, int mask)
* Only use supported missions:
*/
if (((1 << g_iwads[i].mission) & mask) == 0) continue;
if (((1 << g_iwads[i].mission) & mask) == 0)
{
continue;
}
/* Check if it ends in this IWAD name. */
@ -271,6 +274,10 @@ static void buld_iwad_dir_list(void)
add_iwad_dir(m_dir_name(myargv[0]));
/* Add the configured DOOM data directory */
add_iwad_dir(CONFIG_GAMES_NXDOOM_PREFDIR);
/* Add DOOMWADDIR if it is in the environment */
env = getenv("DOOMWADDIR");

View file

@ -598,43 +598,50 @@ static boolean d_display(void)
switch (gamestate)
{
case GS_LEVEL:
if (!gametic)
case GS_LEVEL:
{
if (!gametic)
{
break;
}
if (automapactive)
{
am_drawer();
}
if (wipe || (viewheight != SCREENHEIGHT && d_fullscreen))
{
redrawsbar = true;
}
if (inhelpscreensstate && !inhelpscreens)
{
redrawsbar = true; /* just put away the help screen */
}
st_drawer(viewheight == SCREENHEIGHT, redrawsbar);
d_fullscreen = viewheight == SCREENHEIGHT;
break;
}
if (automapactive)
case GS_INTERMISSION:
{
am_drawer();
wi_drawer();
break;
}
if (wipe || (viewheight != SCREENHEIGHT && d_fullscreen))
case GS_FINALE:
{
redrawsbar = true;
f_drawer();
break;
}
if (inhelpscreensstate && !inhelpscreens)
case GS_DEMOSCREEN:
{
redrawsbar = true; /* just put away the help screen */
d_page_drawer();
break;
}
st_drawer(viewheight == SCREENHEIGHT, redrawsbar);
d_fullscreen = viewheight == SCREENHEIGHT;
break;
case GS_INTERMISSION:
wi_drawer();
break;
case GS_FINALE:
f_drawer();
break;
case GS_DEMOSCREEN:
d_page_drawer();
break;
}
/* draw buffered stuff to screen */
@ -656,7 +663,9 @@ static boolean d_display(void)
/* clean up border stuff */
if (gamestate != oldgamestate && gamestate != GS_LEVEL)
i_set_palette(w_cache_lump_name(("PLAYPAL"), PU_CACHE));
{
i_set_palette(w_cache_lump_name(("PLAYPAL"), PU_CACHE));
}
/* see if the border needs to be initially drawn */
@ -672,7 +681,10 @@ static boolean d_display(void)
scaledviewwidth != SCREENWIDTH)
{
if (g_menuactive || g_menuactivestate || !viewactivestate)
borderdrawcount = 3;
{
borderdrawcount = 3;
}
if (borderdrawcount)
{
r_draw_view_border(); /* erase old menu stuff */
@ -697,11 +709,16 @@ static boolean d_display(void)
if (paused)
{
if (automapactive)
y = 4;
{
y = 4;
}
else
y = viewwindowy + 4;
{
y = viewwindowy + 4;
}
v_draw_patch_direct(viewwindowx + (scaledviewwidth - 68) / 2, y,
w_cache_lump_name(("M_PAUSE"), PU_CACHE));
w_cache_lump_name(("M_PAUSE"), PU_CACHE));
}
/* menus go directly to the screen */
@ -725,12 +742,18 @@ static boolean d_grab_mouse_callback(void)
/* Drone players don't need mouse focus */
#ifdef CONFIG_GAMES_NXDOOM_NET
if (drone) return false;
if (drone)
{
return false;
}
#endif
/* when menu is active or game is paused, release the mouse */
if (g_menuactive || paused) return false;
if (g_menuactive || paused)
{
return false;
}
/* only grab mouse when playing levels (but not demos) */
@ -1144,28 +1167,45 @@ static void init_game_version(void)
status = true;
switch (demoversion)
{
case 0:
case 1:
case 2:
case 3:
case 4:
gameversion = exe_doom_1_2;
break;
case 106:
gameversion = exe_doom_1_666;
break;
case 107:
gameversion = exe_doom_1_7;
break;
case 108:
gameversion = exe_doom_1_8;
break;
case 109:
gameversion = exe_doom_1_9;
break;
default:
status = false;
break;
case 0:
case 1:
case 2:
case 3:
case 4:
{
gameversion = exe_doom_1_2;
break;
}
case 106:
{
gameversion = exe_doom_1_666;
break;
}
case 107:
{
gameversion = exe_doom_1_7;
break;
}
case 108:
{
gameversion = exe_doom_1_8;
break;
}
case 109:
{
gameversion = exe_doom_1_9;
break;
}
default:
{
status = false;
break;
}
}
if (status)
@ -1245,11 +1285,18 @@ void d_process_events(void)
/* IF STORE DEMO, DO NOT ACCEPT INPUT */
if (storedemo) return;
if (storedemo)
{
return;
}
while ((ev = d_pop_event()) != NULL)
{
if (m_responder(ev)) continue; /* menu ate the event */
if (m_responder(ev))
{
continue; /* menu ate the event */
}
g_responder(ev);
}
}
@ -1294,6 +1341,7 @@ void d_doomloop(void)
while (1)
{
i_poll_quit_signal();
d_run_frame();
}
}
@ -1304,7 +1352,10 @@ void d_doomloop(void)
void d_page_ticker(void)
{
if (--pagetic < 0) d_advance_demo();
if (--pagetic < 0)
{
d_advance_demo();
}
}
/****************************************************************************
@ -1357,72 +1408,104 @@ void d_do_advance_demo(void)
*/
if (gameversion == exe_ultimate || gameversion == exe_final)
demosequence = (demosequence + 1) % 7;
{
demosequence = (demosequence + 1) % 7;
}
else
demosequence = (demosequence + 1) % 6;
{
demosequence = (demosequence + 1) % 6;
}
switch (demosequence)
{
case 0:
if (gamemode == commercial)
pagetic = TICRATE * 11;
else
pagetic = 170;
gamestate = GS_DEMOSCREEN;
pagename = ("TITLEPIC");
case 0:
{
if (gamemode == commercial)
{
pagetic = TICRATE * 11;
}
else
{
pagetic = 170;
}
#ifdef CONFIG_GAMES_NXDOOM_SOUND
if (gamemode == commercial)
{
s_start_music(MUS_DM2TTL);
}
else
{
s_start_music(MUS_INTRO);
}
#endif
break;
case 1:
g_defered_play_demo(("demo1"));
break;
case 2:
pagetic = 200;
gamestate = GS_DEMOSCREEN;
pagename = ("CREDIT");
break;
case 3:
g_defered_play_demo(("demo2"));
break;
case 4:
gamestate = GS_DEMOSCREEN;
if (gamemode == commercial)
{
pagetic = TICRATE * 11;
gamestate = GS_DEMOSCREEN;
pagename = ("TITLEPIC");
#ifdef CONFIG_GAMES_NXDOOM_SOUND
s_start_music(MUS_DM2TTL);
if (gamemode == commercial)
{
s_start_music(MUS_DM2TTL);
}
else
{
s_start_music(MUS_INTRO);
}
#endif
break;
}
else
case 1:
{
g_defered_play_demo(("demo1"));
break;
}
case 2:
{
pagetic = 200;
if (gameversion >= exe_ultimate)
pagename = ("CREDIT");
else
pagename = ("HELP2");
gamestate = GS_DEMOSCREEN;
pagename = ("CREDIT");
break;
}
case 3:
{
g_defered_play_demo(("demo2"));
break;
}
case 4:
{
gamestate = GS_DEMOSCREEN;
if (gamemode == commercial)
{
pagetic = TICRATE * 11;
pagename = ("TITLEPIC");
#ifdef CONFIG_GAMES_NXDOOM_SOUND
s_start_music(MUS_DM2TTL);
#endif
}
else
{
pagetic = 200;
if (gameversion >= exe_ultimate)
{
pagename = ("CREDIT");
}
else
{
pagename = ("HELP2");
}
}
break;
}
case 5:
{
g_defered_play_demo(("demo3"));
break;
}
break;
case 5:
g_defered_play_demo(("demo3"));
break;
/* THE DEFINITIVE DOOM Special Edition demo */
case 6:
g_defered_play_demo(("demo4"));
break;
case 6:
{
g_defered_play_demo(("demo4"));
break;
}
}
/* The Doom 3: BFG Edition version of doom2.wad does not have a
@ -1565,7 +1648,10 @@ void d_doom_main(void)
*
*/
if (m_check_parm("-deathmatch")) deathmatch = 1;
if (m_check_parm("-deathmatch"))
{
deathmatch = 1;
}
/* @category net
* @vanilla
@ -1575,7 +1661,10 @@ void d_doom_main(void)
*
*/
if (m_check_parm("-altdeath")) deathmatch = 2;
if (m_check_parm("-altdeath"))
{
deathmatch = 2;
}
if (devparm)
{
@ -1601,9 +1690,21 @@ void d_doom_main(void)
{
int scale = 200;
if (p < myargc - 1) scale = atoi(myargv[p + 1]);
if (scale < 10) scale = 10;
if (scale > 400) scale = 400;
if (p < myargc - 1)
{
scale = atoi(myargv[p + 1]);
}
if (scale < 10)
{
scale = 10;
}
if (scale > 400)
{
scale = 400;
}
printf("turbo scale: %i%%\n", scale);
forwardmove[0] = forwardmove[0] * scale / 100;
forwardmove[1] = forwardmove[1] * scale / 100;
@ -1815,6 +1916,7 @@ void d_doom_main(void)
if (p)
{
char *uc_filename = strdup(myargv[p + 1]);
m_force_uppercase(uc_filename);
/* With Vanilla you have to specify the file without extension,
@ -1906,8 +2008,10 @@ void d_doom_main(void)
int i;
if (gamemode == shareware)
i_error(("\nYou cannot -file with the shareware "
"version. Register!"));
{
i_error(("\nYou cannot -file with the shareware "
"version. Register!"));
}
/* Check for fake IWAD with right name,
* but w/o all the lumps of the registered version.
@ -2041,7 +2145,9 @@ void d_doom_main(void)
if (p)
{
if (gamemode == commercial)
startmap = atoi(myargv[p + 1]);
{
startmap = atoi(myargv[p + 1]);
}
else
{
startepisode = myargv[p + 1][0] - '0';
@ -2128,7 +2234,9 @@ void d_doom_main(void)
*/
if (gamemode == commercial && w_check_num_for_name("map01") < 0)
storedemo = true;
{
storedemo = true;
}
if (m_check_parm_with_args("-statdump", 1))
{
@ -2175,9 +2283,13 @@ void d_doom_main(void)
if (gameaction != ga_loadgame)
{
if (autostart || netgame)
g_init_new(startskill, startepisode, startmap);
{
g_init_new(startskill, startepisode, startmap);
}
else
d_start_title(); /* start up intro loop */
{
d_start_title(); /* start up intro loop */
}
}
d_doomloop(); /* never returns */

View file

@ -168,11 +168,16 @@ void r_draw_column(void)
/* Zero length, column does not exceed a pixel. */
if (count < 0) return;
if (count < 0)
{
return;
}
#ifdef CONFIG_GAMES_NXDOOM_RANGECHECK
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
i_error("r_draw_column: %i to %i at %i", dc_yl, dc_yh, dc_x);
{
i_error("r_draw_column: %i to %i at %i", dc_yl, dc_yh, dc_x);
}
#endif
/* Framebuffer destination address.
@ -277,7 +282,10 @@ void r_draw_column_low(void)
/* Zero length. */
if (count < 0) return;
if (count < 0)
{
return;
}
#ifdef CONFIG_GAMES_NXDOOM_RANGECHECK
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
@ -324,17 +332,26 @@ void r_draw_fuzz_column(void)
/* Adjust borders. Low... */
if (!dc_yl) dc_yl = 1;
if (!dc_yl)
{
dc_yl = 1;
}
/* .. and high. */
if (dc_yh == viewheight - 1) dc_yh = viewheight - 2;
if (dc_yh == viewheight - 1)
{
dc_yh = viewheight - 2;
}
count = dc_yh - dc_yl;
/* Zero length. */
if (count < 0) return;
if (count < 0)
{
return;
}
#ifdef CONFIG_GAMES_NXDOOM_RANGECHECK
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
@ -360,7 +377,10 @@ void r_draw_fuzz_column(void)
/* Clamp table lookup index. */
if (++fuzzpos == FUZZTABLE) fuzzpos = 0;
if (++fuzzpos == FUZZTABLE)
{
fuzzpos = 0;
}
dest += SCREENWIDTH;
}
@ -378,17 +398,26 @@ void r_draw_fuzz_column_low(void)
/* Adjust borders. Low... */
if (!dc_yl) dc_yl = 1;
if (!dc_yl)
{
dc_yl = 1;
}
/* .. and high. */
if (dc_yh == viewheight - 1) dc_yh = viewheight - 2;
if (dc_yh == viewheight - 1)
{
dc_yh = viewheight - 2;
}
count = dc_yh - dc_yl;
/* Zero length. */
if (count < 0) return;
if (count < 0)
{
return;
}
/* low detail mode, need to multiply by 2 */
@ -419,7 +448,10 @@ void r_draw_fuzz_column_low(void)
/* Clamp table lookup index. */
if (++fuzzpos == FUZZTABLE) fuzzpos = 0;
if (++fuzzpos == FUZZTABLE)
{
fuzzpos = 0;
}
dest += SCREENWIDTH;
dest2 += SCREENWIDTH;
@ -444,7 +476,10 @@ void r_draw_translated_column(void)
fixed_t fracstep;
count = dc_yh - dc_yl;
if (count < 0) return;
if (count < 0)
{
return;
}
#ifdef CONFIG_GAMES_NXDOOM_RANGECHECK
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
@ -490,7 +525,10 @@ void r_draw_translated_column_low(void)
int x;
count = dc_yh - dc_yl;
if (count < 0) return;
if (count < 0)
{
return;
}
/* low detail, need to scale by 2 */
@ -597,7 +635,7 @@ void r_draw_span(void)
#ifdef CONFIG_GAMES_NXDOOM_RANGECHECK
if (ds_x2 < ds_x1 || ds_x1 < 0 || ds_x2 >= SCREENWIDTH ||
(unsigned)ds_y > SCREENHEIGHT)
ds_y < 0 || ds_y >= viewheight)
{
i_error("r_draw_span: %i to %i at %i", ds_x1, ds_x2, ds_y);
}
@ -724,7 +762,7 @@ void r_draw_span_low(void)
#ifdef CONFIG_GAMES_NXDOOM_RANGECHECK
if (ds_x2 < ds_x1 || ds_x1 < 0 || ds_x2 >= SCREENWIDTH ||
(unsigned)ds_y > SCREENHEIGHT)
ds_y < 0 || ds_y >= viewheight)
{
i_error("r_draw_span: %i to %i at %i", ds_x1, ds_x2, ds_y);
}
@ -783,19 +821,27 @@ void r_init_buffer(int width, int height)
/* Column offset. For windows. */
for (i = 0; i < width; i++)
columnofs[i] = viewwindowx + i;
{
columnofs[i] = viewwindowx + i;
}
/* Samw with base row offset. */
if (width == SCREENWIDTH)
viewwindowy = 0;
{
viewwindowy = 0;
}
else
viewwindowy = (SCREENHEIGHT - SBARHEIGHT - height) >> 1;
{
viewwindowy = (SCREENHEIGHT - SBARHEIGHT - height) >> 1;
}
/* Preclaculate all row offsets. */
for (i = 0; i < height; i++)
ylookup[i] = i_video_buffer + (i + viewwindowy) * SCREENWIDTH;
{
ylookup[i] = i_video_buffer + (i + viewwindowy) * SCREENWIDTH;
}
}
/* r_fill_back_screen
@ -847,9 +893,13 @@ void r_fill_back_screen(void)
}
if (gamemode == commercial)
name = name2;
{
name = name2;
}
else
name = name1;
{
name = name1;
}
src = w_cache_lump_name(name, PU_CACHE);
dest = background_buffer;
@ -876,19 +926,30 @@ void r_fill_back_screen(void)
patch = w_cache_lump_name(("brdr_t"), PU_CACHE);
for (x = 0; x < scaledviewwidth; x += 8)
v_draw_patch(viewwindowx + x, viewwindowy - 8, patch);
{
v_draw_patch(viewwindowx + x, viewwindowy - 8, patch);
}
patch = w_cache_lump_name(("brdr_b"), PU_CACHE);
for (x = 0; x < scaledviewwidth; x += 8)
v_draw_patch(viewwindowx + x, viewwindowy + viewheight, patch);
{
v_draw_patch(viewwindowx + x, viewwindowy + viewheight, patch);
}
patch = w_cache_lump_name(("brdr_l"), PU_CACHE);
for (y = 0; y < viewheight; y += 8)
v_draw_patch(viewwindowx - 8, viewwindowy + y, patch);
{
v_draw_patch(viewwindowx - 8, viewwindowy + y, patch);
}
patch = w_cache_lump_name(("brdr_r"), PU_CACHE);
for (y = 0; y < viewheight; y += 8)
v_draw_patch(viewwindowx + scaledviewwidth, viewwindowy + y, patch);
{
v_draw_patch(viewwindowx + scaledviewwidth, viewwindowy + y, patch);
}
/* Draw beveled edge. */
@ -934,7 +995,10 @@ void r_draw_view_border(void)
int ofs;
int i;
if (scaledviewwidth == SCREENWIDTH) return;
if (scaledviewwidth == SCREENWIDTH)
{
return;
}
top = ((SCREENHEIGHT - SBARHEIGHT) - viewheight) / 2;
side = (SCREENWIDTH - scaledviewwidth) / 2;

View file

@ -31,6 +31,7 @@
#include "d_loop.h"
#include "doomdef.h"
#include "i_system.h"
#include "m_bbox.h"
#include "m_menu.h"
@ -142,10 +143,25 @@ int setdetail;
#if 0 /* UNUSED */
static void r_add_point_to_box(int x, int y, fixed_t *box)
{
if (x < box[BOXLEFT]) box[BOXLEFT] = x;
if (x > box[BOXRIGHT]) box[BOXRIGHT] = x;
if (y < box[BOXBOTTOM]) box[BOXBOTTOM] = y;
if (y > box[BOXTOP]) box[BOXTOP] = y;
if (x < box[BOXLEFT])
{
box[BOXLEFT] = x;
}
if (x > box[BOXRIGHT])
{
box[BOXRIGHT] = x;
}
if (y < box[BOXBOTTOM])
{
box[BOXBOTTOM] = y;
}
if (y > box[BOXTOP])
{
box[BOXTOP] = y;
}
}
#endif
@ -177,10 +193,14 @@ static void r_setup_frame(player_t *player)
walllights = scalelightfixed;
for (i = 0; i < MAXLIGHTSCALE; i++)
scalelightfixed[i] = fixedcolormap;
{
scalelightfixed[i] = fixedcolormap;
}
}
else
fixedcolormap = 0;
{
fixedcolormap = 0;
}
framecount++;
validcount++;
@ -216,9 +236,15 @@ static void r_init_light_tables(void)
scale >>= LIGHTSCALESHIFT;
level = startmap - scale / DISTMAP;
if (level < 0) level = 0;
if (level < 0)
{
level = 0;
}
if (level >= NUMCOLORMAPS) level = NUMCOLORMAPS - 1;
if (level >= NUMCOLORMAPS)
{
level = NUMCOLORMAPS - 1;
}
zlight[i][j] = colormaps + level * 256;
}
@ -307,18 +333,26 @@ static void r_init_texture_mapping(void)
for (i = 0; i < FINEANGLES / 2; i++)
{
if (finetangent[i] > FRACUNIT * 2)
t = -1;
{
t = -1;
}
else if (finetangent[i] < -FRACUNIT * 2)
t = viewwidth + 1;
{
t = viewwidth + 1;
}
else
{
t = fixed_mul(finetangent[i], focallength);
t = (centerxfrac - t + FRACUNIT - 1) >> FRACBITS;
if (t < -1)
t = -1;
{
t = -1;
}
else if (t > viewwidth + 1)
t = viewwidth + 1;
{
t = viewwidth + 1;
}
}
viewangletox[i] = t;
@ -333,7 +367,10 @@ static void r_init_texture_mapping(void)
{
i = 0;
while (viewangletox[i] > x)
i++;
{
i++;
}
xtoviewangle[x] = (i << ANGLETOFINESHIFT) - ANG90;
}
@ -345,9 +382,13 @@ static void r_init_texture_mapping(void)
t = centerx - t;
if (viewangletox[i] == -1)
viewangletox[i] = 0;
{
viewangletox[i] = 0;
}
else if (viewangletox[i] == viewwidth + 1)
viewangletox[i] = viewwidth;
{
viewangletox[i] = viewwidth;
}
}
clipangle = xtoviewangle[0];
@ -376,14 +417,20 @@ int r_point_on_side(fixed_t x, fixed_t y, node_t *node)
if (!node->dx)
{
if (x <= node->x) return node->dy > 0;
if (x <= node->x)
{
return node->dy > 0;
}
return node->dy < 0;
}
if (!node->dy)
{
if (y <= node->y) return node->dx < 0;
if (y <= node->y)
{
return node->dx < 0;
}
return node->dx > 0;
}
@ -437,14 +484,20 @@ int r_point_on_seg_side(fixed_t x, fixed_t y, seg_t *line)
if (!ldx)
{
if (x <= lx) return ldy > 0;
if (x <= lx)
{
return ldy > 0;
}
return ldy < 0;
}
if (!ldy)
{
if (y <= ly) return ldx < 0;
if (y <= ly)
{
return ldx < 0;
}
return ldx > 0;
}
@ -491,7 +544,10 @@ angle_t r_point_to_angle(fixed_t x, fixed_t y)
x -= viewx;
y -= viewy;
if ((!x) && (!y)) return 0;
if ((!x) && (!y))
{
return 0;
}
if (x >= 0)
{
@ -664,12 +720,18 @@ fixed_t r_scale_from_global_angle(angle_t visangle)
scale = fixed_div(num, den);
if (scale > 64 * FRACUNIT)
scale = 64 * FRACUNIT;
{
scale = 64 * FRACUNIT;
}
else if (scale < 256)
scale = 256;
{
scale = 256;
}
}
else
scale = 64 * FRACUNIT;
{
scale = 64 * FRACUNIT;
}
return scale;
}
@ -685,6 +747,13 @@ fixed_t r_scale_from_global_angle(angle_t visangle)
void r_set_view_size(int blocks, int detail)
{
/* Reject invalid screen sizes before calculating view geometry. */
if (blocks < 3 || blocks > 11)
{
i_error("r_set_view_size: screenblocks=%d out of range", blocks);
}
setsizeneeded = true;
setblocks = blocks;
setdetail = detail;
@ -752,7 +821,9 @@ void r_execute_set_view_size(void)
/* thing clipping */
for (i = 0; i < viewwidth; i++)
screenheightarray[i] = viewheight;
{
screenheightarray[i] = viewheight;
}
/* planes */
@ -779,9 +850,15 @@ void r_execute_set_view_size(void)
level = startmap -
j * SCREENWIDTH / (viewwidth << detailshift) / DISTMAP;
if (level < 0) level = 0;
if (level < 0)
{
level = 0;
}
if (level >= NUMCOLORMAPS) level = NUMCOLORMAPS - 1;
if (level >= NUMCOLORMAPS)
{
level = NUMCOLORMAPS - 1;
}
scalelight[i][j] = colormaps + level * 256;
}
@ -828,7 +905,10 @@ subsector_t *r_point_in_subsector(fixed_t x, fixed_t y)
/* single subsector is a special case */
if (!numnodes) return subsectors;
if (!numnodes)
{
return subsectors;
}
nodenum = numnodes - 1;

View file

@ -58,11 +58,11 @@ planefunction_t ceilingfunc;
/* Here comes the obnoxious "visplane". */
visplane_t visplanes[CONFIG_GAMES_NXDOOM_MAXVISPLANES];
short openings[MAXOPENINGS];
visplane_t *lastvisplane;
visplane_t *floorplane;
visplane_t *ceilingplane;
short openings[MAXOPENINGS];
short *lastopening;
/* Clip values are the solid pixel bounding the range. floorclip starts out
@ -114,12 +114,21 @@ static void r_map_plane(int y, int x1, int x2)
fixed_t length;
unsigned index;
#ifdef CONFIG_GAMES_NXDOOM_RANGECHECK
if (x2 < x1 || x1 < 0 || x2 >= viewwidth || y > viewheight)
/* Ensure array indices are in range before access. */
if (x2 < x1 || x1 < 0 || x2 >= viewwidth)
{
i_error("R_MapPlane: %i, %i at %i", x1, x2, y);
return;
}
if (y < 0)
{
y = 0;
}
else if (y >= viewheight)
{
y = viewheight - 1;
}
#endif
if (planeheight != cachedheight[y])
{
@ -141,12 +150,17 @@ static void r_map_plane(int y, int x1, int x2)
ds_yfrac = -viewy - fixed_mul(finesine[angle], length);
if (fixedcolormap)
ds_colormap = fixedcolormap;
{
ds_colormap = fixedcolormap;
}
else
{
index = distance >> LIGHTZSHIFT;
if (index >= MAXLIGHTZ) index = MAXLIGHTZ - 1;
if (index >= MAXLIGHTZ)
{
index = MAXLIGHTZ - 1;
}
ds_colormap = planezlight[index];
}
@ -160,27 +174,42 @@ static void r_map_plane(int y, int x1, int x2)
spanfunc();
}
static inline boolean r_row_in_range(int row)
{
return row >= 0 && row < SCREENHEIGHT;
}
static void r_make_spans(int x, int t1, int b1, int t2, int b2)
{
/* Check that row is in range before indexing arrays. */
while (t1 < t2 && t1 <= b1)
{
r_map_plane(t1, spanstart[t1], x - 1);
r_map_plane(t1, r_row_in_range(t1) ? spanstart[t1] : 0, x - 1);
t1++;
}
while (b1 > b2 && b1 >= t1)
{
r_map_plane(b1, spanstart[b1], x - 1);
r_map_plane(b1, r_row_in_range(b1) ? spanstart[b1] : 0, x - 1);
b1--;
}
while (t2 < t1 && t2 <= b2)
{
spanstart[t2] = x;
if (r_row_in_range(t2))
{
spanstart[t2] = x;
}
t2++;
}
while (b2 > b1 && b2 >= t2)
{
spanstart[b2] = x;
if (r_row_in_range(b2))
{
spanstart[b2] = x;
}
b2--;
}
}
@ -251,10 +280,15 @@ visplane_t *r_find_plane(fixed_t height, int picnum, int lightlevel)
}
}
if (check < lastvisplane) return check;
if (check < lastvisplane)
{
return check;
}
if (lastvisplane - visplanes == CONFIG_GAMES_NXDOOM_MAXVISPLANES)
i_error("r_find_plane: no more visplanes");
{
i_error("r_find_plane: no more visplanes");
}
lastvisplane++;
@ -301,7 +335,10 @@ visplane_t *r_check_plane(visplane_t *pl, int start, int stop)
for (x = intrl; x <= intrh; x++)
{
if (pl->top[x] != 0xff) break;
if (pl->top[x] != 0xff)
{
break;
}
}
if (x > intrh)
@ -314,13 +351,15 @@ visplane_t *r_check_plane(visplane_t *pl, int start, int stop)
/* make a new visplane */
if (lastvisplane - visplanes == CONFIG_GAMES_NXDOOM_MAXVISPLANES)
{
i_error("r_check_plane: no more visplanes");
}
lastvisplane->height = pl->height;
lastvisplane->picnum = pl->picnum;
lastvisplane->lightlevel = pl->lightlevel;
if (lastvisplane - visplanes == CONFIG_GAMES_NXDOOM_MAXVISPLANES)
i_error("r_check_plane: no more visplanes");
pl = lastvisplane++;
pl->minx = start;
pl->maxx = stop;
@ -343,19 +382,29 @@ void r_draw_planes(void)
#ifdef CONFIG_GAMES_NXDOOM_RANGECHECK
if (ds_p - drawsegs > CONFIG_GAMES_NXDOOM_MAXDRAWSEGS)
i_error("r_draw_planes: drawsegs overflow (%td)", ds_p - drawsegs);
{
i_error("r_draw_planes: drawsegs overflow (%td)", ds_p - drawsegs);
}
if (lastvisplane - visplanes > CONFIG_GAMES_NXDOOM_MAXVISPLANES)
i_error("r_draw_planes: visplane overflow (%td)",
lastvisplane - visplanes);
{
i_error("r_draw_planes: visplane overflow (%td)",
lastvisplane - visplanes);
}
if (lastopening - openings > MAXOPENINGS)
i_error("r_draw_planes: opening overflow (%td)", lastopening - openings);
{
i_error("r_draw_planes: opening overflow (%td)",
lastopening - openings);
}
#endif
for (pl = visplanes; pl < lastvisplane; pl++)
{
if (pl->minx > pl->maxx) continue;
if (pl->minx > pl->maxx)
{
continue;
}
/* sky flat */
@ -395,9 +444,15 @@ void r_draw_planes(void)
planeheight = abs(pl->height - viewz);
light = (pl->lightlevel >> LIGHTSEGSHIFT) + extralight;
if (light >= LIGHTLEVELS) light = LIGHTLEVELS - 1;
if (light >= LIGHTLEVELS)
{
light = LIGHTLEVELS - 1;
}
if (light < 0) light = 0;
if (light < 0)
{
light = 0;
}
planezlight = zlight[light];

View file

@ -39,7 +39,7 @@
* Pre-processor Definitions
****************************************************************************/
#define MAX_CAPTURES 32
#define MAX_CAPTURES CONFIG_GAMES_NXDOOM_STATDUMP_MAX_CAPTURES
/****************************************************************************
* Private Data
@ -276,17 +276,25 @@ static void print_level_name(FILE *stream, int episode, int level)
switch (discovered_gamemission)
{
case doom:
fprintf(stream, "E%iM%i\n", episode + 1, level + 1);
break;
case doom2:
fprintf(stream, "MAP%02i\n", level + 1);
break;
default:
case none:
fprintf(stream, "E%iM%i / MAP%02i\n", episode + 1, level + 1,
level + 1);
break;
case doom:
{
fprintf(stream, "E%iM%i\n", episode + 1, level + 1);
break;
}
case doom2:
{
fprintf(stream, "MAP%02i\n", level + 1);
break;
}
default:
case none:
{
fprintf(stream, "E%iM%i / MAP%02i\n", episode + 1, level + 1,
level + 1);
break;
}
}
print_banner(stream);

View file

@ -57,6 +57,8 @@ void d_doom_main(void);
int main(int argc, char **argv)
{
i_install_quit_signal();
/* save arguments */
myargc = argc;

View file

@ -22,6 +22,8 @@
* Included Files
****************************************************************************/
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@ -75,6 +77,10 @@ static atexit_listentry_t *exit_funcs = NULL;
static boolean already_quitting = false;
/* Set by the signal handler and polled from the main loop. */
static volatile sig_atomic_t quit_requested = 0;
/* Read Access Violation emulation.
*
* From PrBoom+, by entryway.
@ -238,7 +244,9 @@ void i_print_banner(const char *msg)
int spaces = 35 - (strlen(msg) / 2);
for (i = 0; i < spaces; ++i)
putchar(' ');
{
putchar(' ');
}
puts(msg);
}
@ -320,6 +328,69 @@ void i_quit(void)
exit(0);
}
/****************************************************************************
* Name: i_quit_signal_handler
*
* Description:
* Records that a quit was requested. The work is deferred to
* i_poll_quit_signal() so that no cleanup runs from signal context.
*
****************************************************************************/
static void i_quit_signal_handler(int signo)
{
(void)signo;
quit_requested = 1;
}
/****************************************************************************
* Name: i_install_quit_signal
*
* Description:
* Installs the SIGTERM handler used to request a clean exit.
*
****************************************************************************/
void i_install_quit_signal(void)
{
struct sigaction sa;
/* Reset state left by an earlier built-in run. */
quit_requested = 0;
exit_funcs = NULL;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = i_quit_signal_handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGTERM, &sa, NULL) < 0)
{
/* Not fatal: the game runs, it just cannot be asked to exit. */
printf("nxdoom: failed to install SIGTERM handler: %d\n",
errno);
}
}
/****************************************************************************
* Name: i_poll_quit_signal
*
* Description:
* Exits if a quit was requested. Called from the main loop, where the
* cleanup i_quit() performs is safe to run.
*
****************************************************************************/
void i_poll_quit_signal(void)
{
if (quit_requested)
{
printf("nxdoom: quit signal seen, calling i_quit\n");
i_quit();
}
}
void i_error(const char *error, ...)
{
char msgbuf[512];
@ -463,19 +534,27 @@ boolean i_get_memory_value(unsigned int offset, void *value, int size)
switch (size)
{
case 1:
*((unsigned char *)value) = dos_mem_dump[offset];
return true;
case 2:
*((unsigned short *)value) =
dos_mem_dump[offset] | (dos_mem_dump[offset + 1] << 8);
return true;
case 4:
*((unsigned int *)value) =
dos_mem_dump[offset] | (dos_mem_dump[offset + 1] << 8) |
(dos_mem_dump[offset + 2] << 16) |
(dos_mem_dump[offset + 3] << 24);
return true;
case 1:
{
*((unsigned char *)value) = dos_mem_dump[offset];
return true;
}
case 2:
{
*((unsigned short *)value) = dos_mem_dump[offset] |
(dos_mem_dump[offset + 1] << 8);
return true;
}
case 4:
{
*((unsigned int *)value) = dos_mem_dump[offset] |
(dos_mem_dump[offset + 1] << 8) |
(dos_mem_dump[offset + 2] << 16) |
(dos_mem_dump[offset + 3] << 24);
return true;
}
}
return false;

View file

@ -73,6 +73,26 @@ ticcmd_t *i_base_ticcmd(void);
void i_quit(void) NORETURN;
/****************************************************************************
* Name: i_install_quit_signal
*
* Description:
* Install the SIGTERM handler used to request a clean exit.
*
****************************************************************************/
void i_install_quit_signal(void);
/****************************************************************************
* Name: i_poll_quit_signal
*
* Description:
* Exit if SIGTERM requested a clean shutdown.
*
****************************************************************************/
void i_poll_quit_signal(void);
void i_error(const char *error, ...) NORETURN PRINTF_ATTR(1, 2);
void i_tactile(int on, int off, int total);

View file

@ -105,6 +105,11 @@ struct graphics_state_s
unsigned outw;
unsigned outh;
/* Scaled image origin in pixels; origin is the byte offset. */
unsigned outx;
unsigned outy;
/* Maps an output column onto the source column it is drawn from, so that
* the inner loop needs neither a division nor a separate case for
* fractional scaling.
@ -487,6 +492,25 @@ static void blit_screen(void)
prevsy = sy;
prevrow = out;
}
#ifdef CONFIG_FB_UPDATE
/* Notify cached or DMA-backed frame buffers after drawing. */
{
struct fb_area_s area;
area.x = g_graphics_state.outx;
area.y = g_graphics_state.outy;
area.w = outw;
area.h = outh;
if (ioctl(g_graphics_state.fd, FBIO_UPDATE,
(unsigned long)((uintptr_t)&area)) < 0)
{
i_error("ioctl(FBIO_UPDATE) failed: %d\n", errno);
}
}
#endif
}
static void update_grab(void)
@ -586,9 +610,15 @@ void i_finish_update(void)
int tics;
int i;
if (!g_graphics_state.inited) return;
if (!g_graphics_state.inited)
{
return;
}
if (noblit) return;
if (noblit)
{
return;
}
/* draws little dots on the bottom of the screen */
@ -597,12 +627,20 @@ void i_finish_update(void)
i = i_get_time();
tics = i - lasttic;
lasttic = i;
if (tics > 20) tics = 20;
if (tics > 20)
{
tics = 20;
}
for (i = 0; i < tics * 4; i += 4)
i_video_buffer[(SCREENHEIGHT - 1) * SCREENWIDTH + i] = 0xff;
{
i_video_buffer[(SCREENHEIGHT - 1) * SCREENWIDTH + i] = 0xff;
}
for (; i < 20 * 4; i += 4)
i_video_buffer[(SCREENHEIGHT - 1) * SCREENWIDTH + i] = 0x0;
{
i_video_buffer[(SCREENHEIGHT - 1) * SCREENWIDTH + i] = 0x0;
}
}
/* Draw disk icon before blit, if necessary. */
@ -830,6 +868,7 @@ void i_graphics_check_commandline(void)
if (i > 0)
{
int display = atoi(myargv[i + 1]);
if (display >= 0)
{
video_display = display;
@ -936,13 +975,12 @@ void i_init_graphics(void)
g_graphics_state.outh = SCREENHEIGHT * g_graphics_state.scale;
#endif
/* Centre the scaled image in the frame buffer */
/* Center after the plane stride and pixel size are known. */
g_graphics_state.origin =
(g_graphics_state.vinfo.yres - g_graphics_state.outh) / 2 *
g_graphics_state.pinfo.stride +
(g_graphics_state.vinfo.xres - g_graphics_state.outw) / 2 *
(g_graphics_state.pinfo.bpp >> 3);
g_graphics_state.outx =
(g_graphics_state.vinfo.xres - g_graphics_state.outw) / 2;
g_graphics_state.outy =
(g_graphics_state.vinfo.yres - g_graphics_state.outh) / 2;
/* Build the output column to source column map once */
@ -965,6 +1003,10 @@ void i_init_graphics(void)
i_error("ioctl(FBIOGET_PLANEINFO) failed: %d\n", errno);
}
g_graphics_state.origin =
g_graphics_state.outy * g_graphics_state.pinfo.stride +
g_graphics_state.outx * (g_graphics_state.pinfo.bpp >> 3);
/* Initialize frame buffer memory for actual rendering */
g_graphics_state.fbmem =