shithub: choc

Download patch

ref: 4a00203152591556f2ba271a446b918b3ea3e172
parent: 4b2dc259269602670c436a25e335608f269ad866
author: Nuke.YKT <alexeytf2@gmail.com>
date: Fri Jul 17 08:28:22 EDT 2015

Doom v1.666, 1.7, 1.8 support.

--- a/src/d_mode.c
+++ b/src/d_mode.c
@@ -120,6 +120,7 @@
     GameMission_t mission;
     GameVersion_t version;
 } valid_versions[] = {
+    { doom,     exe_doom_1_666 },
     { doom,     exe_doom_1_9 },
     { doom,     exe_hacx },
     { doom,     exe_ultimate },
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -607,6 +607,10 @@
     "                         "
     "DOOM 2: Hell on Earth v%i.%i"
     "                           ",
+    // doom2.wad v1.666
+    "                         "
+    "DOOM 2: Hell on Earth v%i.%i66"
+    "                          ",
     // doom1.wad
     "                            "
     "DOOM Shareware Startup v%i.%i"
@@ -619,6 +623,10 @@
     "                          "
     "DOOM System Startup v%i.%i"
     "                          ",
+    // Doom v1.666
+    "                          "
+    "DOOM System Startup v%i.%i66"
+    "                          "
     // doom.wad (Ultimate DOOM)
     "                         "
     "The Ultimate DOOM Startup v%i.%i"
@@ -945,8 +953,12 @@
 
 static void InitGameVersion(void)
 {
+    byte *demolump;
+    byte demolumpname[6];
+    int demoversion;
     int p;
     int i;
+    boolean status;
 
     //! 
     // @arg <version>
@@ -998,13 +1010,46 @@
 
             gameversion = exe_hacx;
         }
-        else if (gamemode == shareware || gamemode == registered)
+        else if (gamemode == shareware || gamemode == registered
+              || (gamemode == commercial && gamemission == doom2))
         {
             // original
-
             gameversion = exe_doom_1_9;
 
-            // TODO: Detect IWADs earlier than Doom v1.9.
+            // Detect version from demo lump
+            for (i = 1; i <= 3; ++i)
+            {
+                M_snprintf(demolumpname, 6, "demo%i", i);
+                if (W_CheckNumForName(demolumpname) > 0)
+                {
+                    demolump = W_CacheLumpName(demolumpname, PU_STATIC);
+                    demoversion = demolump[0];
+                    W_ReleaseLumpName(demolumpname);
+                    status = true;
+                    switch (demoversion)
+                    {
+                        case 106:
+                            gameversion = exe_doom_1_666;
+                            break;
+                        case 107:
+                            gameversion = exe_doom_1_7;
+                            break;
+                        case 108:
+                            gameversion = exe_doom_1_8;
+                            break;
+                        case 109:
+                            gameversion = exe_doom_1_9;
+                            break;
+                        default:
+                            status = false;
+                            break;
+                    }
+                    if (status)
+                    {
+                        break;
+                    }
+                }
+            }
         }
         else if (gamemode == retail)
         {
@@ -1012,20 +1057,13 @@
         }
         else if (gamemode == commercial)
         {
-            if (gamemission == doom2)
-            {
-                gameversion = exe_doom_1_9;
-            }
-            else
-            {
-                // Final Doom: tnt or plutonia
-                // Defaults to emulating the first Final Doom executable,
-                // which has the crash in the demo loop; however, having
-                // this as the default should mean that it plays back
-                // most demos correctly.
+            // Final Doom: tnt or plutonia
+            // Defaults to emulating the first Final Doom executable,
+            // which has the crash in the demo loop; however, having
+            // this as the default should mean that it plays back
+            // most demos correctly.
 
-                gameversion = exe_final;
-            }
+            gameversion = exe_final;
         }
     }
     
--- a/src/doom/m_menu.c
+++ b/src/doom/m_menu.c
@@ -751,6 +751,9 @@
 
     switch (gameversion)
     {
+        case exe_doom_1_666:
+        case exe_doom_1_7:
+        case exe_doom_1_8:
         case exe_doom_1_9:
         case exe_hacx:
 
@@ -1074,7 +1077,7 @@
     // Doom 1.9 had two menus when playing Doom 1
     // All others had only one
 
-    if (gameversion == exe_doom_1_9 && gamemode != commercial)
+    if (gameversion <= exe_doom_1_9 && gamemode != commercial)
     {
         choice = 0;
         M_SetupNextMenu(&ReadDef2);
--- a/src/doom/s_sound.c
+++ b/src/doom/s_sound.c
@@ -116,7 +116,22 @@
 {
     int i;
 
-    I_SetOPLDriverVer(opl_v_new);
+    if (gameversion == exe_doom_1_666)
+    {
+        if (logical_gamemission == doom)
+        {
+            I_SetOPLDriverVer(opl_doom1_1_666);
+        }
+        else
+        {
+            I_SetOPLDriverVer(opl_doom2_1_666);
+        }
+    }
+    else
+    {
+        I_SetOPLDriverVer(opl_doom_1_9);
+    }
+
     I_PrecacheSounds(S_sfx, NUMSFX);
 
     S_SetSfxVolume(sfxVolume);
--- a/src/doom/st_stuff.c
+++ b/src/doom/st_stuff.c
@@ -528,7 +528,8 @@
 	{
 	  musnum = mus_runnin + (buf[0]-'0')*10 + buf[1]-'0' - 1;
 	  
-	  if (((buf[0]-'0')*10 + buf[1]-'0') > 35)
+	  if (((buf[0]-'0')*10 + buf[1]-'0') > 35
+       && gameversion >= exe_doom_1_8)
 	    plyr->message = DEH_String(STSTR_NOMUS);
 	  else
 	    S_ChangeMusic(musnum, 1);
--- a/src/heretic/s_sound.c
+++ b/src/heretic/s_sound.c
@@ -513,7 +513,7 @@
 
 void S_Init(void)
 {
-    I_SetOPLDriverVer(opl_v_old);
+    I_SetOPLDriverVer(opl_doom2_1_666);
     soundCurve = Z_Malloc(MAX_SND_DIST, PU_STATIC, NULL);
     if (snd_Channels > 8)
     {
--- a/src/hexen/s_sound.c
+++ b/src/hexen/s_sound.c
@@ -787,7 +787,7 @@
 
 void S_Init(void)
 {
-    I_SetOPLDriverVer(opl_v_old);
+    I_SetOPLDriverVer(opl_doom2_1_666);
     SoundCurve = W_CacheLumpName("SNDCURVE", PU_STATIC);
 //      SoundCurve = Z_Malloc(MAX_SND_DIST, PU_STATIC, NULL);
 
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -307,7 +307,7 @@
     124, 124, 125, 125, 126, 126, 127, 127
 };
 
-static opl_driver_ver_t opl_drv_ver = opl_v_new;
+static opl_driver_ver_t opl_drv_ver = opl_doom_1_9;
 static boolean music_initialized = false;
 
 //static boolean musicpaused = false;
@@ -470,7 +470,7 @@
     *rover = voice;
     voice->next = NULL;
 
-    if (next != NULL && double_voice && opl_drv_ver == opl_v_old)
+    if (next != NULL && double_voice && opl_drv_ver != opl_doom_1_9)
     {
         VoiceKeyOff(next);
         ReleaseVoice(next);
@@ -770,13 +770,32 @@
     ReleaseVoice(result);
 }
 
-// Alternate version of ReplaceExistingVoice() used when emulating old
-// versions of the DMX library used in Heretic and Hexen.
+// Alternate versions of ReplaceExistingVoice() used when emulating old
+// versions of the DMX library used in Doom 1.666, Heretic and Hexen.
 
-static void ReplaceExistingVoiceOld(opl_channel_data_t *channel)
+static void ReplaceExistingVoiceDoom1(void)
 {
     opl_voice_t *rover;
     opl_voice_t *result;
+
+    result = voice_alloced_list;
+
+    for (rover = voice_alloced_list; rover != NULL; rover = rover->next)
+    {
+        if (rover->channel > result->channel)
+        {
+            result = rover;
+        }
+    }
+
+    VoiceKeyOff(result);
+    ReleaseVoice(result);
+}
+
+static void ReplaceExistingVoiceDoom2(opl_channel_data_t *channel)
+{
+    opl_voice_t *rover;
+    opl_voice_t *result;
     opl_voice_t *roverend;
     int i;
     int priority;
@@ -918,6 +937,11 @@
 {
     opl_voice_t *voice;
 
+    if (!opl_opl3mode && opl_drv_ver == opl_doom1_1_666)
+    {
+        instrument_voice = 0;
+    }
+
     // Find a voice to use for this new note.
 
     voice = GetFreeVoice();
@@ -962,7 +986,7 @@
 {
     genmidi_instr_t *instrument;
     opl_channel_data_t *channel;
-    unsigned int note, key, volume;
+    unsigned int note, key, volume, voicenum;
     boolean double_voice;
 
 /*
@@ -1009,43 +1033,66 @@
 
     double_voice = (SHORT(instrument->flags) & GENMIDI_FLAG_2VOICE) != 0;
 
-    if (opl_drv_ver == opl_v_old)
+    switch (opl_drv_ver)
     {
-        if (voice_alloced_num == num_opl_voices)
-        {
-            ReplaceExistingVoiceOld(channel);
-        }
-        if (voice_alloced_num == num_opl_voices - 1 && double_voice)
-        {
-            ReplaceExistingVoiceOld(channel);
-        }
+        case opl_doom1_1_666:
+            voicenum = double_voice + 1;
+            if (!opl_opl3mode)
+            {
+                voicenum = 1;
+            }
+            while (voice_alloced_num > num_opl_voices - voicenum)
+            {
+                ReplaceExistingVoiceDoom1();
+            }
 
-        // Find and program a voice for this instrument.  If this
-        // is a double voice instrument, we must do this twice.
+            // Find and program a voice for this instrument.  If this
+            // is a double voice instrument, we must do this twice.
 
-        if (double_voice)
-        {
-            VoiceKeyOn(channel, instrument, 1, note, key, volume);
-        }
+            if (double_voice)
+            {
+                VoiceKeyOn(channel, instrument, 1, note, key, volume);
+            }
 
-        VoiceKeyOn(channel, instrument, 0, note, key, volume);
-    }
-    else
-    {
-        if (voice_free_list == NULL)
-        {
-            ReplaceExistingVoice();
-        }
+            VoiceKeyOn(channel, instrument, 0, note, key, volume);
+            break;
+        case opl_doom2_1_666:
+            if (voice_alloced_num == num_opl_voices)
+            {
+                ReplaceExistingVoiceDoom2(channel);
+            }
+            if (voice_alloced_num == num_opl_voices - 1 && double_voice)
+            {
+                ReplaceExistingVoiceDoom2(channel);
+            }
 
-        // Find and program a voice for this instrument.  If this
-        // is a double voice instrument, we must do this twice.
+            // Find and program a voice for this instrument.  If this
+            // is a double voice instrument, we must do this twice.
 
-        VoiceKeyOn(channel, instrument, 0, note, key, volume);
+            if (double_voice)
+            {
+                VoiceKeyOn(channel, instrument, 1, note, key, volume);
+            }
 
-        if (double_voice)
-        {
-            VoiceKeyOn(channel, instrument, 1, note, key, volume);
-        }
+            VoiceKeyOn(channel, instrument, 0, note, key, volume);
+            break;
+        default:
+        case opl_doom_1_9:
+            if (voice_free_list == NULL)
+            {
+                ReplaceExistingVoice();
+            }
+
+            // Find and program a voice for this instrument.  If this
+            // is a double voice instrument, we must do this twice.
+
+            VoiceKeyOn(channel, instrument, 0, note, key, volume);
+
+            if (double_voice)
+            {
+                VoiceKeyOn(channel, instrument, 1, note, key, volume);
+            }
+            break;
     }
 }
 
--- a/src/i_sound.h
+++ b/src/i_sound.h
@@ -239,8 +239,9 @@
 
 // DMX version to emulate for OPL emulation:
 typedef enum {
-    opl_v_old,   // Hexen, Heretic
-    opl_v_new    // Doom, Strife
+    opl_doom1_1_666,    // Doom 1 v1.666
+    opl_doom2_1_666,    // Doom 2 v1.666, Hexen, Heretic
+    opl_doom_1_9        // Doom v1.9, Strife
 } opl_driver_ver_t;
 
 void I_SetOPLDriverVer(opl_driver_ver_t ver);
--- a/src/strife/s_sound.c
+++ b/src/strife/s_sound.c
@@ -138,7 +138,7 @@
 {  
     int i;
 
-    I_SetOPLDriverVer(opl_v_new);
+    I_SetOPLDriverVer(opl_doom_1_9);
     I_PrecacheSounds(S_sfx, NUMSFX);
 
     S_SetSfxVolume(sfxVolume);