pkgsrc-WIP-changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
doomlegacy-devel: Full UMAPINFO support
Module Name: pkgsrc-wip
Committed By: Michael Baeuerle <micha%NetBSD.org@localhost>
Pushed By: micha
Date: Fri Mar 24 12:08:29 2023 +0100
Changeset: 0b28f792144f2c9d4241b70f0ab6e2da9281c68d
Modified Files:
doomlegacy-devel/TODO
doomlegacy-devel/distinfo
doomlegacy-devel/files/umapinfo.c
doomlegacy-devel/files/umapinfo.h
doomlegacy-devel/patches/patch-src_f__finale.c
doomlegacy-devel/patches/patch-src_g__game.c
doomlegacy-devel/patches/patch-src_p__info.c
doomlegacy-devel/patches/patch-src_w__wad.c
doomlegacy-devel/patches/patch-src_wi__stuff.c
Added Files:
doomlegacy-devel/patches/patch-src_d__main.c
doomlegacy-devel/patches/patch-src_m__menu.c
doomlegacy-devel/patches/patch-src_p__enemy.c
Log Message:
doomlegacy-devel: Full UMAPINFO support
To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=0b28f792144f2c9d4241b70f0ab6e2da9281c68d
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
diffstat:
doomlegacy-devel/TODO | 4 +-
doomlegacy-devel/distinfo | 13 +-
doomlegacy-devel/files/umapinfo.c | 274 +++++++++++++++----------
doomlegacy-devel/files/umapinfo.h | 29 +--
doomlegacy-devel/patches/patch-src_d__main.c | 15 ++
doomlegacy-devel/patches/patch-src_f__finale.c | 39 +++-
doomlegacy-devel/patches/patch-src_g__game.c | 33 ++-
doomlegacy-devel/patches/patch-src_m__menu.c | 100 +++++++++
doomlegacy-devel/patches/patch-src_p__enemy.c | 200 ++++++++++++++++++
doomlegacy-devel/patches/patch-src_p__info.c | 106 +++++++---
doomlegacy-devel/patches/patch-src_w__wad.c | 28 ++-
doomlegacy-devel/patches/patch-src_wi__stuff.c | 267 +++++++++++++++++++++++-
12 files changed, 910 insertions(+), 198 deletions(-)
diffs:
diff --git a/doomlegacy-devel/TODO b/doomlegacy-devel/TODO
index 7e4633113e..6cda9c720c 100644
--- a/doomlegacy-devel/TODO
+++ b/doomlegacy-devel/TODO
@@ -10,8 +10,8 @@ Part 25: Add UMAPINFO support
=============================
[X] Based on libdoom-umapinfo-1.0.0
=> Module to parse and import data added
-[ ] Hook keys into game engine
- => All keys except 'enterpic', "emenu' and 'bossactions' should work now
+[X] Hook keys into game engine
+ => All keys should work now, up to the limits of the engine
EOF
diff --git a/doomlegacy-devel/distinfo b/doomlegacy-devel/distinfo
index 714741f84c..8fe4448f02 100644
--- a/doomlegacy-devel/distinfo
+++ b/doomlegacy-devel/distinfo
@@ -6,14 +6,17 @@ Size (doomlegacy_1.48.12_common.zip) = 1055689 bytes
SHA1 (patch-make__options__nix) = 666e4242f07d4d3e42da3b395cf95f07ed3b4c70
SHA1 (patch-src_Makefile) = 7921393b6c4941fd02d9644836991c30b0fb3188
SHA1 (patch-src_am__map.c) = 14b3c8b70c63778ad043827ab2f0b6f4fe07bcde
+SHA1 (patch-src_d__main.c) = b182f7c74899f63cc85dffca03d4e9450389fb21
SHA1 (patch-src_d__player.h) = 5975ea8a714aeb10dcecc7fd42fffcb8f9a2e51b
SHA1 (patch-src_doomstat.h) = baa7387b6271d3064c12e24aaadf40cdb383e395
-SHA1 (patch-src_f__finale.c) = 6de35c080709d6c0fc9e72b46f7c558cc5605de5
+SHA1 (patch-src_f__finale.c) = 675772336bd091ecdcfd32244821b7ae6fc951f6
SHA1 (patch-src_f__finale.h) = 5ba7ae568be4dd97d06e4724dc7e1907f3a09cd8
-SHA1 (patch-src_g__game.c) = c5168003940fff0bfcf2db1937e217f65a911a4d
-SHA1 (patch-src_p__info.c) = 6f13050349238ccabe02b7c1bb1996c5c971fa31
+SHA1 (patch-src_g__game.c) = 1307a1dc8518646aaca9b136819ddd3e13d2b947
+SHA1 (patch-src_m__menu.c) = 7e8b564800c9b3b75f96dae3d9216f8cd6dc195f
+SHA1 (patch-src_p__enemy.c) = 66627e696d01381e8fd772f4d52e5332bcd2399b
+SHA1 (patch-src_p__info.c) = 9a8061b1d183374f1ea3678c6a0ad762ff12f8bd
SHA1 (patch-src_p__info.h) = e24772efb6b42ad5b834b1c12477f2a2feb508aa
SHA1 (patch-src_p__setup.c) = 77ef2316b3d5ac72274ccfcf6bff3229a9245997
-SHA1 (patch-src_w__wad.c) = 237489b5d19e89e36dbf6720467d910cd7b72aa9
+SHA1 (patch-src_w__wad.c) = e410639b34e0b4ac763a41bb5aebaf6993e04d19
SHA1 (patch-src_w__wad.h) = 683283a32222e96a6472f103d3dc51e7229e4753
-SHA1 (patch-src_wi__stuff.c) = 380fdfc31975cad0624460561142ffa22e1233c4
+SHA1 (patch-src_wi__stuff.c) = f708ff6160762862a00fca9d52219ec649c59dfc
diff --git a/doomlegacy-devel/files/umapinfo.c b/doomlegacy-devel/files/umapinfo.c
index 5d43ff1f95..4296533af6 100644
--- a/doomlegacy-devel/files/umapinfo.c
+++ b/doomlegacy-devel/files/umapinfo.c
@@ -1,4 +1,4 @@
-//----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
//
// Copyright(C) 2023 by DooM Legacy Team
//
@@ -15,7 +15,7 @@
// DESCRIPTION:
// Support for additional map information in UMAPINFO format.
//
-//----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
// [MB] 2023-01-21: Support for Rev 2.2 added
// Description of UMAPINFO lump format:
@@ -42,10 +42,13 @@
#include "z_zone.h"
-// UMAPINFO data in local format
-umapinfo_t umapinfo = { NULL };
+// Internal representation of UMAPINFO data (merged from PWADs)
+umapinfo_t umapinfo = { NULL, NULL, false };
+// -----------------------------------------------------------------------------
+// Memory management
+
static void *UMI_Malloc(size_t memsize)
{
return Z_Malloc(memsize, PU_STATIC, 0);
@@ -59,49 +62,8 @@ static void UMI_Free(void *ptr)
}
-static void UMI_InitMapEntry(mapentry_t *entry,
- unsigned int episode, unsigned int map)
-{
- entry->next = NULL;
-
- entry->author = NULL;
- entry->label = NULL;
- entry->levelname = NULL;
- entry->intertext = NULL;
- entry->intertextsecret = NULL;
- entry->interbackdrop = NULL;
- entry->intermusic = NULL;
- entry->nextmap = NULL;
- entry->nextsecret = NULL;
- entry->music = NULL;
- entry->skytexture = NULL;
- entry->levelpic = NULL;
- entry->exitpic = NULL;
- entry->enterpic = NULL;
- entry->endpic = NULL;
- entry->emenu = NULL;
- entry->bossactions = NULL;
- entry->endgame = unchanged;
- entry->episode = episode;
- entry->map = map;
- entry->partime = 0;
- entry->emenu_clear = false;
- entry->bossactions_clear = false;
- entry->nointermission = false;
- entry->endbunny = false;
- entry->endcast = false;
-}
-
-
-static void UMI_InitBossActionEntry(bossaction_t *entry)
-{
- entry->next = NULL;
-
- entry->thing = 0;
- entry->special = 0;
- entry->tag = 0;
-}
-
+// -----------------------------------------------------------------------------
+// Constructors and destructors
static void UMI_InitEpisodeMenuEntry(emenu_t *entry)
{
@@ -128,6 +90,16 @@ static void UMI_DestroyEpisodeMenu(emenu_t *entry)
}
+static void UMI_InitBossActionEntry(bossaction_t *entry)
+{
+ entry->next = NULL;
+
+ entry->thing = 0;
+ entry->special = 0;
+ entry->tag = 0;
+}
+
+
static void UMI_DestroyBossActions(bossaction_t *entry)
{
while (NULL != entry)
@@ -140,6 +112,38 @@ static void UMI_DestroyBossActions(bossaction_t *entry)
}
+static void UMI_InitMapEntry(mapentry_t *entry,
+ unsigned int episode, unsigned int map)
+{
+ entry->next = NULL;
+
+ entry->author = NULL;
+ entry->label = NULL;
+ entry->levelname = NULL;
+ entry->intertext = NULL;
+ entry->intertextsecret = NULL;
+ entry->interbackdrop = NULL;
+ entry->intermusic = NULL;
+ entry->nextmap = NULL;
+ entry->nextsecret = NULL;
+ entry->music = NULL;
+ entry->skytexture = NULL;
+ entry->levelpic = NULL;
+ entry->exitpic = NULL;
+ entry->enterpic = NULL;
+ entry->endpic = NULL;
+ entry->bossactions = NULL;
+ entry->endgame = unchanged;
+ entry->episode = episode;
+ entry->map = map;
+ entry->partime = 0;
+ entry->bossactions_clear = false;
+ entry->nointermission = false;
+ entry->endbunny = false;
+ entry->endcast = false;
+}
+
+
static void UMI_DestroyMaps(mapentry_t *entry)
{
while (NULL != entry)
@@ -161,7 +165,6 @@ static void UMI_DestroyMaps(mapentry_t *entry)
UMI_Free((void*) entry->exitpic);
UMI_Free((void*) entry->enterpic);
UMI_Free((void*) entry->endpic);
- UMI_DestroyEpisodeMenu(entry->emenu);
UMI_DestroyBossActions(entry->bossactions);
UMI_Free(entry);
entry = tmp;
@@ -169,6 +172,9 @@ static void UMI_DestroyMaps(mapentry_t *entry)
}
+// -----------------------------------------------------------------------------
+// Access functions for key values
+
// On error, 0 is returned
static unsigned int UMI_GetNumber(doom_umi1_ts_state state)
{
@@ -381,6 +387,9 @@ static void UMI_ReplaceMultiStringClear(doom_umi1_ts_state state,
}
+// -----------------------------------------------------------------------------
+// Episode menu
+
// Returns true on success
static boolean UMI_PopulateEpisodeMenuEntry(doom_umi1_ts_state state,
emenu_t *entry)
@@ -453,6 +462,7 @@ static boolean UMI_AppendEpisodeMenuEntry(doom_umi1_ts_state state,
}
else
{
+ // Append episode menu entry to list
if (NULL == *em)
*em = entry;
else
@@ -471,6 +481,9 @@ static boolean UMI_AppendEpisodeMenuEntry(doom_umi1_ts_state state,
}
+// -----------------------------------------------------------------------------
+// Boss actions
+
// Returns true on success
static boolean UMI_PopulateBossActionEntry(doom_umi1_ts_state state,
bossaction_t *entry)
@@ -498,6 +511,7 @@ static boolean UMI_PopulateBossActionEntry(doom_umi1_ts_state state,
}
+// Returns true if identifier 'clear' was detected
static boolean UMI_MergeBossAction(doom_umi1_ts_state state,
bossaction_t** ba, size_t valcount)
{
@@ -544,11 +558,49 @@ static boolean UMI_MergeBossAction(doom_umi1_ts_state state,
}
+// -----------------------------------------------------------------------------
+// Import data
+
+// Check whether map entry object for episode/map already exists
+// If not, create an empty map entry object
+static mapentry_t *UMI_GetMapEntry(unsigned int episode, unsigned int map)
+{
+ mapentry_t *entry = umapinfo.entry_first;
+ mapentry_t *entry_last = NULL;
+
+ while (NULL != entry)
+ {
+ entry_last = entry;
+ if (episode == entry->episode && map == entry->map)
+ break;
+
+ entry = entry->next;
+ }
+
+ if (NULL == entry)
+ {
+ // Not found, create new entry
+ entry = UMI_Malloc(sizeof(mapentry_t));
+ if (NULL != entry)
+ {
+ UMI_InitMapEntry(entry, episode, map);
+ if (NULL == umapinfo.entry_first)
+ umapinfo.entry_first = entry;
+ else
+ entry_last->next = entry;
+ }
+ }
+
+ return entry;
+}
+
+
static void UMI_StoreKeyData(doom_umi1_ts_state state, mapentry_t *entry)
{
- size_t key = 0;
- int retval = doom_umi1_ts_key_read(state, NULL, &key);
- size_t valcount = 0;
+ size_t key = 0;
+ int retval = doom_umi1_ts_key_read(state, NULL, &key);
+ size_t valcount = 0;
+ boolean emc = false; // Episode menu clear request
if (0 > retval)
{
@@ -612,12 +664,12 @@ static void UMI_StoreKeyData(doom_umi1_ts_state state, mapentry_t *entry)
UMI_ReplaceStringMax8(state, &entry->endpic);
break;
case DOOM_UMI1_KEY_EPISODE:
- entry->emenu_clear =
- UMI_AppendEpisodeMenuEntry(state, &entry->emenu, valcount);
+ // Associated with global episode list (not the map entry object)
+ emc = UMI_AppendEpisodeMenuEntry(state, &umapinfo.emenu, valcount);
break;
case DOOM_UMI1_KEY_BOSSACTION:
- entry->bossactions_clear =
- UMI_MergeBossAction(state, &entry->bossactions, valcount);
+ if (UMI_MergeBossAction(state, &entry->bossactions, valcount))
+ entry->bossactions_clear = true;
break;
case DOOM_UMI1_KEY_ENDGAME:
entry->endgame = UMI_GetNumber(state) ? enabled : disabled;
@@ -638,38 +690,10 @@ static void UMI_StoreKeyData(doom_umi1_ts_state state, mapentry_t *entry)
GenPrintf(EMSG_warn, "UMAPINFO: Unknown key ignored\n");
break;
}
-}
-
-
-static mapentry_t *UMI_GetMapEntry(unsigned int episode, unsigned int map)
-{
- mapentry_t *entry = umapinfo.entry_first;
- mapentry_t *entry_last = NULL;
-
- while (NULL != entry)
- {
- entry_last = entry;
- if (episode == entry->episode && map == entry->map)
- break;
-
- entry = entry->next;
- }
-
- if (NULL == entry)
- {
- // Not found, create new entry
- entry = UMI_Malloc(sizeof(mapentry_t));
- if (NULL != entry)
- {
- UMI_InitMapEntry(entry, episode, map);
- if (NULL == umapinfo.entry_first)
- umapinfo.entry_first = entry;
- else
- entry_last->next = entry;
- }
- }
- return entry;
+ // Store flag that default episode menu must be cleared
+ if (emc)
+ umapinfo.emenu_clear = true;
}
@@ -728,6 +752,11 @@ static void UMI_ImportUMapInfo(umapinfo_t *umi, doom_umi1_handle data)
}
+// -----------------------------------------------------------------------------
+// API
+
+// Import and merge UMAPINFO lump into current data
+// If parts of the new data are already present, they overwrite the current data
void UMI_LoadUMapInfoLump(lumpnum_t lumpnum)
{
doom_umi1_handle data = NULL; // libdoom-umapinfo UMAPINFO object handle
@@ -762,11 +791,18 @@ void UMI_LoadUMapInfoLump(lumpnum_t lumpnum)
void UMI_DestroyUMapInfo(void)
{
+ UMI_DestroyEpisodeMenu(umapinfo.emenu);
+ umapinfo.emenu = NULL;
+ umapinfo.emenu_clear = false;
+
UMI_DestroyMaps(umapinfo.entry_first);
umapinfo.entry_first = NULL;
}
+// Extract episode and map numbers from map name
+// For Doom 2 map names zero is returned for episode
+// Returns true on success (numbers are valid)
boolean UMI_ParseMapName(const char *name, byte *episode, byte *map)
{
boolean result = false;
@@ -795,6 +831,8 @@ boolean UMI_ParseMapName(const char *name, byte *episode, byte *map)
}
+// Search for UMAPINFO map entry that matches episode and map parameters
+// NULL is returned if nothing was found
mapentry_t *UMI_LookupUMapInfo(byte episode, byte map)
{
mapentry_t *entry = umapinfo.entry_first;
@@ -821,60 +859,52 @@ mapentry_t *UMI_LookupUMapInfo(byte episode, byte map)
}
-// The function S_AddMusic() will add a "d_" prefix
-const char* UMI_GetMusicLumpName(const char* name)
-{
- if (('d' == name[0] || 'D' == name[0]) && '_' == name[1])
- return &name[2];
- else
- return name;
-}
-
-
-// Called from: P_SetupLevel()
+// Load UMAPINFO data for current gameepisode/gamemap
void UMI_Load_LevelInfo(void)
{
gamemapinfo = UMI_LookupUMapInfo(gameepisode, gamemap);
// SMMU level info is replaced with UMAPINFO data, where possible
- if (NULL != gamemapinfo)
+ if (gamemapinfo)
{
- // For now only used by COM_MapInfo_f() for the command "mapinfo"
+ // Key author is handled by WI_Draw_LF() and WI_Draw_EL()
+ // Also mapped to info_creator for COM_MapInfo_f()
if (gamemapinfo->author)
info_creator = gamemapinfo->author;
- // label and levelname are handled by P_LevelName()
+ // Keys label and levelname are handled by P_LevelName()
- // intertext and intertextsecret are handled by F_StartFinale()
+ // Keys intertext and intertextsecret are handled by F_StartFinale()
- // interbackdrop is handled by F_StartFinale()
+ // Key interbackdrop is handled by F_StartFinale()
- // intermusic is handled by WI_Ticker()
+ // Key intermusic is handled by WI_Ticker()
- // nextmap and nextsecret are handled by G_DoUMapInfo()
+ // Keys nextmap and nextsecret are handled by G_DoUMapInfo()
+ // Key music is mapped to info_music
if (gamemapinfo->music)
info_music = UMI_GetMusicLumpName(gamemapinfo->music);
+ // Key skytexture is mapped to info_skyname
if (gamemapinfo->skytexture)
info_skyname = gamemapinfo->skytexture;
- if (gamemapinfo->levelpic)
- info_levelpic = gamemapinfo->levelpic;
+ // Key levelpic is handled by WI_Draw_LF() and WI_Draw_EL()
+ // Key exitpic is mapped to info_interpic
if (gamemapinfo->exitpic)
info_interpic = gamemapinfo->exitpic;
- // FIXME: enterpic is not handled yet
-
- // endpic is handled by F_Drawer()
+ // Key enterpic is handled by WI_Draw_ShowNextLoc()
- // XXX emenu is not handled yet
+ // Key endpic is handled by F_Drawer()
- // XXX bossactions is not handled yet
+ // Key bossactions is handled by A_Bosstype_Death()
- // endgame is handled by G_NextLevel()
+ // Key endgame is handled by G_NextLevel()
+ // Key partime is mapped to info_partime
if (gamemapinfo->partime)
{
if ((unsigned int) INT_MAX < gamemapinfo->partime)
@@ -887,12 +917,27 @@ void UMI_Load_LevelInfo(void)
}
+// Strip "d_" prefix from lump name, if present
+//�(because the�function�S_AddMusic()�adds�a�"d_"�prefix)
+// Returns a pointer into name
+const char* UMI_GetMusicLumpName(const char* name)
+{
+ if (('d' == name[0] || 'D' == name[0]) && '_' == name[1])
+ return &name[2];
+ else
+ return name;
+}
+
+
#else // HAVE_LIBDOOM_UMAPINFO
#include "doomincl.h"
+// -----------------------------------------------------------------------------
+// API stubs (if libdoom-umapinfo is not available)
+
void UMI_LoadUMapInfoLump(lumpnum_t lumpnum)
{
GenPrintf(EMSG_warn, "UMAPINFO: Ignored (libdoom-umapinfo is required)\n");
@@ -923,4 +968,9 @@ void UMI_Load_LevelInfo(void)
}
+const�char*�UMI_GetMusicLumpName(const�char*�name)
+{
+ return name;
+}
+
#endif // HAVE_LIBDOOM_UMAPINFO
diff --git a/doomlegacy-devel/files/umapinfo.h b/doomlegacy-devel/files/umapinfo.h
index c45a3fb773..7f0ed9f535 100644
--- a/doomlegacy-devel/files/umapinfo.h
+++ b/doomlegacy-devel/files/umapinfo.h
@@ -1,4 +1,4 @@
-//----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
//
// Copyright(C) 2023 by DooM Legacy Team
//
@@ -15,7 +15,7 @@
// DESCRIPTION:
// Support for additional map information in UMAPINFO format.
//
-//----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
#ifndef UMAPINFO_H
#define UMAPINFO_H
@@ -76,13 +76,11 @@ struct mapentry_t
const char *exitpic;
const char *enterpic;
const char *endpic;
- emenu_t *emenu; // Linked list
bossaction_t *bossactions; // Linked list
tristate_t endgame; // Can be undefined, false or true
unsigned int episode;
unsigned int map;
unsigned int partime;
- boolean emenu_clear; // Clear all default episode menu entries
boolean bossactions_clear; // Clear all default boss actions
boolean nointermission; // Skip the 'level finished' screen
boolean endbunny; // End game after level, show bunny
@@ -90,42 +88,35 @@ struct mapentry_t
};
-typedef struct
+typedef struct umapinfo_t umapinfo_t;
+struct umapinfo_t
{
mapentry_t *entry_first; // Linked list
-} umapinfo_t;
+
+ emenu_t *emenu; // Linked list
+ boolean emenu_clear; // Clear all default episode menu entries
+};
-// Current data (merged from PWADs)
extern umapinfo_t umapinfo;
-// Import and merge UMAPINFO lump into current data
-// If parts of the new data are already present, they overwrite the current data
void UMI_LoadUMapInfoLump(lumpnum_t lumpnum);
-// Destory current data
void UMI_DestroyUMapInfo(void);
-// Extract episode and map numbers from map name
-// For Doom 2 map names zero is returned for episode
-// Returns true on success (numbers are valid)
boolean UMI_ParseMapName(const char *mapname, byte *episode, byte * map);
-// Search for UMAPINFO map entry that matches episode and map parameters
-// NULL is returned if nothing was found
mapentry_t *UMI_LookupUMapInfo(byte episode, byte map);
-// Returns the position after "D_" prefix (if present) or the start of name
-const char* UMI_GetMusicLumpName(const char* name);
+void UMI_Load_LevelInfo(void);
-// Load UMAPINFO data for current gameepisode/gamemap
-void UMI_Load_LevelInfo(void);
+const char* UMI_GetMusicLumpName(const char* name);
#endif // UMAPINFO_H
diff --git a/doomlegacy-devel/patches/patch-src_d__main.c b/doomlegacy-devel/patches/patch-src_d__main.c
new file mode 100644
index 0000000000..f5d15f72d8
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_d__main.c
@@ -0,0 +1,15 @@
+$NetBSD$
+
+--- src/d_main.c.orig 2023-03-19 11:31:58.068883902 +0000
++++ src/d_main.c
+@@ -3570,6 +3570,10 @@ void D_Quit_Save ( quit_severity_e sever
+ void I_Quit (void)
+ {
+ D_Quit_Save( QUIT_normal );
++
++ // [MB] 2023-03-19: Support for UMAPINFO added
++ UMI_DestroyUMapInfo();
++
+ I_Quit_System(); // No Return
+ }
+
diff --git a/doomlegacy-devel/patches/patch-src_f__finale.c b/doomlegacy-devel/patches/patch-src_f__finale.c
index a33a3d0f95..a67b322a4d 100644
--- a/doomlegacy-devel/patches/patch-src_f__finale.c
+++ b/doomlegacy-devel/patches/patch-src_f__finale.c
@@ -2,7 +2,7 @@ $NetBSD$
Add support for UMAPINFO.
---- src/f_finale.c.orig 2023-01-10 10:38:38.000000000 +0000
+--- src/f_finale.c.orig 2023-02-26 17:42:28.000000000 +0000
+++ src/f_finale.c
@@ -75,8 +75,8 @@ int finalecount;
#define TEXTSPEED 3
@@ -85,15 +85,44 @@ Add support for UMAPINFO.
{
patch_t* pic = W_CachePatchName( name, PU_CACHE ); // endian fix
// Intercept some doom pictures that chex.wad left in (a young kids game).
-@@ -874,7 +899,10 @@ void F_Drawer (void)
+@@ -858,14 +883,14 @@ void F_Drawer (void)
+ // Draw to screen0, scaled
+ V_SetupDraw( 0 | V_SCALESTART | V_SCALEPATCH | V_CENTERHORZ );
+
+- if (finalestage == 2)
++ if( finalestage == 2 )
+ {
+- F_CastDrawer ();
++ F_CastDrawer();
+ return;
+ }
+
+- if (!finalestage)
+- F_TextWrite ();
++ if( !finalestage )
++ F_TextWrite();
+ else
+ {
+ if( gamemode == heretic )
+@@ -874,10 +899,13 @@ void F_Drawer (void)
}
else
{
- switch (gameepisode)
+ // [MB] 2023-02-05: Support for UMAPINFO added
-+ if (gamemapinfo && gamemapinfo->endpic)
++ if( gamemapinfo && gamemapinfo->endpic )
+ F_Draw_interpic_Name( gamemapinfo->endpic );
-+ else switch (gameepisode)
++ else switch( gameepisode )
{
case 1:
- if ( gamemode == ultdoom_retail || gamemode == chexquest1 )
+- if ( gamemode == ultdoom_retail || gamemode == chexquest1 )
++ if( gamemode == ultdoom_retail || gamemode == chexquest1 )
+ F_Draw_interpic_Name( text[CREDIT_NUM] );
+ else
+ F_Draw_interpic_Name( text[HELP2_NUM] );
+@@ -894,5 +922,4 @@ void F_Drawer (void)
+ }
+ }
+ }
+-
+ }
diff --git a/doomlegacy-devel/patches/patch-src_g__game.c b/doomlegacy-devel/patches/patch-src_g__game.c
index dac79bcaa4..e2f19356a3 100644
--- a/doomlegacy-devel/patches/patch-src_g__game.c
+++ b/doomlegacy-devel/patches/patch-src_g__game.c
@@ -2,7 +2,7 @@ $NetBSD$
Add support for UMAPINFO.
---- src/g_game.c.orig 2023-01-10 10:38:23.000000000 +0000
+--- src/g_game.c.orig 2023-02-26 17:42:09.000000000 +0000
+++ src/g_game.c
@@ -225,6 +225,7 @@ uint16_t demoversion_rev; // dem
skill_e gameskill;
@@ -12,7 +12,7 @@ Add support for UMAPINFO.
char game_map_filename[MAX_WADPATH]; // an external wad filename
-@@ -2384,10 +2385,74 @@ void G_DoCompleted (void)
+@@ -2384,10 +2385,80 @@ void G_DoCompleted (void)
automapactive = false;
}
@@ -24,6 +24,7 @@ Add support for UMAPINFO.
+ boolean result = false;
+
+ wminfo.epsd_next = wminfo.epsd;
++ wminfo.lev_next = wminfo.lev_prev + 1;
+ wminfo.lastmapinfo = gamemapinfo;
+ wminfo.nextmapinfo = NULL;
+
@@ -32,7 +33,7 @@ Add support for UMAPINFO.
+ const char *mapname = NULL;
+ int i = 0;
+
-+ // 'nextmap' or 'nextsecret' key overrides default behaviour
++ // Keys nextmap and nextsecret overrides default setup
+ if (secretexit && gamemapinfo->nextsecret)
+ {
+ mapname = gamemapinfo->nextsecret;
@@ -44,7 +45,7 @@ Add support for UMAPINFO.
+
+ if (mapname)
+ {
-+ result = true;
++ result = true; // UMAPINFO overrides default setup
+
+ {
+ byte e = 0;
@@ -76,6 +77,11 @@ Add support for UMAPINFO.
{
int i;
++ // [MB] 2023-01-22: Moved to beginning for G_DoUMapInfo()
++ // 0 based
++ wminfo.epsd = gameepisode - 1;
++ wminfo.lev_prev = gamemap - 1;
++
+ // [MB] 2023-01-22: Support for UMAPINFO added
+ {
+ boolean skip = G_DoUMapInfo();
@@ -87,7 +93,7 @@ Add support for UMAPINFO.
if (gamemode != doom2_commercial)
{
switch(gamemap)
-@@ -2401,7 +2466,7 @@ void G_Start_Intermission( void )
+@@ -2401,7 +2472,7 @@ void G_Start_Intermission( void )
// also for heretic
// disconnect from network
CL_Reset();
@@ -96,7 +102,7 @@ Add support for UMAPINFO.
return;
}
break; // [WDJ] 4/11/2012 map 8 is not secret level, and prboom and boom do not fall thru here.
-@@ -2421,7 +2486,7 @@ void G_Start_Intermission( void )
+@@ -2421,7 +2492,7 @@ void G_Start_Intermission( void )
else
{
CL_Reset();
@@ -105,7 +111,14 @@ Add support for UMAPINFO.
return;
}
}
-@@ -2436,7 +2501,7 @@ void G_Start_Intermission( void )
+@@ -2429,14 +2500,11 @@ void G_Start_Intermission( void )
+
+ if(!dedicated)
+ wminfo.didsecret = consoleplayer_ptr->didsecret;
+- // 0 based
+- wminfo.epsd = gameepisode -1;
+- wminfo.lev_prev = gamemap -1;
+
// go to next level
// wminfo.lev_next is 0 biased, unlike gamemap
wminfo.lev_next = gamemap;
@@ -114,7 +127,7 @@ Add support for UMAPINFO.
// overwrite next level in some cases
if (gamemode == doom2_commercial)
{
-@@ -2490,6 +2555,21 @@ void G_Start_Intermission( void )
+@@ -2490,6 +2558,21 @@ void G_Start_Intermission( void )
wminfo.lev_next = 0; // wrap around in deathmatch
}
}
@@ -136,7 +149,7 @@ Add support for UMAPINFO.
wminfo.maxkills = totalkills;
wminfo.maxitems = totalitems;
-@@ -2542,6 +2622,16 @@ void G_NextLevel (void)
+@@ -2542,6 +2625,16 @@ void G_NextLevel (void)
if( gamemap == 30 )
wminfo.lev_next = 0; // wrap around in deathmatch
}
@@ -153,7 +166,7 @@ Add support for UMAPINFO.
else
{
switch (gamemap)
-@@ -2557,7 +2647,7 @@ void G_NextLevel (void)
+@@ -2557,7 +2650,7 @@ void G_NextLevel (void)
if( gamemap == 30 )
CL_Reset(); // end of game disconnect from server
gameaction = ga_nothing;
diff --git a/doomlegacy-devel/patches/patch-src_m__menu.c b/doomlegacy-devel/patches/patch-src_m__menu.c
new file mode 100644
index 0000000000..c93a0065f6
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_m__menu.c
@@ -0,0 +1,100 @@
+$NetBSD$
+
+Add support for UMAPINFO.
+
+--- src/m_menu.c.orig 2023-02-26 17:42:09.000000000 +0000
++++ src/m_menu.c
+@@ -6300,6 +6300,83 @@ void M_Init (void)
+ CV_RegisterVar(&cv_oof_2s);
+ }
+
++
++// [MB] 2023-03-23: Modify episode menu with data from UMAPINFO
++// If clear is false, the new entries are appended to the existing menu
++static void M_EpisodeMenuFromUMAPINFO (void)
++{
++ boolean modified = false;
++ emenu_t * episode = umapinfo.emenu;
++
++ // Accept clear only for the first UMAPINFO map entry
++ if( umapinfo.emenu_clear )
++ {
++ modified = true;
++ EpiDef.numitems = 0;
++ GenPrintf(EMSG_debug, "UMAPINFO: Default episode menu cleared\n");
++ }
++
++ while( episode )
++ {
++ // UMAPINFO allows 8 episodes, currently only 5 are supported
++ if( EpiDef.numitems < 5 )
++ {
++ // EpisodeMenu[EpiDef.numitems].status is below
++ // FIXME: Cast to char* is ugly
++ // Is it possible to declared elements const in menuitem_t?
++ EpisodeMenu[EpiDef.numitems].patch = (char*)episode->patch;
++ EpisodeMenu[EpiDef.numitems].text = (char*)episode->name;
++ // EpisodeMenu[EpiDef.numitems].itemaction is not changed
++ if( episode->key[0] )
++ {
++ // UMAPINFO value is defined as quoted string
++ // The first character is used, if string is not empty
++ byte k = (byte)episode->key[0];
++
++ EpisodeMenu[EpiDef.numitems].alphaKey = k;
++ }
++ EpiDef.numitems++;
++ GenPrintf(EMSG_debug, "UMAPINFO: Episode entry added\n");
++ }
++ modified = true;
++ episode = episode->next;
++ }
++
++ // Use patches only if all episodes have a valid patch
++ if( modified )
++ {
++ boolean use_patches = true;
++ uint16_t i;
++
++ // FIXME: This should check if the patches are valid too
++ for( i = 0; i < EpiDef.numitems; i++ )
++ if( EpisodeMenu[i].patch == NULL )
++ use_patches = false;
++
++ GenPrintf(EMSG_debug, "UMAPINFO: Modified episode menu ");
++ if( use_patches )
++ GenPrintf(EMSG_debug, "(using patches):\n");
++ else
++ GenPrintf(EMSG_debug, "(using strings):\n");
++
++ for( i = 0; i < EpiDef.numitems; i++ )
++ {
++ GenPrintf(EMSG_debug, " Episode %u: ", (unsigned int) i + 1u);
++ if( use_patches )
++ GenPrintf(EMSG_debug, "%s\n", EpisodeMenu[i].patch);
++ else
++ GenPrintf(EMSG_debug, "%s\n", EpisodeMenu[i].text);
++
++ EpisodeMenu[i].status = IT_CALL;
++ if( use_patches )
++ EpisodeMenu[i].status |= IT_PATCH;
++ else
++ EpisodeMenu[i].status |= IT_STRING2;
++ }
++ }
++}
++
++
+ // Called once after gamemode has been determined, game dependent
+ void M_Configure (void)
+ {
+@@ -6382,6 +6459,9 @@ void M_Configure (void)
+ cv_nextmap.defaultvalue = "11";
+ // We need to remove the fifth episode.
+ EpiDef.numitems--;
++
++ // [MB] 2023-03-23: Support for UMAPINFO added
++ M_EpisodeMenuFromUMAPINFO();
+ break;
+ case heretic:
+ cv_nextmap.PossibleValue = exmy_cons_t;
diff --git a/doomlegacy-devel/patches/patch-src_p__enemy.c b/doomlegacy-devel/patches/patch-src_p__enemy.c
new file mode 100644
index 0000000000..2c6c4473a4
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_p__enemy.c
@@ -0,0 +1,200 @@
+$NetBSD$
+
+--- src/p_enemy.c.orig 2023-02-26 17:42:27.000000000 +0000
++++ src/p_enemy.c
+@@ -3401,6 +3401,66 @@ static state_t *P_FinalState(statenum_t
+ return &states[state];
+ }
+
++// [MB] 2023-03-19: Support for UMAPINFO added
++// Helper function for A_Bosstype_Death(), code is now used more than once
++// Returns false if no player is alive
++static boolean A_Player_Alive(void)
++{
++ boolean alive = true;
++ int i;
++
++ for( i = 0 ; i < MAXPLAYERS ; i++ )
++ if( playeringame[i] && players[i].health > 0 )
++ break;
++
++ if (i == MAXPLAYERS)
++ alive = false;
++
++ return alive;
++}
++
++// [MB] 2023-03-19: Support for UMAPINFO added
++// Helper function for A_Bosstype_Death(), code is now used more than once
++// Parameters are forwarded from A_Bosstype_Death().
++// Returns true if all other bosses (of same type as in parameter mo) are dead
++static boolean A_All_Bosses_Dead(mobj_t* mo, int boss_type)
++{
++ boolean dead = true;
++ thinker_t* th;
++ mobj_t* mo2;
++
++ for( th = thinkercap.next ; th != &thinkercap ; th = th->next )
++ {
++ if( th->function.acp1 != (actionf_p1)P_MobjThinker )
++ continue;
++
++ // Fixes MAP07 bug where if last arachnotron is killed while first
++ // still in death sequence, then both would trigger this code
++ // and the floor would be raised twice (bad).
++ mo2 = (mobj_t *)th;
++ // Check all boss of the same type
++ if ( mo2 != mo
++ && mo2->type == boss_type )
++ {
++ // Check if really dead and finished the death sequence.
++ // [WDJ] Corpse has health < 0.
++ // If two monsters are killed at the same time, this test may occur
++ // while first is corpse and second is not. But the simple health
++ // test may trigger twice because second monster already has
++ // health < 0 during the first death test.
++ if( mo2->health > 0 // the old test (doom original 1.9)
++ || !(mo2->flags & MF_CORPSE)
++ || mo2->state != P_FinalState(mo2->info->deathstate) )
++ {
++ // other boss not dead
++ dead = false;
++ }
++ }
++ }
++
++ return dead;
++}
++
+ //
+ // A_BossDeath
+ // Possibly trigger special effects
+@@ -3412,13 +3472,73 @@ static state_t *P_FinalState(statenum_t
+ // [WDJ] Keen death does not have tests for mo->type and thus allows
+ // Dehacked monsters to trigger Keen death and BossDeath effects.
+ // Should duplicate that ability in Doom maps.
+-void A_Bosstype_Death (mobj_t* mo, int boss_type)
++static void A_Bosstype_Death (mobj_t* mo, int boss_type)
+ {
+- thinker_t* th;
+- mobj_t* mo2;
+- line_t lineop; // operation performed when all bosses are dead.
+- int i;
+-
++ line_t lineop; // operation performed when all bosses are dead.
++
++ // [MB] 2023-03-19: Support for UMAPINFO added
++ if( gamemapinfo && gamemapinfo->bossactions )
++ {
++ struct bossaction_t* umi_ba = gamemapinfo->bossactions;
++ boolean found = false;
++
++ do
++ {
++ if( boss_type == umi_ba->thing)
++ {
++ found = true;
++ break;
++ }
++ umi_ba = umi_ba->next;
++ }
++ while( umi_ba );
++
++ if( !found )
++ return;
++
++ // DEHEXTRA is not supported
++ if( boss_type > ENDDOOM_MT )
++ {
++ GenPrintf(EMSG_debug,
++ "UMAPINFO: Thing for bossaction not supported\n");
++ return;
++ }
++
++ if( ! A_All_Bosses_Dead(mo, boss_type) )
++ return;
++
++ // Execute (potentially multiple) actions defined by UMAPINFO
++ umi_ba = gamemapinfo->bossactions;
++ do
++ {
++ if( boss_type == umi_ba->thing)
++ {
++ // FIXME: Is this allowed for the xxxSoecialLine() functions?
++ memset(&lineop, 0, sizeof(line_t));
++ if (umi_ba->special > (unsigned int)SHRT_MAX)
++ continue;
++ lineop.special = (short)umi_ba->special;
++ if (umi_ba->tag > (unsigned int)UINT16_MAX)
++ continue;
++ lineop.tag = (uint16_t)umi_ba->tag;
++
++ // Try to use the line first, cross it if not successful
++ if( ! P_UseSpecialLine(mo, &lineop, 0) )
++ P_CrossSpecialLine(&lineop, 0, mo);
++ }
++ umi_ba = umi_ba->next;
++ }
++ while( umi_ba );
++ return;
++ }
++
++ if( gamemapinfo && gamemapinfo->bossactions_clear )
++ {
++ // Default handling explicitly cleared by UMAPINFO
++ return;
++ }
++
++ // [MB] Default handling starts here
+ if ( gamemode == doom2_commercial)
+ {
+ // Doom2 MAP07: When last Mancubus is dead,
+@@ -3515,45 +3635,14 @@ void A_Bosstype_Death (mobj_t* mo, int b
+
+ }
+
+-
+ // make sure there is a player alive for victory
+- for (i=0 ; i<MAXPLAYERS ; i++)
+- if (playeringame[i] && players[i].health > 0)
+- break;
+-
+- if (i==MAXPLAYERS)
++ if( ! A_Player_Alive() )
+ return; // no one left alive, so do not end game
+
+ // scan the remaining thinkers to see
+ // if all bosses are dead
+- for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
+- {
+- if (th->function.acp1 != (actionf_p1)P_MobjThinker)
+- continue;
+-
+- // Fixes MAP07 bug where if last arachnotron is killed while first
+- // still in death sequence, then both would trigger this code
+- // and the floor would be raised twice (bad).
+- mo2 = (mobj_t *)th;
+- // Check all boss of the same type
+- if ( mo2 != mo
+- && mo2->type == boss_type )
+- {
+- // Check if really dead and finished the death sequence.
+- // [WDJ] Corpse has health < 0.
+- // If two monsters are killed at the same time, this test may occur
+- // while first is corpse and second is not. But the simple health
+- // test may trigger twice because second monster already has
+- // health < 0 during the first death test.
+- if( mo2->health > 0 // the old test (doom original 1.9)
+- || !(mo2->flags & MF_CORPSE)
+- || mo2->state != P_FinalState(mo2->info->deathstate) )
+- {
+- // other boss not dead
+- goto no_action;
+- }
+- }
+- }
++ if( ! A_All_Bosses_Dead(mo, boss_type) )
++ goto no_action;
+
+ // victory!
+ if ( gamemode == doom2_commercial)
diff --git a/doomlegacy-devel/patches/patch-src_p__info.c b/doomlegacy-devel/patches/patch-src_p__info.c
index 71f1d217f0..cf78581a3d 100644
--- a/doomlegacy-devel/patches/patch-src_p__info.c
+++ b/doomlegacy-devel/patches/patch-src_p__info.c
@@ -2,9 +2,19 @@ $NetBSD$
Add support for UMAPINFO.
---- src/p_info.c.orig 2023-01-10 10:38:38.000000000 +0000
+--- src/p_info.c.orig 2023-02-26 17:42:27.000000000 +0000
+++ src/p_info.c
-@@ -150,13 +150,15 @@ static void P_RemoveEqualses(char *line)
+@@ -79,6 +79,9 @@
+ #include "z_zone.h"
+ #include "p_local.h"
+
++// [MB] 2023-03-12: Size of static buffers used for names of levels, etc.
++#define NAME_BUFSIZE 50
++
+ //----------------------------------------------------------------------------
+ //
+ // Helper functions
+@@ -150,13 +153,15 @@ static void P_RemoveEqualses(char *line)
// '=' sign is optional: all equals signs are internally turned to spaces
//
@@ -25,7 +35,7 @@ Add support for UMAPINFO.
char *info_nextlevel;
char *info_nextsecret;
char *info_intertext = NULL;
-@@ -295,7 +297,10 @@ not_map:
+@@ -295,7 +300,10 @@ not_map:
void P_Clear_LevelVars(void)
{
@@ -37,7 +47,7 @@ Add support for UMAPINFO.
info_music = "";
info_creator = "unknown";
info_partime = -1;
-@@ -673,7 +678,8 @@ void P_Load_LevelInfo( void )
+@@ -673,7 +681,8 @@ void P_Load_LevelInfo( void )
void COM_MapInfo_f(void)
{
@@ -47,47 +57,79 @@ Add support for UMAPINFO.
CONS_Printf("Author: %s\n", info_creator);
}
-@@ -684,12 +690,48 @@ void P_Register_Info_Commands(void)
+@@ -684,12 +693,81 @@ void P_Register_Info_Commands(void)
}
--
- char * P_LevelName(void)
- {
-- return levelname;
-+ // [MB] 2023-01-22: Support for UMAPINFO added
-+ if (gamemapinfo && gamemapinfo->levelname)
++// [MB] 2023-03-12: Get label (prefix) for UMAPINFO levelname
++// Helper function for P_LevelName()
++//
++// Returns the length of the label, even if larger than buffer size
++// (but does not write beyond end of buffer).
++static size_t P_LevelName_GetLabel(char * buffer, size_t size)
++{
++ size_t len_label = 0;
++
++ if (size > 0)
+ {
-+ static char newlevelstr[50];
-+ size_t remaining = 50 - 1; // -1 for NUL-termination
++ int len = -1;
+
-+ newlevelstr[0] = 0;
-+ if (gamemapinfo && gamemapinfo->label)
++ if(gamemapinfo && gamemapinfo->label)
+ {
-+ // The key 'label' contains a prefix for key 'levelname'
-+ size_t len_label = strlen(gamemapinfo->label);
-+ size_t len_level = strlen(gamemapinfo->levelname);
-+
-+ if (remaining < len_label)
-+ len_label = remaining;
-+ remaining -= len_label;
-+ if (remaining < len_level)
-+ len_level = remaining;
++ // Empty string, if "clear" was specified in UMAPINFO
++ const char * label = gamemapinfo->label;
+
-+ memcpy(newlevelstr, gamemapinfo->label, len_label);
-+ memcpy(&newlevelstr[len_label], gamemapinfo->levelname, len_level);
-+ newlevelstr[len_label + len_level] = 0;
++ len = snprintf(buffer, size, "%s", label);
+ }
+ else
+ {
-+ size_t len_level = strlen(gamemapinfo->levelname);
++ // Quoted from UMAPINFO specification Rev 2.2 definition of map
++ // entry:
++ // The [episode and map] numbers [...] can exceed their original
++ // limits, though, so MAP50, E5M6 or even MAP100 or E1M10 are valid
++ // map names for their respective game.
++ //
++ // Quoted from UMAPINFO specification Rev 2.2 definition of label:
++ // If not specified the mapname will be used by default followed by
++ // a colon and a space character (e.g. "E1M1: ").
++ unsigned char e = gameepisode;
++ unsigned char m = gamemap;
+
-+ if (remaining < len_level)
-+ len_level = remaining;
++ if(gamemode == doom2_commercial)
++ len = snprintf(buffer, size, "level %u: ", m);
++ else
++ len = snprintf(buffer, size, "E%uM%u: ", e, m);
+
-+ memcpy(newlevelstr, gamemapinfo->levelname, len_level);
-+ newlevelstr[len_level] = 0;
+ }
++
++ if(len > 0)
++ len_label = len;
++ }
++
++ return len_label;
++}
++
+
+ char * P_LevelName(void)
+ {
+- return levelname;
++ // [MB] 2023-01-22: Support for UMAPINFO added
++ if(gamemapinfo && gamemapinfo->levelname)
++ {
++ static char newlevelstr[NAME_BUFSIZE];
++ size_t remaining = NAME_BUFSIZE - 1; // -1 for NUL-termination
++
++ size_t len_label = P_LevelName_GetLabel(newlevelstr, NAME_BUFSIZE);
++ size_t len_level = strlen(gamemapinfo->levelname);
++
++ if(len_label > remaining)
++ len_label = remaining;
++ remaining -= len_label;
++ if(len_level > remaining)
++ len_level = remaining;
++
++ memcpy(&newlevelstr[len_label], gamemapinfo->levelname, len_level);
++ newlevelstr[len_label + len_level] = 0;
+ return newlevelstr;
+ }
+ else
diff --git a/doomlegacy-devel/patches/patch-src_w__wad.c b/doomlegacy-devel/patches/patch-src_w__wad.c
index d82ff37aed..5cbc2788c3 100644
--- a/doomlegacy-devel/patches/patch-src_w__wad.c
+++ b/doomlegacy-devel/patches/patch-src_w__wad.c
@@ -2,26 +2,32 @@ $NetBSD$
Add support for UMAPINFO.
---- src/w_wad.c.orig 2023-01-10 10:38:38.711741654 +0000
+--- src/w_wad.c.orig 2023-02-26 17:42:27.000000000 +0000
+++ src/w_wad.c
-@@ -118,6 +118,7 @@
- #include "d_netfil.h"
- #include "dehacked.h"
- // DEH_LoadDehackedLump
-+#include "umapinfo.h"
- #include "r_defs.h"
- #include "i_system.h"
+@@ -109,6 +109,9 @@
+ #include <unistd.h>
+ // close, read, lseek
-@@ -589,6 +590,8 @@ int W_Load_WadFile ( const char * filena
++// [MB] 2023-03-19: Support for UMAPINFO added
++#include "doomstat.h"
++
+ #include "doomincl.h"
+ #include "w_wad.h"
+ #include "z_zone.h"
+@@ -589,6 +592,12 @@ int W_Load_WadFile ( const char * filena
GenPrintf(EMSG_info, "Added file %s (%i lumps)\n", filenamebuf, numlumps);
W_Load_DehackedLumps( filenum );
+ // [MB] 2023-01-10: Process UMAPINFO last for highest priority
-+ W_Load_UMapInfoLumps( filenum );
++ if ( EN_doom_etc )
++ {
++ // UMAPINFO is for Doom only (not seuitable for Heretic and Hexen)
++ W_Load_UMapInfoLumps( filenum );
++ }
return filenum;
-@@ -1378,6 +1381,25 @@ void W_Load_DehackedLumps( int wadnum )
+@@ -1378,6 +1387,25 @@ void W_Load_DehackedLumps( int wadnum )
}
}
diff --git a/doomlegacy-devel/patches/patch-src_wi__stuff.c b/doomlegacy-devel/patches/patch-src_wi__stuff.c
index 16ada6ca43..f06abd204e 100644
--- a/doomlegacy-devel/patches/patch-src_wi__stuff.c
+++ b/doomlegacy-devel/patches/patch-src_wi__stuff.c
@@ -2,9 +2,250 @@ $NetBSD$
Add support for UMAPINFO.
---- src/wi_stuff.c.orig 2023-01-29 19:24:45.535984651 +0000
+--- src/wi_stuff.c.orig 2023-02-26 17:42:27.000000000 +0000
+++ src/wi_stuff.c
-@@ -1986,11 +1986,21 @@ void WI_Ticker(void)
+@@ -481,6 +481,28 @@ void detect_range_violation( int item, i
+ // CODE
+ //
+
++
++// [MB] 2023-03-19: Support for UMAPINFO added
++// Moved out of WI_Load_Data() into separate function because with UMAPINFO
++// the LF and EL screens can use different background pictures.
++static void WI_Prepare_Background(void)
++{
++ // Prepare new background from bgname for software renderer
++ if (rendermode == render_soft)
++ {
++ memset(screens[0], 0, vid.screen_size);
++
++ // clear backbuffer from status bar stuff and borders
++ memset(screens[1], 0, vid.screen_size);
++
++ // Draw background on screen1
++ V_SetupDraw(1 | V_SCALESTART | V_SCALEPATCH | V_CENTERHORZ); // screen 1
++ V_DrawScaledPatch(0, 0, W_CachePatchName(bgname, PU_CACHE));
++ V_SetupDraw(drawinfo.prev_screenflags); // restore
++ }
++}
++
++
+ // slam background
+ // UNUSED static unsigned char *background=0;
+
+@@ -523,25 +545,79 @@ static void WI_Draw_LF(void)
+ {
+ // Hardware or software render.
+ patch_t * pp, * pf;
++ int x = 0;
+ int y = WI_TITLEY;
+
+- // draw <LevelName>
+- if( FontBBaseLump )
++ // [MB] 2023-03-12: Support for UMAPINFO added
++ //
++ // Quoted from UMAPINFO specification Rev 2.2 definition of levelpic:
++ // Specifies the patch that is used on the status screen for 'entering' and
++ // 'finished'. [...]
++ // If not given, the status screen will instead print the map's name with a
++ // suitable font (PrBoom uses STFxxx) to ensure that the proper name is
++ // used. If the author field is set, it will also be shown.
++ if (wbs->lastmapinfo && wbs->lastmapinfo->levelpic)
++ {
++ pp = W_CachePatchName(wbs->lastmapinfo->levelpic, PU_CACHE);
++ pf = V_patch(pp); // access patch fields
++ x = (BASEVIDWIDTH - pf->width) / 2;
++ V_DrawScaledPatch(x, y, pp);
++
++ y += (5 * pf->height) / 4;
++
++ x = (BASEVIDWIDTH - (V_patch(finished)->width)) / 2;
++ V_DrawScaledPatch(x, y, finished);
++ }
++ else if (wbs->lastmapinfo && wbs->lastmapinfo->levelname)
+ {
+- V_DrawTextB(P_LevelName(), (BASEVIDWIDTH - V_TextBWidth(P_LevelName()))/2, y);
+- y += (5*V_TextBHeight(P_LevelName()))/4;
+- V_DrawTextB("Finished", (BASEVIDWIDTH - V_TextBWidth("Finished"))/2, y);
++ const char * level_string = wbs->lastmapinfo->levelname;
++
++ x = (BASEVIDWIDTH - V_StringWidth(level_string)) / 2;
++ V_DrawString(x, y, V_WHITEMAP, level_string);
++
++ if (wbs->lastmapinfo && wbs->lastmapinfo->author)
++ {
++ const char * author_string = wbs->lastmapinfo->author;
++
++ y += (5 * V_FontInfo()->height) / 4;
++
++ x = (BASEVIDWIDTH - V_StringWidth(author_string)) / 2;
++ V_DrawString(x, y, V_WHITEMAP, author_string);
++ }
++
++ y += 2 * V_FontInfo()->height;
++
++ x = (BASEVIDWIDTH - (V_patch(finished)->width)) / 2;
++ V_DrawScaledPatch(x, y, finished);
+ }
++ // Normal behaviour without UMAPINFO
+ else
+ {
+- //[segabor]: 'SHORT' BUG ! [WDJ] Patch read does endian conversion
+- pp = lnames[wbs->lev_prev];
+- pf = V_patch( pp ); // access patch fields
+- V_DrawScaledPatch ((BASEVIDWIDTH - pf->width)/2, y, pp);
+- y += (5 * pf->height)/4;
+- // draw "Finished!"
+- V_DrawScaledPatch ((BASEVIDWIDTH - (V_patch(finished)->width))/2,
+- y, finished);
++ // draw <LevelName>
++ if (FontBBaseLump)
++ {
++ x = (BASEVIDWIDTH - V_TextBWidth(P_LevelName())) / 2;
++ V_DrawTextB(P_LevelName(), x, y);
++
++ y += (5 * V_TextBHeight(P_LevelName())) / 4;
++
++ x = (BASEVIDWIDTH - V_TextBWidth("Finished")) / 2;
++ V_DrawTextB("Finished", x, y);
++ }
++ else
++ {
++ //[segabor]: 'SHORT' BUG ! [WDJ] Patch read does endian conversion
++ pp = lnames[wbs->lev_prev];
++ pf = V_patch( pp ); // access patch fields
++ x = (BASEVIDWIDTH - pf->width) / 2;
++ V_DrawScaledPatch(x, y, pp);
++
++ y += (5 * pf->height) / 4;
++
++ x = (BASEVIDWIDTH - (V_patch(finished)->width)) / 2;
++ // draw "Finished!"
++ V_DrawScaledPatch(x, y, finished);
++ }
+ }
+ }
+
+@@ -552,31 +628,81 @@ static void WI_Draw_EL(void)
+ {
+ // Hardware or software render.
+ patch_t * pp, * pf;
++ int x = 0;
+ int y = WI_TITLEY;
+
+- // draw "Entering"
+- if( FontBBaseLump )
++ // [MB] 2023-03-12: Support for UMAPINFO added
++ // See WI_Draw_LF() for additional notes.
++ if (wbs->nextmapinfo && wbs->nextmapinfo->levelpic)
+ {
+- const char * levname = P_LevelNameByNum(wbs->epsd+1, wbs->lev_next+1);
+- V_DrawTextB("Entering", (BASEVIDWIDTH - V_TextBWidth("Entering"))/2, y);
+- y += (5*V_TextBHeight("Entering"))/4;
+- V_DrawTextB( levname, (BASEVIDWIDTH - V_TextBWidth(levname))/2, y);
++ x = (BASEVIDWIDTH - (V_patch(entering)->width)) / 2;
++ V_DrawScaledPatch(x, y, entering);
++
++ y += (5 * V_patch(entering)->height) / 4;
++
++ pp = W_CachePatchName(wbs->nextmapinfo->levelpic, PU_CACHE);
++ pf = V_patch(pp); // access patch fields
++ x = (BASEVIDWIDTH - pf->width) / 2;
++ V_DrawScaledPatch(x, y, pp);
+ }
+- else
++ else if (wbs->nextmapinfo && wbs->nextmapinfo->levelname)
+ {
+- //[segabor]: 'SHORT' BUG ! [WDJ] Patch read does endian conversion
+- V_DrawScaledPatch((BASEVIDWIDTH - (V_patch(entering)->width))/2,
+- y, entering);
+- // draw level
+- pp = lnames[wbs->lev_next];
+- pf = V_patch( pp ); // access patch fields
+- y += (5 * pf->height)/4;
++ const char * level_string = wbs->nextmapinfo->levelname;
+
+- V_DrawScaledPatch((BASEVIDWIDTH - pf->width)/2, y, pp);
++ x = (BASEVIDWIDTH - (V_patch(entering)->width)) / 2;
++ V_DrawScaledPatch(x, y, entering);
++
++ y += V_patch(entering)->height + V_FontInfo()->height;
++
++ x = (BASEVIDWIDTH - V_StringWidth(level_string)) / 2;
++ V_DrawString(x, y, V_WHITEMAP, level_string);
++
++ if (wbs->nextmapinfo && wbs->nextmapinfo->author)
++ {
++ const char * author_string = wbs->nextmapinfo->author;
++
++ y += (5 * V_FontInfo()->height) / 4;
++
++ x = (BASEVIDWIDTH - V_StringWidth(author_string)) / 2;
++ V_DrawString(x, y, V_WHITEMAP, author_string);
++ }
+ }
++ // Normal behaviour without UMAPINFO
++ else
++ {
++ // draw "Entering"
++ if (FontBBaseLump)
++ {
++ const char * level_string = P_LevelNameByNum(wbs->epsd + 1,
++ wbs->lev_next + 1);
+
++ x = (BASEVIDWIDTH - V_TextBWidth("Entering")) / 2;
++ V_DrawTextB("Entering", x, y);
++
++ y += (5 * V_TextBHeight("Entering")) / 4;
++
++ x = (BASEVIDWIDTH - V_TextBWidth(level_string)) / 2;
++ V_DrawTextB(level_string, x, y);
++ }
++ else
++ {
++ //[segabor]: 'SHORT' BUG ! [WDJ] Patch read does endian conversion
++ x = (BASEVIDWIDTH - (V_patch(entering)->width)) / 2;
++ V_DrawScaledPatch(x, y, entering);
++
++ // draw level
++ pp = lnames[wbs->lev_next];
++ pf = V_patch(pp); // access patch fields
++
++ y += (5 * pf->height) / 4;
++
++ x = (BASEVIDWIDTH - pf->width) / 2;
++ V_DrawScaledPatch(x, y, pp);
++ }
++ }
+ }
+
++
+ // [WDJ] Made more resistent to segfault.
+ // Doom YAH draw
+ // n : YAH index
+@@ -958,6 +1084,13 @@ static void WI_Draw_ShowNextLoc(void)
+ if (cnt<=0) // all removed no draw !!!
+ return;
+
++ // [MB] 2023-03-19: Support for UMAPINFO added
++ if (wbs->nextmapinfo && wbs->nextmapinfo->enterpic)
++ {
++ strcpy(bgname, wbs->nextmapinfo->enterpic);
++ WI_Prepare_Background();
++ }
++
+ WI_Slam_Background();
+
+ // draw animated background
+@@ -1977,7 +2110,6 @@ static void WI_checkForAccelerate(void)
+ }
+
+
+-
+ // Updates stuff each client tick.
+ void WI_Ticker(void)
+ {
+@@ -1986,11 +2118,21 @@ void WI_Ticker(void)
if (bcnt == 1)
{
@@ -30,3 +271,25 @@ Add support for UMAPINFO.
}
WI_checkForAccelerate();
+@@ -2097,20 +2239,8 @@ void WI_Load_Data(void)
+ if (wb_epsd == 3)
+ strcpy(bgname,"INTERPIC");
+ }
+-
+-
+- if( rendermode == render_soft )
+- {
+- memset(screens[0], 0, vid.screen_size);
+
+- // clear backbuffer from status bar stuff and borders
+- memset(screens[1], 0, vid.screen_size);
+-
+- // Draw background on screen1
+- V_SetupDraw( 1 | V_SCALESTART | V_SCALEPATCH | V_CENTERHORZ ); // screen 1
+- V_DrawScaledPatch(0, 0, W_CachePatchName(bgname, PU_CACHE));
+- V_SetupDraw( drawinfo.prev_screenflags ); // restore
+- }
++ WI_Prepare_Background();
+
+ // UNUSED unsigned char *pic = screens[1];
+ // if (gamemode == doom2_commercial)
Home |
Main Index |
Thread Index |
Old Index