From 6a723cff5853a1d644377f3cb01011947bfb0645 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 24 Jan 2023 16:10:01 +0000 Subject: [PATCH] Support for user-specified minimap bounds The totally-not-a-secret reason I made this branch. - doomednum 770 (associated with polyobject anchors 760/761 and skybox centerpoint 780) - Place exactly two in a map to draw an implicit rectangle. - Supports top-left/bottom-right AND bottom-left/top-right placements. - I_Errors if you place too many (or only one). - You don't *have* to have these, this is just a bonus if you're a map like Power Plant or CDSS1 negatively affected by your skybox. --- src/deh_tables.c | 1 + src/info.c | 27 +++++++++++++++++ src/info.h | 1 + src/p_local.h | 1 - src/p_setup.c | 79 ++++++++++++++++++++++++++++++++++++------------ 5 files changed, 88 insertions(+), 21 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 4761c96e7..69a4e0caa 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5273,6 +5273,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_ANGLEMAN", "MT_POLYANCHOR", "MT_POLYSPAWN", + "MT_MINIMAPBOUND", // Skybox objects "MT_SKYBOX", diff --git a/src/info.c b/src/info.c index 592487f3e..063c48220 100644 --- a/src/info.c +++ b/src/info.c @@ -21497,6 +21497,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_MINIMAPBOUND + 770, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 12*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 10, // mass + 0, // damage + sfx_None, // activesound + MF_SCENERY|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + { // MT_SKYBOX 780, // doomednum S_INVISIBLE, // spawnstate diff --git a/src/info.h b/src/info.h index 2b768691d..fb932676d 100644 --- a/src/info.h +++ b/src/info.h @@ -6340,6 +6340,7 @@ typedef enum mobj_type MT_ANGLEMAN, MT_POLYANCHOR, MT_POLYSPAWN, + MT_MINIMAPBOUND, // Skybox objects MT_SKYBOX, diff --git a/src/p_local.h b/src/p_local.h index 3ffbae9c1..6f0577767 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -507,7 +507,6 @@ extern mobj_t **blocklinks; // for thing chains extern struct minimapinfo { patch_t *minimap_pic; - UINT8 mapthingcount; INT32 min_x, min_y; INT32 max_x, max_y; INT32 map_w, map_h; diff --git a/src/p_setup.c b/src/p_setup.c index 35243b09c..f7d27dc1c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7349,6 +7349,7 @@ struct minimapinfo minimapinfo; static void P_InitMinimapInfo(void) { + size_t i, count; fixed_t a; fixed_t b; @@ -7356,29 +7357,67 @@ static void P_InitMinimapInfo(void) minimapinfo.minimap_pic = mapheaderinfo[gamemap-1]->minimapPic; - minimapinfo.mapthingcount = 0; - // TODO iterate over mapthings to look for possible user-defined bounds + minimapinfo.min_x = minimapinfo.max_x = minimapinfo.min_y = minimapinfo.max_y = INT32_MAX; + count = 0; + for (i = 0; i < nummapthings; i++) + { + if (mapthings[i].type != mobjinfo[MT_MINIMAPBOUND].doomednum) + continue; + count++; - minimapinfo.min_x = bsp->bbox[0][BOXLEFT]; - minimapinfo.max_x = bsp->bbox[0][BOXRIGHT]; - minimapinfo.min_y = bsp->bbox[0][BOXBOTTOM]; - minimapinfo.max_y = bsp->bbox[0][BOXTOP]; + if (mapthings[i].x < minimapinfo.min_x) + { + minimapinfo.max_x = minimapinfo.min_x; + minimapinfo.min_x = mapthings[i].x; + } + else + { + minimapinfo.max_x = mapthings[i].x; + } - if (bsp->bbox[1][BOXLEFT] < minimapinfo.min_x) - minimapinfo.min_x = bsp->bbox[1][BOXLEFT]; - if (bsp->bbox[1][BOXRIGHT] > minimapinfo.max_x) - minimapinfo.max_x = bsp->bbox[1][BOXRIGHT]; - if (bsp->bbox[1][BOXBOTTOM] < minimapinfo.min_y) - minimapinfo.min_y = bsp->bbox[1][BOXBOTTOM]; - if (bsp->bbox[1][BOXTOP] > minimapinfo.max_y) - minimapinfo.max_y = bsp->bbox[1][BOXTOP]; + if (mapthings[i].y < minimapinfo.min_y) + { + minimapinfo.max_y = minimapinfo.min_y; + minimapinfo.min_y = mapthings[i].y; + } + else + { + minimapinfo.max_y = mapthings[i].y; + } + } - // You might be wondering why these are being bitshift here - // it's because mapwidth and height would otherwise overflow for maps larger than half the size possible... - // map boundaries and sizes will ALWAYS be whole numbers thankfully - // later calculations take into consideration that these are actually not in terms of FRACUNIT though - minimapinfo.map_w = (minimapinfo.max_x >>= FRACBITS) - (minimapinfo.min_x >>= FRACBITS); - minimapinfo.map_h = (minimapinfo.max_y >>= FRACBITS) - (minimapinfo.min_y >>= FRACBITS); + if (count == 0) + { + minimapinfo.min_x = bsp->bbox[0][BOXLEFT]; + minimapinfo.max_x = bsp->bbox[0][BOXRIGHT]; + minimapinfo.min_y = bsp->bbox[0][BOXBOTTOM]; + minimapinfo.max_y = bsp->bbox[0][BOXTOP]; + + if (bsp->bbox[1][BOXLEFT] < minimapinfo.min_x) + minimapinfo.min_x = bsp->bbox[1][BOXLEFT]; + if (bsp->bbox[1][BOXRIGHT] > minimapinfo.max_x) + minimapinfo.max_x = bsp->bbox[1][BOXRIGHT]; + if (bsp->bbox[1][BOXBOTTOM] < minimapinfo.min_y) + minimapinfo.min_y = bsp->bbox[1][BOXBOTTOM]; + if (bsp->bbox[1][BOXTOP] > minimapinfo.max_y) + minimapinfo.max_y = bsp->bbox[1][BOXTOP]; + + // You might be wondering why these are being bitshift here + // it's because mapwidth and height would otherwise overflow for maps larger than half the size possible... + // map boundaries and sizes will ALWAYS be whole numbers thankfully + // later calculations take into consideration that these are actually not in terms of FRACUNIT though + minimapinfo.min_x >>= FRACBITS; + minimapinfo.max_x >>= FRACBITS; + minimapinfo.min_y >>= FRACBITS; + minimapinfo.max_y >>= FRACBITS; + } + else if (count != 2) + { + I_Error("P_InitMinimapInfo: Too %s minimap helper objects! (found %s of mapthingnum %d, should have 2)", + (count < 2 ? "few" : "many"), sizeu1(count), mobjinfo[MT_MINIMAPBOUND].doomednum); + } + minimapinfo.map_w = minimapinfo.max_x - minimapinfo.min_x; + minimapinfo.map_h = minimapinfo.max_y - minimapinfo.min_y; minimapinfo.minimap_w = minimapinfo.minimap_h = 100;