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);