pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

doomlegacy-devel: More UMAPINFO support



Module Name:	pkgsrc-wip
Committed By:	Michael Baeuerle <micha%NetBSD.org@localhost>
Pushed By:	micha
Date:		Mon Feb 27 14:15:41 2023 +0100
Changeset:	54948caf8b1f94d27428e75c0eda283d46011f14

Modified Files:
	doomlegacy-devel/TODO
	doomlegacy-devel/distinfo
	doomlegacy-devel/files/umapinfo.c
	doomlegacy-devel/files/umapinfo.h
	doomlegacy-devel/patches/patch-src_g__game.c
	doomlegacy-devel/patches/patch-src_p__info.c
Added Files:
	doomlegacy-devel/patches/patch-src_f__finale.c
	doomlegacy-devel/patches/patch-src_f__finale.h
	doomlegacy-devel/patches/patch-src_p__info.h
	doomlegacy-devel/patches/patch-src_p__setup.c
	doomlegacy-devel/patches/patch-src_wi__stuff.c

Log Message:
doomlegacy-devel: More UMAPINFO support

Now based on libdoom-umapinfo-1.

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=54948caf8b1f94d27428e75c0eda283d46011f14

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 doomlegacy-devel/TODO                          |   6 +-
 doomlegacy-devel/distinfo                      |   9 +-
 doomlegacy-devel/files/umapinfo.c              | 323 ++++++++++++++++---------
 doomlegacy-devel/files/umapinfo.h              |  14 +-
 doomlegacy-devel/patches/patch-src_f__finale.c |  99 ++++++++
 doomlegacy-devel/patches/patch-src_f__finale.h |  16 ++
 doomlegacy-devel/patches/patch-src_g__game.c   |  88 ++++---
 doomlegacy-devel/patches/patch-src_p__info.c   | 142 ++++++-----
 doomlegacy-devel/patches/patch-src_p__info.h   |  28 +++
 doomlegacy-devel/patches/patch-src_p__setup.c  |  24 ++
 doomlegacy-devel/patches/patch-src_wi__stuff.c |  32 +++
 11 files changed, 572 insertions(+), 209 deletions(-)

diffs:
diff --git a/doomlegacy-devel/TODO b/doomlegacy-devel/TODO
index 48891feb73..7e4633113e 100644
--- a/doomlegacy-devel/TODO
+++ b/doomlegacy-devel/TODO
@@ -8,10 +8,10 @@ Part 24: Middle-texture rendering
 
 Part 25: Add UMAPINFO support
 =============================
-[ ] Based on libdoom-umapinfo
+[X] Based on libdoom-umapinfo-1.0.0
     => Module to parse and import data added
-    => Hooked in keys 'label', "levelname', 'next' and 'nextsecret'
-       The default prefix for 'levelname' does not work yet
+[ ] Hook keys into game engine
+    => All keys except 'enterpic', "emenu' and 'bossactions' should work now
 
 
 EOF
diff --git a/doomlegacy-devel/distinfo b/doomlegacy-devel/distinfo
index b2081ff970..714741f84c 100644
--- a/doomlegacy-devel/distinfo
+++ b/doomlegacy-devel/distinfo
@@ -8,7 +8,12 @@ SHA1 (patch-src_Makefile) = 7921393b6c4941fd02d9644836991c30b0fb3188
 SHA1 (patch-src_am__map.c) = 14b3c8b70c63778ad043827ab2f0b6f4fe07bcde
 SHA1 (patch-src_d__player.h) = 5975ea8a714aeb10dcecc7fd42fffcb8f9a2e51b
 SHA1 (patch-src_doomstat.h) = baa7387b6271d3064c12e24aaadf40cdb383e395
-SHA1 (patch-src_g__game.c) = bd31af700dd5ba7ffee84bec1a7caf7d37ab2d84
-SHA1 (patch-src_p__info.c) = e492f67a4c8f04779b267d6ef3b7faa75ef7779c
+SHA1 (patch-src_f__finale.c) = 6de35c080709d6c0fc9e72b46f7c558cc5605de5
+SHA1 (patch-src_f__finale.h) = 5ba7ae568be4dd97d06e4724dc7e1907f3a09cd8
+SHA1 (patch-src_g__game.c) = c5168003940fff0bfcf2db1937e217f65a911a4d
+SHA1 (patch-src_p__info.c) = 6f13050349238ccabe02b7c1bb1996c5c971fa31
+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.h) = 683283a32222e96a6472f103d3dc51e7229e4753
+SHA1 (patch-src_wi__stuff.c) = 380fdfc31975cad0624460561142ffa22e1233c4
diff --git a/doomlegacy-devel/files/umapinfo.c b/doomlegacy-devel/files/umapinfo.c
index cf52841985..5d43ff1f95 100644
--- a/doomlegacy-devel/files/umapinfo.c
+++ b/doomlegacy-devel/files/umapinfo.c
@@ -26,13 +26,17 @@
 
 
 #include <assert.h>
+#include <limits.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <string.h>
 
-#include "libdoom-umapinfo-0/doom_umi.h"
+#include "libdoom-umapinfo-1/doom_umi.h"
 
+#include "dehacked.h"
 #include "doomincl.h"
+#include "doomstat.h"
+#include "p_info.h"
 #include "umapinfo.h"
 #include "w_wad.h"
 #include "z_zone.h"
@@ -72,9 +76,9 @@ static void UMI_InitMapEntry(mapentry_t *entry,
     entry->music             = NULL;
     entry->skytexture        = NULL;
     entry->levelpic          = NULL;
-    entry->endpic            = NULL;
     entry->exitpic           = NULL;
     entry->enterpic          = NULL;
+    entry->endpic            = NULL;
     entry->emenu             = NULL;
     entry->bossactions       = NULL;
     entry->endgame           = unchanged;
@@ -154,9 +158,9 @@ static void UMI_DestroyMaps(mapentry_t *entry)
         UMI_Free((void*) entry->music);
         UMI_Free((void*) entry->skytexture);
         UMI_Free((void*) entry->levelpic);
-        UMI_Free((void*) entry->endpic);
         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);
@@ -166,10 +170,10 @@ static void UMI_DestroyMaps(mapentry_t *entry)
 
 
 // On error, 0 is returned
-static unsigned int UMI_GetNumber(doom_umi0_ts_state state)
+static unsigned int UMI_GetNumber(doom_umi1_ts_state state)
 {
     unsigned int number = 0;
-    int          retval = doom_umi0_ts_value_read_number(state, &number);
+    int          retval = doom_umi1_ts_value_read_number(state, &number);
 
     if (0 > retval)
     {
@@ -186,14 +190,14 @@ static unsigned int UMI_GetNumber(doom_umi0_ts_state state)
 // A termination with NUL is appended, but not counted for 'len'
 // Attention: libdoom-umapinfo supports arbitrary encodings for quoted strings,
 // the result must be post-processed!
-static char *UMI_GetQString(doom_umi0_ts_state state, size_t *len)
+static char *UMI_GetQString(doom_umi1_ts_state state, size_t *len)
 {
     char                *result  = NULL;
     size_t               length  = 0;
     const unsigned char *qstring = NULL;
-    int                  retval  = DOOM_UMI0_ERROR_NOTFOUND;
+    int                  retval  = DOOM_UMI1_ERROR_NOTFOUND;
 
-    retval = doom_umi0_ts_value_read_qstring(state, &length, &qstring);
+    retval = doom_umi1_ts_value_read_qstring(state, &length, &qstring);
     if (0 > retval || 0 == length + 1u)
         GenPrintf(EMSG_warn, "UMAPINFO: Error while reading value (qstring)\n");
     else
@@ -222,17 +226,17 @@ static void UMI_ConvertToASCII(char *str, size_t length, boolean multiline)
 
     for (i = 0; length > i; ++i)
     {
-       if (multiline && 0x0A != str[i])
+       if (multiline && 0x0A == str[i])
            continue;
 
-       if (0x20u > str[i] || 0x7Eu < str[i])
+       if (0x20 > str[i] || 0x7E < str[i])
             str[i] = '?';
     }
 }
 
 
 // Control characters (e.g. line breaks) are not allowed
-static void UMI_ReplaceString(doom_umi0_ts_state state, const char** str)
+static void UMI_ReplaceString(doom_umi1_ts_state state, const char** str)
 {
     size_t  length = 0;
     char   *string = UMI_GetQString(state, &length);
@@ -246,6 +250,26 @@ static void UMI_ReplaceString(doom_umi0_ts_state state, const char** str)
 }
 
 
+// Like UMI_ReplaceString(), but ignores strings with more than 8 characters
+static void UMI_ReplaceStringMax8(doom_umi1_ts_state state, const char** str)
+{
+    size_t  length = 0;
+    char   *string = UMI_GetQString(state, &length);
+
+    if (NULL != string)
+    {
+        if (8u < length)
+            UMI_Free(string);
+        else
+        {
+            UMI_ConvertToASCII(string, length, false);
+            UMI_Free((void*) *str);
+            *str = string;
+        }
+    }
+}
+
+
 static const char* UMI_CreateEmptyString()
 {
     char *string = UMI_Malloc(1);
@@ -260,12 +284,12 @@ static const char* UMI_CreateEmptyString()
 
 
 // Same as UMI_ReplaceString(), but 'clear' identifier gives empty string
-static void UMI_ReplaceStringClear(doom_umi0_ts_state state, const char** str)
+static void UMI_ReplaceStringClear(doom_umi1_ts_state state, const char** str)
 {
-    int type   = DOOM_UMI0_TYPE_INVALID;
-    int retval = doom_umi0_ts_value_type(state, &type);
+    int type   = DOOM_UMI1_TYPE_INVALID;
+    int retval = doom_umi1_ts_value_type(state, &type);
 
-    if (0 <= retval && DOOM_UMI0_TYPE_CLEAR == type)
+    if (0 <= retval && DOOM_UMI1_TYPE_CLEAR == type)
     {
         const char *string = UMI_CreateEmptyString();
 
@@ -278,7 +302,7 @@ static void UMI_ReplaceStringClear(doom_umi0_ts_state state, const char** str)
 
 
 // It is allowed that multiple lines are contained in one value
-static void UMI_ReplaceMultiString(doom_umi0_ts_state state,
+static void UMI_ReplaceMultiString(doom_umi1_ts_state state,
                                    const char** str, size_t valcount)
 {
     char   *multi        = NULL;
@@ -289,7 +313,7 @@ static void UMI_ReplaceMultiString(doom_umi0_ts_state state,
     {
         size_t  length = 0;
         char   *string = UMI_GetQString(state, &length);
-        int     retval = DOOM_UMI0_ERROR_NOTFOUND;
+        int     retval = DOOM_UMI1_ERROR_NOTFOUND;
 
         if (NULL == string)
             break;
@@ -299,26 +323,28 @@ static void UMI_ReplaceMultiString(doom_umi0_ts_state state,
             multi        = string;
             multi_length = length;
         }
-        else  // Append
+        else if (0 != length)  // Append
         {
             char   *tmp        = NULL;
             size_t  tmp_length = multi_length + length;
 
-            if (multi_length > tmp_length || 0 == tmp_length + 1u)
+            tmp_length += 2u;  // For LF and NUL-termination
+            if (multi_length > tmp_length)
                 break;
-            tmp = UMI_Malloc(tmp_length + 1u);
+            tmp = UMI_Malloc(tmp_length);
             if (NULL == tmp)
                 break;
             memcpy(tmp, multi, multi_length);
-            memcpy(&tmp[multi_length], string, length + 1u);
+            tmp[multi_length] = 0x0A;  // LF
+            memcpy(&tmp[multi_length + 1u], string, length + 1u);
             UMI_Free(multi);
             multi        = tmp;
-            multi_length = tmp_length;
+            multi_length = tmp_length - 1u;  // Without NUL-termination
         }
 
         if (valcount - 1u != val)
         {
-            retval = doom_umi0_ts_value_next(state);
+            retval = doom_umi1_ts_value_next(state);
             if (0 > retval)
                 break;
         }
@@ -337,13 +363,13 @@ static void UMI_ReplaceMultiString(doom_umi0_ts_state state,
 
 
 // Same as UMI_ReplaceMultiString(), but 'clear' identifier gives empty string
-static void UMI_ReplaceMultiStringClear(doom_umi0_ts_state state,
+static void UMI_ReplaceMultiStringClear(doom_umi1_ts_state state,
                                         const char** str, size_t valcount)
 {
-    int type   = DOOM_UMI0_TYPE_INVALID;
-    int retval = doom_umi0_ts_value_type(state, &type);
+    int type   = DOOM_UMI1_TYPE_INVALID;
+    int retval = doom_umi1_ts_value_type(state, &type);
 
-    if (0 <= retval && DOOM_UMI0_TYPE_CLEAR == type)
+    if (0 <= retval && DOOM_UMI1_TYPE_CLEAR == type)
     {
         const char *string = UMI_CreateEmptyString();
 
@@ -356,12 +382,12 @@ static void UMI_ReplaceMultiStringClear(doom_umi0_ts_state state,
 
 
 // Returns true on success
-static boolean UMI_PopulateEpisodeMenuEntry(doom_umi0_ts_state state,
+static boolean UMI_PopulateEpisodeMenuEntry(doom_umi1_ts_state state,
                                             emenu_t *entry)
 {
     boolean  result = false;
     size_t   length = 0;
-    int      retval = DOOM_UMI0_ERROR_NOTFOUND;
+    int      retval = DOOM_UMI1_ERROR_NOTFOUND;
     char    *tmp    = NULL;
 
     tmp = UMI_GetQString(state, &length);
@@ -369,7 +395,7 @@ static boolean UMI_PopulateEpisodeMenuEntry(doom_umi0_ts_state state,
     {
         UMI_ConvertToASCII(tmp, length, false);
         entry->patch = tmp;
-        retval = doom_umi0_ts_value_next(state);
+        retval = doom_umi1_ts_value_next(state);
     }
 
     if (0 <= retval)
@@ -379,7 +405,7 @@ static boolean UMI_PopulateEpisodeMenuEntry(doom_umi0_ts_state state,
         {
             UMI_ConvertToASCII(tmp, length, false);
             entry->name = tmp;
-            retval = doom_umi0_ts_value_next(state);
+            retval = doom_umi1_ts_value_next(state);
         }
     }
 
@@ -399,14 +425,14 @@ static boolean UMI_PopulateEpisodeMenuEntry(doom_umi0_ts_state state,
 
 
 // Returns true if identifier 'clear' was detected
-static boolean UMI_AppendEpisodeMenuEntry(doom_umi0_ts_state state,
+static boolean UMI_AppendEpisodeMenuEntry(doom_umi1_ts_state state,
                                           emenu_t** em, size_t valcount)
 {
     boolean  result = false;
-    int      type   = DOOM_UMI0_TYPE_INVALID;
-    int      retval = doom_umi0_ts_value_type(state, &type);
+    int      type   = DOOM_UMI1_TYPE_INVALID;
+    int      retval = doom_umi1_ts_value_type(state, &type);
 
-    if (0 <= retval && DOOM_UMI0_TYPE_CLEAR == type)
+    if (0 <= retval && DOOM_UMI1_TYPE_CLEAR == type)
     {
         UMI_DestroyEpisodeMenu(*em);
         *em    = NULL;
@@ -446,24 +472,24 @@ static boolean UMI_AppendEpisodeMenuEntry(doom_umi0_ts_state state,
 
 
 // Returns true on success
-static boolean UMI_PopulateBossActionEntry(doom_umi0_ts_state state,
+static boolean UMI_PopulateBossActionEntry(doom_umi1_ts_state state,
                                            bossaction_t *entry)
 {
     boolean result      = false;
     size_t  thing_index = 0;
-    int     retval      = DOOM_UMI0_ERROR_NOTFOUND;
+    int     retval      = DOOM_UMI1_ERROR_NOTFOUND;
 
-    retval = doom_umi0_ts_value_read_thing(state, NULL, &thing_index);
+    retval = doom_umi1_ts_value_read_thing(state, NULL, &thing_index);
     if (0 <= retval && (size_t) INT_MAX >= thing_index)
     {
         entry->thing = thing_index;
-        retval = doom_umi0_ts_value_next(state);
+        retval = doom_umi1_ts_value_next(state);
         if (0 <= retval)
-            retval = doom_umi0_ts_value_read_number(state, &entry->special);
+            retval = doom_umi1_ts_value_read_number(state, &entry->special);
         if (0 <= retval)
-            retval = doom_umi0_ts_value_next(state);
+            retval = doom_umi1_ts_value_next(state);
         if (0 <= retval)
-            retval = doom_umi0_ts_value_read_number(state, &entry->tag);
+            retval = doom_umi1_ts_value_read_number(state, &entry->tag);
         if (0 <= retval)
             result = true;
     }
@@ -472,20 +498,20 @@ static boolean UMI_PopulateBossActionEntry(doom_umi0_ts_state state,
 }
 
 
-static boolean UMI_MergeBossAction(doom_umi0_ts_state state,
+static boolean UMI_MergeBossAction(doom_umi1_ts_state state,
                                    bossaction_t** ba, size_t valcount)
 {
     boolean  result = false;
-    int      type   = DOOM_UMI0_TYPE_INVALID;
-    int      retval = doom_umi0_ts_value_type(state, &type);
+    int      type   = DOOM_UMI1_TYPE_INVALID;
+    int      retval = doom_umi1_ts_value_type(state, &type);
 
-    if (0 <= retval && DOOM_UMI0_TYPE_CLEAR == type)
+    if (0 <= retval && DOOM_UMI1_TYPE_CLEAR == type)
     {
         UMI_DestroyBossActions(*ba);
         *ba    = NULL;
         result = true;
     }
-    else if (DOOM_UMI0_TYPE_THING == type)
+    else if (DOOM_UMI1_TYPE_THING == type)
     {
         bossaction_t *entry = UMI_Malloc(sizeof(bossaction_t));
 
@@ -518,10 +544,10 @@ static boolean UMI_MergeBossAction(doom_umi0_ts_state state,
 }
 
 
-static void UMI_StoreKeyData(doom_umi0_ts_state state, mapentry_t *entry)
+static void UMI_StoreKeyData(doom_umi1_ts_state state, mapentry_t *entry)
 {
     size_t key      = 0;
-    int    retval   = doom_umi0_ts_key_read(state, NULL, &key);
+    int    retval   = doom_umi1_ts_key_read(state, NULL, &key);
     size_t valcount = 0;
 
     if (0 > retval)
@@ -530,7 +556,7 @@ static void UMI_StoreKeyData(doom_umi0_ts_state state, mapentry_t *entry)
         return;
     }
 
-    retval = doom_umi0_ts_value_count(state, &valcount);
+    retval = doom_umi1_ts_value_count(state, &valcount);
     if (0 > retval || 0 == valcount)
     {
         GenPrintf(EMSG_warn, "UMAPINFO: Error while reading value\n");
@@ -539,73 +565,73 @@ static void UMI_StoreKeyData(doom_umi0_ts_state state, mapentry_t *entry)
 
     switch (key)
     {
-        case DOOM_UMI0_KEY_AUTHOR:
+        case DOOM_UMI1_KEY_AUTHOR:
             UMI_ReplaceString(state, &entry->author);
             break;
-        case DOOM_UMI0_KEY_LABEL:
+        case DOOM_UMI1_KEY_LABEL:
             UMI_ReplaceStringClear(state, &entry->label);
             break;
-        case DOOM_UMI0_KEY_LEVELNAME:
+        case DOOM_UMI1_KEY_LEVELNAME:
             UMI_ReplaceString(state, &entry->levelname);
             break;
-        case DOOM_UMI0_KEY_INTERTEXT:
+        case DOOM_UMI1_KEY_INTERTEXT:
             UMI_ReplaceMultiStringClear(state, &entry->intertext, valcount);
             break;
-        case DOOM_UMI0_KEY_INTERTEXTSECRET:
+        case DOOM_UMI1_KEY_INTERTEXTSECRET:
             UMI_ReplaceMultiStringClear(state,
                                         &entry->intertextsecret, valcount);
             break;
-        case DOOM_UMI0_KEY_INTERBACKDROP:
-            UMI_ReplaceString(state, &entry->interbackdrop);
+        case DOOM_UMI1_KEY_INTERBACKDROP:
+            UMI_ReplaceStringMax8(state, &entry->interbackdrop);
             break;
-        case DOOM_UMI0_KEY_INTERMUSIC:
-            UMI_ReplaceString(state, &entry->intermusic);
+        case DOOM_UMI1_KEY_INTERMUSIC:
+            UMI_ReplaceStringMax8(state, &entry->intermusic);
             break;
-        case DOOM_UMI0_KEY_NEXT:
-            UMI_ReplaceString(state, &entry->nextmap);
+        case DOOM_UMI1_KEY_NEXT:
+            UMI_ReplaceStringMax8(state, &entry->nextmap);
             break;
-        case DOOM_UMI0_KEY_NEXTSECRET:
-            UMI_ReplaceString(state, &entry->nextsecret);
+        case DOOM_UMI1_KEY_NEXTSECRET:
+            UMI_ReplaceStringMax8(state, &entry->nextsecret);
             break;
-        case DOOM_UMI0_KEY_MUSIC:
-            UMI_ReplaceString(state, &entry->music);
+        case DOOM_UMI1_KEY_MUSIC:
+            UMI_ReplaceStringMax8(state, &entry->music);
             break;
-        case DOOM_UMI0_KEY_SKYTEXTURE:
-            UMI_ReplaceString(state, &entry->skytexture);
+        case DOOM_UMI1_KEY_SKYTEXTURE:
+            UMI_ReplaceStringMax8(state, &entry->skytexture);
             break;
-        case DOOM_UMI0_KEY_LEVELPIC:
-            UMI_ReplaceString(state, &entry->levelpic);
+        case DOOM_UMI1_KEY_LEVELPIC:
+            UMI_ReplaceStringMax8(state, &entry->levelpic);
             break;
-        case DOOM_UMI0_KEY_ENDPIC:
-            UMI_ReplaceString(state, &entry->endpic);
+        case DOOM_UMI1_KEY_EXITPIC:
+            UMI_ReplaceStringMax8(state, &entry->exitpic);
             break;
-        case DOOM_UMI0_KEY_EXITPIC:
-            UMI_ReplaceString(state, &entry->exitpic);
+        case DOOM_UMI1_KEY_ENTERPIC:
+            UMI_ReplaceStringMax8(state, &entry->enterpic);
             break;
-        case DOOM_UMI0_KEY_ENTERPIC:
-            UMI_ReplaceString(state, &entry->enterpic);
+        case DOOM_UMI1_KEY_ENDPIC:
+            UMI_ReplaceStringMax8(state, &entry->endpic);
             break;
-        case DOOM_UMI0_KEY_EPISODE:
+        case DOOM_UMI1_KEY_EPISODE:
             entry->emenu_clear =
                 UMI_AppendEpisodeMenuEntry(state, &entry->emenu, valcount);
             break;
-        case DOOM_UMI0_KEY_BOSSACTION:
+        case DOOM_UMI1_KEY_BOSSACTION:
             entry->bossactions_clear =
                 UMI_MergeBossAction(state, &entry->bossactions, valcount);
             break;
-        case DOOM_UMI0_KEY_ENDGAME:
+        case DOOM_UMI1_KEY_ENDGAME:
             entry->endgame = UMI_GetNumber(state) ? enabled : disabled;
             break;
-        case DOOM_UMI0_KEY_PARTIME:
+        case DOOM_UMI1_KEY_PARTIME:
             entry->partime = UMI_GetNumber(state);
             break;
-        case DOOM_UMI0_KEY_NOINTERMISSION:
+        case DOOM_UMI1_KEY_NOINTERMISSION:
             entry->nointermission = UMI_GetNumber(state) ? true : false;
             break;
-        case DOOM_UMI0_KEY_ENDBUNNY:
+        case DOOM_UMI1_KEY_ENDBUNNY:
             entry->endbunny = UMI_GetNumber(state) ? true : false;
             break;
-        case DOOM_UMI0_KEY_ENDCAST:
+        case DOOM_UMI1_KEY_ENDCAST:
             entry->endcast = UMI_GetNumber(state) ? true : false;
             break;
         default:
@@ -617,7 +643,7 @@ static void UMI_StoreKeyData(doom_umi0_ts_state state, mapentry_t *entry)
 
 static mapentry_t *UMI_GetMapEntry(unsigned int episode, unsigned int map)
 {
-    mapentry_t *entry      = umapinfo.entry;
+    mapentry_t *entry      = umapinfo.entry_first;
     mapentry_t *entry_last = NULL;
 
     while (NULL != entry)
@@ -636,8 +662,8 @@ static mapentry_t *UMI_GetMapEntry(unsigned int episode, unsigned int map)
         if (NULL != entry)
         {
             UMI_InitMapEntry(entry, episode, map);
-            if (NULL == umapinfo.entry)
-                umapinfo.entry = entry;
+            if (NULL == umapinfo.entry_first)
+                umapinfo.entry_first = entry;
             else
                 entry_last->next = entry;
         }
@@ -647,29 +673,29 @@ static mapentry_t *UMI_GetMapEntry(unsigned int episode, unsigned int map)
 }
 
 
-static void UMI_MergeMapEntry(doom_umi0_ts_state state)
+static void UMI_MergeMapEntry(doom_umi1_ts_state state)
 {
     mapentry_t   *entry   = NULL;
     unsigned int  episode = 0;
     unsigned int  map     = 0;
-    int           retval  = doom_umi0_ts_map_read(state, &episode, &map);
+    int           retval  = doom_umi1_ts_map_read(state, &episode, &map);
 
     if (0 <= retval)
         entry = UMI_GetMapEntry(episode, map);
 
     if (NULL == entry)
-        retval = DOOM_UMI0_ERROR_NOTFOUND;
+        retval = DOOM_UMI1_ERROR_NOTFOUND;
     else
     {
         size_t keycount = 0;
 
-        retval = doom_umi0_ts_key_count(state, &keycount);
+        retval = doom_umi1_ts_key_count(state, &keycount);
         while (0 <= retval && keycount)
         {
             UMI_StoreKeyData(state, entry);
 
             if (--keycount)
-                retval = doom_umi0_ts_key_next(state);
+                retval = doom_umi1_ts_key_next(state);
         }
     }
 
@@ -678,24 +704,24 @@ static void UMI_MergeMapEntry(doom_umi0_ts_state state)
 }
 
 
-static void UMI_ImportUMapInfo(umapinfo_t *umi, doom_umi0_handle data)
+static void UMI_ImportUMapInfo(umapinfo_t *umi, doom_umi1_handle data)
 {
-    doom_umi0_ts_state state    = NULL;
+    doom_umi1_ts_state state    = NULL;
     size_t             mapcount = 0;  // Number of toplevel map entries
-    int                retval   = doom_umi0_ts_state_create(&state, data);
+    int                retval   = doom_umi1_ts_state_create(&state, data);
 
     if (0 <= retval)
-        retval = doom_umi0_ts_map_count(state, &mapcount);
+        retval = doom_umi1_ts_map_count(state, &mapcount);
 
     while (0 <= retval && mapcount)
     {
         UMI_MergeMapEntry(state);
 
         if (--mapcount)
-            retval = doom_umi0_ts_map_next(state);
+            retval = doom_umi1_ts_map_next(state);
     }
 
-    doom_umi0_ts_state_destroy(&state);
+    doom_umi1_ts_state_destroy(&state);
 
     if (0 > retval)
         GenPrintf(EMSG_warn, "UMAPINFO: Error while importing map entry\n");
@@ -704,13 +730,13 @@ static void UMI_ImportUMapInfo(umapinfo_t *umi, doom_umi0_handle data)
 
 void UMI_LoadUMapInfoLump(lumpnum_t lumpnum)
 {
-    doom_umi0_handle  data = NULL; // libdoom-umapinfo UMAPINFO object handle
+    doom_umi1_handle  data = NULL; // libdoom-umapinfo UMAPINFO object handle
     int               len  = W_LumpLength(lumpnum);
 
     assert(0 <= len);
 
     {
-        int            retval  = DOOM_UMI0_ERROR_MEMORY;
+        int            retval  = DOOM_UMI1_ERROR_MEMORY;
         unsigned char *lump    = UMI_Malloc(len);
         size_t         length  = len;
         int            verbose = 0;
@@ -718,7 +744,7 @@ void UMI_LoadUMapInfoLump(lumpnum_t lumpnum)
         if (NULL != lump)
         {
             W_ReadLump(lumpnum, lump);
-            retval = doom_umi0_create(&data, lump, length, verbose);
+            retval = doom_umi1_create(&data, lump, length, verbose);
             UMI_Free(lump);
         }
         if (0 > retval)
@@ -729,15 +755,15 @@ void UMI_LoadUMapInfoLump(lumpnum_t lumpnum)
         if (0 <= retval)
             UMI_ImportUMapInfo(&umapinfo, data);
 
-        doom_umi0_destroy(&data);
+        doom_umi1_destroy(&data);
     }
 }
 
 
 void UMI_DestroyUMapInfo(void)
 {
-    UMI_DestroyMaps(umapinfo.entry);
-    umapinfo.entry = NULL;
+    UMI_DestroyMaps(umapinfo.entry_first);
+    umapinfo.entry_first = NULL;
 }
 
 
@@ -755,7 +781,7 @@ boolean UMI_ParseMapName(const char *name, byte *episode, byte *map)
     if (false == result)
     {
         retval = sscanf(name, "%*[Ee]%u%*[Mm]%u", &e, &m);
-        if (2 == retval && 255u >= e && 255u >= m)
+        if (2 == retval && 0 < e && 255u >= e && 0 < m && 255u >= m)
             result = true;
     }
 
@@ -769,55 +795,132 @@ boolean UMI_ParseMapName(const char *name, byte *episode, byte *map)
 }
 
 
-// DooM Legacy uses an unsigned type for 'byte'
 mapentry_t *UMI_LookupUMapInfo(byte episode, byte map)
 {
-    mapentry_t   *entry = umapinfo.entry;
+    mapentry_t   *entry = umapinfo.entry_first;
+    unsigned int  e     = episode;
+    unsigned int  m     = map;
+
+    // libdoom-umapinfo uses episode 0 for Doom 2
+    if (doom2_commercial == gamemode)
+        e = 0;
 
     while (NULL != entry)
     {
         // Entries with numbers beyond the range of 'byte' will never match
-        if (entry->episode == episode && entry->map == map)
+        if (entry->episode == e && entry->map == m)
             break;
         entry = entry->next;
     }
 
+    if (NULL != entry)
+        GenPrintf(EMSG_info,
+                  "UMAPINFO: Map entry found for Episode %u, Map %u\n", e, m);
+
     return entry;
 }
 
 
+// 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()
+void UMI_Load_LevelInfo(void)
+{
+    gamemapinfo = UMI_LookupUMapInfo(gameepisode, gamemap);
+
+    // SMMU level info is replaced with UMAPINFO data, where possible
+    if (NULL != gamemapinfo)
+    {
+        // For now only used by COM_MapInfo_f() for the command "mapinfo"
+        if (gamemapinfo->author)
+            info_creator = gamemapinfo->author;
+
+        // label and levelname are handled by P_LevelName()
+
+        // intertext and intertextsecret are handled by F_StartFinale()
+
+        // interbackdrop is handled by F_StartFinale()
+
+        // intermusic is handled by WI_Ticker()
+
+        // nextmap and nextsecret are handled by G_DoUMapInfo()
+
+        if (gamemapinfo->music)
+            info_music = UMI_GetMusicLumpName(gamemapinfo->music);
+
+        if (gamemapinfo->skytexture)
+            info_skyname = gamemapinfo->skytexture;
+
+        if (gamemapinfo->levelpic)
+            info_levelpic = gamemapinfo->levelpic;
+
+        if (gamemapinfo->exitpic)
+            info_interpic = gamemapinfo->exitpic;
+
+        // FIXME: enterpic is not handled yet
+
+        // endpic is handled by F_Drawer()
+
+        // XXX emenu is not handled yet
+
+        // XXX bossactions is not handled yet
+
+        // endgame is handled by G_NextLevel()
+
+        if (gamemapinfo->partime)
+        {
+            if ((unsigned int) INT_MAX < gamemapinfo->partime)
+                info_partime = INT_MAX;
+            else
+                info_partime = gamemapinfo->partime;
+            pars_valid_bex = true;  // Abuse this flag for activation with PWAD
+        }
+    }
+}
+
+
 #else  // HAVE_LIBDOOM_UMAPINFO
 
 
 #include "doomincl.h"
 
 
-// Stub if libdoom-umapinfo is not available
 void UMI_LoadUMapInfoLump(lumpnum_t lumpnum)
 {
     GenPrintf(EMSG_warn, "UMAPINFO: Ignored (libdoom-umapinfo is required)\n");
 }
 
 
-// Stub if libdoom-umapinfo is not available
 void UMI_DestroyUMapInfo(void)
 {
     return;
 }
 
 
-// Stub if libdoom-umapinfo is not available
 boolean UMI_ParseMapName(const char *mapname, byte *episode, byte * map)
 {
     return false;
 }
 
 
-// Stub if libdoom-umapinfo is not available
 mapentry_t *UMI_LookupUMapinfo(byte episode, byte map)
 {
     return NULL;
 }
 
 
+void UMI_Load_LevelInfo(void)
+{
+    return;
+}
+
+
 #endif  // HAVE_LIBDOOM_UMAPINFO
diff --git a/doomlegacy-devel/files/umapinfo.h b/doomlegacy-devel/files/umapinfo.h
index b0087b744b..c45a3fb773 100644
--- a/doomlegacy-devel/files/umapinfo.h
+++ b/doomlegacy-devel/files/umapinfo.h
@@ -73,9 +73,9 @@ struct mapentry_t
     const char   *music;
     const char   *skytexture;
     const char   *levelpic;
-    const char   *endpic;
     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
@@ -92,11 +92,11 @@ struct mapentry_t
 
 typedef struct
 {
-    mapentry_t *entry;  // Linked list
+    mapentry_t *entry_first;  // Linked list
 } umapinfo_t;
 
 
-// Current data
+// Current data (merged from PWADs)
 extern umapinfo_t umapinfo;
 
 
@@ -120,4 +120,12 @@ boolean UMI_ParseMapName(const char *mapname, byte *episode, byte * map);
 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);
+
+
+// Load UMAPINFO data for current gameepisode/gamemap
+void UMI_Load_LevelInfo(void);
+
+
 #endif  // UMAPINFO_H
diff --git a/doomlegacy-devel/patches/patch-src_f__finale.c b/doomlegacy-devel/patches/patch-src_f__finale.c
new file mode 100644
index 0000000000..a33a3d0f95
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_f__finale.c
@@ -0,0 +1,99 @@
+$NetBSD$
+
+Add support for UMAPINFO.
+
+--- src/f_finale.c.orig	2023-01-10 10:38:38.000000000 +0000
++++ src/f_finale.c
+@@ -75,8 +75,8 @@ int             finalecount;
+ #define TEXTSPEED       3
+ #define TEXTWAIT        250
+ 
+-char*   finaletext;
+-char*   finaleflat;
++const char*   finaletext;  // [MB] 2023-01-29: Changed to const
++const char*   finaleflat;  // [MB] 2023-01-29: Changed to const
+ static boolean keypressed=false;
+ static byte    finale_palette = 0;  // [WDJ] 0 is PLAYPAL
+ 
+@@ -84,16 +84,39 @@ void    F_StartCast (void);
+ void    F_CastTicker (void);
+ boolean F_CastResponder (event_t *ev);
+ void    F_CastDrawer (void);
+-void    F_Draw_interpic_Name( char * name );
++// [MB] 2023-02-05: Changed to static and parameter to const for UMAPINFO
++static void F_Draw_interpic_Name( const char * name );
+ 
+ //
+ // F_StartFinale
+ //
+-void F_StartFinale (void)
++void F_StartFinale (boolean secretexit)
+ {
+     gamestate = GS_FINALE;
+ 
+-    if(info_intertext)
++    if (gamemapinfo)
++    {
++        // [MB] 2023-01-29: Support for UMAPINFO added
++        if (!secretexit && gamemapinfo->intertext)
++        {
++            finaletext = gamemapinfo->intertext;
++            if (gamemapinfo->interbackdrop)
++              finaleflat = gamemapinfo->interbackdrop;
++            else
++              finaleflat = text[BGFLATE1_NUM]; // Doom E1, FLOOR4_8
++            goto umapinfo_used;
++        }
++        else if (secretexit && gamemapinfo->intertextsecret)
++        {
++            finaletext = gamemapinfo->intertextsecret;
++            if (gamemapinfo->interbackdrop)
++              finaleflat = gamemapinfo->interbackdrop;
++            else
++              finaleflat = text[BGFLATE1_NUM]; // Doom E1, FLOOR4_8
++            goto umapinfo_used;
++        }
++    }
++    else if(info_intertext)
+     {
+       //SoM: Use FS level info intermission.
+       finaletext = info_intertext;
+@@ -248,6 +271,7 @@ void F_StartFinale (void)
+         break;
+     }
+ 
++umapinfo_used:
+     finalestage = 0;
+     finalecount = 0;
+ 
+@@ -363,7 +387,7 @@ void F_TextWrite (void)
+     // vid : from video setup
+     int         w;
+     int         count;
+-    char*       ch;
++    const char* ch;  // [MB] 2023-01-29: Changed to const
+     int         c;
+     int         cx, cy;
+ 
+@@ -840,7 +864,8 @@ credit_page:
+ 
+ 
+ // Called from F_Drawer, to draw full screen
+-void F_Draw_interpic_Name( char * name )
++// [MB] 2023-02-05: Changed to static and parameter to const for UMAPINFO
++static void F_Draw_interpic_Name( const char * name )
+ {
+    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)
+         }
+         else
+         {
+-           switch (gameepisode)
++           // [MB] 2023-02-05: Support for UMAPINFO added
++           if (gamemapinfo && gamemapinfo->endpic)
++              F_Draw_interpic_Name( gamemapinfo->endpic );
++           else switch (gameepisode)
+            {
+             case 1:
+               if ( gamemode == ultdoom_retail || gamemode == chexquest1 )
diff --git a/doomlegacy-devel/patches/patch-src_f__finale.h b/doomlegacy-devel/patches/patch-src_f__finale.h
new file mode 100644
index 0000000000..6974aa101e
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_f__finale.h
@@ -0,0 +1,16 @@
+$NetBSD$
+
+Add support for UMAPINFO.
+
+--- src/f_finale.h.orig	2023-01-10 10:38:38.000000000 +0000
++++ src/f_finale.h
+@@ -48,7 +48,8 @@ void F_Ticker (void);
+ void F_Drawer (void);
+ 
+ 
+-void F_StartFinale (void);
++// 2023-02-04: Added parameter for UMAPINFO support
++void F_StartFinale (boolean secretexit);
+ 
+ 
+ #endif
diff --git a/doomlegacy-devel/patches/patch-src_g__game.c b/doomlegacy-devel/patches/patch-src_g__game.c
index 53a3135fd1..dac79bcaa4 100644
--- a/doomlegacy-devel/patches/patch-src_g__game.c
+++ b/doomlegacy-devel/patches/patch-src_g__game.c
@@ -12,7 +12,7 @@ Add support for UMAPINFO.
  char            game_map_filename[MAX_WADPATH];      // an external wad filename
  
  
-@@ -2384,10 +2385,69 @@ void G_DoCompleted (void)
+@@ -2384,10 +2385,74 @@ void G_DoCompleted (void)
      automapactive = false;
  }
  
@@ -30,10 +30,15 @@ Add support for UMAPINFO.
 +    if (gamemapinfo)
 +    {
 +        const char *mapname = NULL;
++        int         i = 0;
 +
 +        // 'nextmap' or 'nextsecret' key overrides default behaviour
 +        if (secretexit && gamemapinfo->nextsecret)
++        {
 +            mapname = gamemapinfo->nextsecret;
++            for (i = 0; MAXPLAYERS > i; ++i)
++                players[i].didsecret = true;
++        }
 +        else if (gamemapinfo->nextmap)
 +            mapname = gamemapinfo->nextmap;
 +
@@ -48,6 +53,8 @@ Add support for UMAPINFO.
 +                UMI_ParseMapName(mapname, &e, &m);
 +                wminfo.epsd_next = e;
 +                wminfo.lev_next = m;
++                GenPrintf(EMSG_info, "UMAPINFO: Go to Episode %d, Map %d\n",
++                          wminfo.epsd_next, wminfo.lev_next);
 +            }
 +            wminfo.epsd_next--;
 +            wminfo.lev_next--;
@@ -55,8 +62,6 @@ Add support for UMAPINFO.
 +            if (wminfo.epsd_next != wminfo.epsd)
 +            {
 +                // Jump to different episode
-+                int  i;
-+
 +                for (i = 0; MAXPLAYERS > i; ++i)
 +                    players[i].didsecret = false;
 +            }
@@ -82,7 +87,25 @@ Add support for UMAPINFO.
      if (gamemode != doom2_commercial)
      {
          switch(gamemap)
-@@ -2436,7 +2496,7 @@ void G_Start_Intermission( void )
+@@ -2401,7 +2466,7 @@ void G_Start_Intermission( void )
+                 // also for heretic
+                 // disconnect from network
+                 CL_Reset();
+-                F_StartFinale();
++                F_StartFinale(secretexit);  // [MB] 2023-03-04: Parameter added
+                 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 )
+             else
+             {
+                 CL_Reset();
+-                F_StartFinale();
++                F_StartFinale(secretexit);  // [MB] 2023-03-04: Parameter added
+                 return;
+             }
+         }
+@@ -2436,7 +2501,7 @@ void G_Start_Intermission( void )
      // go to next level
      // wminfo.lev_next is 0 biased, unlike gamemap
      wminfo.lev_next = gamemap;
@@ -91,7 +114,7 @@ Add support for UMAPINFO.
      // overwrite next level in some cases
      if (gamemode == doom2_commercial)
      {
-@@ -2490,6 +2550,21 @@ void G_Start_Intermission( void )
+@@ -2490,6 +2555,21 @@ void G_Start_Intermission( void )
                  wminfo.lev_next = 0; // wrap around in deathmatch
          }
      }
@@ -102,7 +125,7 @@ Add support for UMAPINFO.
 +        int e = wminfo.epsd_next + 1;
 +        int m = wminfo.lev_next + 1;
 +
-+        if (0 <= e && 256 > e && 0 < m && 256 > m)
++        if (0 <= e && 255u >= e && 0 < m && 255u >= m)
 +        {
 +            byte epsd = e;
 +            byte map  = m;
@@ -113,36 +136,29 @@ Add support for UMAPINFO.
  
      wminfo.maxkills = totalkills;
      wminfo.maxitems = totalitems;
-@@ -2566,6 +2641,22 @@ void G_NextLevel (void)
- 
- void G_DoWorldDone (void)
- {
-+    // [MB] 2023-01-22: Support for UMAPINFO added
-+    {
-+        int e = wminfo.epsd_next + 1;
-+        int m = wminfo.lev_next + 1;
-+
-+        if (0 <= e && 256 > e && 0 < m && 256 > m)
+@@ -2542,6 +2622,16 @@ void G_NextLevel (void)
+             if( gamemap == 30 )
+                 wminfo.lev_next = 0; // wrap around in deathmatch
+         }
++        // [MB] 2023-01-29: Support for UMAPINFO added
++        else if (gamemapinfo && gamemapinfo->endgame)
 +        {
-+            byte epsd = e;
-+            byte map  = m;
++            tristate_t end = gamemapinfo->endgame;
 +
-+            gameepisode = epsd;
-+            gamemap     = map;
-+            gamemapinfo = UMI_LookupUMapInfo(gameepisode, gamemap);
++            if( (end == unchanged && gamemap == 30) || end == enabled )
++                CL_Reset(); // end of game disconnect from server
++            gameaction = ga_nothing;
++            F_StartFinale(secretexit);  // [MB] 2023-03-04: Parameter added
 +        }
-+    }
-+
-     if( demoversion<129 )
-     {
-         gamemap = wminfo.lev_next+1;
-@@ -2880,6 +2971,9 @@ void G_InitNew (skill_e skill, const cha
-     playerdeadview = false;
-     automapactive  = false;
- 
-+    // [MB] 2023-01-22: Support for UMAPINFO added
-+    gamemapinfo    = UMI_LookupUMapInfo(gameepisode, gamemap);
-+
-     G_DoLoadLevel (resetplayer);
- }
- 
+         else
+         {
+             switch (gamemap)
+@@ -2557,7 +2647,7 @@ void G_NextLevel (void)
+                 if( gamemap == 30 )
+                     CL_Reset(); // end of game disconnect from server
+                 gameaction = ga_nothing;
+-                F_StartFinale ();
++                F_StartFinale (secretexit);  // [MB] 2023-03-04: Parameter added
+                 break;
+             }
+         }
diff --git a/doomlegacy-devel/patches/patch-src_p__info.c b/doomlegacy-devel/patches/patch-src_p__info.c
index 51e1899d8e..71f1d217f0 100644
--- a/doomlegacy-devel/patches/patch-src_p__info.c
+++ b/doomlegacy-devel/patches/patch-src_p__info.c
@@ -4,65 +4,97 @@ Add support for UMAPINFO.
 
 --- src/p_info.c.orig	2023-01-10 10:38:38.000000000 +0000
 +++ src/p_info.c
-@@ -471,11 +471,50 @@ static char * levelname;
- // Called by P_Load_LevelInfo
- void P_FindLevelName(void)
- {
-+  // [MB] 2023-01-22: Common buffer
-+  //      Size is unchanged, but only 44 characters are displayed in worst case
-+#define P_NEWLEVELSTR_SIZE 50u
-+  static char newlevelstr[P_NEWLEVELSTR_SIZE];
+@@ -150,13 +150,15 @@ static void P_RemoveEqualses(char *line)
+ //  '=' sign is optional: all equals signs are internally turned to spaces
+ //
+ 
+-char *info_interpic;
++// [MB] 2023-01-22: Changed to const (used for UMAPINFO too)
++const char *info_creator;
++const char *info_music;
++const char *info_skyname;
++const char *info_interpic;
++const char *info_levelpic;
 +
-   // Determine the level name.
-   // There are a number of sources from which it can come from,
-   // getting the right one is the tricky bit =).
--  
--  if(*info_levelname)
+ char *info_levelname;
+ int info_partime;
+-char *info_music;
+-char *info_skyname;
+-char *info_creator;
+-char *info_levelpic;
+ char *info_nextlevel;
+ char *info_nextsecret;
+ char *info_intertext = NULL;
+@@ -295,7 +297,10 @@ not_map:
+ 
+ void P_Clear_LevelVars(void)
+ {
+-  info_levelname = info_skyname = info_levelpic = info_interpic = "";
++  info_levelname = "";
++  info_skyname = "";
++  info_levelpic = "";
++  info_interpic = "";
+   info_music = "";
+   info_creator = "unknown";
+   info_partime = -1;
+@@ -673,7 +678,8 @@ void P_Load_LevelInfo( void )
+ 
+ void COM_MapInfo_f(void)
+ {
+-  CONS_Printf("Name: %s\n", levelname);
++  // [MB] 2023-02-04: Call P_LevelName() to catch levelname from UMAPINFO
++  CONS_Printf("Name: %s\n", P_LevelName());
+   CONS_Printf("Author: %s\n", info_creator);
+ }
+ 
+@@ -684,12 +690,48 @@ void P_Register_Info_Commands(void)
+ }
+ 
+ 
+-
+ char * P_LevelName(void)
+ {
+-  return levelname;
++    // [MB] 2023-01-22: Support for UMAPINFO added
++    if (gamemapinfo && gamemapinfo->levelname)
++    {
++        static char newlevelstr[50];
++        size_t      remaining = 50 - 1;  // -1 for NUL-termination
 +
-+  // [MB] 2023-01-22: Support for UMAPINFO added
-+  if (gamemapinfo && gamemapinfo->levelname)
-+  {
-+      size_t remaining = P_NEWLEVELSTR_SIZE - 1;  // -1 for NUL-termination
++        newlevelstr[0] = 0;
++        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);
 +
-+      newlevelstr[0] = 0;
-+      if (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;
 +
-+          if (remaining < len_label)
-+              len_label = remaining;
-+          remaining -= len_label;
-+          if (remaining < len_level)
-+              len_level = remaining;
++            memcpy(newlevelstr, gamemapinfo->label, len_label);
++            memcpy(&newlevelstr[len_label], gamemapinfo->levelname, len_level);
++            newlevelstr[len_label + len_level] = 0;
++        }
++        else
++        {
++            size_t len_level = strlen(gamemapinfo->levelname);
 +
-+          memcpy(newlevelstr, gamemapinfo->label, len_label);
-+          memcpy(&newlevelstr[len_label], gamemapinfo->levelname, len_level);
-+          newlevelstr[len_label + len_level] = 0;
-+      }
-+      else
-+      {
-+          size_t len_level = strlen(gamemapinfo->levelname);
++            if (remaining < len_level)
++                len_level = remaining;
 +
-+          if (remaining < len_level)
-+              len_level = remaining;
++            memcpy(newlevelstr, gamemapinfo->levelname, len_level);
++            newlevelstr[len_level] = 0;
++        }
++        return newlevelstr;
++    }
++    else
++        return levelname;
+ }
+ 
 +
-+          memcpy(newlevelstr, gamemapinfo->levelname, len_level);
-+          newlevelstr[len_level] = 0;
-+      }
-+      levelname = newlevelstr;
-+  }
-+  else if(*info_levelname)
-   {
-       // info level name from level lump (p_info.c) ?
-       levelname = info_levelname;
-@@ -516,8 +555,6 @@ void P_FindLevelName(void)
-   }
-   else        //  otherwise just put "new level"
-   {
--      static char newlevelstr[50];
--
-       sprintf(newlevelstr, "%s: new level", level_mapname);
-       levelname = newlevelstr;
-   }
+ // todo : make this use mapinfo lump
+ // Called by WI_Draw_EL "Entering <LevelName>"
+ // Called by IN_Draw_YAH "NOW ENTERING"
diff --git a/doomlegacy-devel/patches/patch-src_p__info.h b/doomlegacy-devel/patches/patch-src_p__info.h
new file mode 100644
index 0000000000..6d1a9704cd
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_p__info.h
@@ -0,0 +1,28 @@
+$NetBSD$
+
+Add support for UMAPINFO.
+
+--- src/p_info.h.orig	2023-01-10 10:38:38.000000000 +0000
++++ src/p_info.h
+@@ -50,14 +50,16 @@ void P_Load_LevelInfo(void);
+ 
+ void P_CleanLine(char *line);
+ 
+-extern char *info_interpic;
++// [MB] 2023-01-22: Changed to const (used for UMAPINFO too)
++extern const char *info_creator;
++extern const char *info_music;
++extern const char *info_skyname;
++extern const char *info_interpic;
++extern const char *info_levelpic;
++
+ extern char *info_levelname;
+-extern char *info_levelpic;
+-extern char *info_music;
+ extern int info_partime;
+ extern char *info_levelcmd[128];
+-extern char *info_skyname;
+-extern char *info_creator;
+ extern char *info_nextlevel;
+ extern char *info_nextsecret;
+ extern char *info_intertext;
diff --git a/doomlegacy-devel/patches/patch-src_p__setup.c b/doomlegacy-devel/patches/patch-src_p__setup.c
new file mode 100644
index 0000000000..1fc1ab4e1a
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_p__setup.c
@@ -0,0 +1,24 @@
+$NetBSD$
+
+Add support for UMAPINFO.
+
+--- src/p_setup.c.orig	2023-01-10 10:38:38.000000000 +0000
++++ src/p_setup.c
+@@ -2087,7 +2087,7 @@ fail:
+ // The sky texture to be used instead of the F_SKY1 dummy.
+ void P_Setup_LevelSky (void)
+ {
+-    char * sn = "SKY1";
++    const char * sn = "SKY1";
+     char   skytexname[12];
+ 
+     // DOOM determines the sky texture to be used
+@@ -2282,6 +2282,8 @@ boolean P_SetupLevel (int      to_episod
+     // Dependent upon level_mapname, level_lumpnum.
+     P_Load_LevelInfo();
+ #endif
++    // [MB] 2023-01-22: Support for UMAPINFO added
++    UMI_Load_LevelInfo();
+ 
+     //SoM: We've loaded the music lump, start the music.
+     S_Start_LevelSound();
diff --git a/doomlegacy-devel/patches/patch-src_wi__stuff.c b/doomlegacy-devel/patches/patch-src_wi__stuff.c
new file mode 100644
index 0000000000..16ada6ca43
--- /dev/null
+++ b/doomlegacy-devel/patches/patch-src_wi__stuff.c
@@ -0,0 +1,32 @@
+$NetBSD$
+
+Add support for UMAPINFO.
+
+--- src/wi_stuff.c.orig	2023-01-29 19:24:45.535984651 +0000
++++ src/wi_stuff.c
+@@ -1986,11 +1986,21 @@ void WI_Ticker(void)
+ 
+     if (bcnt == 1)
+     {
+-        // intermission music
+-        if ( gamemode == doom2_commercial )
+-          S_ChangeMusic(mus_dm2int, true);
++        // [MB] 2023-01-22: Support for UMAPINFO added
++        if (gamemapinfo && gamemapinfo->intermusic)
++        {
++            const char *mus_umi = UMI_GetMusicLumpName(gamemapinfo->intermusic);
++
++            S_ChangeMusicName(mus_umi, true);
++        }
+         else
+-          S_ChangeMusic(mus_inter, true);
++        {
++            // intermission music
++            if ( gamemode == doom2_commercial )
++              S_ChangeMusic(mus_dm2int, true);
++            else
++              S_ChangeMusic(mus_inter, true);
++        }
+     }
+ 
+     WI_checkForAccelerate();



Home | Main Index | Thread Index | Old Index