mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-18 02:21:47 +00:00
Merge branch 'EOL-35' into EOL
# Conflicts: # src/p_enemy.c
This commit is contained in:
commit
4bd2781055
56 changed files with 4363 additions and 2450 deletions
21
src/Makefile
21
src/Makefile
|
@ -64,6 +64,7 @@
|
||||||
# Compile without 3D sound support, add 'NOHS=1'
|
# Compile without 3D sound support, add 'NOHS=1'
|
||||||
# Compile with GDBstubs, add 'RDB=1'
|
# Compile with GDBstubs, add 'RDB=1'
|
||||||
# Compile without PNG, add 'NOPNG=1'
|
# Compile without PNG, add 'NOPNG=1'
|
||||||
|
# Compile without zlib, add 'NOZLIB=1'
|
||||||
#
|
#
|
||||||
# Addon for SDL:
|
# Addon for SDL:
|
||||||
# To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config'
|
# To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config'
|
||||||
|
@ -107,6 +108,7 @@ include Makefile.cfg
|
||||||
|
|
||||||
ifdef DUMMY
|
ifdef DUMMY
|
||||||
NOPNG=1
|
NOPNG=1
|
||||||
|
NOZLIB=1
|
||||||
NONET=1
|
NONET=1
|
||||||
NOHW=1
|
NOHW=1
|
||||||
NOHS=1
|
NOHS=1
|
||||||
|
@ -269,13 +271,6 @@ LIBS+=$(PNG_LDFLAGS)
|
||||||
CFLAGS+=$(PNG_CFLAGS)
|
CFLAGS+=$(PNG_CFLAGS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ZLIB_PKGCONFIG?=zlib
|
|
||||||
ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags)
|
|
||||||
ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs)
|
|
||||||
|
|
||||||
LIBS+=$(ZLIB_LDFLAGS)
|
|
||||||
CFLAGS+=$(ZLIB_CFLAGS)
|
|
||||||
|
|
||||||
ifdef HAVE_LIBGME
|
ifdef HAVE_LIBGME
|
||||||
OPTS+=-DHAVE_LIBGME
|
OPTS+=-DHAVE_LIBGME
|
||||||
|
|
||||||
|
@ -287,6 +282,18 @@ LIBS+=$(LIBGME_LDFLAGS)
|
||||||
CFLAGS+=$(LIBGME_CFLAGS)
|
CFLAGS+=$(LIBGME_CFLAGS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifndef NOZLIB
|
||||||
|
OPTS+=-DHAVE_ZLIB
|
||||||
|
ZLIB_PKGCONFIG?=zlib
|
||||||
|
ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags)
|
||||||
|
ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs)
|
||||||
|
|
||||||
|
LIBS+=$(ZLIB_LDFLAGS)
|
||||||
|
CFLAGS+=$(ZLIB_CFLAGS)
|
||||||
|
else
|
||||||
|
NOPNG=1
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef STATIC
|
ifdef STATIC
|
||||||
LIBS:=-static $(LIBS)
|
LIBS:=-static $(LIBS)
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -21,13 +21,14 @@ void I_ShutdownSound(void){}
|
||||||
// SFX I/O
|
// SFX I/O
|
||||||
//
|
//
|
||||||
|
|
||||||
INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority)
|
INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority, INT32 channel)
|
||||||
{
|
{
|
||||||
(void)id;
|
(void)id;
|
||||||
(void)vol;
|
(void)vol;
|
||||||
(void)sep;
|
(void)sep;
|
||||||
(void)pitch;
|
(void)pitch;
|
||||||
(void)priority;
|
(void)priority;
|
||||||
|
(void)channel;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,90 +56,87 @@ void I_SetSfxVolume(INT32 volume)
|
||||||
(void)volume;
|
(void)volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/// ------------------------
|
||||||
// MUSIC I/O
|
// MUSIC SYSTEM
|
||||||
//
|
/// ------------------------
|
||||||
|
|
||||||
UINT8 music_started = 0;
|
UINT8 music_started = 0;
|
||||||
|
UINT8 digmusic_started = 0;
|
||||||
|
|
||||||
void I_InitMusic(void){}
|
void I_InitMusic(void){}
|
||||||
|
|
||||||
void I_ShutdownMusic(void){}
|
void I_ShutdownMusic(void){}
|
||||||
|
|
||||||
void I_PauseSong(INT32 handle)
|
/// ------------------------
|
||||||
|
// MUSIC PROPERTIES
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
musictype_t I_SongType(void)
|
||||||
{
|
{
|
||||||
(void)handle;
|
return MU_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_ResumeSong(INT32 handle)
|
boolean I_SongPlaying(void)
|
||||||
{
|
{
|
||||||
(void)handle;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
boolean I_SongPaused(void)
|
||||||
// MIDI I/O
|
|
||||||
//
|
|
||||||
|
|
||||||
UINT8 midimusic_started = 0;
|
|
||||||
|
|
||||||
void I_InitMIDIMusic(void){}
|
|
||||||
|
|
||||||
void I_ShutdownMIDIMusic(void){}
|
|
||||||
|
|
||||||
void I_SetMIDIMusicVolume(INT32 volume)
|
|
||||||
{
|
{
|
||||||
(void)volume;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT32 I_RegisterSong(void *data, size_t len)
|
/// ------------------------
|
||||||
{
|
// MUSIC EFFECTS
|
||||||
(void)data;
|
/// ------------------------
|
||||||
(void)len;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_PlaySong(INT32 handle, INT32 looping)
|
|
||||||
{
|
|
||||||
(void)handle;
|
|
||||||
(void)looping;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_StopSong(INT32 handle)
|
|
||||||
{
|
|
||||||
(void)handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_UnRegisterSong(INT32 handle)
|
|
||||||
{
|
|
||||||
(void)handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// DIGMUSIC I/O
|
|
||||||
//
|
|
||||||
|
|
||||||
UINT8 digmusic_started = 0;
|
|
||||||
|
|
||||||
void I_InitDigMusic(void){}
|
|
||||||
|
|
||||||
void I_ShutdownDigMusic(void){}
|
|
||||||
|
|
||||||
boolean I_StartDigSong(const char *musicname, INT32 looping)
|
|
||||||
{
|
|
||||||
(void)musicname;
|
|
||||||
(void)looping;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_StopDigSong(void){}
|
|
||||||
|
|
||||||
void I_SetDigMusicVolume(INT32 volume)
|
|
||||||
{
|
|
||||||
(void)volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_SetSongSpeed(float speed)
|
boolean I_SetSongSpeed(float speed)
|
||||||
{
|
{
|
||||||
(void)speed;
|
(void)speed;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC PLAYBACK
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
UINT8 midimusic_started = 0;
|
||||||
|
|
||||||
|
boolean I_LoadSong(char *data, size_t len)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
(void)len;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_UnloadSong()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_PlaySong(boolean looping)
|
||||||
|
{
|
||||||
|
(void)handle;
|
||||||
|
(void)looping;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_StopSong(void)
|
||||||
|
{
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_PauseSong(void)
|
||||||
|
{
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ResumeSong(void)
|
||||||
|
{
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_SetMusicVolume(INT32 volume)
|
||||||
|
{
|
||||||
|
(void)volume;
|
||||||
|
}
|
||||||
|
|
25
src/d_main.c
25
src/d_main.c
|
@ -112,13 +112,10 @@ INT32 postimgparam;
|
||||||
postimg_t postimgtype2 = postimg_none;
|
postimg_t postimgtype2 = postimg_none;
|
||||||
INT32 postimgparam2;
|
INT32 postimgparam2;
|
||||||
|
|
||||||
boolean nomidimusic = false, nosound = false;
|
|
||||||
boolean nodigimusic = false; // No fmod-based music
|
|
||||||
|
|
||||||
// These variables are only true if
|
// These variables are only true if
|
||||||
// the respective sound system is initialized
|
// whether the respective sound system is disabled
|
||||||
// and active, but no sounds/music should play.
|
// or they're init'ed, but the player just toggled them
|
||||||
boolean music_disabled = false;
|
boolean midi_disabled = false;
|
||||||
boolean sound_disabled = false;
|
boolean sound_disabled = false;
|
||||||
boolean digital_disabled = false;
|
boolean digital_disabled = false;
|
||||||
|
|
||||||
|
@ -1192,27 +1189,27 @@ void D_SRB2Main(void)
|
||||||
// setting up sound
|
// setting up sound
|
||||||
if (dedicated)
|
if (dedicated)
|
||||||
{
|
{
|
||||||
nosound = true;
|
sound_disabled = true;
|
||||||
nomidimusic = nodigimusic = true;
|
midi_disabled = digital_disabled = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CONS_Printf("S_Init(): Setting up sound.\n");
|
CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n");
|
||||||
}
|
}
|
||||||
if (M_CheckParm("-nosound"))
|
if (M_CheckParm("-nosound"))
|
||||||
nosound = true;
|
sound_disabled = true;
|
||||||
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
|
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
|
||||||
nomidimusic = nodigimusic = true;
|
midi_disabled = digital_disabled = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (M_CheckParm("-nomidimusic"))
|
if (M_CheckParm("-nomidimusic"))
|
||||||
nomidimusic = true; ; // WARNING: DOS version initmusic in I_StartupSound
|
midi_disabled = true; ; // WARNING: DOS version initmusic in I_StartupSound
|
||||||
if (M_CheckParm("-nodigmusic"))
|
if (M_CheckParm("-nodigmusic"))
|
||||||
nodigimusic = true; // WARNING: DOS version initmusic in I_StartupSound
|
digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
|
||||||
}
|
}
|
||||||
I_StartupSound();
|
I_StartupSound();
|
||||||
I_InitMusic();
|
I_InitMusic();
|
||||||
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
|
S_InitSfxChannels(cv_soundvolume.value);
|
||||||
|
|
||||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||||
ST_Init();
|
ST_Init();
|
||||||
|
|
|
@ -4061,6 +4061,7 @@ static void Command_RestartAudio_f(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
S_StopMusic();
|
S_StopMusic();
|
||||||
|
S_StopSounds();
|
||||||
I_ShutdownMusic();
|
I_ShutdownMusic();
|
||||||
I_ShutdownSound();
|
I_ShutdownSound();
|
||||||
I_StartupSound();
|
I_StartupSound();
|
||||||
|
@ -4069,11 +4070,9 @@ static void Command_RestartAudio_f(void)
|
||||||
// These must be called or no sound and music until manually set.
|
// These must be called or no sound and music until manually set.
|
||||||
|
|
||||||
I_SetSfxVolume(cv_soundvolume.value);
|
I_SetSfxVolume(cv_soundvolume.value);
|
||||||
I_SetDigMusicVolume(cv_digmusicvolume.value);
|
S_SetMusicVolume(cv_digmusicvolume.value, cv_midimusicvolume.value);
|
||||||
I_SetMIDIMusicVolume(cv_midimusicvolume.value);
|
|
||||||
if (Playing()) // Gotta make sure the player is in a level
|
if (Playing()) // Gotta make sure the player is in a level
|
||||||
P_RestoreMusic(&players[consoleplayer]);
|
P_RestoreMusic(&players[consoleplayer]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Quits a game and returns to the title screen.
|
/** Quits a game and returns to the title screen.
|
||||||
|
|
|
@ -1196,8 +1196,10 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
||||||
else if (fastcmp(word2, "NORMAL")) i = 0;
|
else if (fastcmp(word2, "NORMAL")) i = 0;
|
||||||
else if (fastcmp(word2, "BOSS")) i = 1;
|
else if (fastcmp(word2, "BOSS")) i = 1;
|
||||||
else if (fastcmp(word2, "ERZ3")) i = 2;
|
else if (fastcmp(word2, "ERZ3")) i = 2;
|
||||||
|
else if (fastcmp(word2, "NIGHTS")) i = 3;
|
||||||
|
else if (fastcmp(word2, "NIGHTSLINK")) i = 4;
|
||||||
|
|
||||||
if (i >= -1 && i <= 2) // -1 for no bonus. Max is 2.
|
if (i >= -1 && i <= 4) // -1 for no bonus. Max is 4.
|
||||||
mapheaderinfo[num-1]->bonustype = (SINT8)i;
|
mapheaderinfo[num-1]->bonustype = (SINT8)i;
|
||||||
else
|
else
|
||||||
deh_warning("Level header %d: invalid bonus type number %d", num, i);
|
deh_warning("Level header %d: invalid bonus type number %d", num, i);
|
||||||
|
@ -8867,17 +8869,17 @@ static int lib_getActionName(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_settop(L, 1); // set top of stack to 1 (removing any extra args, which there shouldn't be)
|
lua_settop(L, 1); // set top of stack to 1 (removing any extra args, which there shouldn't be)
|
||||||
// get the name for this action, if possible.
|
// get the name for this action, if possible.
|
||||||
lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS);
|
lua_getfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS);
|
||||||
lua_pushnil(gL);
|
lua_pushnil(L);
|
||||||
// Lua stack at this point:
|
// Lua stack at this point:
|
||||||
// 1 ... -2 -1
|
// 1 ... -2 -1
|
||||||
// arg ... LREG_ACTIONS nil
|
// arg ... LREG_ACTIONS nil
|
||||||
while (lua_next(gL, -2))
|
while (lua_next(L, -2))
|
||||||
{
|
{
|
||||||
// Lua stack at this point:
|
// Lua stack at this point:
|
||||||
// 1 ... -3 -2 -1
|
// 1 ... -3 -2 -1
|
||||||
// arg ... LREG_ACTIONS "A_ACTION" function
|
// arg ... LREG_ACTIONS "A_ACTION" function
|
||||||
if (lua_rawequal(gL, -1, 1)) // is this the same as the arg?
|
if (lua_rawequal(L, -1, 1)) // is this the same as the arg?
|
||||||
{
|
{
|
||||||
// make sure the key (i.e. "A_ACTION") is a string first
|
// make sure the key (i.e. "A_ACTION") is a string first
|
||||||
// (note: we don't use lua_isstring because it also returns true for numbers)
|
// (note: we don't use lua_isstring because it also returns true for numbers)
|
||||||
|
@ -8886,12 +8888,12 @@ static int lib_getActionName(lua_State *L)
|
||||||
lua_pushvalue(L, -2); // push "A_ACTION" string to top of stack
|
lua_pushvalue(L, -2); // push "A_ACTION" string to top of stack
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lua_pop(gL, 2); // pop the name and function
|
lua_pop(L, 2); // pop the name and function
|
||||||
break; // probably should have succeeded but we didn't, so end the loop
|
break; // probably should have succeeded but we didn't, so end the loop
|
||||||
}
|
}
|
||||||
lua_pop(gL, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
lua_pop(gL, 1); // pop LREG_ACTIONS
|
lua_pop(L, 1); // pop LREG_ACTIONS
|
||||||
return 0; // return nothing (don't error)
|
return 0; // return nothing (don't error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,21 +134,12 @@ FUNCINLINE static ATTRINLINE int Volset(int vol)
|
||||||
|
|
||||||
void I_SetSfxVolume(INT32 volume)
|
void I_SetSfxVolume(INT32 volume)
|
||||||
{
|
{
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
set_volume (Volset(volume),-1);
|
set_volume (Volset(volume),-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_SetMIDIMusicVolume(INT32 volume)
|
|
||||||
{
|
|
||||||
if (nomidimusic)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Now set volume on output device.
|
|
||||||
set_volume (-1, Volset(volume));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Starting a sound means adding it
|
// Starting a sound means adding it
|
||||||
// to the current list of active sounds
|
// to the current list of active sounds
|
||||||
|
@ -165,11 +156,13 @@ INT32 I_StartSound ( sfxenum_t id,
|
||||||
INT32 vol,
|
INT32 vol,
|
||||||
INT32 sep,
|
INT32 sep,
|
||||||
INT32 pitch,
|
INT32 pitch,
|
||||||
INT32 priority )
|
INT32 priority,
|
||||||
|
INT32 channel)
|
||||||
{
|
{
|
||||||
int voice;
|
int voice;
|
||||||
|
(void)channel;
|
||||||
|
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// UNUSED
|
// UNUSED
|
||||||
|
@ -190,7 +183,7 @@ void I_StopSound (INT32 handle)
|
||||||
// an setting the channel to zero.
|
// an setting the channel to zero.
|
||||||
int voice=handle & (VIRTUAL_VOICES-1);
|
int voice=handle & (VIRTUAL_VOICES-1);
|
||||||
|
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (voice_check(voice)==S_sfx[handle>>VOICESSHIFT].data)
|
if (voice_check(voice)==S_sfx[handle>>VOICESSHIFT].data)
|
||||||
|
@ -199,7 +192,7 @@ void I_StopSound (INT32 handle)
|
||||||
|
|
||||||
INT32 I_SoundIsPlaying(INT32 handle)
|
INT32 I_SoundIsPlaying(INT32 handle)
|
||||||
{
|
{
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (voice_check(handle & (VIRTUAL_VOICES-1))==S_sfx[handle>>VOICESSHIFT].data)
|
if (voice_check(handle & (VIRTUAL_VOICES-1))==S_sfx[handle>>VOICESSHIFT].data)
|
||||||
|
@ -229,7 +222,7 @@ void I_UpdateSoundParams( INT32 handle,
|
||||||
int voice=handle & (VIRTUAL_VOICES-1);
|
int voice=handle & (VIRTUAL_VOICES-1);
|
||||||
int numsfx=handle>>VOICESSHIFT;
|
int numsfx=handle>>VOICESSHIFT;
|
||||||
|
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (voice_check(voice)==S_sfx[numsfx].data)
|
if (voice_check(voice)==S_sfx[numsfx].data)
|
||||||
|
@ -270,17 +263,17 @@ void I_StartupSound(void)
|
||||||
char err[255];
|
char err[255];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
sfxcard=DIGI_NONE;
|
sfxcard=DIGI_NONE;
|
||||||
else
|
else
|
||||||
sfxcard=DIGI_AUTODETECT;
|
sfxcard=DIGI_AUTODETECT;
|
||||||
|
|
||||||
if (nomidimusic)
|
if (midi_disabled)
|
||||||
midicard=MIDI_NONE;
|
midicard=MIDI_NONE;
|
||||||
else
|
else
|
||||||
midicard=MIDI_AUTODETECT; //DetectMusicCard();
|
midicard=MIDI_AUTODETECT; //DetectMusicCard();
|
||||||
|
|
||||||
nodigimusic=true; //Alam: No OGG/MP3/IT/MOD support
|
digital_disabled=true; //Alam: No OGG/MP3/IT/MOD support
|
||||||
|
|
||||||
// Secure and configure sound device first.
|
// Secure and configure sound device first.
|
||||||
CONS_Printf("I_StartupSound: ");
|
CONS_Printf("I_StartupSound: ");
|
||||||
|
@ -293,8 +286,8 @@ void I_StartupSound(void)
|
||||||
{
|
{
|
||||||
sprintf (err,"Sound init error : %s\n",allegro_error);
|
sprintf (err,"Sound init error : %s\n",allegro_error);
|
||||||
CONS_Error (err);
|
CONS_Error (err);
|
||||||
nosound=true;
|
sound_disabled=true;
|
||||||
nomidimusic=true;
|
midi_disabled=true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -321,7 +314,11 @@ static MIDI* currsong; //im assuming only 1 song will be played at once
|
||||||
static int islooping=0;
|
static int islooping=0;
|
||||||
static int musicdies=-1;
|
static int musicdies=-1;
|
||||||
UINT8 music_started=0;
|
UINT8 music_started=0;
|
||||||
|
boolean songpaused=false;
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC SYSTEM
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
/* load_midi_mem:
|
/* load_midi_mem:
|
||||||
* Loads a standard MIDI file from memory, returning a pointer to
|
* Loads a standard MIDI file from memory, returning a pointer to
|
||||||
|
@ -389,116 +386,66 @@ static MIDI *load_midi_mem(char *mempointer,int *e)
|
||||||
return midi;
|
return midi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_InitMIDIMusic(void)
|
void I_InitMusic(void)
|
||||||
{
|
{
|
||||||
if (nomidimusic)
|
if (midi_disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
I_AddExitFunc(I_ShutdownMusic);
|
I_AddExitFunc(I_ShutdownMusic);
|
||||||
music_started = true;
|
music_started = true;
|
||||||
}
|
songpaused = false;
|
||||||
|
|
||||||
void I_ShutdownMIDIMusic(void)
|
|
||||||
{
|
|
||||||
if ( !music_started )
|
|
||||||
return;
|
|
||||||
|
|
||||||
I_StopSong(1);
|
|
||||||
|
|
||||||
music_started=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_InitDigMusic(void)
|
|
||||||
{
|
|
||||||
// CONS_Printf("Digital music not yet supported under DOS.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_ShutdownDigMusic(void)
|
|
||||||
{
|
|
||||||
// CONS_Printf("Digital music not yet supported under DOS.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_InitMusic(void)
|
|
||||||
{
|
|
||||||
if (!nodigimusic)
|
|
||||||
I_InitDigMusic();
|
|
||||||
if (!nomidimusic)
|
|
||||||
I_InitMIDIMusic();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_ShutdownMusic(void)
|
void I_ShutdownMusic(void)
|
||||||
{
|
{
|
||||||
I_ShutdownMIDIMusic();
|
if ( !music_started )
|
||||||
I_ShutdownDigMusic();
|
return;
|
||||||
|
|
||||||
|
I_StopSong();
|
||||||
|
|
||||||
|
music_started=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean I_PlaySong(INT32 handle, INT32 looping)
|
/// ------------------------
|
||||||
{
|
// MUSIC PROPERTIES
|
||||||
handle = 0;
|
/// ------------------------
|
||||||
if (nomidimusic)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
islooping = looping;
|
musictype_t I_SongType(void)
|
||||||
musicdies = gametic + NEWTICRATE*30;
|
{
|
||||||
if (play_midi(currsong,looping)==0)
|
if (currsong)
|
||||||
return true;
|
return MU_MID;
|
||||||
|
else
|
||||||
|
return MU_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SongPlaying()
|
||||||
|
{
|
||||||
|
return (boolean)currsong;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SongPaused()
|
||||||
|
{
|
||||||
|
return songpaused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC EFFECTS
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
boolean I_SetSongSpeed(float speed)
|
||||||
|
{
|
||||||
|
(void)speed;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_PauseSong (INT32 handle)
|
/// ------------------------
|
||||||
{
|
// MUSIC PLAYBACK
|
||||||
handle = 0;
|
/// ------------------------
|
||||||
if (nomidimusic)
|
|
||||||
return;
|
|
||||||
|
|
||||||
midi_pause();
|
boolean I_LoadSong(char *data, size_t len)
|
||||||
}
|
|
||||||
|
|
||||||
void I_ResumeSong (INT32 handle)
|
|
||||||
{
|
|
||||||
handle = 0;
|
|
||||||
if (nomidimusic)
|
|
||||||
return;
|
|
||||||
|
|
||||||
midi_resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_StopSong(INT32 handle)
|
|
||||||
{
|
|
||||||
handle = 0;
|
|
||||||
if (nomidimusic)
|
|
||||||
return;
|
|
||||||
|
|
||||||
islooping = 0;
|
|
||||||
musicdies = 0;
|
|
||||||
stop_midi();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the song playing?
|
|
||||||
#if 0
|
|
||||||
int I_QrySongPlaying(int handle)
|
|
||||||
{
|
|
||||||
if (nomidimusic)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
//return islooping || musicdies > gametic;
|
|
||||||
return (midi_pos==-1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void I_UnRegisterSong(INT32 handle)
|
|
||||||
{
|
|
||||||
handle = 0;
|
|
||||||
if (nomidimusic)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//destroy_midi(currsong);
|
|
||||||
}
|
|
||||||
|
|
||||||
INT32 I_RegisterSong(void *data, size_t len)
|
|
||||||
{
|
{
|
||||||
int e = len; //Alam: For error
|
int e = len; //Alam: For error
|
||||||
if (nomidimusic)
|
if (midi_disabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (memcmp(data,"MThd",4)==0) // support mid file in WAD !!!
|
if (memcmp(data,"MThd",4)==0) // support mid file in WAD !!!
|
||||||
|
@ -520,32 +467,81 @@ INT32 I_RegisterSong(void *data, size_t len)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \todo Add OGG/MP3 support for dos
|
void I_UnloadSong(void)
|
||||||
boolean I_StartDigSong(const char *musicname, INT32 looping)
|
|
||||||
{
|
{
|
||||||
musicname = NULL;
|
handle = 0;
|
||||||
looping = 0;
|
if (midi_disabled)
|
||||||
//CONS_Printf("I_StartDigSong: Not yet supported under DOS.\n");
|
return;
|
||||||
|
|
||||||
|
//destroy_midi(currsong);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_PlaySong(boolean looping)
|
||||||
|
{
|
||||||
|
handle = 0;
|
||||||
|
if (midi_disabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
islooping = looping;
|
||||||
|
musicdies = gametic + NEWTICRATE*30;
|
||||||
|
if (play_midi(currsong,looping)==0)
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_StopDigSong(void)
|
void I_StopSong(void)
|
||||||
{
|
{
|
||||||
// CONS_Printf("I_StopDigSong: Not yet supported under DOS.\n");
|
handle = 0;
|
||||||
|
if (midi_disabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
islooping = 0;
|
||||||
|
musicdies = 0;
|
||||||
|
stop_midi();
|
||||||
|
songpaused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_SetDigMusicVolume(INT32 volume)
|
void I_PauseSong (INT32 handle)
|
||||||
{
|
{
|
||||||
volume = 0;
|
handle = 0;
|
||||||
if (nodigimusic)
|
if (midi_disabled)
|
||||||
|
return;
|
||||||
|
midi_pause();
|
||||||
|
songpaused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ResumeSong (INT32 handle)
|
||||||
|
{
|
||||||
|
handle = 0;
|
||||||
|
if (midi_disabled)
|
||||||
|
return;
|
||||||
|
midi_resume();
|
||||||
|
songpaused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_SetMusicVolume(INT32 volume)
|
||||||
|
{
|
||||||
|
if (midi_disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Now set volume on output device.
|
// Now set volume on output device.
|
||||||
// CONS_Printf("Digital music not yet supported under DOS.\n");
|
set_volume (-1, Volset(volume));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean I_SetSongSpeed(float speed)
|
boolean I_SetSongTrack(INT32 track)
|
||||||
{
|
{
|
||||||
(void)speed;
|
(void)track;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is the song playing?
|
||||||
|
#if 0
|
||||||
|
int I_QrySongPlaying(int handle)
|
||||||
|
{
|
||||||
|
if (midi_disabled)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
//return islooping || musicdies > gametic;
|
||||||
|
return (midi_pos==-1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -90,10 +90,7 @@ extern boolean fromlevelselect;
|
||||||
// Internal parameters for sound rendering.
|
// Internal parameters for sound rendering.
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
extern boolean nomidimusic; // defined in d_main.c
|
extern boolean midi_disabled;
|
||||||
extern boolean nosound;
|
|
||||||
extern boolean nodigimusic;
|
|
||||||
extern boolean music_disabled;
|
|
||||||
extern boolean sound_disabled;
|
extern boolean sound_disabled;
|
||||||
extern boolean digital_disabled;
|
extern boolean digital_disabled;
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,14 @@ void I_UpdateSound(void){};
|
||||||
// SFX I/O
|
// SFX I/O
|
||||||
//
|
//
|
||||||
|
|
||||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
|
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
|
||||||
{
|
{
|
||||||
(void)id;
|
(void)id;
|
||||||
(void)vol;
|
(void)vol;
|
||||||
(void)sep;
|
(void)sep;
|
||||||
(void)pitch;
|
(void)pitch;
|
||||||
(void)priority;
|
(void)priority;
|
||||||
|
(void)channel;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,82 +58,36 @@ void I_SetSfxVolume(UINT8 volume)
|
||||||
(void)volume;
|
(void)volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/// ------------------------
|
||||||
// MUSIC I/O
|
// MUSIC SYSTEM
|
||||||
//
|
/// ------------------------
|
||||||
|
|
||||||
void I_InitMusic(void){}
|
void I_InitMusic(void){}
|
||||||
|
|
||||||
void I_ShutdownMusic(void){}
|
void I_ShutdownMusic(void){}
|
||||||
|
|
||||||
void I_PauseSong(INT32 handle)
|
/// ------------------------
|
||||||
|
// MUSIC PROPERTIES
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
musictype_t I_SongType(void)
|
||||||
{
|
{
|
||||||
(void)handle;
|
return MU_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_ResumeSong(INT32 handle)
|
boolean I_SongPlaying(void)
|
||||||
{
|
{
|
||||||
(void)handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// MIDI I/O
|
|
||||||
//
|
|
||||||
|
|
||||||
void I_InitMIDIMusic(void){}
|
|
||||||
|
|
||||||
void I_ShutdownMIDIMusic(void){}
|
|
||||||
|
|
||||||
void I_SetMIDIMusicVolume(UINT8 volume)
|
|
||||||
{
|
|
||||||
(void)volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT32 I_RegisterSong(void *data, size_t len)
|
|
||||||
{
|
|
||||||
(void)data;
|
|
||||||
(void)len;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_PlaySong(INT32 handle, boolean looping)
|
|
||||||
{
|
|
||||||
(void)handle;
|
|
||||||
(void)looping;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_StopSong(INT32 handle)
|
boolean I_SongPaused(void)
|
||||||
{
|
{
|
||||||
(void)handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_UnRegisterSong(INT32 handle)
|
|
||||||
{
|
|
||||||
(void)handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// DIGMUSIC I/O
|
|
||||||
//
|
|
||||||
|
|
||||||
void I_InitDigMusic(void){}
|
|
||||||
|
|
||||||
void I_ShutdownDigMusic(void){}
|
|
||||||
|
|
||||||
boolean I_StartDigSong(const char *musicname, boolean looping)
|
|
||||||
{
|
|
||||||
(void)musicname;
|
|
||||||
(void)looping;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_StopDigSong(void){}
|
/// ------------------------
|
||||||
|
// MUSIC EFFECTS
|
||||||
void I_SetDigMusicVolume(UINT8 volume)
|
/// ------------------------
|
||||||
{
|
|
||||||
(void)volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_SetSongSpeed(float speed)
|
boolean I_SetSongSpeed(float speed)
|
||||||
{
|
{
|
||||||
|
@ -140,8 +95,51 @@ boolean I_SetSongSpeed(float speed)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC PLAYBACK
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
boolean I_LoadSong(char *data, size_t len)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
(void)len;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_UnloadSong(void)
|
||||||
|
{
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_PlaySong(boolean looping)
|
||||||
|
{
|
||||||
|
(void)handle;
|
||||||
|
(void)looping;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_StopSong(void)
|
||||||
|
{
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_PauseSong(void)
|
||||||
|
{
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ResumeSong(void)
|
||||||
|
{
|
||||||
|
(void)handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_SetMusicVolume(UINT8 volume)
|
||||||
|
{
|
||||||
|
(void)volume;
|
||||||
|
}
|
||||||
|
|
||||||
boolean I_SetSongTrack(int track)
|
boolean I_SetSongTrack(int track)
|
||||||
{
|
{
|
||||||
(void)track;
|
(void)track;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
|
@ -361,7 +361,7 @@ INT32 HW3S_I_StartSound(const void *origin_p, source3D_data_t *source_parm, chan
|
||||||
|
|
||||||
if (splitscreen) listenmobj2 = players[secondarydisplayplayer].mo;
|
if (splitscreen) listenmobj2 = players[secondarydisplayplayer].mo;
|
||||||
|
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
sfx = &S_sfx[sfx_id];
|
sfx = &S_sfx[sfx_id];
|
||||||
|
|
|
@ -1126,7 +1126,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lightnum = *list[i].lightlevel;
|
lightnum = *list[i].lightlevel;
|
||||||
colormap = list[i].extra_colormap;
|
colormap = *list[i].extra_colormap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2116,6 +2116,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fixed_t texturevpeg;
|
fixed_t texturevpeg;
|
||||||
|
boolean attachtobottom = false;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
boolean slopeskew = false; // skew FOF walls with slopes?
|
||||||
|
#endif
|
||||||
|
|
||||||
// Wow, how was this missing from OpenGL for so long?
|
// Wow, how was this missing from OpenGL for so long?
|
||||||
// ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software
|
// ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software
|
||||||
|
@ -2123,24 +2127,50 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
||||||
if (newline)
|
if (newline)
|
||||||
{
|
{
|
||||||
texturevpeg = sides[newline->sidenum[0]].rowoffset;
|
texturevpeg = sides[newline->sidenum[0]].rowoffset;
|
||||||
if (newline->flags & ML_DONTPEGBOTTOM)
|
attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM);
|
||||||
texturevpeg -= *rover->topheight - *rover->bottomheight;
|
#ifdef ESLOPE
|
||||||
|
slopeskew = !!(newline->flags & ML_DONTPEGTOP);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
texturevpeg = sides[rover->master->sidenum[0]].rowoffset;
|
texturevpeg = sides[rover->master->sidenum[0]].rowoffset;
|
||||||
if (gr_linedef->flags & ML_DONTPEGBOTTOM)
|
attachtobottom = !!(gr_linedef->flags & ML_DONTPEGBOTTOM);
|
||||||
texturevpeg -= *rover->topheight - *rover->bottomheight;
|
#ifdef ESLOPE
|
||||||
|
slopeskew = !!(rover->master->flags & ML_DONTPEGTOP);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
grTex = HWR_GetTexture(texnum);
|
grTex = HWR_GetTexture(texnum);
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
|
if (!slopeskew) // no skewing
|
||||||
wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY;
|
{
|
||||||
wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY;
|
if (attachtobottom)
|
||||||
wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY;
|
texturevpeg -= *rover->topheight - *rover->bottomheight;
|
||||||
|
wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
|
||||||
|
wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY;
|
||||||
|
wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY;
|
||||||
|
wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!attachtobottom) // skew by top
|
||||||
|
{
|
||||||
|
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||||
|
wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY;
|
||||||
|
wallVerts[1].t = (hS - lS + texturevpeg) * grTex->scaleY;
|
||||||
|
}
|
||||||
|
else // skew by bottom
|
||||||
|
{
|
||||||
|
wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY;
|
||||||
|
wallVerts[3].t = wallVerts[0].t - (h - l) * grTex->scaleY;
|
||||||
|
wallVerts[2].t = wallVerts[1].t - (hS - lS) * grTex->scaleY;
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
|
if (attachtobottom)
|
||||||
|
texturevpeg -= *rover->topheight - *rover->bottomheight;
|
||||||
wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
|
wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
|
||||||
wallVerts[0].t = wallVerts[1].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY;
|
wallVerts[0].t = wallVerts[1].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY;
|
||||||
#endif
|
#endif
|
||||||
|
@ -3486,12 +3516,12 @@ static void HWR_Subsector(size_t num)
|
||||||
light = R_GetPlaneLight(gr_frontsector, locFloorHeight, false);
|
light = R_GetPlaneLight(gr_frontsector, locFloorHeight, false);
|
||||||
if (gr_frontsector->floorlightsec == -1)
|
if (gr_frontsector->floorlightsec == -1)
|
||||||
floorlightlevel = *gr_frontsector->lightlist[light].lightlevel;
|
floorlightlevel = *gr_frontsector->lightlist[light].lightlevel;
|
||||||
floorcolormap = gr_frontsector->lightlist[light].extra_colormap;
|
floorcolormap = *gr_frontsector->lightlist[light].extra_colormap;
|
||||||
|
|
||||||
light = R_GetPlaneLight(gr_frontsector, locCeilingHeight, false);
|
light = R_GetPlaneLight(gr_frontsector, locCeilingHeight, false);
|
||||||
if (gr_frontsector->ceilinglightsec == -1)
|
if (gr_frontsector->ceilinglightsec == -1)
|
||||||
ceilinglightlevel = *gr_frontsector->lightlist[light].lightlevel;
|
ceilinglightlevel = *gr_frontsector->lightlist[light].lightlevel;
|
||||||
ceilingcolormap = gr_frontsector->lightlist[light].extra_colormap;
|
ceilingcolormap = *gr_frontsector->lightlist[light].extra_colormap;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub->sector->extra_colormap = gr_frontsector->extra_colormap;
|
sub->sector->extra_colormap = gr_frontsector->extra_colormap;
|
||||||
|
@ -3617,7 +3647,7 @@ static void HWR_Subsector(size_t num)
|
||||||
*rover->bottomheight,
|
*rover->bottomheight,
|
||||||
*gr_frontsector->lightlist[light].lightlevel,
|
*gr_frontsector->lightlist[light].lightlevel,
|
||||||
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent,
|
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent,
|
||||||
false, gr_frontsector->lightlist[light].extra_colormap);
|
false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3625,7 +3655,7 @@ static void HWR_Subsector(size_t num)
|
||||||
HWR_GetFlat(levelflats[*rover->bottompic].lumpnum);
|
HWR_GetFlat(levelflats[*rover->bottompic].lumpnum);
|
||||||
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
||||||
HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum,
|
HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum,
|
||||||
rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap);
|
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3680,7 +3710,7 @@ static void HWR_Subsector(size_t num)
|
||||||
*rover->topheight,
|
*rover->topheight,
|
||||||
*gr_frontsector->lightlist[light].lightlevel,
|
*gr_frontsector->lightlist[light].lightlevel,
|
||||||
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent,
|
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent,
|
||||||
false, gr_frontsector->lightlist[light].extra_colormap);
|
false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3689,7 +3719,7 @@ static void HWR_Subsector(size_t num)
|
||||||
HWR_GetFlat(levelflats[*rover->toppic].lumpnum);
|
HWR_GetFlat(levelflats[*rover->toppic].lumpnum);
|
||||||
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
||||||
HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum,
|
HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum,
|
||||||
rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap);
|
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4200,8 +4230,8 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t
|
||||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||||
lightlevel = *sector->lightlist[light].lightlevel;
|
lightlevel = *sector->lightlist[light].lightlevel;
|
||||||
|
|
||||||
if (sector->lightlist[light].extra_colormap)
|
if (*sector->lightlist[light].extra_colormap)
|
||||||
colormap = sector->lightlist[light].extra_colormap;
|
colormap = *sector->lightlist[light].extra_colormap;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4362,7 +4392,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
||||||
|
|
||||||
// Start with the lightlevel and colormap from the top of the sprite
|
// Start with the lightlevel and colormap from the top of the sprite
|
||||||
lightlevel = *list[sector->numlights - 1].lightlevel;
|
lightlevel = *list[sector->numlights - 1].lightlevel;
|
||||||
colormap = list[sector->numlights - 1].extra_colormap;
|
colormap = *list[sector->numlights - 1].extra_colormap;
|
||||||
i = 0;
|
i = 0;
|
||||||
temp = FLOAT_TO_FIXED(realtop);
|
temp = FLOAT_TO_FIXED(realtop);
|
||||||
|
|
||||||
|
@ -4378,7 +4408,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
||||||
{
|
{
|
||||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||||
lightlevel = *list[i-1].lightlevel;
|
lightlevel = *list[i-1].lightlevel;
|
||||||
colormap = list[i-1].extra_colormap;
|
colormap = *list[i-1].extra_colormap;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4386,7 +4416,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
||||||
i = R_GetPlaneLight(sector, temp, false);
|
i = R_GetPlaneLight(sector, temp, false);
|
||||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||||
lightlevel = *list[i].lightlevel;
|
lightlevel = *list[i].lightlevel;
|
||||||
colormap = list[i].extra_colormap;
|
colormap = *list[i].extra_colormap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < sector->numlights; i++)
|
for (i = 0; i < sector->numlights; i++)
|
||||||
|
@ -4402,7 +4432,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
||||||
{
|
{
|
||||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||||
lightlevel = *list[i].lightlevel;
|
lightlevel = *list[i].lightlevel;
|
||||||
colormap = list[i].extra_colormap;
|
colormap = *list[i].extra_colormap;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
|
@ -4734,8 +4764,8 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
|
||||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||||
lightlevel = *sector->lightlist[light].lightlevel;
|
lightlevel = *sector->lightlist[light].lightlevel;
|
||||||
|
|
||||||
if (sector->lightlist[light].extra_colormap)
|
if (*sector->lightlist[light].extra_colormap)
|
||||||
colormap = sector->lightlist[light].extra_colormap;
|
colormap = *sector->lightlist[light].extra_colormap;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5270,8 +5300,10 @@ static void HWR_AddSprites(sector_t *sec)
|
||||||
|
|
||||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||||
|
|
||||||
if (approx_dist <= limit_dist)
|
if (approx_dist > limit_dist)
|
||||||
HWR_ProjectSprite(thing);
|
continue;
|
||||||
|
|
||||||
|
HWR_ProjectSprite(thing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5293,8 +5325,10 @@ static void HWR_AddSprites(sector_t *sec)
|
||||||
|
|
||||||
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
||||||
|
|
||||||
if (approx_dist <= limit_dist)
|
if (approx_dist > limit_dist)
|
||||||
HWR_ProjectPrecipitationSprite(precipthing);
|
continue;
|
||||||
|
|
||||||
|
HWR_ProjectPrecipitationSprite(precipthing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5624,6 +5658,16 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||||
x1 = tr_x + x1 * rightcos;
|
x1 = tr_x + x1 * rightcos;
|
||||||
x2 = tr_x - x2 * rightcos;
|
x2 = tr_x - x2 * rightcos;
|
||||||
|
|
||||||
|
// okay, we can't return now... this is a hack, but weather isn't networked, so it should be ok
|
||||||
|
if (!(thing->precipflags & PCF_THUNK))
|
||||||
|
{
|
||||||
|
if (thing->precipflags & PCF_RAIN)
|
||||||
|
P_RainThinker(thing);
|
||||||
|
else
|
||||||
|
P_SnowThinker(thing);
|
||||||
|
thing->precipflags |= PCF_THUNK;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// store information in a vissprite
|
// store information in a vissprite
|
||||||
//
|
//
|
||||||
|
|
|
@ -1194,8 +1194,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||||
lightlevel = *sector->lightlist[light].lightlevel;
|
lightlevel = *sector->lightlist[light].lightlevel;
|
||||||
|
|
||||||
if (sector->lightlist[light].extra_colormap)
|
if (*sector->lightlist[light].extra_colormap)
|
||||||
colormap = sector->lightlist[light].extra_colormap;
|
colormap = *sector->lightlist[light].extra_colormap;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
140
src/i_sound.h
140
src/i_sound.h
|
@ -18,6 +18,21 @@
|
||||||
#include "sounds.h"
|
#include "sounds.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
|
||||||
|
// copied from SDL mixer, plus GME
|
||||||
|
typedef enum {
|
||||||
|
MU_NONE,
|
||||||
|
MU_CMD,
|
||||||
|
MU_WAV,
|
||||||
|
MU_MOD,
|
||||||
|
MU_MID,
|
||||||
|
MU_OGG,
|
||||||
|
MU_MP3,
|
||||||
|
MU_MP3_MAD_UNUSED, // use MU_MP3 instead
|
||||||
|
MU_FLAC,
|
||||||
|
MU_MODPLUG_UNUSED, // use MU_MOD instead
|
||||||
|
MU_GME
|
||||||
|
} musictype_t;
|
||||||
|
|
||||||
/** \brief Sound subsystem runing and waiting
|
/** \brief Sound subsystem runing and waiting
|
||||||
*/
|
*/
|
||||||
extern UINT8 sound_started;
|
extern UINT8 sound_started;
|
||||||
|
@ -51,9 +66,9 @@ void I_StartupSound(void);
|
||||||
*/
|
*/
|
||||||
void I_ShutdownSound(void);
|
void I_ShutdownSound(void);
|
||||||
|
|
||||||
//
|
/// ------------------------
|
||||||
// SFX I/O
|
/// SFX I/O
|
||||||
//
|
/// ------------------------
|
||||||
|
|
||||||
/** \brief Starts a sound in a particular sound channel.
|
/** \brief Starts a sound in a particular sound channel.
|
||||||
\param id sfxid
|
\param id sfxid
|
||||||
|
@ -64,7 +79,7 @@ void I_ShutdownSound(void);
|
||||||
|
|
||||||
\return sfx handle
|
\return sfx handle
|
||||||
*/
|
*/
|
||||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority);
|
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel);
|
||||||
|
|
||||||
/** \brief Stops a sound channel.
|
/** \brief Stops a sound channel.
|
||||||
|
|
||||||
|
@ -105,9 +120,10 @@ void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch);
|
||||||
*/
|
*/
|
||||||
void I_SetSfxVolume(UINT8 volume);
|
void I_SetSfxVolume(UINT8 volume);
|
||||||
|
|
||||||
//
|
/// ------------------------
|
||||||
// MUSIC I/O
|
// MUSIC SYSTEM
|
||||||
//
|
/// ------------------------
|
||||||
|
|
||||||
/** \brief Init the music systems
|
/** \brief Init the music systems
|
||||||
*/
|
*/
|
||||||
void I_InitMusic(void);
|
void I_InitMusic(void);
|
||||||
|
@ -116,41 +132,23 @@ void I_InitMusic(void);
|
||||||
*/
|
*/
|
||||||
void I_ShutdownMusic(void);
|
void I_ShutdownMusic(void);
|
||||||
|
|
||||||
/** \brief PAUSE game handling.
|
/// ------------------------
|
||||||
|
// MUSIC PROPERTIES
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
\param handle song handle
|
musictype_t I_SongType(void);
|
||||||
|
boolean I_SongPlaying(void);
|
||||||
|
boolean I_SongPaused(void);
|
||||||
|
|
||||||
\return void
|
/// ------------------------
|
||||||
*/
|
// MUSIC EFFECTS
|
||||||
void I_PauseSong(INT32 handle);
|
/// ------------------------
|
||||||
|
|
||||||
/** \brief RESUME game handling
|
boolean I_SetSongSpeed(float speed);
|
||||||
|
|
||||||
\param handle song handle
|
/// ------------------------
|
||||||
|
// MUSIC PLAYBACK
|
||||||
\return void
|
/// ------------------------
|
||||||
*/
|
|
||||||
void I_ResumeSong(INT32 handle);
|
|
||||||
|
|
||||||
//
|
|
||||||
// MIDI I/O
|
|
||||||
//
|
|
||||||
|
|
||||||
/** \brief Startup the MIDI music system
|
|
||||||
*/
|
|
||||||
void I_InitMIDIMusic(void);
|
|
||||||
|
|
||||||
/** \brief Shutdown the MIDI music system
|
|
||||||
*/
|
|
||||||
void I_ShutdownMIDIMusic(void);
|
|
||||||
|
|
||||||
/** \brief The I_SetMIDIMusicVolume function
|
|
||||||
|
|
||||||
\param volume volume to set at
|
|
||||||
|
|
||||||
\return void
|
|
||||||
*/
|
|
||||||
void I_SetMIDIMusicVolume(UINT8 volume);
|
|
||||||
|
|
||||||
/** \brief Registers a song handle to song data.
|
/** \brief Registers a song handle to song data.
|
||||||
|
|
||||||
|
@ -161,7 +159,16 @@ void I_SetMIDIMusicVolume(UINT8 volume);
|
||||||
|
|
||||||
\todo Remove this
|
\todo Remove this
|
||||||
*/
|
*/
|
||||||
INT32 I_RegisterSong(void *data, size_t len);
|
boolean I_LoadSong(char *data, size_t len);
|
||||||
|
|
||||||
|
/** \brief See ::I_LoadSong, then think backwards
|
||||||
|
|
||||||
|
\param handle song handle
|
||||||
|
|
||||||
|
\sa I_LoadSong
|
||||||
|
\todo remove midi handle
|
||||||
|
*/
|
||||||
|
void I_UnloadSong(void);
|
||||||
|
|
||||||
/** \brief Called by anything that wishes to start music
|
/** \brief Called by anything that wishes to start music
|
||||||
|
|
||||||
|
@ -172,7 +179,7 @@ INT32 I_RegisterSong(void *data, size_t len);
|
||||||
|
|
||||||
\todo pass music name, not handle
|
\todo pass music name, not handle
|
||||||
*/
|
*/
|
||||||
boolean I_PlaySong(INT32 handle, boolean looping);
|
boolean I_PlaySong(boolean looping);
|
||||||
|
|
||||||
/** \brief Stops a song over 3 seconds
|
/** \brief Stops a song over 3 seconds
|
||||||
|
|
||||||
|
@ -181,58 +188,37 @@ boolean I_PlaySong(INT32 handle, boolean looping);
|
||||||
|
|
||||||
/todo drop handle
|
/todo drop handle
|
||||||
*/
|
*/
|
||||||
void I_StopSong(INT32 handle);
|
void I_StopSong(void);
|
||||||
|
|
||||||
/** \brief See ::I_RegisterSong, then think backwards
|
/** \brief PAUSE game handling.
|
||||||
|
|
||||||
\param handle song handle
|
\param handle song handle
|
||||||
|
|
||||||
\sa I_RegisterSong
|
\return void
|
||||||
\todo remove midi handle
|
|
||||||
*/
|
*/
|
||||||
void I_UnRegisterSong(INT32 handle);
|
void I_PauseSong(void);
|
||||||
|
|
||||||
//
|
/** \brief RESUME game handling
|
||||||
// DIGMUSIC I/O
|
|
||||||
//
|
|
||||||
|
|
||||||
/** \brief Startup the music system
|
\param handle song handle
|
||||||
|
|
||||||
|
\return void
|
||||||
*/
|
*/
|
||||||
void I_InitDigMusic(void);
|
void I_ResumeSong(void);
|
||||||
|
|
||||||
/** \brief Shutdown the music system
|
/** \brief The I_SetMusicVolume function
|
||||||
*/
|
|
||||||
void I_ShutdownDigMusic(void);
|
|
||||||
|
|
||||||
boolean I_SetSongSpeed(float speed);
|
|
||||||
|
|
||||||
boolean I_SetSongTrack(INT32 track);
|
|
||||||
|
|
||||||
/** \brief The I_StartDigSong function
|
|
||||||
|
|
||||||
\param musicname music lump name
|
|
||||||
\param looping if true, loop the song
|
|
||||||
|
|
||||||
\return if true, song playing
|
|
||||||
*/
|
|
||||||
boolean I_StartDigSong(const char *musicname, boolean looping);
|
|
||||||
|
|
||||||
/** \brief stop non-MIDI song
|
|
||||||
*/
|
|
||||||
void I_StopDigSong(void);
|
|
||||||
|
|
||||||
/** \brief The I_SetDigMusicVolume function
|
|
||||||
|
|
||||||
\param volume volume to set at
|
\param volume volume to set at
|
||||||
|
|
||||||
\return void
|
\return void
|
||||||
*/
|
*/
|
||||||
void I_SetDigMusicVolume(UINT8 volume);
|
void I_SetMusicVolume(UINT8 volume);
|
||||||
|
|
||||||
//
|
boolean I_SetSongTrack(INT32 track);
|
||||||
// CD MUSIC I/O
|
|
||||||
//
|
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// CD MUSIC I/O
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
/** \brief cd music interface
|
/** \brief cd music interface
|
||||||
*/
|
*/
|
||||||
|
@ -279,4 +265,4 @@ void I_PlayCD(UINT8 track, UINT8 looping);
|
||||||
*/
|
*/
|
||||||
boolean I_SetVolumeCD(INT32 volume);
|
boolean I_SetVolumeCD(INT32 volume);
|
||||||
|
|
||||||
#endif
|
#endif
|
68
src/i_tcp.c
68
src/i_tcp.c
|
@ -649,14 +649,29 @@ static boolean SOCK_CanGet(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
static void SOCK_Send(void)
|
static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr)
|
||||||
{
|
{
|
||||||
ssize_t c = ERRSOCKET;
|
|
||||||
socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in);
|
socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in);
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6);
|
socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6);
|
||||||
#endif
|
#endif
|
||||||
socklen_t d, da = (socklen_t)sizeof(mysockaddr_t);
|
socklen_t d, da = (socklen_t)sizeof(mysockaddr_t);
|
||||||
|
|
||||||
|
switch (sockaddr->any.sa_family)
|
||||||
|
{
|
||||||
|
case AF_INET: d = d4; break;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
case AF_INET6: d = d6; break;
|
||||||
|
#endif
|
||||||
|
default: d = da; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SOCK_Send(void)
|
||||||
|
{
|
||||||
|
ssize_t c = ERRSOCKET;
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
|
|
||||||
if (!nodeconnected[doomcom->remotenode])
|
if (!nodeconnected[doomcom->remotenode])
|
||||||
|
@ -669,19 +684,7 @@ static void SOCK_Send(void)
|
||||||
for (j = 0; j < broadcastaddresses; j++)
|
for (j = 0; j < broadcastaddresses; j++)
|
||||||
{
|
{
|
||||||
if (myfamily[i] == broadcastaddress[j].any.sa_family)
|
if (myfamily[i] == broadcastaddress[j].any.sa_family)
|
||||||
{
|
SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
|
||||||
if (broadcastaddress[i].any.sa_family == AF_INET)
|
|
||||||
d = d4;
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
else if (broadcastaddress[i].any.sa_family == AF_INET6)
|
|
||||||
d = d6;
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
d = da;
|
|
||||||
|
|
||||||
c = sendto(mysockets[i], (char *)&doomcom->data, doomcom->datalength, 0,
|
|
||||||
&broadcastaddress[j].any, d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -691,35 +694,13 @@ static void SOCK_Send(void)
|
||||||
for (i = 0; i < mysocketses; i++)
|
for (i = 0; i < mysocketses; i++)
|
||||||
{
|
{
|
||||||
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
|
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
|
||||||
{
|
SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
|
||||||
if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET)
|
|
||||||
d = d4;
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
else if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET6)
|
|
||||||
d = d6;
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
d = da;
|
|
||||||
|
|
||||||
sendto(mysockets[i], (char *)&doomcom->data, doomcom->datalength, 0,
|
|
||||||
&clientaddress[doomcom->remotenode].any, d);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET)
|
c = SOCK_SendToAddr(nodesocket[doomcom->remotenode], &clientaddress[doomcom->remotenode]);
|
||||||
d = d4;
|
|
||||||
#ifdef HAVE_IPV6
|
|
||||||
else if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET6)
|
|
||||||
d = d6;
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
d = da;
|
|
||||||
|
|
||||||
c = sendto(nodesocket[doomcom->remotenode], (char *)&doomcom->data, doomcom->datalength, 0,
|
|
||||||
&clientaddress[doomcom->remotenode].any, d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == ERRSOCKET && errno != ECONNREFUSED && errno != EWOULDBLOCK)
|
if (c == ERRSOCKET && errno != ECONNREFUSED && errno != EWOULDBLOCK)
|
||||||
|
@ -1007,7 +988,7 @@ static boolean UDP_Socket(void)
|
||||||
if (gaie == 0)
|
if (gaie == 0)
|
||||||
{
|
{
|
||||||
runp = ai;
|
runp = ai;
|
||||||
while (runp != NULL)
|
while (runp != NULL && s < MAXNETNODES+1)
|
||||||
{
|
{
|
||||||
memcpy(&clientaddress[s], runp->ai_addr, runp->ai_addrlen);
|
memcpy(&clientaddress[s], runp->ai_addr, runp->ai_addrlen);
|
||||||
s++;
|
s++;
|
||||||
|
@ -1022,12 +1003,15 @@ static boolean UDP_Socket(void)
|
||||||
clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip
|
clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s = 0;
|
||||||
|
|
||||||
// setup broadcast adress to BROADCASTADDR entry
|
// setup broadcast adress to BROADCASTADDR entry
|
||||||
gaie = I_getaddrinfo("255.255.255.255", "0", &hints, &ai);
|
gaie = I_getaddrinfo("255.255.255.255", "0", &hints, &ai);
|
||||||
if (gaie == 0)
|
if (gaie == 0)
|
||||||
{
|
{
|
||||||
runp = ai;
|
runp = ai;
|
||||||
while (runp != NULL)
|
while (runp != NULL && s < MAXNETNODES+1)
|
||||||
{
|
{
|
||||||
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
|
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
|
||||||
s++;
|
s++;
|
||||||
|
@ -1050,7 +1034,7 @@ static boolean UDP_Socket(void)
|
||||||
if (gaie == 0)
|
if (gaie == 0)
|
||||||
{
|
{
|
||||||
runp = ai;
|
runp = ai;
|
||||||
while (runp != NULL)
|
while (runp != NULL && s < MAXNETNODES+1)
|
||||||
{
|
{
|
||||||
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
|
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
|
||||||
s++;
|
s++;
|
||||||
|
|
|
@ -3458,8 +3458,8 @@ state_t states[NUMSTATES] =
|
||||||
|
|
||||||
{SPR_FMCE, 0, 20, {NULL}, 0, 0, S_SMASHSPIKE_EASE1}, // S_SMASHSPIKE_FLOAT
|
{SPR_FMCE, 0, 20, {NULL}, 0, 0, S_SMASHSPIKE_EASE1}, // S_SMASHSPIKE_FLOAT
|
||||||
{SPR_FMCE, 0, 4, {A_ZThrust}, 4, (1<<16)|1, S_SMASHSPIKE_EASE2}, // S_SMASHSPIKE_EASE1
|
{SPR_FMCE, 0, 4, {A_ZThrust}, 4, (1<<16)|1, S_SMASHSPIKE_EASE2}, // S_SMASHSPIKE_EASE1
|
||||||
{SPR_FMCE, 0, 4, {A_ZThrust}, 0, (1<<16)|1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_EASE1
|
{SPR_FMCE, 0, 4, {A_ZThrust}, 0, (1<<16)|1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_EASE2
|
||||||
{SPR_FMCE, 0, 2, {A_ZThrust}, -6, (1<<16)|1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_FALL
|
{SPR_FMCE, 0, 2, {A_ZThrust}, -6, 1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_FALL
|
||||||
{SPR_FMCE, 1, 2, {A_MultiShotDist}, (MT_DUST<<16)|10, -48, S_SMASHSPIKE_STOMP2}, // S_SMASHSPIKE_STOMP1
|
{SPR_FMCE, 1, 2, {A_MultiShotDist}, (MT_DUST<<16)|10, -48, S_SMASHSPIKE_STOMP2}, // S_SMASHSPIKE_STOMP1
|
||||||
{SPR_FMCE, 2, 14, {NULL}, 0, 0, S_SMASHSPIKE_RISE1}, // S_SMASHSPIKE_STOMP2
|
{SPR_FMCE, 2, 14, {NULL}, 0, 0, S_SMASHSPIKE_RISE1}, // S_SMASHSPIKE_STOMP2
|
||||||
{SPR_FMCE, 1, 2, {NULL}, 0, 0, S_SMASHSPIKE_RISE2}, // S_SMASHSPIKE_RISE1
|
{SPR_FMCE, 1, 2, {NULL}, 0, 0, S_SMASHSPIKE_RISE2}, // S_SMASHSPIKE_RISE1
|
||||||
|
|
|
@ -1809,9 +1809,11 @@ static int lib_pFadeLight(lua_State *L)
|
||||||
INT16 tag = (INT16)luaL_checkinteger(L, 1);
|
INT16 tag = (INT16)luaL_checkinteger(L, 1);
|
||||||
INT32 destvalue = (INT32)luaL_checkinteger(L, 2);
|
INT32 destvalue = (INT32)luaL_checkinteger(L, 2);
|
||||||
INT32 speed = (INT32)luaL_checkinteger(L, 3);
|
INT32 speed = (INT32)luaL_checkinteger(L, 3);
|
||||||
|
boolean ticbased = lua_optboolean(L, 4);
|
||||||
|
boolean force = lua_optboolean(L, 5);
|
||||||
NOHUD
|
NOHUD
|
||||||
INLEVEL
|
INLEVEL
|
||||||
P_FadeLight(tag, destvalue, speed);
|
P_FadeLight(tag, destvalue, speed, ticbased, force);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@ enum mobj_e {
|
||||||
mobj_subsector,
|
mobj_subsector,
|
||||||
mobj_floorz,
|
mobj_floorz,
|
||||||
mobj_ceilingz,
|
mobj_ceilingz,
|
||||||
|
mobj_floorrover,
|
||||||
|
mobj_ceilingrover,
|
||||||
mobj_radius,
|
mobj_radius,
|
||||||
mobj_height,
|
mobj_height,
|
||||||
mobj_momx,
|
mobj_momx,
|
||||||
|
@ -100,6 +102,8 @@ static const char *const mobj_opt[] = {
|
||||||
"subsector",
|
"subsector",
|
||||||
"floorz",
|
"floorz",
|
||||||
"ceilingz",
|
"ceilingz",
|
||||||
|
"floorrover",
|
||||||
|
"ceilingrover",
|
||||||
"radius",
|
"radius",
|
||||||
"height",
|
"height",
|
||||||
"momx",
|
"momx",
|
||||||
|
@ -208,6 +212,12 @@ static int mobj_get(lua_State *L)
|
||||||
case mobj_ceilingz:
|
case mobj_ceilingz:
|
||||||
lua_pushfixed(L, mo->ceilingz);
|
lua_pushfixed(L, mo->ceilingz);
|
||||||
break;
|
break;
|
||||||
|
case mobj_floorrover:
|
||||||
|
LUA_PushUserdata(L, mo->floorrover, META_FFLOOR);
|
||||||
|
break;
|
||||||
|
case mobj_ceilingrover:
|
||||||
|
LUA_PushUserdata(L, mo->ceilingrover, META_FFLOOR);
|
||||||
|
break;
|
||||||
case mobj_radius:
|
case mobj_radius:
|
||||||
lua_pushfixed(L, mo->radius);
|
lua_pushfixed(L, mo->radius);
|
||||||
break;
|
break;
|
||||||
|
@ -396,6 +406,8 @@ static int mobj_set(lua_State *L)
|
||||||
P_CheckPosition(mo, mo->x, mo->y);
|
P_CheckPosition(mo, mo->x, mo->y);
|
||||||
mo->floorz = tmfloorz;
|
mo->floorz = tmfloorz;
|
||||||
mo->ceilingz = tmceilingz;
|
mo->ceilingz = tmceilingz;
|
||||||
|
mo->floorrover = tmfloorrover;
|
||||||
|
mo->ceilingrover = tmceilingrover;
|
||||||
P_SetTarget(&tmthing, ptmthing);
|
P_SetTarget(&tmthing, ptmthing);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -430,6 +442,10 @@ static int mobj_set(lua_State *L)
|
||||||
return NOSETPOS;
|
return NOSETPOS;
|
||||||
case mobj_ceilingz:
|
case mobj_ceilingz:
|
||||||
return NOSETPOS;
|
return NOSETPOS;
|
||||||
|
case mobj_floorrover:
|
||||||
|
return NOSET;
|
||||||
|
case mobj_ceilingrover:
|
||||||
|
return NOSET;
|
||||||
case mobj_radius:
|
case mobj_radius:
|
||||||
{
|
{
|
||||||
mobj_t *ptmthing = tmthing;
|
mobj_t *ptmthing = tmthing;
|
||||||
|
@ -439,6 +455,8 @@ static int mobj_set(lua_State *L)
|
||||||
P_CheckPosition(mo, mo->x, mo->y);
|
P_CheckPosition(mo, mo->x, mo->y);
|
||||||
mo->floorz = tmfloorz;
|
mo->floorz = tmfloorz;
|
||||||
mo->ceilingz = tmceilingz;
|
mo->ceilingz = tmceilingz;
|
||||||
|
mo->floorrover = tmfloorrover;
|
||||||
|
mo->ceilingrover = tmceilingrover;
|
||||||
P_SetTarget(&tmthing, ptmthing);
|
P_SetTarget(&tmthing, ptmthing);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -451,6 +469,8 @@ static int mobj_set(lua_State *L)
|
||||||
P_CheckPosition(mo, mo->x, mo->y);
|
P_CheckPosition(mo, mo->x, mo->y);
|
||||||
mo->floorz = tmfloorz;
|
mo->floorz = tmfloorz;
|
||||||
mo->ceilingz = tmceilingz;
|
mo->ceilingz = tmceilingz;
|
||||||
|
mo->floorrover = tmfloorrover;
|
||||||
|
mo->ceilingrover = tmceilingrover;
|
||||||
P_SetTarget(&tmthing, ptmthing);
|
P_SetTarget(&tmthing, ptmthing);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,25 +193,27 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
|
||||||
{
|
{
|
||||||
MYFILE f;
|
MYFILE f;
|
||||||
char *name;
|
char *name;
|
||||||
|
size_t len;
|
||||||
f.wad = wad;
|
f.wad = wad;
|
||||||
f.size = W_LumpLengthPwad(wad, lump);
|
f.size = W_LumpLengthPwad(wad, lump);
|
||||||
f.data = Z_Malloc(f.size, PU_LUA, NULL);
|
f.data = Z_Malloc(f.size, PU_LUA, NULL);
|
||||||
W_ReadLumpPwad(wad, lump, f.data);
|
W_ReadLumpPwad(wad, lump, f.data);
|
||||||
f.curpos = f.data;
|
f.curpos = f.data;
|
||||||
|
|
||||||
|
len = strlen(wadfiles[wad]->filename); // length of file name
|
||||||
|
|
||||||
if (wadfiles[wad]->type == RET_LUA)
|
if (wadfiles[wad]->type == RET_LUA)
|
||||||
{
|
{
|
||||||
name = malloc(strlen(wadfiles[wad]->filename)+1);
|
name = malloc(len+1);
|
||||||
strcpy(name, wadfiles[wad]->filename);
|
strcpy(name, wadfiles[wad]->filename);
|
||||||
}
|
}
|
||||||
else // If it's not a .lua file, copy the lump name in too.
|
else // If it's not a .lua file, copy the lump name in too.
|
||||||
{
|
{
|
||||||
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
|
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
|
||||||
size_t length = strlen(wadfiles[wad]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
len += 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
||||||
name = malloc(length + 1);
|
name = malloc(len+1);
|
||||||
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->name2);
|
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->name2);
|
||||||
name[length] = '\0';
|
name[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
LUA_LoadFile(&f, name); // actually load file!
|
LUA_LoadFile(&f, name); // actually load file!
|
||||||
|
|
|
@ -497,7 +497,9 @@ static void GIF_framewrite(void)
|
||||||
|
|
||||||
// screen regions are handled in GIF_lzw
|
// screen regions are handled in GIF_lzw
|
||||||
{
|
{
|
||||||
UINT16 delay = 3; // todo
|
int d1 = (int)((100.0/NEWTICRATE)*(gif_frames+1));
|
||||||
|
int d2 = (int)((100.0/NEWTICRATE)*(gif_frames));
|
||||||
|
UINT16 delay = d1-d2;
|
||||||
INT32 startline;
|
INT32 startline;
|
||||||
|
|
||||||
WRITEMEM(p, gifframe_gchead, 4);
|
WRITEMEM(p, gifframe_gchead, 4);
|
||||||
|
|
129
src/m_menu.c
129
src/m_menu.c
|
@ -9350,7 +9350,7 @@ static void M_SoundMenu(INT32 choice)
|
||||||
{
|
{
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
|
||||||
OP_SoundOptionsMenu[6].status = ((nosound || sound_disabled) ? IT_GRAYEDOUT : (IT_STRING | IT_CVAR));
|
OP_SoundOptionsMenu[6].status = (sound_disabled ? IT_GRAYEDOUT : (IT_STRING | IT_CVAR));
|
||||||
M_SetupNextMenu(&OP_SoundOptionsDef);
|
M_SetupNextMenu(&OP_SoundOptionsDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9363,25 +9363,25 @@ void M_DrawSoundMenu(void)
|
||||||
|
|
||||||
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x,
|
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x,
|
||||||
currentMenu->y+currentMenu->menuitems[0].alphaKey,
|
currentMenu->y+currentMenu->menuitems[0].alphaKey,
|
||||||
(nosound ? V_REDMAP : V_YELLOWMAP),
|
(sound_disabled ? V_REDMAP : V_YELLOWMAP),
|
||||||
((nosound || sound_disabled) ? offstring : onstring));
|
(sound_disabled ? offstring : onstring));
|
||||||
|
|
||||||
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x,
|
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x,
|
||||||
currentMenu->y+currentMenu->menuitems[2].alphaKey,
|
currentMenu->y+currentMenu->menuitems[2].alphaKey,
|
||||||
(nodigimusic ? V_REDMAP : V_YELLOWMAP),
|
(digital_disabled ? V_REDMAP : V_YELLOWMAP),
|
||||||
((nodigimusic || digital_disabled) ? offstring : onstring));
|
(digital_disabled ? offstring : onstring));
|
||||||
|
|
||||||
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x,
|
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x,
|
||||||
currentMenu->y+currentMenu->menuitems[4].alphaKey,
|
currentMenu->y+currentMenu->menuitems[4].alphaKey,
|
||||||
(nomidimusic ? V_REDMAP : V_YELLOWMAP),
|
(midi_disabled ? V_REDMAP : V_YELLOWMAP),
|
||||||
((nomidimusic || music_disabled) ? offstring : onstring));
|
(midi_disabled ? offstring : onstring));
|
||||||
|
|
||||||
if (itemOn == 0)
|
if (itemOn == 0)
|
||||||
lengthstring = ((nosound || sound_disabled) ? 3 : 2);
|
lengthstring = (sound_disabled ? 3 : 2);
|
||||||
else if (itemOn == 2)
|
else if (itemOn == 2)
|
||||||
lengthstring = ((nodigimusic || digital_disabled) ? 3 : 2);
|
lengthstring = (digital_disabled ? 3 : 2);
|
||||||
else if (itemOn == 4)
|
else if (itemOn == 4)
|
||||||
lengthstring = ((nomidimusic || music_disabled) ? 3 : 2);
|
lengthstring = (midi_disabled ? 3 : 2);
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -9416,32 +9416,20 @@ static void M_ToggleSFX(INT32 choice)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
{
|
{
|
||||||
nosound = false;
|
sound_disabled = false;
|
||||||
I_StartupSound();
|
S_InitSfxChannels(cv_soundvolume.value);
|
||||||
if (nosound) return;
|
|
||||||
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
|
|
||||||
S_StartSound(NULL, sfx_strpst);
|
S_StartSound(NULL, sfx_strpst);
|
||||||
OP_SoundOptionsMenu[6].status = IT_STRING | IT_CVAR;
|
OP_SoundOptionsMenu[6].status = IT_STRING | IT_CVAR;
|
||||||
//M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING);
|
//M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (sound_disabled)
|
sound_disabled = true;
|
||||||
{
|
S_StopSounds();
|
||||||
sound_disabled = false;
|
OP_SoundOptionsMenu[6].status = IT_GRAYEDOUT;
|
||||||
S_StartSound(NULL, sfx_strpst);
|
//M_StartMessage(M_GetText("SFX Disabled\n"), NULL, MM_NOTHING);
|
||||||
OP_SoundOptionsMenu[6].status = IT_STRING | IT_CVAR;
|
|
||||||
//M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sound_disabled = true;
|
|
||||||
S_StopSounds();
|
|
||||||
OP_SoundOptionsMenu[6].status = IT_GRAYEDOUT;
|
|
||||||
//M_StartMessage(M_GetText("SFX Disabled\n"), NULL, MM_NOTHING);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9469,12 +9457,10 @@ static void M_ToggleDigital(INT32 choice)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodigimusic)
|
if (digital_disabled)
|
||||||
{
|
{
|
||||||
nodigimusic = false;
|
digital_disabled = false;
|
||||||
I_InitDigMusic();
|
I_InitMusic();
|
||||||
if (nodigimusic) return;
|
|
||||||
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
|
|
||||||
S_StopMusic();
|
S_StopMusic();
|
||||||
if (Playing())
|
if (Playing())
|
||||||
P_RestoreMusic(&players[consoleplayer]);
|
P_RestoreMusic(&players[consoleplayer]);
|
||||||
|
@ -9484,21 +9470,27 @@ static void M_ToggleDigital(INT32 choice)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (digital_disabled)
|
digital_disabled = true;
|
||||||
|
if (S_MusicType() != MU_MID)
|
||||||
{
|
{
|
||||||
digital_disabled = false;
|
if (midi_disabled)
|
||||||
if (Playing())
|
S_StopMusic();
|
||||||
P_RestoreMusic(&players[consoleplayer]);
|
|
||||||
else
|
else
|
||||||
S_ChangeMusicInternal("_clear", false);
|
{
|
||||||
//M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING);
|
char mmusic[7];
|
||||||
}
|
UINT16 mflags;
|
||||||
else
|
boolean looping;
|
||||||
{
|
|
||||||
digital_disabled = true;
|
if (S_MusicInfo(mmusic, &mflags, &looping) && S_MIDIExists(mmusic))
|
||||||
S_StopMusic();
|
{
|
||||||
//M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING);
|
S_StopMusic();
|
||||||
|
S_ChangeMusic(mmusic, mflags, looping);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
S_StopMusic();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9516,6 +9508,12 @@ static void M_ToggleMIDI(INT32 choice)
|
||||||
itemOn--;
|
itemOn--;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case KEY_LEFTARROW:
|
||||||
|
case KEY_RIGHTARROW:
|
||||||
|
if (S_MusicType() != MU_MID && S_MusicType() != MU_NONE)
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
break;
|
||||||
|
|
||||||
case KEY_ESCAPE:
|
case KEY_ESCAPE:
|
||||||
if (currentMenu->prevMenu)
|
if (currentMenu->prevMenu)
|
||||||
M_SetupNextMenu(currentMenu->prevMenu);
|
M_SetupNextMenu(currentMenu->prevMenu);
|
||||||
|
@ -9525,13 +9523,10 @@ static void M_ToggleMIDI(INT32 choice)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (midi_disabled)
|
||||||
if (nomidimusic)
|
|
||||||
{
|
{
|
||||||
nomidimusic = false;
|
midi_disabled = false;
|
||||||
I_InitMIDIMusic();
|
I_InitMusic();
|
||||||
if (nomidimusic) return;
|
|
||||||
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
|
|
||||||
if (Playing())
|
if (Playing())
|
||||||
P_RestoreMusic(&players[consoleplayer]);
|
P_RestoreMusic(&players[consoleplayer]);
|
||||||
else
|
else
|
||||||
|
@ -9540,21 +9535,27 @@ static void M_ToggleMIDI(INT32 choice)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (music_disabled)
|
midi_disabled = true;
|
||||||
|
if (S_MusicType() == MU_MID)
|
||||||
{
|
{
|
||||||
music_disabled = false;
|
if (digital_disabled)
|
||||||
if (Playing())
|
S_StopMusic();
|
||||||
P_RestoreMusic(&players[consoleplayer]);
|
|
||||||
else
|
else
|
||||||
S_ChangeMusicInternal("_clear", false);
|
{
|
||||||
//M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING);
|
char mmusic[7];
|
||||||
}
|
UINT16 mflags;
|
||||||
else
|
boolean looping;
|
||||||
{
|
|
||||||
music_disabled = true;
|
if (S_MusicInfo(mmusic, &mflags, &looping) && S_DigExists(mmusic))
|
||||||
S_StopMusic();
|
{
|
||||||
//M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING);
|
S_StopMusic();
|
||||||
|
S_ChangeMusic(mmusic, mflags, looping);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
S_StopMusic();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3324,6 +3324,11 @@ void A_MonitorPop(mobj_t *actor)
|
||||||
newmobj->sprite = SPR_TV1P;
|
newmobj->sprite = SPR_TV1P;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run a linedef executor immediately upon popping
|
||||||
|
// You may want to delay your effects by 18 tics to sync with the reward giving
|
||||||
|
if (actor->spawnpoint && (actor->spawnpoint->options & MTF_EXTRA) && (actor->spawnpoint->angle & 16384))
|
||||||
|
P_LinedefExecute((actor->spawnpoint->angle & 16383), actor->target, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function: A_GoldMonitorPop
|
// Function: A_GoldMonitorPop
|
||||||
|
|
|
@ -1839,6 +1839,7 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
||||||
#define ceilingwasheight vars[5]
|
#define ceilingwasheight vars[5]
|
||||||
fixed_t thwompx, thwompy;
|
fixed_t thwompx, thwompy;
|
||||||
sector_t *actionsector;
|
sector_t *actionsector;
|
||||||
|
ffloor_t *rover = NULL;
|
||||||
INT32 secnum;
|
INT32 secnum;
|
||||||
|
|
||||||
// If you just crashed down, wait a second before coming back up.
|
// If you just crashed down, wait a second before coming back up.
|
||||||
|
@ -1853,7 +1854,16 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
||||||
secnum = P_FindSectorFromTag((INT16)thwomp->vars[0], -1);
|
secnum = P_FindSectorFromTag((INT16)thwomp->vars[0], -1);
|
||||||
|
|
||||||
if (secnum > 0)
|
if (secnum > 0)
|
||||||
|
{
|
||||||
actionsector = §ors[secnum];
|
actionsector = §ors[secnum];
|
||||||
|
|
||||||
|
// Look for thwomp FFloor
|
||||||
|
for (rover = actionsector->ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (rover->master == thwomp->sourceline)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return; // Bad bad bad!
|
return; // Bad bad bad!
|
||||||
|
|
||||||
|
@ -1942,10 +1952,13 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
||||||
{
|
{
|
||||||
mobj_t *mp = (void *)&actionsector->soundorg;
|
mobj_t *mp = (void *)&actionsector->soundorg;
|
||||||
|
|
||||||
if (thwomp->sourceline->flags & ML_EFFECT4)
|
if (!rover || (rover->flags & FF_EXISTS))
|
||||||
S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS);
|
{
|
||||||
else
|
if (thwomp->sourceline->flags & ML_EFFECT4)
|
||||||
S_StartSound(mp, sfx_thwomp);
|
S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS);
|
||||||
|
else
|
||||||
|
S_StartSound(mp, sfx_thwomp);
|
||||||
|
}
|
||||||
|
|
||||||
thwomp->direction = 1; // start heading back up
|
thwomp->direction = 1; // start heading back up
|
||||||
thwomp->distance = TICRATE; // but only after a small delay
|
thwomp->distance = TICRATE; // but only after a small delay
|
||||||
|
@ -1959,18 +1972,22 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
||||||
thinker_t *th;
|
thinker_t *th;
|
||||||
mobj_t *mo;
|
mobj_t *mo;
|
||||||
|
|
||||||
// scan the thinkers to find players!
|
if (!rover || (rover->flags & FF_EXISTS))
|
||||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
|
||||||
{
|
{
|
||||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
// scan the thinkers to find players!
|
||||||
continue;
|
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||||
|
|
||||||
mo = (mobj_t *)th;
|
|
||||||
if (mo->type == MT_PLAYER && mo->health && mo->z <= thwomp->sector->ceilingheight
|
|
||||||
&& P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT)
|
|
||||||
{
|
{
|
||||||
thwomp->direction = -1;
|
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
|
mo = (mobj_t *)th;
|
||||||
|
if (mo->type == MT_PLAYER && mo->health && mo->player && !mo->player->spectator
|
||||||
|
&& mo->z <= thwomp->sector->ceilingheight
|
||||||
|
&& P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT)
|
||||||
|
{
|
||||||
|
thwomp->direction = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3313,12 +3313,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
}
|
}
|
||||||
else if (player->powers[pw_carry] == CR_NIGHTSFALL)
|
else if (player->powers[pw_carry] == CR_NIGHTSFALL)
|
||||||
{
|
{
|
||||||
if (player->spheres > 0)
|
// always damage so we can recoil upon losing points
|
||||||
{
|
damage = player->spheres;
|
||||||
damage = player->spheres;
|
P_RingDamage(player, inflictor, source, damage, damagetype, true);
|
||||||
P_RingDamage(player, inflictor, source, damage, damagetype, true);
|
damage = 0;
|
||||||
damage = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (player->rings > 0) // No shield but have rings.
|
else if (player->rings > 0) // No shield but have rings.
|
||||||
{
|
{
|
||||||
|
|
106
src/p_lights.c
106
src/p_lights.c
|
@ -23,7 +23,7 @@
|
||||||
*
|
*
|
||||||
* \param sector The sector to remove effects from.
|
* \param sector The sector to remove effects from.
|
||||||
*/
|
*/
|
||||||
static void P_RemoveLighting(sector_t *sector)
|
void P_RemoveLighting(sector_t *sector)
|
||||||
{
|
{
|
||||||
if (sector->lightingdata)
|
if (sector->lightingdata)
|
||||||
{
|
{
|
||||||
|
@ -322,39 +322,70 @@ glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector,
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fades all the lights in sectors with a particular tag to a new
|
/** Fades all the lights in specified sector to a new
|
||||||
* value.
|
* value.
|
||||||
*
|
*
|
||||||
* \param tag Tag to look for sectors by.
|
* \param sector Target sector
|
||||||
* \param destvalue The final light value in these sectors.
|
* \param destvalue The final light value in these sectors.
|
||||||
* \param speed Speed of the fade; the change to the ligh
|
* \param speed If tic-based: total duration of effect.
|
||||||
|
* If speed-based: Speed of the fade; the change to the ligh
|
||||||
* level in each sector per tic.
|
* level in each sector per tic.
|
||||||
* \todo Calculate speed better so that it is possible to specify
|
* \param ticbased Use a specific duration for the fade, defined by speed
|
||||||
* the time for completion of the fade, and all lights fade
|
|
||||||
* in this time regardless of initial values.
|
|
||||||
* \sa T_LightFade
|
* \sa T_LightFade
|
||||||
*/
|
*/
|
||||||
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed)
|
void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean ticbased)
|
||||||
|
{
|
||||||
|
lightlevel_t *ll;
|
||||||
|
|
||||||
|
P_RemoveLighting(sector); // remove the old lighting effect first
|
||||||
|
|
||||||
|
if ((ticbased && !speed) || sector->lightlevel == destvalue) // set immediately
|
||||||
|
{
|
||||||
|
sector->lightlevel = destvalue;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ll = Z_Calloc(sizeof (*ll), PU_LEVSPEC, NULL);
|
||||||
|
ll->thinker.function.acp1 = (actionf_p1)T_LightFade;
|
||||||
|
sector->lightingdata = ll; // set it to the lightlevel_t
|
||||||
|
|
||||||
|
P_AddThinker(&ll->thinker); // add thinker
|
||||||
|
|
||||||
|
ll->sector = sector;
|
||||||
|
ll->sourcelevel = sector->lightlevel;
|
||||||
|
ll->destlevel = destvalue;
|
||||||
|
|
||||||
|
ll->fixedcurlevel = sector->lightlevel<<FRACBITS;
|
||||||
|
|
||||||
|
if (ticbased)
|
||||||
|
{
|
||||||
|
// Speed means duration.
|
||||||
|
ll->timer = abs(speed);
|
||||||
|
ll->fixedpertic = FixedDiv((destvalue<<FRACBITS) - ll->fixedcurlevel, speed<<FRACBITS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Speed means increment per tic (literally speed).
|
||||||
|
ll->timer = FixedDiv((destvalue<<FRACBITS) - ll->fixedcurlevel, speed<<FRACBITS)>>FRACBITS;
|
||||||
|
ll->fixedpertic = speed<<FRACBITS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
lightlevel_t *ll;
|
|
||||||
sector_t *sector;
|
|
||||||
|
|
||||||
// search all sectors for ones with tag
|
// search all sectors for ones with tag
|
||||||
for (i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0 ;)
|
for (i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0 ;)
|
||||||
{
|
{
|
||||||
sector = §ors[i];
|
if (!force && ticbased // always let speed fader execute
|
||||||
|
&& sectors[i].lightingdata
|
||||||
P_RemoveLighting(sector); // remove the old lighting effect first
|
&& ((lightlevel_t*)sectors[i].lightingdata)->thinker.function.acp1 == (actionf_p1)T_LightFade)
|
||||||
ll = Z_Calloc(sizeof (*ll), PU_LEVSPEC, NULL);
|
// && ((lightlevel_t*)sectors[i].lightingdata)->timer > 2)
|
||||||
ll->thinker.function.acp1 = (actionf_p1)T_LightFade;
|
{
|
||||||
sector->lightingdata = ll; // set it to the lightlevel_t
|
CONS_Debug(DBG_GAMELOGIC, "Line type 420 Executor: Fade light thinker already exists, timer: %d\n", ((lightlevel_t*)sectors[i].lightingdata)->timer);
|
||||||
|
continue;
|
||||||
P_AddThinker(&ll->thinker); // add thinker
|
}
|
||||||
|
P_FadeLightBySector(§ors[i], destvalue, speed, ticbased);
|
||||||
ll->sector = sector;
|
|
||||||
ll->destlevel = destvalue;
|
|
||||||
ll->speed = speed;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,30 +396,13 @@ void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed)
|
||||||
*/
|
*/
|
||||||
void T_LightFade(lightlevel_t *ll)
|
void T_LightFade(lightlevel_t *ll)
|
||||||
{
|
{
|
||||||
if (ll->sector->lightlevel < ll->destlevel)
|
if (--ll->timer <= 0)
|
||||||
{
|
{
|
||||||
// increase the lightlevel
|
ll->sector->lightlevel = ll->destlevel; // set to dest lightlevel
|
||||||
if (ll->sector->lightlevel + ll->speed >= ll->destlevel)
|
P_RemoveLighting(ll->sector); // clear lightingdata, remove thinker
|
||||||
{
|
return;
|
||||||
// stop changing light level
|
|
||||||
ll->sector->lightlevel = (INT16)ll->destlevel; // set to dest lightlevel
|
|
||||||
|
|
||||||
P_RemoveLighting(ll->sector); // clear lightingdata, remove thinker
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ll->sector->lightlevel = (INT16)(ll->sector->lightlevel + (INT16)ll->speed); // move lightlevel
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// decrease lightlevel
|
|
||||||
if (ll->sector->lightlevel - ll->speed <= ll->destlevel)
|
|
||||||
{
|
|
||||||
// stop changing light level
|
|
||||||
ll->sector->lightlevel = (INT16)ll->destlevel; // set to dest lightlevel
|
|
||||||
|
|
||||||
P_RemoveLighting(ll->sector); // clear lightingdata, remove thinker
|
ll->fixedcurlevel = ll->fixedcurlevel + ll->fixedpertic;
|
||||||
}
|
ll->sector->lightlevel = (ll->fixedcurlevel)>>FRACBITS;
|
||||||
else
|
|
||||||
ll->sector->lightlevel = (INT16)(ll->sector->lightlevel - (INT16)ll->speed); // move lightlevel
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -326,6 +326,7 @@ void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angl
|
||||||
extern boolean floatok;
|
extern boolean floatok;
|
||||||
extern fixed_t tmfloorz;
|
extern fixed_t tmfloorz;
|
||||||
extern fixed_t tmceilingz;
|
extern fixed_t tmceilingz;
|
||||||
|
extern ffloor_t *tmfloorrover, *tmceilingrover;
|
||||||
extern mobj_t *tmfloorthing, *tmhitthing, *tmthing;
|
extern mobj_t *tmfloorthing, *tmhitthing, *tmthing;
|
||||||
extern camera_t *mapcampointer;
|
extern camera_t *mapcampointer;
|
||||||
extern fixed_t tmx;
|
extern fixed_t tmx;
|
||||||
|
|
60
src/p_map.c
60
src/p_map.c
|
@ -52,6 +52,7 @@ fixed_t tmfloorz, tmceilingz;
|
||||||
static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights
|
static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights
|
||||||
mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector
|
mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector
|
||||||
mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
|
mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
|
||||||
|
ffloor_t *tmfloorrover, *tmceilingrover;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
pslope_t *tmfloorslope, *tmceilingslope;
|
pslope_t *tmfloorslope, *tmceilingslope;
|
||||||
#endif
|
#endif
|
||||||
|
@ -101,6 +102,8 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
|
||||||
|
|
||||||
thing->floorz = tmfloorz;
|
thing->floorz = tmfloorz;
|
||||||
thing->ceilingz = tmceilingz;
|
thing->ceilingz = tmceilingz;
|
||||||
|
thing->floorrover = tmfloorrover;
|
||||||
|
thing->ceilingrover = tmceilingrover;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1417,6 +1420,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
if (thing->z + thing->height > tmfloorz)
|
if (thing->z + thing->height > tmfloorz)
|
||||||
{
|
{
|
||||||
tmfloorz = thing->z + thing->height;
|
tmfloorz = thing->z + thing->height;
|
||||||
|
tmfloorrover = NULL;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmfloorslope = NULL;
|
tmfloorslope = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1437,6 +1441,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tmfloorz = tmceilingz = topz; // block while in air
|
tmfloorz = tmceilingz = topz; // block while in air
|
||||||
|
tmceilingrover = NULL;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmceilingslope = NULL;
|
tmceilingslope = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1445,6 +1450,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
|
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
|
||||||
{
|
{
|
||||||
tmceilingz = topz;
|
tmceilingz = topz;
|
||||||
|
tmceilingrover = NULL;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmceilingslope = NULL;
|
tmceilingslope = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1461,6 +1467,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
if (thing->z < tmceilingz)
|
if (thing->z < tmceilingz)
|
||||||
{
|
{
|
||||||
tmceilingz = thing->z;
|
tmceilingz = thing->z;
|
||||||
|
tmceilingrover = NULL;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmceilingslope = NULL;
|
tmceilingslope = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1481,6 +1488,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tmfloorz = tmceilingz = topz; // block while in air
|
tmfloorz = tmceilingz = topz; // block while in air
|
||||||
|
tmfloorrover = NULL;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmfloorslope = NULL;
|
tmfloorslope = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1489,6 +1497,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
|
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
|
||||||
{
|
{
|
||||||
tmfloorz = topz;
|
tmfloorz = topz;
|
||||||
|
tmfloorrover = NULL;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmfloorslope = NULL;
|
tmfloorslope = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1640,6 +1649,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
||||||
{
|
{
|
||||||
tmceilingz = opentop;
|
tmceilingz = opentop;
|
||||||
ceilingline = ld;
|
ceilingline = ld;
|
||||||
|
tmceilingrover = NULL;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmceilingslope = opentopslope;
|
tmceilingslope = opentopslope;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1648,6 +1658,7 @@ static boolean PIT_CheckLine(line_t *ld)
|
||||||
if (openbottom > tmfloorz)
|
if (openbottom > tmfloorz)
|
||||||
{
|
{
|
||||||
tmfloorz = openbottom;
|
tmfloorz = openbottom;
|
||||||
|
tmfloorrover = NULL;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmfloorslope = openbottomslope;
|
tmfloorslope = openbottomslope;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1729,6 +1740,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
||||||
// will adjust them.
|
// will adjust them.
|
||||||
tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight;
|
tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight;
|
||||||
tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight;
|
tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight;
|
||||||
|
tmfloorrover = NULL;
|
||||||
|
tmceilingrover = NULL;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmfloorslope = newsubsec->sector->f_slope;
|
tmfloorslope = newsubsec->sector->f_slope;
|
||||||
tmceilingslope = newsubsec->sector->c_slope;
|
tmceilingslope = newsubsec->sector->c_slope;
|
||||||
|
@ -1772,6 +1785,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
if (tmfloorz < topheight - sinklevel) {
|
if (tmfloorz < topheight - sinklevel) {
|
||||||
tmfloorz = topheight - sinklevel;
|
tmfloorz = topheight - sinklevel;
|
||||||
|
tmfloorrover = rover;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmfloorslope = *rover->t_slope;
|
tmfloorslope = *rover->t_slope;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1781,6 +1795,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
if (tmceilingz > bottomheight + sinklevel) {
|
if (tmceilingz > bottomheight + sinklevel) {
|
||||||
tmceilingz = bottomheight + sinklevel;
|
tmceilingz = bottomheight + sinklevel;
|
||||||
|
tmceilingrover = rover;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmceilingslope = *rover->b_slope;
|
tmceilingslope = *rover->b_slope;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1805,6 +1820,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
if (tmfloorz < thing->z) {
|
if (tmfloorz < thing->z) {
|
||||||
tmfloorz = thing->z;
|
tmfloorz = thing->z;
|
||||||
|
tmfloorrover = rover;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmfloorslope = NULL;
|
tmfloorslope = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1823,6 +1839,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
||||||
&& !(rover->flags & FF_REVERSEPLATFORM))
|
&& !(rover->flags & FF_REVERSEPLATFORM))
|
||||||
{
|
{
|
||||||
tmfloorz = tmdropoffz = topheight;
|
tmfloorz = tmdropoffz = topheight;
|
||||||
|
tmfloorrover = rover;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmfloorslope = *rover->t_slope;
|
tmfloorslope = *rover->t_slope;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1832,6 +1849,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
||||||
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)))
|
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)))
|
||||||
{
|
{
|
||||||
tmceilingz = tmdrpoffceilz = bottomheight;
|
tmceilingz = tmdrpoffceilz = bottomheight;
|
||||||
|
tmceilingrover = rover;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmceilingslope = *rover->b_slope;
|
tmceilingslope = *rover->b_slope;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2328,6 +2346,8 @@ boolean PIT_PushableMoved(mobj_t *thing)
|
||||||
mobj_t *oldthing = tmthing;
|
mobj_t *oldthing = tmthing;
|
||||||
line_t *oldceilline = ceilingline;
|
line_t *oldceilline = ceilingline;
|
||||||
line_t *oldblockline = blockingline;
|
line_t *oldblockline = blockingline;
|
||||||
|
ffloor_t *oldflrrover = tmfloorrover;
|
||||||
|
ffloor_t *oldceilrover = tmceilingrover;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
pslope_t *oldfslope = tmfloorslope;
|
pslope_t *oldfslope = tmfloorslope;
|
||||||
pslope_t *oldcslope = tmceilingslope;
|
pslope_t *oldcslope = tmceilingslope;
|
||||||
|
@ -2344,6 +2364,8 @@ boolean PIT_PushableMoved(mobj_t *thing)
|
||||||
P_SetTarget(&tmthing, oldthing);
|
P_SetTarget(&tmthing, oldthing);
|
||||||
ceilingline = oldceilline;
|
ceilingline = oldceilline;
|
||||||
blockingline = oldblockline;
|
blockingline = oldblockline;
|
||||||
|
tmfloorrover = oldflrrover;
|
||||||
|
tmceilingrover = oldceilrover;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
tmfloorslope = oldfslope;
|
tmfloorslope = oldfslope;
|
||||||
tmceilingslope = oldcslope;
|
tmceilingslope = oldcslope;
|
||||||
|
@ -2465,6 +2487,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||||
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
|
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
|
||||||
{
|
{
|
||||||
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
|
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
|
||||||
|
thing->ceilingrover = tmceilingrover;
|
||||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||||
}
|
}
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
|
@ -2472,6 +2495,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||||
else if (tmceilingslope && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
|
else if (tmceilingslope && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
|
||||||
{
|
{
|
||||||
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
|
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
|
||||||
|
thing->ceilingrover = tmceilingrover;
|
||||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2479,6 +2503,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||||
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
|
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
|
||||||
{
|
{
|
||||||
thing->z = thing->floorz = tmfloorz;
|
thing->z = thing->floorz = tmfloorz;
|
||||||
|
thing->floorrover = tmfloorrover;
|
||||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||||
}
|
}
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
|
@ -2486,6 +2511,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||||
else if (tmfloorslope && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
|
else if (tmfloorslope && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
|
||||||
{
|
{
|
||||||
thing->z = thing->floorz = tmfloorz;
|
thing->z = thing->floorz = tmfloorz;
|
||||||
|
thing->floorrover = tmfloorrover;
|
||||||
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2557,6 +2583,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||||
|
|
||||||
thing->floorz = tmfloorz;
|
thing->floorz = tmfloorz;
|
||||||
thing->ceilingz = tmceilingz;
|
thing->ceilingz = tmceilingz;
|
||||||
|
thing->floorrover = tmfloorrover;
|
||||||
|
thing->ceilingrover = tmceilingrover;
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
if (!(thing->flags & MF_NOCLIPHEIGHT))
|
if (!(thing->flags & MF_NOCLIPHEIGHT))
|
||||||
|
@ -2637,6 +2665,8 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
|
||||||
|
|
||||||
thing->floorz = tmfloorz;
|
thing->floorz = tmfloorz;
|
||||||
thing->ceilingz = tmceilingz;
|
thing->ceilingz = tmceilingz;
|
||||||
|
thing->floorrover = tmfloorrover;
|
||||||
|
thing->ceilingrover = tmceilingrover;
|
||||||
thing->x = x;
|
thing->x = x;
|
||||||
thing->y = y;
|
thing->y = y;
|
||||||
|
|
||||||
|
@ -2663,7 +2693,10 @@ static boolean P_ThingHeightClip(mobj_t *thing)
|
||||||
{
|
{
|
||||||
boolean floormoved;
|
boolean floormoved;
|
||||||
fixed_t oldfloorz = thing->floorz;
|
fixed_t oldfloorz = thing->floorz;
|
||||||
|
ffloor_t *oldfloorrover = thing->floorrover;
|
||||||
|
ffloor_t *oldceilingrover = thing->ceilingrover;
|
||||||
boolean onfloor = P_IsObjectOnGround(thing);//(thing->z <= thing->floorz);
|
boolean onfloor = P_IsObjectOnGround(thing);//(thing->z <= thing->floorz);
|
||||||
|
ffloor_t *rover = NULL;
|
||||||
|
|
||||||
if (thing->flags & MF_NOCLIPHEIGHT)
|
if (thing->flags & MF_NOCLIPHEIGHT)
|
||||||
return true;
|
return true;
|
||||||
|
@ -2678,6 +2711,8 @@ static boolean P_ThingHeightClip(mobj_t *thing)
|
||||||
|
|
||||||
thing->floorz = tmfloorz;
|
thing->floorz = tmfloorz;
|
||||||
thing->ceilingz = tmceilingz;
|
thing->ceilingz = tmceilingz;
|
||||||
|
thing->floorrover = tmfloorrover;
|
||||||
|
thing->ceilingrover = tmceilingrover;
|
||||||
|
|
||||||
// Ugly hack?!?! As long as just ceilingz is the lowest,
|
// Ugly hack?!?! As long as just ceilingz is the lowest,
|
||||||
// you'll still get crushed, right?
|
// you'll still get crushed, right?
|
||||||
|
@ -2686,16 +2721,23 @@ static boolean P_ThingHeightClip(mobj_t *thing)
|
||||||
|
|
||||||
if (onfloor && !(thing->flags & MF_NOGRAVITY) && floormoved)
|
if (onfloor && !(thing->flags & MF_NOGRAVITY) && floormoved)
|
||||||
{
|
{
|
||||||
if (thing->eflags & MFE_VERTICALFLIP)
|
rover = (thing->eflags & MFE_VERTICALFLIP) ? oldceilingrover : oldfloorrover;
|
||||||
thing->pmomz = thing->ceilingz - (thing->z + thing->height);
|
|
||||||
else
|
|
||||||
thing->pmomz = thing->floorz - thing->z;
|
|
||||||
thing->eflags |= MFE_APPLYPMOMZ;
|
|
||||||
|
|
||||||
if (thing->eflags & MFE_VERTICALFLIP)
|
// Match the Thing's old floorz to an FOF and check for FF_EXISTS
|
||||||
thing->z = thing->ceilingz - thing->height;
|
// If ~FF_EXISTS, don't set mobj Z.
|
||||||
else
|
if (!rover || ((rover->flags & FF_EXISTS) && (rover->flags & FF_SOLID)))
|
||||||
thing->z = thing->floorz;
|
{
|
||||||
|
if (thing->eflags & MFE_VERTICALFLIP)
|
||||||
|
thing->pmomz = thing->ceilingz - (thing->z + thing->height);
|
||||||
|
else
|
||||||
|
thing->pmomz = thing->floorz - thing->z;
|
||||||
|
thing->eflags |= MFE_APPLYPMOMZ;
|
||||||
|
|
||||||
|
if (thing->eflags & MFE_VERTICALFLIP)
|
||||||
|
thing->z = thing->ceilingz - thing->height;
|
||||||
|
else
|
||||||
|
thing->z = thing->floorz;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!tmfloorthing)
|
else if (!tmfloorthing)
|
||||||
{
|
{
|
||||||
|
|
49
src/p_mobj.c
49
src/p_mobj.c
|
@ -4059,7 +4059,8 @@ void P_RecalcPrecipInSector(sector_t *sector)
|
||||||
//
|
//
|
||||||
void P_NullPrecipThinker(precipmobj_t *mobj)
|
void P_NullPrecipThinker(precipmobj_t *mobj)
|
||||||
{
|
{
|
||||||
(void)mobj;
|
//(void)mobj;
|
||||||
|
mobj->precipflags &= ~PCF_THUNK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_SnowThinker(precipmobj_t *mobj)
|
void P_SnowThinker(precipmobj_t *mobj)
|
||||||
|
@ -4079,25 +4080,26 @@ void P_RainThinker(precipmobj_t *mobj)
|
||||||
{
|
{
|
||||||
// cycle through states,
|
// cycle through states,
|
||||||
// calling action functions at transitions
|
// calling action functions at transitions
|
||||||
if (mobj->tics > 0 && --mobj->tics == 0)
|
if (mobj->tics <= 0)
|
||||||
{
|
return;
|
||||||
// you can cycle through multiple states in a tic
|
|
||||||
if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate))
|
if (--mobj->tics)
|
||||||
return; // freed itself
|
return;
|
||||||
}
|
|
||||||
|
if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mobj->state != &states[S_RAINRETURN])
|
||||||
|
return;
|
||||||
|
|
||||||
|
mobj->z = mobj->ceilingz;
|
||||||
|
P_SetPrecipMobjState(mobj, S_RAIN1);
|
||||||
|
|
||||||
if (mobj->state == &states[S_RAINRETURN])
|
|
||||||
{
|
|
||||||
mobj->z = mobj->ceilingz;
|
|
||||||
P_SetPrecipMobjState(mobj, S_RAIN1);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust height
|
// adjust height
|
||||||
mobj->z += mobj->momz;
|
if ((mobj->z += mobj->momz) <= mobj->floorz)
|
||||||
|
|
||||||
if (mobj->z <= mobj->floorz)
|
|
||||||
{
|
{
|
||||||
// no splashes on sky or bottomless pits
|
// no splashes on sky or bottomless pits
|
||||||
if (mobj->precipflags & PCF_PIT)
|
if (mobj->precipflags & PCF_PIT)
|
||||||
|
@ -8027,6 +8029,8 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
return;
|
return;
|
||||||
mobj->floorz = tmfloorz;
|
mobj->floorz = tmfloorz;
|
||||||
mobj->ceilingz = tmceilingz;
|
mobj->ceilingz = tmceilingz;
|
||||||
|
mobj->floorrover = tmfloorrover;
|
||||||
|
mobj->ceilingrover = tmceilingrover;
|
||||||
|
|
||||||
if ((mobj->eflags & MFE_UNDERWATER) && mobj->health > 0)
|
if ((mobj->eflags & MFE_UNDERWATER) && mobj->health > 0)
|
||||||
{
|
{
|
||||||
|
@ -8545,6 +8549,8 @@ void P_SceneryThinker(mobj_t *mobj)
|
||||||
return;
|
return;
|
||||||
mobj->floorz = tmfloorz;
|
mobj->floorz = tmfloorz;
|
||||||
mobj->ceilingz = tmceilingz;
|
mobj->ceilingz = tmceilingz;
|
||||||
|
mobj->floorrover = tmfloorrover;
|
||||||
|
mobj->ceilingrover = tmceilingrover;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -8627,6 +8633,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
#endif
|
#endif
|
||||||
mobj->subsector->sector->ceilingheight;
|
mobj->subsector->sector->ceilingheight;
|
||||||
|
|
||||||
|
mobj->floorrover = NULL;
|
||||||
|
mobj->ceilingrover = NULL;
|
||||||
|
|
||||||
// Tells MobjCheckWater that the water height was not set.
|
// Tells MobjCheckWater that the water height was not set.
|
||||||
mobj->watertop = INT32_MAX;
|
mobj->watertop = INT32_MAX;
|
||||||
|
|
||||||
|
@ -8890,6 +8899,9 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
||||||
#endif
|
#endif
|
||||||
mobj->subsector->sector->ceilingheight;
|
mobj->subsector->sector->ceilingheight;
|
||||||
|
|
||||||
|
mobj->floorrover = NULL;
|
||||||
|
mobj->ceilingrover = NULL;
|
||||||
|
|
||||||
mobj->z = z;
|
mobj->z = z;
|
||||||
mobj->momz = mobjinfo[type].speed;
|
mobj->momz = mobjinfo[type].speed;
|
||||||
|
|
||||||
|
@ -8911,14 +8923,15 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
||||||
static inline precipmobj_t *P_SpawnRainMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
static inline precipmobj_t *P_SpawnRainMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
{
|
{
|
||||||
precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type);
|
precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type);
|
||||||
mo->thinker.function.acp1 = (actionf_p1)P_RainThinker;
|
mo->precipflags |= PCF_RAIN;
|
||||||
|
//mo->thinker.function.acp1 = (actionf_p1)P_RainThinker;
|
||||||
return mo;
|
return mo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline precipmobj_t *P_SpawnSnowMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
static inline precipmobj_t *P_SpawnSnowMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
{
|
{
|
||||||
precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type);
|
precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type);
|
||||||
mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker;
|
//mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker;
|
||||||
return mo;
|
return mo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9225,7 +9238,7 @@ void P_PrecipitationEffects(void)
|
||||||
if (!playeringame[displayplayer] || !players[displayplayer].mo)
|
if (!playeringame[displayplayer] || !players[displayplayer].mo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (nosound || sound_disabled)
|
if (sound_disabled)
|
||||||
return; // Sound off? D'aw, no fun.
|
return; // Sound off? D'aw, no fun.
|
||||||
|
|
||||||
if (players[displayplayer].mo->subsector->sector->ceilingpic == skyflatnum)
|
if (players[displayplayer].mo->subsector->sector->ceilingpic == skyflatnum)
|
||||||
|
|
|
@ -254,6 +254,10 @@ typedef enum {
|
||||||
PCF_FOF = 4,
|
PCF_FOF = 4,
|
||||||
// Above MOVING FOF (this means we need to keep floorz up to date...)
|
// Above MOVING FOF (this means we need to keep floorz up to date...)
|
||||||
PCF_MOVINGFOF = 8,
|
PCF_MOVINGFOF = 8,
|
||||||
|
// Is rain.
|
||||||
|
PCF_RAIN = 16,
|
||||||
|
// Ran the thinker this tic.
|
||||||
|
PCF_THUNK = 32,
|
||||||
} precipflag_t;
|
} precipflag_t;
|
||||||
// Map Object definition.
|
// Map Object definition.
|
||||||
typedef struct mobj_s
|
typedef struct mobj_s
|
||||||
|
@ -282,6 +286,8 @@ typedef struct mobj_s
|
||||||
// The closest interval over all contacted sectors (or things).
|
// The closest interval over all contacted sectors (or things).
|
||||||
fixed_t floorz; // Nearest floor below.
|
fixed_t floorz; // Nearest floor below.
|
||||||
fixed_t ceilingz; // Nearest ceiling above.
|
fixed_t ceilingz; // Nearest ceiling above.
|
||||||
|
struct ffloor_s *floorrover; // FOF referred by floorz
|
||||||
|
struct ffloor_s *ceilingrover; // FOF referred by ceilingz
|
||||||
|
|
||||||
// For movement checking.
|
// For movement checking.
|
||||||
fixed_t radius;
|
fixed_t radius;
|
||||||
|
@ -398,6 +404,8 @@ typedef struct precipmobj_s
|
||||||
// The closest interval over all contacted sectors (or things).
|
// The closest interval over all contacted sectors (or things).
|
||||||
fixed_t floorz; // Nearest floor below.
|
fixed_t floorz; // Nearest floor below.
|
||||||
fixed_t ceilingz; // Nearest ceiling above.
|
fixed_t ceilingz; // Nearest ceiling above.
|
||||||
|
struct ffloor_s *floorrover; // FOF referred by floorz
|
||||||
|
struct ffloor_s *ceilingrover; // FOF referred by ceilingz
|
||||||
|
|
||||||
// For movement checking.
|
// For movement checking.
|
||||||
fixed_t radius; // Fixed at 2*FRACUNIT
|
fixed_t radius; // Fixed at 2*FRACUNIT
|
||||||
|
|
161
src/p_polyobj.c
161
src/p_polyobj.c
|
@ -985,6 +985,8 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo)
|
||||||
P_CheckPosition(mo, mo->x + momx, mo->y + momy);
|
P_CheckPosition(mo, mo->x + momx, mo->y + momy);
|
||||||
mo->floorz = tmfloorz;
|
mo->floorz = tmfloorz;
|
||||||
mo->ceilingz = tmceilingz;
|
mo->ceilingz = tmceilingz;
|
||||||
|
mo->floorrover = tmfloorrover;
|
||||||
|
mo->ceilingrover = tmceilingrover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2853,6 +2855,165 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void T_PolyObjFade(polyfade_t *th)
|
||||||
|
{
|
||||||
|
boolean stillfading = false;
|
||||||
|
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||||
|
|
||||||
|
if (!po)
|
||||||
|
#ifdef RANGECHECK
|
||||||
|
I_Error("T_PolyObjFade: thinker has invalid id %d\n", th->polyObjNum);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_POLYOBJ, "T_PolyObjFade: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||||
|
P_RemoveThinkerDelayed(&th->thinker);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// check for displacement due to override and reattach when possible
|
||||||
|
if (po->thinker == NULL)
|
||||||
|
po->thinker = &th->thinker;
|
||||||
|
|
||||||
|
stillfading = th->ticbased ? !(--(th->timer) <= 0)
|
||||||
|
: !((th->timer -= th->duration) <= 0);
|
||||||
|
|
||||||
|
if (th->timer <= 0)
|
||||||
|
{
|
||||||
|
po->translucency = max(min(th->destvalue, NUMTRANSMAPS), 0);
|
||||||
|
|
||||||
|
// remove thinker
|
||||||
|
if (po->thinker == &th->thinker)
|
||||||
|
po->thinker = NULL;
|
||||||
|
P_RemoveThinker(&th->thinker);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
INT16 delta = abs(th->destvalue - th->sourcevalue);
|
||||||
|
INT32 duration = th->ticbased ? th->duration
|
||||||
|
: abs(FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->destvalue)
|
||||||
|
- FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->sourcevalue)); // speed-based internal counter duration: delta in 256 scale
|
||||||
|
fixed_t factor = min(FixedDiv(duration - th->timer, duration), 1*FRACUNIT);
|
||||||
|
if (th->destvalue < th->sourcevalue)
|
||||||
|
po->translucency = max(min(po->translucency, th->sourcevalue - (INT16)FixedMul(delta, factor)), th->destvalue);
|
||||||
|
else if (th->destvalue > th->sourcevalue)
|
||||||
|
po->translucency = min(max(po->translucency, th->sourcevalue + (INT16)FixedMul(delta, factor)), th->destvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stillfading)
|
||||||
|
{
|
||||||
|
// set render flags
|
||||||
|
if (po->translucency >= NUMTRANSMAPS) // invisible
|
||||||
|
po->flags &= ~POF_RENDERALL;
|
||||||
|
else
|
||||||
|
po->flags |= (po->spawnflags & POF_RENDERALL);
|
||||||
|
|
||||||
|
// set collision
|
||||||
|
if (th->docollision)
|
||||||
|
{
|
||||||
|
if (th->destvalue > th->sourcevalue) // faded out
|
||||||
|
{
|
||||||
|
po->flags &= ~POF_SOLID;
|
||||||
|
po->flags |= POF_NOSPECIALS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
po->flags |= (po->spawnflags & POF_SOLID);
|
||||||
|
if (!(po->spawnflags & POF_NOSPECIALS))
|
||||||
|
po->flags &= ~POF_NOSPECIALS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (po->translucency >= NUMTRANSMAPS)
|
||||||
|
// HACK: OpenGL renders fully opaque when >= NUMTRANSMAPS
|
||||||
|
po->translucency = NUMTRANSMAPS-1;
|
||||||
|
|
||||||
|
po->flags |= (po->spawnflags & POF_RENDERALL);
|
||||||
|
|
||||||
|
// set collision
|
||||||
|
if (th->docollision)
|
||||||
|
{
|
||||||
|
if (th->doghostfade)
|
||||||
|
{
|
||||||
|
po->flags &= ~POF_SOLID;
|
||||||
|
po->flags |= POF_NOSPECIALS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
po->flags |= (po->spawnflags & POF_SOLID);
|
||||||
|
if (!(po->spawnflags & POF_NOSPECIALS))
|
||||||
|
po->flags &= ~POF_NOSPECIALS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata)
|
||||||
|
{
|
||||||
|
polyobj_t *po;
|
||||||
|
polyobj_t *oldpo;
|
||||||
|
polyfade_t *th;
|
||||||
|
INT32 start;
|
||||||
|
|
||||||
|
if (!(po = Polyobj_GetForNum(pfdata->polyObjNum)))
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjFade: bad polyobj %d\n", pfdata->polyObjNum);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't allow line actions to affect bad polyobjects
|
||||||
|
if (po->isBad)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// already equal, nothing to do
|
||||||
|
if (po->translucency == pfdata->destvalue)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (po->thinker && po->thinker->function.acp1 == (actionf_p1)T_PolyObjFade)
|
||||||
|
P_RemoveThinker(po->thinker);
|
||||||
|
|
||||||
|
// create a new thinker
|
||||||
|
th = Z_Malloc(sizeof(polyfade_t), PU_LEVSPEC, NULL);
|
||||||
|
th->thinker.function.acp1 = (actionf_p1)T_PolyObjFade;
|
||||||
|
PolyObj_AddThinker(&th->thinker);
|
||||||
|
po->thinker = &th->thinker;
|
||||||
|
|
||||||
|
// set fields
|
||||||
|
th->polyObjNum = pfdata->polyObjNum;
|
||||||
|
th->sourcevalue = po->translucency;
|
||||||
|
th->destvalue = pfdata->destvalue;
|
||||||
|
th->docollision = pfdata->docollision;
|
||||||
|
th->doghostfade = pfdata->doghostfade;
|
||||||
|
|
||||||
|
if (pfdata->ticbased)
|
||||||
|
{
|
||||||
|
th->ticbased = true;
|
||||||
|
th->timer = th->duration = abs(pfdata->speed); // pfdata->speed is duration
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
th->ticbased = false;
|
||||||
|
th->timer = abs(FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->destvalue)
|
||||||
|
- FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->sourcevalue)); // delta converted to 256 scale, use as internal counter
|
||||||
|
th->duration = abs(pfdata->speed); // use th->duration as speed decrement
|
||||||
|
}
|
||||||
|
|
||||||
|
oldpo = po;
|
||||||
|
|
||||||
|
// apply action to mirroring polyobjects as well
|
||||||
|
start = 0;
|
||||||
|
while ((po = Polyobj_GetChild(oldpo, &start)))
|
||||||
|
{
|
||||||
|
pfdata->polyObjNum = po->id;
|
||||||
|
EV_DoPolyObjFade(pfdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
// action was successful
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ifdef POLYOBJECTS
|
#endif // ifdef POLYOBJECTS
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -207,6 +207,20 @@ typedef struct polydisplace_s
|
||||||
fixed_t oldHeights;
|
fixed_t oldHeights;
|
||||||
} polydisplace_t;
|
} polydisplace_t;
|
||||||
|
|
||||||
|
typedef struct polyfade_s
|
||||||
|
{
|
||||||
|
thinker_t thinker; // must be first
|
||||||
|
|
||||||
|
INT32 polyObjNum;
|
||||||
|
INT32 sourcevalue;
|
||||||
|
INT32 destvalue;
|
||||||
|
boolean docollision;
|
||||||
|
boolean doghostfade;
|
||||||
|
boolean ticbased;
|
||||||
|
INT32 duration;
|
||||||
|
INT32 timer;
|
||||||
|
} polyfade_t;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Line Activation Data Structures
|
// Line Activation Data Structures
|
||||||
//
|
//
|
||||||
|
@ -266,6 +280,16 @@ typedef struct polydisplacedata_s
|
||||||
fixed_t dy;
|
fixed_t dy;
|
||||||
} polydisplacedata_t;
|
} polydisplacedata_t;
|
||||||
|
|
||||||
|
typedef struct polyfadedata_s
|
||||||
|
{
|
||||||
|
INT32 polyObjNum;
|
||||||
|
INT32 destvalue;
|
||||||
|
boolean docollision;
|
||||||
|
boolean doghostfade;
|
||||||
|
boolean ticbased;
|
||||||
|
INT32 speed;
|
||||||
|
} polyfadedata_t;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Functions
|
// Functions
|
||||||
//
|
//
|
||||||
|
@ -287,6 +311,7 @@ void T_PolyDoorSlide(polyslidedoor_t *);
|
||||||
void T_PolyDoorSwing(polyswingdoor_t *);
|
void T_PolyDoorSwing(polyswingdoor_t *);
|
||||||
void T_PolyObjDisplace (polydisplace_t *);
|
void T_PolyObjDisplace (polydisplace_t *);
|
||||||
void T_PolyObjFlag (polymove_t *);
|
void T_PolyObjFlag (polymove_t *);
|
||||||
|
void T_PolyObjFade (polyfade_t *);
|
||||||
|
|
||||||
INT32 EV_DoPolyDoor(polydoordata_t *);
|
INT32 EV_DoPolyDoor(polydoordata_t *);
|
||||||
INT32 EV_DoPolyObjMove(polymovedata_t *);
|
INT32 EV_DoPolyObjMove(polymovedata_t *);
|
||||||
|
@ -294,6 +319,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *);
|
||||||
INT32 EV_DoPolyObjRotate(polyrotdata_t *);
|
INT32 EV_DoPolyObjRotate(polyrotdata_t *);
|
||||||
INT32 EV_DoPolyObjDisplace(polydisplacedata_t *);
|
INT32 EV_DoPolyObjDisplace(polydisplacedata_t *);
|
||||||
INT32 EV_DoPolyObjFlag(struct line_s *);
|
INT32 EV_DoPolyObjFlag(struct line_s *);
|
||||||
|
INT32 EV_DoPolyObjFade(polyfadedata_t *);
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
619
src/p_saveg.c
619
src/p_saveg.c
|
@ -21,6 +21,7 @@
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "p_saveg.h"
|
#include "p_saveg.h"
|
||||||
|
#include "r_data.h"
|
||||||
#include "r_things.h"
|
#include "r_things.h"
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
|
@ -473,6 +474,243 @@ static void P_NetUnArchivePlayers(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Colormaps
|
||||||
|
///
|
||||||
|
|
||||||
|
static extracolormap_t *net_colormaps = NULL;
|
||||||
|
static UINT32 num_net_colormaps = 0;
|
||||||
|
static UINT32 num_ffloors = 0; // for loading
|
||||||
|
|
||||||
|
// Copypasta from r_data.c AddColormapToList
|
||||||
|
// But also check for equality and return the matching index
|
||||||
|
static UINT32 CheckAddNetColormapToList(extracolormap_t *extra_colormap)
|
||||||
|
{
|
||||||
|
extracolormap_t *exc, *exc_prev;
|
||||||
|
UINT32 i = 0;
|
||||||
|
|
||||||
|
if (!net_colormaps)
|
||||||
|
{
|
||||||
|
net_colormaps = R_CopyColormap(extra_colormap, false);
|
||||||
|
net_colormaps->next = 0;
|
||||||
|
net_colormaps->prev = 0;
|
||||||
|
num_net_colormaps = i+1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (exc = net_colormaps; exc; exc_prev = exc, exc = exc->next)
|
||||||
|
{
|
||||||
|
if (R_CheckEqualColormaps(exc, extra_colormap, true, true, true))
|
||||||
|
return i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
exc_prev->next = R_CopyColormap(extra_colormap, false);
|
||||||
|
extra_colormap->prev = exc_prev;
|
||||||
|
extra_colormap->next = 0;
|
||||||
|
|
||||||
|
num_net_colormaps = i+1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static extracolormap_t *GetNetColormapFromList(UINT32 index)
|
||||||
|
{
|
||||||
|
// For loading, we have to be tricky:
|
||||||
|
// We load the sectors BEFORE knowing the colormap values
|
||||||
|
// So if an index doesn't exist, fill our list with dummy colormaps
|
||||||
|
// until we get the index we want
|
||||||
|
// Then when we load the color data, we set up the dummy colormaps
|
||||||
|
|
||||||
|
extracolormap_t *exc, *last_exc = NULL;
|
||||||
|
UINT32 i = 0;
|
||||||
|
|
||||||
|
if (!net_colormaps) // initialize our list
|
||||||
|
net_colormaps = R_CreateDefaultColormap(false);
|
||||||
|
|
||||||
|
for (exc = net_colormaps; exc; last_exc = exc, exc = exc->next)
|
||||||
|
{
|
||||||
|
if (i++ == index)
|
||||||
|
return exc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// LET'S HOPE that index is a sane value, because we create up to [index]
|
||||||
|
// entries in net_colormaps. At this point, we don't know
|
||||||
|
// what the total colormap count is
|
||||||
|
if (index >= numsectors*3 + num_ffloors)
|
||||||
|
// if every sector had a unique colormap change AND a fade color thinker which has two colormap entries
|
||||||
|
// AND every ffloor had a fade FOF thinker with one colormap entry
|
||||||
|
I_Error("Colormap %d from server is too high for sectors %d", index, (UINT32)numsectors);
|
||||||
|
|
||||||
|
// our index doesn't exist, so just make the entry
|
||||||
|
for (; i <= index; i++)
|
||||||
|
{
|
||||||
|
exc = R_CreateDefaultColormap(false);
|
||||||
|
if (last_exc)
|
||||||
|
last_exc->next = exc;
|
||||||
|
exc->prev = last_exc;
|
||||||
|
exc->next = NULL;
|
||||||
|
last_exc = exc;
|
||||||
|
}
|
||||||
|
return exc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ClearNetColormaps(void)
|
||||||
|
{
|
||||||
|
// We're actually Z_Freeing each entry here,
|
||||||
|
// so don't call this in P_NetUnArchiveColormaps (where entries will be used in-game)
|
||||||
|
extracolormap_t *exc, *exc_next;
|
||||||
|
|
||||||
|
for (exc = net_colormaps; exc; exc = exc_next)
|
||||||
|
{
|
||||||
|
exc_next = exc->next;
|
||||||
|
Z_Free(exc);
|
||||||
|
}
|
||||||
|
num_net_colormaps = 0;
|
||||||
|
num_ffloors = 0;
|
||||||
|
net_colormaps = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_NetArchiveColormaps(void)
|
||||||
|
{
|
||||||
|
// We save and then we clean up our colormap mess
|
||||||
|
extracolormap_t *exc, *exc_next;
|
||||||
|
UINT32 i = 0;
|
||||||
|
WRITEUINT32(save_p, num_net_colormaps); // save for safety
|
||||||
|
|
||||||
|
for (exc = net_colormaps; i < num_net_colormaps; i++, exc = exc_next)
|
||||||
|
{
|
||||||
|
// We must save num_net_colormaps worth of data
|
||||||
|
// So fill non-existent entries with default.
|
||||||
|
if (!exc)
|
||||||
|
exc = R_CreateDefaultColormap(false);
|
||||||
|
|
||||||
|
WRITEUINT8(save_p, exc->fadestart);
|
||||||
|
WRITEUINT8(save_p, exc->fadeend);
|
||||||
|
WRITEUINT8(save_p, exc->fog);
|
||||||
|
|
||||||
|
WRITEINT32(save_p, exc->rgba);
|
||||||
|
WRITEINT32(save_p, exc->fadergba);
|
||||||
|
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
WRITESTRINGN(save_p, exc->lumpname, 9);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
exc_next = exc->next;
|
||||||
|
Z_Free(exc); // don't need anymore
|
||||||
|
}
|
||||||
|
|
||||||
|
num_net_colormaps = 0;
|
||||||
|
num_ffloors = 0;
|
||||||
|
net_colormaps = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void P_NetUnArchiveColormaps(void)
|
||||||
|
{
|
||||||
|
// When we reach this point, we already populated our list with
|
||||||
|
// dummy colormaps. Now that we are loading the color data,
|
||||||
|
// set up the dummies.
|
||||||
|
extracolormap_t *exc, *existing_exc, *exc_next = NULL;
|
||||||
|
UINT32 i = 0;
|
||||||
|
|
||||||
|
num_net_colormaps = READUINT32(save_p);
|
||||||
|
|
||||||
|
for (exc = net_colormaps; i < num_net_colormaps; i++, exc = exc_next)
|
||||||
|
{
|
||||||
|
UINT8 fadestart, fadeend, fog;
|
||||||
|
INT32 rgba, fadergba;
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
char lumpname[9];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fadestart = READUINT8(save_p);
|
||||||
|
fadeend = READUINT8(save_p);
|
||||||
|
fog = READUINT8(save_p);
|
||||||
|
|
||||||
|
rgba = READINT32(save_p);
|
||||||
|
fadergba = READINT32(save_p);
|
||||||
|
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
READSTRINGN(save_p, lumpname, 9);
|
||||||
|
|
||||||
|
if (lumpname[0])
|
||||||
|
{
|
||||||
|
if (!exc)
|
||||||
|
// no point making a new entry since nothing points to it,
|
||||||
|
// but we needed to read the data so now continue
|
||||||
|
continue;
|
||||||
|
|
||||||
|
exc_next = exc->next; // this gets overwritten during our operations here, so get it now
|
||||||
|
existing_exc = R_ColormapForName(lumpname);
|
||||||
|
*exc = *existing_exc;
|
||||||
|
R_AddColormapToList(exc); // see HACK note below on why we're adding duplicates
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!exc)
|
||||||
|
// no point making a new entry since nothing points to it,
|
||||||
|
// but we needed to read the data so now continue
|
||||||
|
continue;
|
||||||
|
|
||||||
|
exc_next = exc->next; // this gets overwritten during our operations here, so get it now
|
||||||
|
|
||||||
|
exc->fadestart = fadestart;
|
||||||
|
exc->fadeend = fadeend;
|
||||||
|
exc->fog = fog;
|
||||||
|
|
||||||
|
exc->rgba = rgba;
|
||||||
|
exc->fadergba = fadergba;
|
||||||
|
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
exc->lump = LUMPERROR;
|
||||||
|
exc->lumpname[0] = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
existing_exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog);
|
||||||
|
|
||||||
|
if (existing_exc)
|
||||||
|
exc->colormap = existing_exc->colormap;
|
||||||
|
else
|
||||||
|
// CONS_Debug(DBG_RENDER, "Creating Colormap: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n",
|
||||||
|
// R_GetRgbaR(rgba), R_GetRgbaG(rgba), R_GetRgbaB(rgba), R_GetRgbaA(rgba),
|
||||||
|
// R_GetRgbaR(fadergba), R_GetRgbaG(fadergba), R_GetRgbaB(fadergba), R_GetRgbaA(fadergba));
|
||||||
|
exc->colormap = R_CreateLightTable(exc);
|
||||||
|
|
||||||
|
// HACK: If this dummy is a duplicate, we're going to add it
|
||||||
|
// to the extra_colormaps list anyway. I think this is faster
|
||||||
|
// than going through every loaded sector and correcting their
|
||||||
|
// colormap address to the pre-existing one, PER net_colormap entry
|
||||||
|
R_AddColormapToList(exc);
|
||||||
|
|
||||||
|
if (i < num_net_colormaps-1 && !exc_next)
|
||||||
|
exc_next = R_CreateDefaultColormap(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we still have a valid net_colormap after iterating up to num_net_colormaps,
|
||||||
|
// some sector had a colormap index higher than num_net_colormaps. We done goofed or $$$ was corrupted.
|
||||||
|
// In any case, add them to the colormap list too so that at least the sectors' colormap
|
||||||
|
// addresses are valid and accounted properly
|
||||||
|
if (exc_next)
|
||||||
|
{
|
||||||
|
existing_exc = R_GetDefaultColormap();
|
||||||
|
for (exc = exc_next; exc; exc = exc->next)
|
||||||
|
{
|
||||||
|
exc->colormap = existing_exc->colormap; // all our dummies are default values
|
||||||
|
R_AddColormapToList(exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't need these anymore
|
||||||
|
num_net_colormaps = 0;
|
||||||
|
num_ffloors = 0;
|
||||||
|
net_colormaps = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// World Archiving
|
||||||
|
///
|
||||||
|
|
||||||
#define SD_FLOORHT 0x01
|
#define SD_FLOORHT 0x01
|
||||||
#define SD_CEILHT 0x02
|
#define SD_CEILHT 0x02
|
||||||
#define SD_FLOORPIC 0x04
|
#define SD_FLOORPIC 0x04
|
||||||
|
@ -487,10 +725,14 @@ static void P_NetUnArchivePlayers(void)
|
||||||
#define SD_FYOFFS 0x02
|
#define SD_FYOFFS 0x02
|
||||||
#define SD_CXOFFS 0x04
|
#define SD_CXOFFS 0x04
|
||||||
#define SD_CYOFFS 0x08
|
#define SD_CYOFFS 0x08
|
||||||
#define SD_TAG 0x10
|
#define SD_FLOORANG 0x10
|
||||||
#define SD_FLOORANG 0x20
|
#define SD_CEILANG 0x20
|
||||||
#define SD_CEILANG 0x40
|
#define SD_TAG 0x40
|
||||||
#define SD_TAGLIST 0x80
|
#define SD_DIFF3 0x80
|
||||||
|
|
||||||
|
// diff3 flags
|
||||||
|
#define SD_TAGLIST 0x01
|
||||||
|
#define SD_COLORMAP 0x02
|
||||||
|
|
||||||
#define LD_FLAG 0x01
|
#define LD_FLAG 0x01
|
||||||
#define LD_SPECIAL 0x02
|
#define LD_SPECIAL 0x02
|
||||||
|
@ -523,7 +765,10 @@ static void P_NetArchiveWorld(void)
|
||||||
mapsidedef_t *msd;
|
mapsidedef_t *msd;
|
||||||
maplinedef_t *mld;
|
maplinedef_t *mld;
|
||||||
const sector_t *ss = sectors;
|
const sector_t *ss = sectors;
|
||||||
UINT8 diff, diff2;
|
UINT8 diff, diff2, diff3;
|
||||||
|
|
||||||
|
// initialize colormap vars because paranoia
|
||||||
|
ClearNetColormaps();
|
||||||
|
|
||||||
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
||||||
put = save_p;
|
put = save_p;
|
||||||
|
@ -550,7 +795,7 @@ static void P_NetArchiveWorld(void)
|
||||||
|
|
||||||
for (i = 0; i < numsectors; i++, ss++, ms++)
|
for (i = 0; i < numsectors; i++, ss++, ms++)
|
||||||
{
|
{
|
||||||
diff = diff2 = 0;
|
diff = diff2 = diff3 = 0;
|
||||||
if (ss->floorheight != SHORT(ms->floorheight)<<FRACBITS)
|
if (ss->floorheight != SHORT(ms->floorheight)<<FRACBITS)
|
||||||
diff |= SD_FLOORHT;
|
diff |= SD_FLOORHT;
|
||||||
if (ss->ceilingheight != SHORT(ms->ceilingheight)<<FRACBITS)
|
if (ss->ceilingheight != SHORT(ms->ceilingheight)<<FRACBITS)
|
||||||
|
@ -584,7 +829,10 @@ static void P_NetArchiveWorld(void)
|
||||||
if (ss->tag != SHORT(ms->tag))
|
if (ss->tag != SHORT(ms->tag))
|
||||||
diff2 |= SD_TAG;
|
diff2 |= SD_TAG;
|
||||||
if (ss->nexttag != ss->spawn_nexttag || ss->firsttag != ss->spawn_firsttag)
|
if (ss->nexttag != ss->spawn_nexttag || ss->firsttag != ss->spawn_firsttag)
|
||||||
diff2 |= SD_TAGLIST;
|
diff3 |= SD_TAGLIST;
|
||||||
|
|
||||||
|
if (ss->extra_colormap != ss->spawn_extra_colormap)
|
||||||
|
diff3 |= SD_COLORMAP;
|
||||||
|
|
||||||
// Check if any of the sector's FOFs differ from how they spawned
|
// Check if any of the sector's FOFs differ from how they spawned
|
||||||
if (ss->ffloors)
|
if (ss->ffloors)
|
||||||
|
@ -601,6 +849,9 @@ static void P_NetArchiveWorld(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (diff3)
|
||||||
|
diff2 |= SD_DIFF3;
|
||||||
|
|
||||||
if (diff2)
|
if (diff2)
|
||||||
diff |= SD_DIFF2;
|
diff |= SD_DIFF2;
|
||||||
|
|
||||||
|
@ -612,6 +863,8 @@ static void P_NetArchiveWorld(void)
|
||||||
WRITEUINT8(put, diff);
|
WRITEUINT8(put, diff);
|
||||||
if (diff & SD_DIFF2)
|
if (diff & SD_DIFF2)
|
||||||
WRITEUINT8(put, diff2);
|
WRITEUINT8(put, diff2);
|
||||||
|
if (diff2 & SD_DIFF3)
|
||||||
|
WRITEUINT8(put, diff3);
|
||||||
if (diff & SD_FLOORHT)
|
if (diff & SD_FLOORHT)
|
||||||
WRITEFIXED(put, ss->floorheight);
|
WRITEFIXED(put, ss->floorheight);
|
||||||
if (diff & SD_CEILHT)
|
if (diff & SD_CEILHT)
|
||||||
|
@ -632,18 +885,22 @@ static void P_NetArchiveWorld(void)
|
||||||
WRITEFIXED(put, ss->ceiling_xoffs);
|
WRITEFIXED(put, ss->ceiling_xoffs);
|
||||||
if (diff2 & SD_CYOFFS)
|
if (diff2 & SD_CYOFFS)
|
||||||
WRITEFIXED(put, ss->ceiling_yoffs);
|
WRITEFIXED(put, ss->ceiling_yoffs);
|
||||||
if (diff2 & SD_TAG) // save only the tag
|
|
||||||
WRITEINT16(put, ss->tag);
|
|
||||||
if (diff2 & SD_FLOORANG)
|
if (diff2 & SD_FLOORANG)
|
||||||
WRITEANGLE(put, ss->floorpic_angle);
|
WRITEANGLE(put, ss->floorpic_angle);
|
||||||
if (diff2 & SD_CEILANG)
|
if (diff2 & SD_CEILANG)
|
||||||
WRITEANGLE(put, ss->ceilingpic_angle);
|
WRITEANGLE(put, ss->ceilingpic_angle);
|
||||||
if (diff2 & SD_TAGLIST) // save both firsttag and nexttag
|
if (diff2 & SD_TAG) // save only the tag
|
||||||
|
WRITEINT16(put, ss->tag);
|
||||||
|
if (diff3 & SD_TAGLIST) // save both firsttag and nexttag
|
||||||
{ // either of these could be changed even if tag isn't
|
{ // either of these could be changed even if tag isn't
|
||||||
WRITEINT32(put, ss->firsttag);
|
WRITEINT32(put, ss->firsttag);
|
||||||
WRITEINT32(put, ss->nexttag);
|
WRITEINT32(put, ss->nexttag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (diff3 & SD_COLORMAP)
|
||||||
|
WRITEUINT32(put, CheckAddNetColormapToList(ss->extra_colormap));
|
||||||
|
// returns existing index if already added, or appends to net_colormaps and returns new index
|
||||||
|
|
||||||
// Special case: save the stats of all modified ffloors along with their ffloor "number"s
|
// Special case: save the stats of all modified ffloors along with their ffloor "number"s
|
||||||
// we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed
|
// we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed
|
||||||
if (diff & SD_FFLOORS)
|
if (diff & SD_FFLOORS)
|
||||||
|
@ -680,7 +937,7 @@ static void P_NetArchiveWorld(void)
|
||||||
// do lines
|
// do lines
|
||||||
for (i = 0; i < numlines; i++, mld++, li++)
|
for (i = 0; i < numlines; i++, mld++, li++)
|
||||||
{
|
{
|
||||||
diff = diff2 = 0;
|
diff = diff2 = diff3 = 0;
|
||||||
|
|
||||||
if (li->special != SHORT(mld->special))
|
if (li->special != SHORT(mld->special))
|
||||||
diff |= LD_SPECIAL;
|
diff |= LD_SPECIAL;
|
||||||
|
@ -772,11 +1029,22 @@ static void P_NetUnArchiveWorld(void)
|
||||||
line_t *li;
|
line_t *li;
|
||||||
side_t *si;
|
side_t *si;
|
||||||
UINT8 *get;
|
UINT8 *get;
|
||||||
UINT8 diff, diff2;
|
UINT8 diff, diff2, diff3;
|
||||||
|
|
||||||
if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD)
|
if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD)
|
||||||
I_Error("Bad $$$.sav at archive block World");
|
I_Error("Bad $$$.sav at archive block World");
|
||||||
|
|
||||||
|
// initialize colormap vars because paranoia
|
||||||
|
ClearNetColormaps();
|
||||||
|
|
||||||
|
// count the level's ffloors so that colormap loading can have an upper limit
|
||||||
|
for (i = 0; i < numsectors; i++)
|
||||||
|
{
|
||||||
|
ffloor_t *rover;
|
||||||
|
for (rover = sectors[i].ffloors; rover; rover = rover->next)
|
||||||
|
num_ffloors++;
|
||||||
|
}
|
||||||
|
|
||||||
get = save_p;
|
get = save_p;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -794,6 +1062,10 @@ static void P_NetUnArchiveWorld(void)
|
||||||
diff2 = READUINT8(get);
|
diff2 = READUINT8(get);
|
||||||
else
|
else
|
||||||
diff2 = 0;
|
diff2 = 0;
|
||||||
|
if (diff2 & SD_DIFF3)
|
||||||
|
diff3 = READUINT8(get);
|
||||||
|
else
|
||||||
|
diff3 = 0;
|
||||||
|
|
||||||
if (diff & SD_FLOORHT)
|
if (diff & SD_FLOORHT)
|
||||||
sectors[i].floorheight = READFIXED(get);
|
sectors[i].floorheight = READFIXED(get);
|
||||||
|
@ -822,17 +1094,20 @@ static void P_NetUnArchiveWorld(void)
|
||||||
sectors[i].ceiling_xoffs = READFIXED(get);
|
sectors[i].ceiling_xoffs = READFIXED(get);
|
||||||
if (diff2 & SD_CYOFFS)
|
if (diff2 & SD_CYOFFS)
|
||||||
sectors[i].ceiling_yoffs = READFIXED(get);
|
sectors[i].ceiling_yoffs = READFIXED(get);
|
||||||
if (diff2 & SD_TAG)
|
|
||||||
sectors[i].tag = READINT16(get); // DON'T use P_ChangeSectorTag
|
|
||||||
if (diff2 & SD_TAGLIST)
|
|
||||||
{
|
|
||||||
sectors[i].firsttag = READINT32(get);
|
|
||||||
sectors[i].nexttag = READINT32(get);
|
|
||||||
}
|
|
||||||
if (diff2 & SD_FLOORANG)
|
if (diff2 & SD_FLOORANG)
|
||||||
sectors[i].floorpic_angle = READANGLE(get);
|
sectors[i].floorpic_angle = READANGLE(get);
|
||||||
if (diff2 & SD_CEILANG)
|
if (diff2 & SD_CEILANG)
|
||||||
sectors[i].ceilingpic_angle = READANGLE(get);
|
sectors[i].ceilingpic_angle = READANGLE(get);
|
||||||
|
if (diff2 & SD_TAG)
|
||||||
|
sectors[i].tag = READINT16(get); // DON'T use P_ChangeSectorTag
|
||||||
|
if (diff3 & SD_TAGLIST)
|
||||||
|
{
|
||||||
|
sectors[i].firsttag = READINT32(get);
|
||||||
|
sectors[i].nexttag = READINT32(get);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diff3 & SD_COLORMAP)
|
||||||
|
sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get));
|
||||||
|
|
||||||
if (diff & SD_FFLOORS)
|
if (diff & SD_FFLOORS)
|
||||||
{
|
{
|
||||||
|
@ -891,6 +1166,9 @@ static void P_NetUnArchiveWorld(void)
|
||||||
diff2 = READUINT8(get);
|
diff2 = READUINT8(get);
|
||||||
else
|
else
|
||||||
diff2 = 0;
|
diff2 = 0;
|
||||||
|
|
||||||
|
diff3 = 0;
|
||||||
|
|
||||||
if (diff & LD_FLAG)
|
if (diff & LD_FLAG)
|
||||||
li->flags = READINT16(get);
|
li->flags = READINT16(get);
|
||||||
if (diff & LD_SPECIAL)
|
if (diff & LD_SPECIAL)
|
||||||
|
@ -972,11 +1250,13 @@ typedef enum
|
||||||
MD2_EXTVAL1 = 1<<5,
|
MD2_EXTVAL1 = 1<<5,
|
||||||
MD2_EXTVAL2 = 1<<6,
|
MD2_EXTVAL2 = 1<<6,
|
||||||
MD2_HNEXT = 1<<7,
|
MD2_HNEXT = 1<<7,
|
||||||
#ifdef ESLOPE
|
|
||||||
MD2_HPREV = 1<<8,
|
MD2_HPREV = 1<<8,
|
||||||
MD2_SLOPE = 1<<9
|
MD2_FLOORROVER = 1<<9,
|
||||||
|
#ifdef ESLOPE
|
||||||
|
MD2_CEILINGROVER = 1<<10,
|
||||||
|
MD2_SLOPE = 1<<11
|
||||||
#else
|
#else
|
||||||
MD2_HPREV = 1<<8
|
MD2_CEILINGROVER = 1<<10
|
||||||
#endif
|
#endif
|
||||||
} mobj_diff2_t;
|
} mobj_diff2_t;
|
||||||
|
|
||||||
|
@ -996,6 +1276,7 @@ typedef enum
|
||||||
tc_bouncecheese,
|
tc_bouncecheese,
|
||||||
tc_startcrumble,
|
tc_startcrumble,
|
||||||
tc_marioblock,
|
tc_marioblock,
|
||||||
|
tc_marioblockchecker,
|
||||||
tc_spikesector,
|
tc_spikesector,
|
||||||
tc_floatsector,
|
tc_floatsector,
|
||||||
tc_bridgethinker,
|
tc_bridgethinker,
|
||||||
|
@ -1010,6 +1291,8 @@ typedef enum
|
||||||
tc_noenemies,
|
tc_noenemies,
|
||||||
tc_eachtime,
|
tc_eachtime,
|
||||||
tc_disappear,
|
tc_disappear,
|
||||||
|
tc_fade,
|
||||||
|
tc_fadecolormap,
|
||||||
tc_planedisplace,
|
tc_planedisplace,
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
tc_polyrotate, // haleyjd 03/26/06: polyobjects
|
tc_polyrotate, // haleyjd 03/26/06: polyobjects
|
||||||
|
@ -1019,6 +1302,7 @@ typedef enum
|
||||||
tc_polyswingdoor,
|
tc_polyswingdoor,
|
||||||
tc_polyflag,
|
tc_polyflag,
|
||||||
tc_polydisplace,
|
tc_polydisplace,
|
||||||
|
tc_polyfade,
|
||||||
#endif
|
#endif
|
||||||
tc_end
|
tc_end
|
||||||
} specials_e;
|
} specials_e;
|
||||||
|
@ -1170,6 +1454,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
||||||
diff2 |= MD2_HNEXT;
|
diff2 |= MD2_HNEXT;
|
||||||
if (mobj->hprev)
|
if (mobj->hprev)
|
||||||
diff2 |= MD2_HPREV;
|
diff2 |= MD2_HPREV;
|
||||||
|
if (mobj->floorrover)
|
||||||
|
diff2 |= MD2_FLOORROVER;
|
||||||
|
if (mobj->ceilingrover)
|
||||||
|
diff2 |= MD2_CEILINGROVER;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
if (mobj->standingslope)
|
if (mobj->standingslope)
|
||||||
diff2 |= MD2_SLOPE;
|
diff2 |= MD2_SLOPE;
|
||||||
|
@ -1193,6 +1481,46 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
||||||
WRITEFIXED(save_p, mobj->floorz);
|
WRITEFIXED(save_p, mobj->floorz);
|
||||||
WRITEFIXED(save_p, mobj->ceilingz);
|
WRITEFIXED(save_p, mobj->ceilingz);
|
||||||
|
|
||||||
|
if (diff2 & MD2_FLOORROVER)
|
||||||
|
{
|
||||||
|
ffloor_t *rover;
|
||||||
|
size_t i = 0;
|
||||||
|
UINT32 roverindex = 0;
|
||||||
|
|
||||||
|
for (rover = mobj->floorrover->target->ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (rover == mobj->floorrover)
|
||||||
|
{
|
||||||
|
roverindex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITEUINT32(save_p, (UINT32)(mobj->floorrover->target - sectors));
|
||||||
|
WRITEUINT32(save_p, rover ? roverindex : i); // store max index to denote invalid ffloor ref
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diff2 & MD2_CEILINGROVER)
|
||||||
|
{
|
||||||
|
ffloor_t *rover;
|
||||||
|
size_t i = 0;
|
||||||
|
UINT32 roverindex = 0;
|
||||||
|
|
||||||
|
for (rover = mobj->ceilingrover->target->ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (rover == mobj->ceilingrover)
|
||||||
|
{
|
||||||
|
roverindex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITEUINT32(save_p, (UINT32)(mobj->ceilingrover->target - sectors));
|
||||||
|
WRITEUINT32(save_p, rover ? roverindex : i); // store max index to denote invalid ffloor ref
|
||||||
|
}
|
||||||
|
|
||||||
if (diff & MD_SPAWNPOINT)
|
if (diff & MD_SPAWNPOINT)
|
||||||
{
|
{
|
||||||
size_t z;
|
size_t z;
|
||||||
|
@ -1311,7 +1639,10 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
|
||||||
size_t i;
|
size_t i;
|
||||||
WRITEUINT8(save_p, type);
|
WRITEUINT8(save_p, type);
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
WRITEFIXED(save_p, ht->vars[i]); //var[16]
|
WRITEFIXED(save_p, ht->vars[i]); //var[16]
|
||||||
|
WRITEFIXED(save_p, ht->var2s[i]); //var[16]
|
||||||
|
}
|
||||||
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||||
}
|
}
|
||||||
|
@ -1537,8 +1868,11 @@ static void SaveLightlevelThinker(const thinker_t *th, const UINT8 type)
|
||||||
const lightlevel_t *ht = (const void *)th;
|
const lightlevel_t *ht = (const void *)th;
|
||||||
WRITEUINT8(save_p, type);
|
WRITEUINT8(save_p, type);
|
||||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||||
WRITEINT32(save_p, ht->destlevel);
|
WRITEINT16(save_p, ht->sourcelevel);
|
||||||
WRITEINT32(save_p, ht->speed);
|
WRITEINT16(save_p, ht->destlevel);
|
||||||
|
WRITEFIXED(save_p, ht->fixedcurlevel);
|
||||||
|
WRITEFIXED(save_p, ht->fixedpertic);
|
||||||
|
WRITEINT32(save_p, ht->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1574,6 +1908,51 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type)
|
||||||
WRITEINT32(save_p, ht->exists);
|
WRITEINT32(save_p, ht->exists);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// SaveFadeThinker
|
||||||
|
//
|
||||||
|
// Saves a fade_t thinker
|
||||||
|
//
|
||||||
|
static void SaveFadeThinker(const thinker_t *th, const UINT8 type)
|
||||||
|
{
|
||||||
|
const fade_t *ht = (const void *)th;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEUINT32(save_p, CheckAddNetColormapToList(ht->dest_exc));
|
||||||
|
WRITEUINT32(save_p, ht->sectornum);
|
||||||
|
WRITEUINT32(save_p, ht->ffloornum);
|
||||||
|
WRITEINT32(save_p, ht->alpha);
|
||||||
|
WRITEINT16(save_p, ht->sourcevalue);
|
||||||
|
WRITEINT16(save_p, ht->destvalue);
|
||||||
|
WRITEINT16(save_p, ht->destlightlevel);
|
||||||
|
WRITEINT16(save_p, ht->speed);
|
||||||
|
WRITEUINT8(save_p, (UINT8)ht->ticbased);
|
||||||
|
WRITEINT32(save_p, ht->timer);
|
||||||
|
WRITEUINT8(save_p, ht->doexists);
|
||||||
|
WRITEUINT8(save_p, ht->dotranslucent);
|
||||||
|
WRITEUINT8(save_p, ht->dolighting);
|
||||||
|
WRITEUINT8(save_p, ht->docolormap);
|
||||||
|
WRITEUINT8(save_p, ht->docollision);
|
||||||
|
WRITEUINT8(save_p, ht->doghostfade);
|
||||||
|
WRITEUINT8(save_p, ht->exactalpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// SaveFadeColormapThinker
|
||||||
|
//
|
||||||
|
// Saves a fadecolormap_t thinker
|
||||||
|
//
|
||||||
|
static void SaveFadeColormapThinker(const thinker_t *th, const UINT8 type)
|
||||||
|
{
|
||||||
|
const fadecolormap_t *ht = (const void *)th;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||||
|
WRITEUINT32(save_p, CheckAddNetColormapToList(ht->source_exc));
|
||||||
|
WRITEUINT32(save_p, CheckAddNetColormapToList(ht->dest_exc));
|
||||||
|
WRITEUINT8(save_p, (UINT8)ht->ticbased);
|
||||||
|
WRITEINT32(save_p, ht->duration);
|
||||||
|
WRITEINT32(save_p, ht->timer);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// SavePlaneDisplaceThinker
|
// SavePlaneDisplaceThinker
|
||||||
//
|
//
|
||||||
|
@ -1699,6 +2078,20 @@ static void SavePolydisplaceThinker(const thinker_t *th, const UINT8 type)
|
||||||
WRITEFIXED(save_p, ht->oldHeights);
|
WRITEFIXED(save_p, ht->oldHeights);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type)
|
||||||
|
{
|
||||||
|
const polyfade_t *ht = (const void *)th;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEINT32(save_p, ht->polyObjNum);
|
||||||
|
WRITEINT32(save_p, ht->sourcevalue);
|
||||||
|
WRITEINT32(save_p, ht->destvalue);
|
||||||
|
WRITEUINT8(save_p, (UINT8)ht->docollision);
|
||||||
|
WRITEUINT8(save_p, (UINT8)ht->doghostfade);
|
||||||
|
WRITEUINT8(save_p, (UINT8)ht->ticbased);
|
||||||
|
WRITEINT32(save_p, ht->duration);
|
||||||
|
WRITEINT32(save_p, ht->timer);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
//
|
//
|
||||||
|
@ -1728,8 +2121,7 @@ static void P_NetArchiveThinkers(void)
|
||||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||||
{
|
{
|
||||||
if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed
|
if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed
|
||||||
|| th->function.acp1 == (actionf_p1)P_RainThinker
|
|| th->function.acp1 == (actionf_p1)P_NullPrecipThinker))
|
||||||
|| th->function.acp1 == (actionf_p1)P_SnowThinker))
|
|
||||||
numsaved++;
|
numsaved++;
|
||||||
|
|
||||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||||
|
@ -1738,8 +2130,7 @@ static void P_NetArchiveThinkers(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
else if (th->function.acp1 == (actionf_p1)P_RainThinker
|
else if (th->function.acp1 == (actionf_p1)P_NullPrecipThinker);
|
||||||
|| th->function.acp1 == (actionf_p1)P_SnowThinker);
|
|
||||||
#endif
|
#endif
|
||||||
else if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
|
else if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
|
||||||
{
|
{
|
||||||
|
@ -1841,6 +2232,11 @@ static void P_NetArchiveThinkers(void)
|
||||||
SaveSpecialLevelThinker(th, tc_marioblock);
|
SaveSpecialLevelThinker(th, tc_marioblock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker)
|
||||||
|
{
|
||||||
|
SaveSpecialLevelThinker(th, tc_marioblockchecker);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
else if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
||||||
{
|
{
|
||||||
SaveSpecialLevelThinker(th, tc_spikesector);
|
SaveSpecialLevelThinker(th, tc_spikesector);
|
||||||
|
@ -1876,7 +2272,16 @@ static void P_NetArchiveThinkers(void)
|
||||||
SaveDisappearThinker(th, tc_disappear);
|
SaveDisappearThinker(th, tc_disappear);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (th->function.acp1 == (actionf_p1)T_Fade)
|
||||||
|
{
|
||||||
|
SaveFadeThinker(th, tc_fade);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (th->function.acp1 == (actionf_p1)T_FadeColormap)
|
||||||
|
{
|
||||||
|
SaveFadeColormapThinker(th, tc_fadecolormap);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace)
|
else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace)
|
||||||
{
|
{
|
||||||
SavePlaneDisplaceThinker(th, tc_planedisplace);
|
SavePlaneDisplaceThinker(th, tc_planedisplace);
|
||||||
|
@ -1918,6 +2323,11 @@ static void P_NetArchiveThinkers(void)
|
||||||
SavePolydisplaceThinker(th, tc_polydisplace);
|
SavePolydisplaceThinker(th, tc_polydisplace);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (th->function.acp1 == (actionf_p1)T_PolyObjFade)
|
||||||
|
{
|
||||||
|
SavePolyfadeThinker(th, tc_polyfade);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection
|
else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection
|
||||||
|
@ -1989,6 +2399,7 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
||||||
UINT16 diff2;
|
UINT16 diff2;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
fixed_t z, floorz, ceilingz;
|
fixed_t z, floorz, ceilingz;
|
||||||
|
ffloor_t *floorrover = NULL, *ceilingrover = NULL;
|
||||||
|
|
||||||
diff = READUINT32(save_p);
|
diff = READUINT32(save_p);
|
||||||
if (diff & MD_MORE)
|
if (diff & MD_MORE)
|
||||||
|
@ -2002,6 +2413,38 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
||||||
floorz = READFIXED(save_p);
|
floorz = READFIXED(save_p);
|
||||||
ceilingz = READFIXED(save_p);
|
ceilingz = READFIXED(save_p);
|
||||||
|
|
||||||
|
if (diff2 & MD2_FLOORROVER)
|
||||||
|
{
|
||||||
|
size_t floor_sectornum = (size_t)READUINT32(save_p);
|
||||||
|
size_t floor_rovernum = (size_t)READUINT32(save_p);
|
||||||
|
ffloor_t *rover = NULL;
|
||||||
|
size_t rovernum = 0;
|
||||||
|
|
||||||
|
for (rover = sectors[floor_sectornum].ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (rovernum == floor_rovernum)
|
||||||
|
break;
|
||||||
|
rovernum++;
|
||||||
|
}
|
||||||
|
floorrover = rover;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diff2 & MD2_CEILINGROVER)
|
||||||
|
{
|
||||||
|
size_t ceiling_sectornum = (size_t)READUINT32(save_p);
|
||||||
|
size_t ceiling_rovernum = (size_t)READUINT32(save_p);
|
||||||
|
ffloor_t *rover = NULL;
|
||||||
|
size_t rovernum = 0;
|
||||||
|
|
||||||
|
for (rover = sectors[ceiling_sectornum].ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (rovernum == ceiling_rovernum)
|
||||||
|
break;
|
||||||
|
rovernum++;
|
||||||
|
}
|
||||||
|
ceilingrover = rover;
|
||||||
|
}
|
||||||
|
|
||||||
if (diff & MD_SPAWNPOINT)
|
if (diff & MD_SPAWNPOINT)
|
||||||
{
|
{
|
||||||
UINT16 spawnpointnum = READUINT16(save_p);
|
UINT16 spawnpointnum = READUINT16(save_p);
|
||||||
|
@ -2026,6 +2469,8 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
||||||
mobj->z = z;
|
mobj->z = z;
|
||||||
mobj->floorz = floorz;
|
mobj->floorz = floorz;
|
||||||
mobj->ceilingz = ceilingz;
|
mobj->ceilingz = ceilingz;
|
||||||
|
mobj->floorrover = floorrover;
|
||||||
|
mobj->ceilingrover = ceilingrover;
|
||||||
|
|
||||||
if (diff & MD_TYPE)
|
if (diff & MD_TYPE)
|
||||||
mobj->type = READUINT32(save_p);
|
mobj->type = READUINT32(save_p);
|
||||||
|
@ -2236,7 +2681,10 @@ static void LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling)
|
||||||
size_t i;
|
size_t i;
|
||||||
ht->thinker.function.acp1 = thinker;
|
ht->thinker.function.acp1 = thinker;
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
ht->vars[i] = READFIXED(save_p); //var[16]
|
ht->vars[i] = READFIXED(save_p); //var[16]
|
||||||
|
ht->var2s[i] = READFIXED(save_p); //var[16]
|
||||||
|
}
|
||||||
ht->sourceline = LoadLine(READUINT32(save_p));
|
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||||
ht->sector = LoadSector(READUINT32(save_p));
|
ht->sector = LoadSector(READUINT32(save_p));
|
||||||
|
|
||||||
|
@ -2510,8 +2958,11 @@ static inline void LoadLightlevelThinker(actionf_p1 thinker)
|
||||||
lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||||
ht->thinker.function.acp1 = thinker;
|
ht->thinker.function.acp1 = thinker;
|
||||||
ht->sector = LoadSector(READUINT32(save_p));
|
ht->sector = LoadSector(READUINT32(save_p));
|
||||||
ht->destlevel = READINT32(save_p);
|
ht->sourcelevel = READINT16(save_p);
|
||||||
ht->speed = READINT32(save_p);
|
ht->destlevel = READINT16(save_p);
|
||||||
|
ht->fixedcurlevel = READFIXED(save_p);
|
||||||
|
ht->fixedpertic = READFIXED(save_p);
|
||||||
|
ht->timer = READINT32(save_p);
|
||||||
if (ht->sector)
|
if (ht->sector)
|
||||||
ht->sector->lightingdata = ht;
|
ht->sector->lightingdata = ht;
|
||||||
P_AddThinker(&ht->thinker);
|
P_AddThinker(&ht->thinker);
|
||||||
|
@ -2552,6 +3003,72 @@ static inline void LoadDisappearThinker(actionf_p1 thinker)
|
||||||
P_AddThinker(&ht->thinker);
|
P_AddThinker(&ht->thinker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// LoadFadeThinker
|
||||||
|
//
|
||||||
|
// Loads a fade_t thinker
|
||||||
|
//
|
||||||
|
static inline void LoadFadeThinker(actionf_p1 thinker)
|
||||||
|
{
|
||||||
|
sector_t *ss;
|
||||||
|
fade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->dest_exc = GetNetColormapFromList(READUINT32(save_p));
|
||||||
|
ht->sectornum = READUINT32(save_p);
|
||||||
|
ht->ffloornum = READUINT32(save_p);
|
||||||
|
ht->alpha = READINT32(save_p);
|
||||||
|
ht->sourcevalue = READINT16(save_p);
|
||||||
|
ht->destvalue = READINT16(save_p);
|
||||||
|
ht->destlightlevel = READINT16(save_p);
|
||||||
|
ht->speed = READINT16(save_p);
|
||||||
|
ht->ticbased = (boolean)READUINT8(save_p);
|
||||||
|
ht->timer = READINT32(save_p);
|
||||||
|
ht->doexists = READUINT8(save_p);
|
||||||
|
ht->dotranslucent = READUINT8(save_p);
|
||||||
|
ht->dolighting = READUINT8(save_p);
|
||||||
|
ht->docolormap = READUINT8(save_p);
|
||||||
|
ht->docollision = READUINT8(save_p);
|
||||||
|
ht->doghostfade = READUINT8(save_p);
|
||||||
|
ht->exactalpha = READUINT8(save_p);
|
||||||
|
|
||||||
|
ss = LoadSector(ht->sectornum);
|
||||||
|
if (ss)
|
||||||
|
{
|
||||||
|
size_t j = 0; // ss->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc
|
||||||
|
ffloor_t *rover;
|
||||||
|
for (rover = ss->ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (j == ht->ffloornum)
|
||||||
|
{
|
||||||
|
ht->rover = rover;
|
||||||
|
rover->fadingdata = ht;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
P_AddThinker(&ht->thinker);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadFadeColormapThinker
|
||||||
|
//
|
||||||
|
// Loads a fadecolormap_t from a save game
|
||||||
|
//
|
||||||
|
static inline void LoadFadeColormapThinker(actionf_p1 thinker)
|
||||||
|
{
|
||||||
|
fadecolormap_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->sector = LoadSector(READUINT32(save_p));
|
||||||
|
ht->source_exc = GetNetColormapFromList(READUINT32(save_p));
|
||||||
|
ht->dest_exc = GetNetColormapFromList(READUINT32(save_p));
|
||||||
|
ht->ticbased = (boolean)READUINT8(save_p);
|
||||||
|
ht->duration = READINT32(save_p);
|
||||||
|
ht->timer = READINT32(save_p);
|
||||||
|
if (ht->sector)
|
||||||
|
ht->sector->fadecolormapdata = ht;
|
||||||
|
P_AddThinker(&ht->thinker);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// LoadPlaneDisplaceThinker
|
// LoadPlaneDisplaceThinker
|
||||||
//
|
//
|
||||||
|
@ -2689,6 +3206,26 @@ static inline void LoadPolydisplaceThinker(actionf_p1 thinker)
|
||||||
ht->oldHeights = READFIXED(save_p);
|
ht->oldHeights = READFIXED(save_p);
|
||||||
P_AddThinker(&ht->thinker);
|
P_AddThinker(&ht->thinker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// LoadPolyfadeThinker
|
||||||
|
//
|
||||||
|
// Loads a polyfadet_t thinker
|
||||||
|
//
|
||||||
|
static void LoadPolyfadeThinker(actionf_p1 thinker)
|
||||||
|
{
|
||||||
|
polyfade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->polyObjNum = READINT32(save_p);
|
||||||
|
ht->sourcevalue = READINT32(save_p);
|
||||||
|
ht->destvalue = READINT32(save_p);
|
||||||
|
ht->docollision = (boolean)READUINT8(save_p);
|
||||||
|
ht->doghostfade = (boolean)READUINT8(save_p);
|
||||||
|
ht->ticbased = (boolean)READUINT8(save_p);
|
||||||
|
ht->duration = READINT32(save_p);
|
||||||
|
ht->timer = READINT32(save_p);
|
||||||
|
P_AddThinker(&ht->thinker);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2738,7 +3275,7 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
// clear sector thinker pointers so they don't point to non-existant thinkers for all of eternity
|
// clear sector thinker pointers so they don't point to non-existant thinkers for all of eternity
|
||||||
for (i = 0; i < numsectors; i++)
|
for (i = 0; i < numsectors; i++)
|
||||||
{
|
{
|
||||||
sectors[i].floordata = sectors[i].ceilingdata = sectors[i].lightingdata = NULL;
|
sectors[i].floordata = sectors[i].ceilingdata = sectors[i].lightingdata = sectors[i].fadecolormapdata = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read in saved thinkers
|
// read in saved thinkers
|
||||||
|
@ -2826,6 +3363,10 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3);
|
LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case tc_marioblockchecker:
|
||||||
|
LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case tc_spikesector:
|
case tc_spikesector:
|
||||||
LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0);
|
LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -2855,6 +3396,14 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
LoadDisappearThinker((actionf_p1)T_Disappear);
|
LoadDisappearThinker((actionf_p1)T_Disappear);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case tc_fade:
|
||||||
|
LoadFadeThinker((actionf_p1)T_Fade);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tc_fadecolormap:
|
||||||
|
LoadFadeColormapThinker((actionf_p1)T_FadeColormap);
|
||||||
|
break;
|
||||||
|
|
||||||
case tc_planedisplace:
|
case tc_planedisplace:
|
||||||
LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace);
|
LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace);
|
||||||
break;
|
break;
|
||||||
|
@ -2886,6 +3435,10 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
case tc_polydisplace:
|
case tc_polydisplace:
|
||||||
LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace);
|
LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case tc_polyfade:
|
||||||
|
LoadPolyfadeThinker((actionf_p1)T_PolyObjFade);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case tc_scroll:
|
case tc_scroll:
|
||||||
LoadScrollThinker((actionf_p1)T_Scroll);
|
LoadScrollThinker((actionf_p1)T_Scroll);
|
||||||
|
@ -3438,6 +3991,7 @@ void P_SaveNetGame(void)
|
||||||
#endif
|
#endif
|
||||||
P_NetArchiveThinkers();
|
P_NetArchiveThinkers();
|
||||||
P_NetArchiveSpecials();
|
P_NetArchiveSpecials();
|
||||||
|
P_NetArchiveColormaps();
|
||||||
}
|
}
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
LUA_Archive();
|
LUA_Archive();
|
||||||
|
@ -3480,6 +4034,7 @@ boolean P_LoadNetGame(void)
|
||||||
#endif
|
#endif
|
||||||
P_NetUnArchiveThinkers();
|
P_NetUnArchiveThinkers();
|
||||||
P_NetUnArchiveSpecials();
|
P_NetUnArchiveSpecials();
|
||||||
|
P_NetUnArchiveColormaps();
|
||||||
P_RelinkPointers();
|
P_RelinkPointers();
|
||||||
P_FinishMobjs();
|
P_FinishMobjs();
|
||||||
}
|
}
|
||||||
|
|
119
src/p_setup.c
119
src/p_setup.c
|
@ -678,6 +678,7 @@ static void P_LoadRawSectors(UINT8 *data, size_t i)
|
||||||
ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats);
|
ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats);
|
||||||
|
|
||||||
ss->lightlevel = SHORT(ms->lightlevel);
|
ss->lightlevel = SHORT(ms->lightlevel);
|
||||||
|
ss->spawn_lightlevel = SHORT(ms->lightlevel);
|
||||||
ss->special = SHORT(ms->special);
|
ss->special = SHORT(ms->special);
|
||||||
ss->tag = SHORT(ms->tag);
|
ss->tag = SHORT(ms->tag);
|
||||||
ss->nexttag = ss->firsttag = -1;
|
ss->nexttag = ss->firsttag = -1;
|
||||||
|
@ -713,12 +714,12 @@ static void P_LoadRawSectors(UINT8 *data, size_t i)
|
||||||
ss->moved = true;
|
ss->moved = true;
|
||||||
|
|
||||||
ss->extra_colormap = NULL;
|
ss->extra_colormap = NULL;
|
||||||
|
ss->spawn_extra_colormap = NULL;
|
||||||
|
|
||||||
ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0;
|
ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0;
|
||||||
ss->spawn_flr_xoffs = ss->spawn_ceil_xoffs = ss->spawn_flr_yoffs = ss->spawn_ceil_yoffs = 0;
|
ss->spawn_flr_xoffs = ss->spawn_ceil_xoffs = ss->spawn_flr_yoffs = ss->spawn_ceil_yoffs = 0;
|
||||||
ss->floorpic_angle = ss->ceilingpic_angle = 0;
|
ss->floorpic_angle = ss->ceilingpic_angle = 0;
|
||||||
ss->spawn_flrpic_angle = ss->spawn_ceilpic_angle = 0;
|
ss->spawn_flrpic_angle = ss->spawn_ceilpic_angle = 0;
|
||||||
ss->bottommap = ss->midmap = ss->topmap = -1;
|
|
||||||
ss->gravity = NULL;
|
ss->gravity = NULL;
|
||||||
ss->cullheight = NULL;
|
ss->cullheight = NULL;
|
||||||
ss->verticalflip = false;
|
ss->verticalflip = false;
|
||||||
|
@ -1331,7 +1332,8 @@ static void P_LoadLineDefs2(void)
|
||||||
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
|
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
|
||||||
|
|
||||||
// Repeat count for midtexture
|
// Repeat count for midtexture
|
||||||
if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff))
|
if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff)
|
||||||
|
&& !(ld->special >= 300 && ld->special < 500)) // exempt linedef exec specials
|
||||||
{
|
{
|
||||||
sides[ld->sidenum[0]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) >> 12);
|
sides[ld->sidenum[0]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) >> 12);
|
||||||
sides[ld->sidenum[0]].textureoffset = (((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) & 2047) << FRACBITS;
|
sides[ld->sidenum[0]].textureoffset = (((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) & 2047) << FRACBITS;
|
||||||
|
@ -1438,7 +1440,6 @@ static inline void P_LoadSideDefs(lumpnum_t lumpnum)
|
||||||
static void P_LoadRawSideDefs2(void *data)
|
static void P_LoadRawSideDefs2(void *data)
|
||||||
{
|
{
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
INT32 num;
|
|
||||||
|
|
||||||
for (i = 0; i < numsides; i++)
|
for (i = 0; i < numsides; i++)
|
||||||
{
|
{
|
||||||
|
@ -1460,117 +1461,23 @@ static void P_LoadRawSideDefs2(void *data)
|
||||||
sd->sector = sec = §ors[sector_num];
|
sd->sector = sec = §ors[sector_num];
|
||||||
}
|
}
|
||||||
|
|
||||||
// refined to allow colormaps to work as wall textures if invalid as colormaps
|
|
||||||
// but valid as textures.
|
|
||||||
|
|
||||||
sd->sector = sec = §ors[SHORT(msd->sector)];
|
sd->sector = sec = §ors[SHORT(msd->sector)];
|
||||||
|
|
||||||
|
sd->colormap_data = NULL;
|
||||||
|
|
||||||
// Colormaps!
|
// Colormaps!
|
||||||
switch (sd->special)
|
switch (sd->special)
|
||||||
{
|
{
|
||||||
case 63: // variable colormap via 242 linedef
|
case 63: // variable colormap via 242 linedef
|
||||||
case 606: //SoM: 4/4/2000: Just colormap transfer
|
case 606: //SoM: 4/4/2000: Just colormap transfer
|
||||||
|
case 447: // Change colormap of tagged sectors! -- Monster Iestyn 14/06/18
|
||||||
|
case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:)
|
||||||
// SoM: R_CreateColormap will only create a colormap in software mode...
|
// SoM: R_CreateColormap will only create a colormap in software mode...
|
||||||
// Perhaps we should just call it instead of doing the calculations here.
|
// Perhaps we should just call it instead of doing the calculations here.
|
||||||
if (rendermode == render_soft || rendermode == render_none)
|
sd->colormap_data = R_CreateColormap(msd->toptexture, msd->midtexture,
|
||||||
{
|
msd->bottomtexture);
|
||||||
if (msd->toptexture[0] == '#' || msd->bottomtexture[0] == '#')
|
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||||
{
|
break;
|
||||||
sec->midmap = R_CreateColormap(msd->toptexture, msd->midtexture,
|
|
||||||
msd->bottomtexture);
|
|
||||||
sd->toptexture = sd->bottomtexture = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1)
|
|
||||||
sd->toptexture = 0;
|
|
||||||
else
|
|
||||||
sd->toptexture = num;
|
|
||||||
if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1)
|
|
||||||
sd->midtexture = 0;
|
|
||||||
else
|
|
||||||
sd->midtexture = num;
|
|
||||||
if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1)
|
|
||||||
sd->bottomtexture = 0;
|
|
||||||
else
|
|
||||||
sd->bottomtexture = num;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#ifdef HWRENDER
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// for now, full support of toptexture only
|
|
||||||
if ((msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6])
|
|
||||||
|| (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6]))
|
|
||||||
{
|
|
||||||
char *col;
|
|
||||||
|
|
||||||
sec->midmap = R_CreateColormap(msd->toptexture, msd->midtexture,
|
|
||||||
msd->bottomtexture);
|
|
||||||
sd->toptexture = sd->bottomtexture = 0;
|
|
||||||
#define HEX2INT(x) (x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0)
|
|
||||||
#define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0)
|
|
||||||
sec->extra_colormap = &extra_colormaps[sec->midmap];
|
|
||||||
|
|
||||||
if (msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6])
|
|
||||||
{
|
|
||||||
col = msd->toptexture;
|
|
||||||
|
|
||||||
sec->extra_colormap->rgba =
|
|
||||||
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
|
|
||||||
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) +
|
|
||||||
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
|
|
||||||
|
|
||||||
// alpha
|
|
||||||
if (msd->toptexture[7])
|
|
||||||
sec->extra_colormap->rgba += (ALPHA2INT(col[7]) << 24);
|
|
||||||
else
|
|
||||||
sec->extra_colormap->rgba += (25 << 24);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sec->extra_colormap->rgba = 0;
|
|
||||||
|
|
||||||
if (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6])
|
|
||||||
{
|
|
||||||
col = msd->bottomtexture;
|
|
||||||
|
|
||||||
sec->extra_colormap->fadergba =
|
|
||||||
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
|
|
||||||
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) +
|
|
||||||
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
|
|
||||||
|
|
||||||
// alpha
|
|
||||||
if (msd->bottomtexture[7])
|
|
||||||
sec->extra_colormap->fadergba += (ALPHA2INT(col[7]) << 24);
|
|
||||||
else
|
|
||||||
sec->extra_colormap->fadergba += (25 << 24);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sec->extra_colormap->fadergba = 0x19000000; // default alpha, (25 << 24)
|
|
||||||
#undef ALPHA2INT
|
|
||||||
#undef HEX2INT
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1)
|
|
||||||
sd->toptexture = 0;
|
|
||||||
else
|
|
||||||
sd->toptexture = num;
|
|
||||||
|
|
||||||
if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1)
|
|
||||||
sd->midtexture = 0;
|
|
||||||
else
|
|
||||||
sd->midtexture = num;
|
|
||||||
|
|
||||||
if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1)
|
|
||||||
sd->bottomtexture = 0;
|
|
||||||
else
|
|
||||||
sd->bottomtexture = num;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case 413: // Change music
|
case 413: // Change music
|
||||||
{
|
{
|
||||||
|
@ -2937,7 +2844,6 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
// Important: take care of the ordering of the next functions.
|
// Important: take care of the ordering of the next functions.
|
||||||
if (!loadedbm)
|
if (!loadedbm)
|
||||||
P_CreateBlockMap(); // Graue 02-29-2004
|
P_CreateBlockMap(); // Graue 02-29-2004
|
||||||
R_MakeColormaps();
|
|
||||||
P_LoadLineDefs2();
|
P_LoadLineDefs2();
|
||||||
P_GroupLines();
|
P_GroupLines();
|
||||||
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||||
|
@ -2974,7 +2880,6 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
// Important: take care of the ordering of the next functions.
|
// Important: take care of the ordering of the next functions.
|
||||||
if (!loadedbm)
|
if (!loadedbm)
|
||||||
P_CreateBlockMap(); // Graue 02-29-2004
|
P_CreateBlockMap(); // Graue 02-29-2004
|
||||||
R_MakeColormaps();
|
|
||||||
P_LoadLineDefs2();
|
P_LoadLineDefs2();
|
||||||
P_GroupLines();
|
P_GroupLines();
|
||||||
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
numdmstarts = numredctfstarts = numbluectfstarts = 0;
|
||||||
|
|
1143
src/p_spec.c
1143
src/p_spec.c
File diff suppressed because it is too large
Load diff
59
src/p_spec.h
59
src/p_spec.h
|
@ -134,10 +134,15 @@ typedef struct
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
thinker_t thinker; ///< Thinker in use for the effect.
|
thinker_t thinker; ///< Thinker in use for the effect.
|
||||||
sector_t *sector; ///< Sector where action is taking place.
|
sector_t *sector; ///< Sector where action is taking place.
|
||||||
INT32 destlevel; ///< Light level we're fading to.
|
INT16 sourcelevel; ///< Light level we're fading from.
|
||||||
INT32 speed; ///< Speed at which to change light level.
|
INT16 destlevel; ///< Light level we're fading to.
|
||||||
|
|
||||||
|
fixed_t fixedcurlevel; ///< Fixed point for current light level.
|
||||||
|
fixed_t fixedpertic; ///< Fixed point for increment per tic.
|
||||||
|
// The reason for those two above to be fixed point is to deal with decimal values that would otherwise get trimmed away.
|
||||||
|
INT32 timer; ///< Internal timer.
|
||||||
} lightlevel_t;
|
} lightlevel_t;
|
||||||
|
|
||||||
#define GLOWSPEED 8
|
#define GLOWSPEED 8
|
||||||
|
@ -145,6 +150,8 @@ typedef struct
|
||||||
#define FASTDARK 15
|
#define FASTDARK 15
|
||||||
#define SLOWDARK 35
|
#define SLOWDARK 35
|
||||||
|
|
||||||
|
void P_RemoveLighting(sector_t *sector);
|
||||||
|
|
||||||
void T_FireFlicker(fireflicker_t *flick);
|
void T_FireFlicker(fireflicker_t *flick);
|
||||||
fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxsector, INT32 length);
|
fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxsector, INT32 length);
|
||||||
void T_LightningFlash(lightflash_t *flash);
|
void T_LightningFlash(lightflash_t *flash);
|
||||||
|
@ -156,7 +163,8 @@ strobe_t * P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector
|
||||||
void T_Glow(glow_t *g);
|
void T_Glow(glow_t *g);
|
||||||
glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, INT32 length);
|
glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, INT32 length);
|
||||||
|
|
||||||
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed);
|
void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean ticbased);
|
||||||
|
void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force);
|
||||||
void T_LightFade(lightlevel_t *ll);
|
void T_LightFade(lightlevel_t *ll);
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -453,6 +461,47 @@ typedef struct
|
||||||
|
|
||||||
void T_Disappear(disappear_t *d);
|
void T_Disappear(disappear_t *d);
|
||||||
|
|
||||||
|
// Model for fading FOFs
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker; ///< Thinker structure for effect.
|
||||||
|
ffloor_t *rover; ///< Target ffloor
|
||||||
|
extracolormap_t *dest_exc; ///< Colormap to fade to
|
||||||
|
UINT32 sectornum; ///< Number of ffloor target sector
|
||||||
|
UINT32 ffloornum; ///< Number of ffloor of target sector
|
||||||
|
INT32 alpha; ///< Internal alpha counter
|
||||||
|
INT16 sourcevalue; ///< Transparency value to fade from
|
||||||
|
INT16 destvalue; ///< Transparency value to fade to
|
||||||
|
INT16 destlightlevel; ///< Light level to fade to
|
||||||
|
INT16 speed; ///< Speed to fade by
|
||||||
|
boolean ticbased; ///< Tic-based logic toggle
|
||||||
|
INT32 timer; ///< Timer for tic-based logic
|
||||||
|
boolean doexists; ///< Handle FF_EXISTS
|
||||||
|
boolean dotranslucent; ///< Handle FF_TRANSLUCENT
|
||||||
|
boolean dolighting; ///< Handle shadows and light blocks
|
||||||
|
boolean docolormap; ///< Handle colormaps
|
||||||
|
boolean docollision; ///< Handle interactive flags
|
||||||
|
boolean doghostfade; ///< No interactive flags during fading
|
||||||
|
boolean exactalpha; ///< Use exact alpha values (opengl)
|
||||||
|
} fade_t;
|
||||||
|
|
||||||
|
void T_Fade(fade_t *d);
|
||||||
|
|
||||||
|
// Model for fading colormaps
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
thinker_t thinker; ///< Thinker structure for effect.
|
||||||
|
sector_t *sector; ///< Sector where action is taking place.
|
||||||
|
extracolormap_t *source_exc;
|
||||||
|
extracolormap_t *dest_exc;
|
||||||
|
boolean ticbased; ///< Tic-based timing
|
||||||
|
INT32 duration; ///< Total duration for tic-based logic (OR: speed increment)
|
||||||
|
INT32 timer; ///< Timer for tic-based logic (OR: internal speed counter)
|
||||||
|
} fadecolormap_t;
|
||||||
|
|
||||||
|
void T_FadeColormap(fadecolormap_t *d);
|
||||||
|
|
||||||
// Prototype functions for pushers
|
// Prototype functions for pushers
|
||||||
void T_Pusher(pusher_t *p);
|
void T_Pusher(pusher_t *p);
|
||||||
mobj_t *P_GetPushThing(UINT32 s);
|
mobj_t *P_GetPushThing(UINT32 s);
|
||||||
|
|
24
src/p_tick.c
24
src/p_tick.c
|
@ -56,12 +56,12 @@ void Command_Numthinkers_f(void)
|
||||||
CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n"));
|
CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n"));
|
||||||
CONS_Printf(
|
CONS_Printf(
|
||||||
"\t1: P_MobjThinker\n"
|
"\t1: P_MobjThinker\n"
|
||||||
"\t2: P_RainThinker\n"
|
/*"\t2: P_RainThinker\n"
|
||||||
"\t3: P_SnowThinker\n"
|
"\t3: P_SnowThinker\n"*/
|
||||||
"\t4: P_NullPrecipThinker\n"
|
"\t2: P_NullPrecipThinker\n"
|
||||||
"\t5: T_Friction\n"
|
"\t3: T_Friction\n"
|
||||||
"\t6: T_Pusher\n"
|
"\t4: T_Pusher\n"
|
||||||
"\t7: P_RemoveThinkerDelayed\n");
|
"\t5: P_RemoveThinkerDelayed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,27 +73,27 @@ void Command_Numthinkers_f(void)
|
||||||
action = (actionf_p1)P_MobjThinker;
|
action = (actionf_p1)P_MobjThinker;
|
||||||
CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker");
|
CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker");
|
||||||
break;
|
break;
|
||||||
case 2:
|
/*case 2:
|
||||||
action = (actionf_p1)P_RainThinker;
|
action = (actionf_p1)P_RainThinker;
|
||||||
CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker");
|
CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
action = (actionf_p1)P_SnowThinker;
|
action = (actionf_p1)P_SnowThinker;
|
||||||
CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker");
|
CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker");
|
||||||
break;
|
break;*/
|
||||||
case 4:
|
case 2:
|
||||||
action = (actionf_p1)P_NullPrecipThinker;
|
action = (actionf_p1)P_NullPrecipThinker;
|
||||||
CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker");
|
CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker");
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 3:
|
||||||
action = (actionf_p1)T_Friction;
|
action = (actionf_p1)T_Friction;
|
||||||
CONS_Printf(M_GetText("Number of %s: "), "T_Friction");
|
CONS_Printf(M_GetText("Number of %s: "), "T_Friction");
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 4:
|
||||||
action = (actionf_p1)T_Pusher;
|
action = (actionf_p1)T_Pusher;
|
||||||
CONS_Printf(M_GetText("Number of %s: "), "T_Pusher");
|
CONS_Printf(M_GetText("Number of %s: "), "T_Pusher");
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 5:
|
||||||
action = (actionf_p1)P_RemoveThinkerDelayed;
|
action = (actionf_p1)P_RemoveThinkerDelayed;
|
||||||
CONS_Printf(M_GetText("Number of %s: "), "P_RemoveThinkerDelayed");
|
CONS_Printf(M_GetText("Number of %s: "), "P_RemoveThinkerDelayed");
|
||||||
break;
|
break;
|
||||||
|
|
61
src/p_user.c
61
src/p_user.c
|
@ -596,10 +596,6 @@ static void P_DeNightserizePlayer(player_t *player)
|
||||||
else if (player == &players[secondarydisplayplayer])
|
else if (player == &players[secondarydisplayplayer])
|
||||||
localaiming2 = 0;
|
localaiming2 = 0;
|
||||||
|
|
||||||
// If you screwed up, kiss your score and ring bonus goodbye.
|
|
||||||
player->marescore = 0;
|
|
||||||
player->rings = 0;
|
|
||||||
|
|
||||||
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
|
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
|
||||||
|
|
||||||
// If in a special stage, add some preliminary exit time.
|
// If in a special stage, add some preliminary exit time.
|
||||||
|
@ -611,6 +607,11 @@ static void P_DeNightserizePlayer(player_t *player)
|
||||||
players[i].nightstime = 1; // force everyone else to fall too.
|
players[i].nightstime = 1; // force everyone else to fall too.
|
||||||
player->exiting = 3*TICRATE;
|
player->exiting = 3*TICRATE;
|
||||||
stagefailed = true; // NIGHT OVER
|
stagefailed = true; // NIGHT OVER
|
||||||
|
|
||||||
|
// If you screwed up, kiss your score and ring bonus goodbye.
|
||||||
|
// But only do this in special stage (and instakill!) In regular stages, wait til we hit the ground.
|
||||||
|
player->marescore = player->spheres =\
|
||||||
|
player->rings = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if the player should be killed.
|
// Check to see if the player should be killed.
|
||||||
|
@ -624,7 +625,11 @@ static void P_DeNightserizePlayer(player_t *player)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mo2->flags2 & MF2_AMBUSH)
|
if (mo2->flags2 & MF2_AMBUSH)
|
||||||
|
{
|
||||||
|
player->marescore = player->spheres =\
|
||||||
|
player->rings = 0;
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
|
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7077,8 +7082,14 @@ static void P_MovePlayer(player_t *player)
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
players[i].exiting = (14*TICRATE)/5 + 1;
|
players[i].exiting = (14*TICRATE)/5 + 1;
|
||||||
}
|
}
|
||||||
else if (player->spheres > 0)
|
else {
|
||||||
|
// Damage whether or not we have spheres, as player should recoil upon losing points
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 1, 0);
|
P_DamageMobj(player->mo, NULL, NULL, 1, 0);
|
||||||
|
|
||||||
|
// Now deduct our mare score!
|
||||||
|
player->marescore = player->spheres =\
|
||||||
|
player->rings = 0;
|
||||||
|
}
|
||||||
player->powers[pw_carry] = CR_NONE;
|
player->powers[pw_carry] = CR_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8766,7 +8777,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
subsector_t *newsubsec;
|
subsector_t *newsubsec;
|
||||||
fixed_t f1, f2;
|
fixed_t f1, f2;
|
||||||
|
|
||||||
cameranoclip = (player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (player->mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
|
// We probably shouldn't move the camera if there is no player or player mobj somehow
|
||||||
|
if (!player || !player->mo)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
mo = player->mo;
|
||||||
|
|
||||||
|
cameranoclip = (player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
|
||||||
|
|
||||||
if (!(player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD))
|
if (!(player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD))
|
||||||
{
|
{
|
||||||
|
@ -8787,7 +8804,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
else if (player == &players[secondarydisplayplayer])
|
else if (player == &players[secondarydisplayplayer])
|
||||||
focusangle = localangle2;
|
focusangle = localangle2;
|
||||||
else
|
else
|
||||||
focusangle = player->mo->angle;
|
focusangle = mo->angle;
|
||||||
if (thiscam == &camera)
|
if (thiscam == &camera)
|
||||||
camrotate = cv_cam_rotate.value;
|
camrotate = cv_cam_rotate.value;
|
||||||
else if (thiscam == &camera2)
|
else if (thiscam == &camera2)
|
||||||
|
@ -8799,17 +8816,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!player || !player->mo)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
mo = player->mo;
|
|
||||||
|
|
||||||
thiscam->radius = FixedMul(20*FRACUNIT, mo->scale);
|
thiscam->radius = FixedMul(20*FRACUNIT, mo->scale);
|
||||||
thiscam->height = FixedMul(16*FRACUNIT, mo->scale);
|
thiscam->height = FixedMul(16*FRACUNIT, mo->scale);
|
||||||
|
|
||||||
if (!mo)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Don't run while respawning from a starpost
|
// Don't run while respawning from a starpost
|
||||||
// Inu 4/8/13 Why not?!
|
// Inu 4/8/13 Why not?!
|
||||||
// if (leveltime > 0 && timeinmap <= 0)
|
// if (leveltime > 0 && timeinmap <= 0)
|
||||||
|
@ -8817,7 +8826,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
|
|
||||||
if (player->powers[pw_carry] == CR_NIGHTSMODE)
|
if (player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||||
{
|
{
|
||||||
focusangle = player->mo->angle;
|
focusangle = mo->angle;
|
||||||
focusaiming = 0;
|
focusaiming = 0;
|
||||||
}
|
}
|
||||||
else if (player == &players[consoleplayer])
|
else if (player == &players[consoleplayer])
|
||||||
|
@ -8832,7 +8841,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
focusangle = player->mo->angle;
|
focusangle = mo->angle;
|
||||||
focusaiming = player->aiming;
|
focusaiming = player->aiming;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8879,12 +8888,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
angle = R_PointToAngle2(player->axis1->x, player->axis1->y, player->axis2->x, player->axis2->y);
|
angle = R_PointToAngle2(player->axis1->x, player->axis1->y, player->axis2->x, player->axis2->y);
|
||||||
angle += ANGLE_90;
|
angle += ANGLE_90;
|
||||||
}
|
}
|
||||||
else if (player->mo->target)
|
else if (mo->target)
|
||||||
{
|
{
|
||||||
if (player->mo->target->flags2 & MF2_AMBUSH)
|
if (mo->target->flags2 & MF2_AMBUSH)
|
||||||
angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y);
|
angle = R_PointToAngle2(mo->target->x, mo->target->y, mo->x, mo->y);
|
||||||
else
|
else
|
||||||
angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->target->x, player->mo->target->y);
|
angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (P_AnalogMove(player)) // Analog
|
else if (P_AnalogMove(player)) // Analog
|
||||||
|
@ -8973,7 +8982,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
if (twodlevel || (mo->flags2 & MF2_TWOD))
|
if (twodlevel || (mo->flags2 & MF2_TWOD))
|
||||||
{
|
{
|
||||||
// Camera doesn't ALWAYS need to move, only when running...
|
// Camera doesn't ALWAYS need to move, only when running...
|
||||||
if (abs(player->mo->momx) > 10)
|
if (abs(mo->momx) > 10)
|
||||||
{
|
{
|
||||||
// Move the camera all smooth-like, not jerk it around...
|
// Move the camera all smooth-like, not jerk it around...
|
||||||
if (mo->momx > 0)
|
if (mo->momx > 0)
|
||||||
|
@ -9291,13 +9300,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
vy = thiscam->y;
|
vy = thiscam->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P_AproxDistance(vx - player->mo->x, vy - player->mo->y) < FixedMul(48*FRACUNIT, mo->scale))
|
if (P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale))
|
||||||
player->mo->flags2 |= MF2_SHADOW;
|
mo->flags2 |= MF2_SHADOW;
|
||||||
else
|
else
|
||||||
player->mo->flags2 &= ~MF2_SHADOW;
|
mo->flags2 &= ~MF2_SHADOW;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
player->mo->flags2 &= ~MF2_SHADOW;
|
mo->flags2 &= ~MF2_SHADOW;
|
||||||
|
|
||||||
/* if (!resetcalled && (player->powers[pw_carry] == CR_NIGHTSMODE && player->exiting))
|
/* if (!resetcalled && (player->powers[pw_carry] == CR_NIGHTSMODE && player->exiting))
|
||||||
{
|
{
|
||||||
|
|
41
src/r_bsp.c
41
src/r_bsp.c
|
@ -234,8 +234,6 @@ static INT32 R_DoorClosed(void)
|
||||||
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
INT32 *ceilinglightlevel, boolean back)
|
INT32 *ceilinglightlevel, boolean back)
|
||||||
{
|
{
|
||||||
INT32 mapnum = -1;
|
|
||||||
|
|
||||||
if (floorlightlevel)
|
if (floorlightlevel)
|
||||||
*floorlightlevel = sec->floorlightsec == -1 ?
|
*floorlightlevel = sec->floorlightsec == -1 ?
|
||||||
sec->lightlevel : sectors[sec->floorlightsec].lightlevel;
|
sec->lightlevel : sectors[sec->floorlightsec].lightlevel;
|
||||||
|
@ -244,10 +242,10 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
*ceilinglightlevel = sec->ceilinglightsec == -1 ?
|
*ceilinglightlevel = sec->ceilinglightsec == -1 ?
|
||||||
sec->lightlevel : sectors[sec->ceilinglightsec].lightlevel;
|
sec->lightlevel : sectors[sec->ceilinglightsec].lightlevel;
|
||||||
|
|
||||||
// If the sector has a midmap, it's probably from 280 type
|
// if (sec->midmap != -1)
|
||||||
if (sec->midmap != -1)
|
// mapnum = sec->midmap;
|
||||||
mapnum = sec->midmap;
|
// In original colormap code, this block did not run if sec->midmap was set
|
||||||
else if (sec->heightsec != -1)
|
if (!sec->extra_colormap && sec->heightsec != -1)
|
||||||
{
|
{
|
||||||
const sector_t *s = §ors[sec->heightsec];
|
const sector_t *s = §ors[sec->heightsec];
|
||||||
mobj_t *viewmobj = viewplayer->mo;
|
mobj_t *viewmobj = viewplayer->mo;
|
||||||
|
@ -271,8 +269,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
tempsec->floorheight = s->floorheight;
|
tempsec->floorheight = s->floorheight;
|
||||||
tempsec->ceilingheight = s->ceilingheight;
|
tempsec->ceilingheight = s->ceilingheight;
|
||||||
|
|
||||||
mapnum = s->midmap;
|
|
||||||
|
|
||||||
if ((underwater && (tempsec-> floorheight = sec->floorheight,
|
if ((underwater && (tempsec-> floorheight = sec->floorheight,
|
||||||
tempsec->ceilingheight = s->floorheight - 1, !back)) || viewz <= s->floorheight)
|
tempsec->ceilingheight = s->floorheight - 1, !back)) || viewz <= s->floorheight)
|
||||||
{ // head-below-floor hack
|
{ // head-below-floor hack
|
||||||
|
@ -298,7 +294,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
tempsec->ceiling_yoffs = s->ceiling_yoffs;
|
tempsec->ceiling_yoffs = s->ceiling_yoffs;
|
||||||
tempsec->ceilingpic_angle = s->ceilingpic_angle;
|
tempsec->ceilingpic_angle = s->ceilingpic_angle;
|
||||||
}
|
}
|
||||||
mapnum = s->bottommap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tempsec->lightlevel = s->lightlevel;
|
tempsec->lightlevel = s->lightlevel;
|
||||||
|
@ -322,8 +317,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
tempsec->floor_yoffs = tempsec->ceiling_yoffs = s->ceiling_yoffs;
|
tempsec->floor_yoffs = tempsec->ceiling_yoffs = s->ceiling_yoffs;
|
||||||
tempsec->floorpic_angle = tempsec->ceilingpic_angle = s->ceilingpic_angle;
|
tempsec->floorpic_angle = tempsec->ceilingpic_angle = s->ceilingpic_angle;
|
||||||
|
|
||||||
mapnum = s->topmap;
|
|
||||||
|
|
||||||
if (s->floorpic == skyflatnum) // SKYFIX?
|
if (s->floorpic == skyflatnum) // SKYFIX?
|
||||||
{
|
{
|
||||||
tempsec->ceilingheight = tempsec->floorheight-1;
|
tempsec->ceilingheight = tempsec->floorheight-1;
|
||||||
|
@ -354,11 +347,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||||
sec = tempsec;
|
sec = tempsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps)
|
|
||||||
sec->extra_colormap = &extra_colormaps[mapnum];
|
|
||||||
else
|
|
||||||
sec->extra_colormap = NULL;
|
|
||||||
|
|
||||||
return sec;
|
return sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -937,11 +925,11 @@ static void R_Subsector(size_t num)
|
||||||
light = R_GetPlaneLight(frontsector, floorcenterz, false);
|
light = R_GetPlaneLight(frontsector, floorcenterz, false);
|
||||||
if (frontsector->floorlightsec == -1)
|
if (frontsector->floorlightsec == -1)
|
||||||
floorlightlevel = *frontsector->lightlist[light].lightlevel;
|
floorlightlevel = *frontsector->lightlist[light].lightlevel;
|
||||||
floorcolormap = frontsector->lightlist[light].extra_colormap;
|
floorcolormap = *frontsector->lightlist[light].extra_colormap;
|
||||||
light = R_GetPlaneLight(frontsector, ceilingcenterz, false);
|
light = R_GetPlaneLight(frontsector, ceilingcenterz, false);
|
||||||
if (frontsector->ceilinglightsec == -1)
|
if (frontsector->ceilinglightsec == -1)
|
||||||
ceilinglightlevel = *frontsector->lightlist[light].lightlevel;
|
ceilinglightlevel = *frontsector->lightlist[light].lightlevel;
|
||||||
ceilingcolormap = frontsector->lightlist[light].extra_colormap;
|
ceilingcolormap = *frontsector->lightlist[light].extra_colormap;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub->sector->extra_colormap = frontsector->extra_colormap;
|
sub->sector->extra_colormap = frontsector->extra_colormap;
|
||||||
|
@ -1038,7 +1026,7 @@ static void R_Subsector(size_t num)
|
||||||
|
|
||||||
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
|
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
|
||||||
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
|
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
|
||||||
*rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover
|
*rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover
|
||||||
#ifdef POLYOBJECTS_PLANES
|
#ifdef POLYOBJECTS_PLANES
|
||||||
, NULL
|
, NULL
|
||||||
#endif
|
#endif
|
||||||
|
@ -1084,7 +1072,7 @@ static void R_Subsector(size_t num)
|
||||||
|
|
||||||
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
|
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
|
||||||
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
|
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
|
||||||
frontsector->lightlist[light].extra_colormap, rover
|
*frontsector->lightlist[light].extra_colormap, rover
|
||||||
#ifdef POLYOBJECTS_PLANES
|
#ifdef POLYOBJECTS_PLANES
|
||||||
, NULL
|
, NULL
|
||||||
#endif
|
#endif
|
||||||
|
@ -1237,7 +1225,7 @@ void R_Prep3DFloors(sector_t *sector)
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
ffloor_t *best;
|
ffloor_t *best;
|
||||||
fixed_t bestheight, maxheight;
|
fixed_t bestheight, maxheight;
|
||||||
INT32 count, i, mapnum;
|
INT32 count, i;
|
||||||
sector_t *sec;
|
sector_t *sec;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
pslope_t *bestslope = NULL;
|
pslope_t *bestslope = NULL;
|
||||||
|
@ -1276,7 +1264,7 @@ void R_Prep3DFloors(sector_t *sector)
|
||||||
#endif
|
#endif
|
||||||
sector->lightlist[0].lightlevel = §or->lightlevel;
|
sector->lightlist[0].lightlevel = §or->lightlevel;
|
||||||
sector->lightlist[0].caster = NULL;
|
sector->lightlist[0].caster = NULL;
|
||||||
sector->lightlist[0].extra_colormap = sector->extra_colormap;
|
sector->lightlist[0].extra_colormap = §or->extra_colormap;
|
||||||
sector->lightlist[0].flags = 0;
|
sector->lightlist[0].flags = 0;
|
||||||
|
|
||||||
maxheight = INT32_MAX;
|
maxheight = INT32_MAX;
|
||||||
|
@ -1342,11 +1330,6 @@ void R_Prep3DFloors(sector_t *sector)
|
||||||
sector->lightlist[i].slope = bestslope;
|
sector->lightlist[i].slope = bestslope;
|
||||||
#endif
|
#endif
|
||||||
sec = §ors[best->secnum];
|
sec = §ors[best->secnum];
|
||||||
mapnum = sec->midmap;
|
|
||||||
if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps)
|
|
||||||
sec->extra_colormap = &extra_colormaps[mapnum];
|
|
||||||
else
|
|
||||||
sec->extra_colormap = NULL;
|
|
||||||
|
|
||||||
if (best->flags & FF_NOSHADE)
|
if (best->flags & FF_NOSHADE)
|
||||||
{
|
{
|
||||||
|
@ -1356,12 +1339,12 @@ void R_Prep3DFloors(sector_t *sector)
|
||||||
else if (best->flags & FF_COLORMAPONLY)
|
else if (best->flags & FF_COLORMAPONLY)
|
||||||
{
|
{
|
||||||
sector->lightlist[i].lightlevel = sector->lightlist[i-1].lightlevel;
|
sector->lightlist[i].lightlevel = sector->lightlist[i-1].lightlevel;
|
||||||
sector->lightlist[i].extra_colormap = sec->extra_colormap;
|
sector->lightlist[i].extra_colormap = &sec->extra_colormap;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sector->lightlist[i].lightlevel = best->toplightlevel;
|
sector->lightlist[i].lightlevel = best->toplightlevel;
|
||||||
sector->lightlist[i].extra_colormap = sec->extra_colormap;
|
sector->lightlist[i].extra_colormap = &sec->extra_colormap;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best->flags & FF_DOUBLESHADOW)
|
if (best->flags & FF_DOUBLESHADOW)
|
||||||
|
|
882
src/r_data.c
882
src/r_data.c
|
@ -1144,6 +1144,10 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex)
|
||||||
Z_Free((void *)texturesText);
|
Z_Free((void *)texturesText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
static lumplist_t *colormaplumps = NULL; ///\todo free leak
|
||||||
|
static size_t numcolormaplumps = 0;
|
||||||
|
|
||||||
static inline lumpnum_t R_CheckNumForNameList(const char *name, lumplist_t *list, size_t listsize)
|
static inline lumpnum_t R_CheckNumForNameList(const char *name, lumplist_t *list, size_t listsize)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -1160,9 +1164,6 @@ static inline lumpnum_t R_CheckNumForNameList(const char *name, lumplist_t *list
|
||||||
return LUMPERROR;
|
return LUMPERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static lumplist_t *colormaplumps = NULL; ///\todo free leak
|
|
||||||
static size_t numcolormaplumps = 0;
|
|
||||||
|
|
||||||
static void R_InitExtraColormaps(void)
|
static void R_InitExtraColormaps(void)
|
||||||
{
|
{
|
||||||
lumpnum_t startnum, endnum;
|
lumpnum_t startnum, endnum;
|
||||||
|
@ -1195,6 +1196,7 @@ static void R_InitExtraColormaps(void)
|
||||||
}
|
}
|
||||||
CONS_Printf(M_GetText("Number of Extra Colormaps: %s\n"), sizeu1(numcolormaplumps));
|
CONS_Printf(M_GetText("Number of Extra Colormaps: %s\n"), sizeu1(numcolormaplumps));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Search for flat name through all
|
// Search for flat name through all
|
||||||
lumpnum_t R_GetFlatNumForName(const char *name)
|
lumpnum_t R_GetFlatNumForName(const char *name)
|
||||||
|
@ -1291,7 +1293,9 @@ static void R_InitColormaps(void)
|
||||||
|
|
||||||
// Init Boom colormaps.
|
// Init Boom colormaps.
|
||||||
R_ClearColormaps();
|
R_ClearColormaps();
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
R_InitExtraColormaps();
|
R_InitExtraColormaps();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_ReInitColormaps(UINT16 num)
|
void R_ReInitColormaps(UINT16 num)
|
||||||
|
@ -1311,11 +1315,6 @@ void R_ReInitColormaps(UINT16 num)
|
||||||
R_ClearColormaps();
|
R_ClearColormaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
static lumpnum_t foundcolormaps[MAXCOLORMAPS];
|
|
||||||
|
|
||||||
static char colormapFixingArray[MAXCOLORMAPS][3][9];
|
|
||||||
static size_t carrayindex;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_ClearColormaps
|
// R_ClearColormaps
|
||||||
//
|
//
|
||||||
|
@ -1323,51 +1322,264 @@ static size_t carrayindex;
|
||||||
//
|
//
|
||||||
void R_ClearColormaps(void)
|
void R_ClearColormaps(void)
|
||||||
{
|
{
|
||||||
size_t i;
|
// Purged by PU_LEVEL, just overwrite the pointer
|
||||||
|
extra_colormaps = R_CreateDefaultColormap(true);
|
||||||
num_extra_colormaps = 0;
|
|
||||||
|
|
||||||
carrayindex = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < MAXCOLORMAPS; i++)
|
|
||||||
foundcolormaps[i] = LUMPERROR;
|
|
||||||
|
|
||||||
memset(extra_colormaps, 0, sizeof (extra_colormaps));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INT32 R_ColormapNumForName(char *name)
|
//
|
||||||
|
// R_CreateDefaultColormap()
|
||||||
|
// NOTE: The result colormap is not added to the extra_colormaps chain. You must do that yourself!
|
||||||
|
//
|
||||||
|
extracolormap_t *R_CreateDefaultColormap(boolean lighttable)
|
||||||
{
|
{
|
||||||
lumpnum_t lump, i;
|
extracolormap_t *exc = Z_Calloc(sizeof (*exc), PU_LEVEL, NULL);
|
||||||
|
exc->fadestart = 0;
|
||||||
|
exc->fadeend = 31;
|
||||||
|
exc->fog = 0;
|
||||||
|
exc->rgba = 0;
|
||||||
|
exc->fadergba = 0x19000000;
|
||||||
|
exc->colormap = lighttable ? R_CreateLightTable(exc) : NULL;
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
exc->lump = LUMPERROR;
|
||||||
|
exc->lumpname[0] = 0;
|
||||||
|
#endif
|
||||||
|
exc->next = exc->prev = NULL;
|
||||||
|
return exc;
|
||||||
|
}
|
||||||
|
|
||||||
if (num_extra_colormaps == MAXCOLORMAPS)
|
//
|
||||||
I_Error("R_ColormapNumForName: Too many colormaps! the limit is %d\n", MAXCOLORMAPS);
|
// R_GetDefaultColormap()
|
||||||
|
//
|
||||||
|
extracolormap_t *R_GetDefaultColormap(void)
|
||||||
|
{
|
||||||
|
#ifdef COLORMAPREVERSELIST
|
||||||
|
extracolormap_t *exc;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!extra_colormaps)
|
||||||
|
return (extra_colormaps = R_CreateDefaultColormap(true));
|
||||||
|
|
||||||
|
#ifdef COLORMAPREVERSELIST
|
||||||
|
for (exc = extra_colormaps; exc->next; exc = exc->next);
|
||||||
|
return exc;
|
||||||
|
#else
|
||||||
|
return extra_colormaps;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// R_CopyColormap()
|
||||||
|
// NOTE: The result colormap is not added to the extra_colormaps chain. You must do that yourself!
|
||||||
|
//
|
||||||
|
extracolormap_t *R_CopyColormap(extracolormap_t *extra_colormap, boolean lighttable)
|
||||||
|
{
|
||||||
|
extracolormap_t *exc = Z_Calloc(sizeof (*exc), PU_LEVEL, NULL);
|
||||||
|
|
||||||
|
if (!extra_colormap)
|
||||||
|
extra_colormap = R_GetDefaultColormap();
|
||||||
|
|
||||||
|
*exc = *extra_colormap;
|
||||||
|
exc->next = exc->prev = NULL;
|
||||||
|
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
strncpy(exc->lumpname, extra_colormap->lumpname, 9);
|
||||||
|
|
||||||
|
if (exc->lump != LUMPERROR && lighttable)
|
||||||
|
{
|
||||||
|
// aligned on 8 bit for asm code
|
||||||
|
exc->colormap = Z_MallocAlign(W_LumpLength(lump), PU_LEVEL, NULL, 16);
|
||||||
|
W_ReadLump(lump, exc->colormap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (lighttable)
|
||||||
|
exc->colormap = R_CreateLightTable(exc);
|
||||||
|
else
|
||||||
|
exc->colormap = NULL;
|
||||||
|
|
||||||
|
return exc;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// R_AddColormapToList
|
||||||
|
//
|
||||||
|
// Sets prev/next chain for extra_colormaps var
|
||||||
|
// Copypasta from P_AddFFloorToList
|
||||||
|
//
|
||||||
|
void R_AddColormapToList(extracolormap_t *extra_colormap)
|
||||||
|
{
|
||||||
|
#ifndef COLORMAPREVERSELIST
|
||||||
|
extracolormap_t *exc;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!extra_colormaps)
|
||||||
|
{
|
||||||
|
extra_colormaps = extra_colormap;
|
||||||
|
extra_colormap->next = 0;
|
||||||
|
extra_colormap->prev = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef COLORMAPREVERSELIST
|
||||||
|
extra_colormaps->prev = extra_colormap;
|
||||||
|
extra_colormap->next = extra_colormaps;
|
||||||
|
extra_colormaps = extra_colormap;
|
||||||
|
extra_colormap->prev = 0;
|
||||||
|
#else
|
||||||
|
for (exc = extra_colormaps; exc->next; exc = exc->next);
|
||||||
|
|
||||||
|
exc->next = extra_colormap;
|
||||||
|
extra_colormap->prev = exc;
|
||||||
|
extra_colormap->next = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// R_CheckDefaultColormapByValues()
|
||||||
|
//
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||||
|
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump)
|
||||||
|
#else
|
||||||
|
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||||
|
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(!checkparams ? true :
|
||||||
|
(fadestart == 0
|
||||||
|
&& fadeend == 31
|
||||||
|
&& !fog)
|
||||||
|
)
|
||||||
|
&& (!checkrgba ? true : rgba == 0)
|
||||||
|
&& (!checkfadergba ? true : fadergba == 0x19000000)
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
&& lump == LUMPERROR
|
||||||
|
&& extra_colormap->lumpname[0] == 0
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgba, boolean checkfadergba, boolean checkparams)
|
||||||
|
{
|
||||||
|
if (!extra_colormap)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
return R_CheckDefaultColormapByValues(checkrgba, checkfadergba, checkparams, extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog, extra_colormap->lump);
|
||||||
|
#else
|
||||||
|
return R_CheckDefaultColormapByValues(checkrgba, checkfadergba, checkparams, extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams)
|
||||||
|
{
|
||||||
|
// Treat NULL as default colormap
|
||||||
|
// We need this because what if one exc is a default colormap, and the other is NULL? They're really both equal.
|
||||||
|
if (!exc_a)
|
||||||
|
exc_a = R_GetDefaultColormap();
|
||||||
|
if (!exc_b)
|
||||||
|
exc_b = R_GetDefaultColormap();
|
||||||
|
|
||||||
|
if (exc_a == exc_b)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return (
|
||||||
|
(!checkparams ? true :
|
||||||
|
(exc_a->fadestart == exc_b->fadestart
|
||||||
|
&& exc_a->fadeend == exc_b->fadeend
|
||||||
|
&& exc_a->fog == exc_b->fog)
|
||||||
|
)
|
||||||
|
&& (!checkrgba ? true : exc_a->rgba == exc_b->rgba)
|
||||||
|
&& (!checkfadergba ? true : exc_a->fadergba == exc_b->fadergba)
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
&& exc_a->lump == exc_b->lump
|
||||||
|
&& !strncmp(exc_a->lumpname, exc_b->lumpname, 9)
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// R_GetColormapFromListByValues()
|
||||||
|
// NOTE: Returns NULL if no match is found
|
||||||
|
//
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump)
|
||||||
|
#else
|
||||||
|
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
extracolormap_t *exc;
|
||||||
|
UINT32 dbg_i = 0;
|
||||||
|
|
||||||
|
for (exc = extra_colormaps; exc; exc = exc->next)
|
||||||
|
{
|
||||||
|
if (rgba == exc->rgba
|
||||||
|
&& fadergba == exc->fadergba
|
||||||
|
&& fadestart == exc->fadestart
|
||||||
|
&& fadeend == exc->fadeend
|
||||||
|
&& fog == exc->fog
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
&& (lump != LUMPERROR && lump == exc->lump)
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_RENDER, "Found Colormap %d: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n",
|
||||||
|
dbg_i, R_GetRgbaR(rgba), R_GetRgbaG(rgba), R_GetRgbaB(rgba), R_GetRgbaA(rgba),
|
||||||
|
R_GetRgbaR(fadergba), R_GetRgbaG(fadergba), R_GetRgbaB(fadergba), R_GetRgbaA(fadergba));
|
||||||
|
return exc;
|
||||||
|
}
|
||||||
|
dbg_i++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap)
|
||||||
|
{
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
return R_GetColormapFromListByValues(extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog, extra_colormap->lump);
|
||||||
|
#else
|
||||||
|
return R_GetColormapFromListByValues(extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
extracolormap_t *R_ColormapForName(char *name)
|
||||||
|
{
|
||||||
|
lumpnum_t lump;
|
||||||
|
extracolormap_t *exc;
|
||||||
|
|
||||||
lump = R_CheckNumForNameList(name, colormaplumps, numcolormaplumps);
|
lump = R_CheckNumForNameList(name, colormaplumps, numcolormaplumps);
|
||||||
if (lump == LUMPERROR)
|
if (lump == LUMPERROR)
|
||||||
I_Error("R_ColormapNumForName: Cannot find colormap lump %.8s\n", name);
|
I_Error("R_ColormapForName: Cannot find colormap lump %.8s\n", name);
|
||||||
|
|
||||||
for (i = 0; i < num_extra_colormaps; i++)
|
exc = R_GetColormapFromListByValues(0, 0x19000000, 0, 31, 0, lump);
|
||||||
if (lump == foundcolormaps[i])
|
if (exc)
|
||||||
return i;
|
return exc;
|
||||||
|
|
||||||
foundcolormaps[num_extra_colormaps] = lump;
|
exc = Z_Calloc(sizeof (*exc), PU_LEVEL, NULL);
|
||||||
|
|
||||||
|
exc->lump = lump;
|
||||||
|
strncpy(exc->lumpname, name, 9);
|
||||||
|
exc->lumpname[8] = 0;
|
||||||
|
|
||||||
// aligned on 8 bit for asm code
|
// aligned on 8 bit for asm code
|
||||||
extra_colormaps[num_extra_colormaps].colormap = Z_MallocAlign(W_LumpLength(lump), PU_LEVEL, NULL, 16);
|
exc->colormap = Z_MallocAlign(W_LumpLength(lump), PU_LEVEL, NULL, 16);
|
||||||
W_ReadLump(lump, extra_colormaps[num_extra_colormaps].colormap);
|
W_ReadLump(lump, exc->colormap);
|
||||||
|
|
||||||
// We set all params of the colormap to normal because there
|
// We set all params of the colormap to normal because there
|
||||||
// is no real way to tell how GL should handle a colormap lump anyway..
|
// is no real way to tell how GL should handle a colormap lump anyway..
|
||||||
extra_colormaps[num_extra_colormaps].maskcolor = 0xffff;
|
exc->fadestart = 0;
|
||||||
extra_colormaps[num_extra_colormaps].fadecolor = 0x0;
|
exc->fadeend = 31;
|
||||||
extra_colormaps[num_extra_colormaps].maskamt = 0x0;
|
exc->fog = 0;
|
||||||
extra_colormaps[num_extra_colormaps].fadestart = 0;
|
exc->rgba = 0;
|
||||||
extra_colormaps[num_extra_colormaps].fadeend = 31;
|
exc->fadergba = 0x19000000;
|
||||||
extra_colormaps[num_extra_colormaps].fog = 0;
|
|
||||||
|
|
||||||
num_extra_colormaps++;
|
R_AddColormapToList(exc);
|
||||||
return (INT32)num_extra_colormaps - 1;
|
|
||||||
|
return exc;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_CreateColormap
|
// R_CreateColormap
|
||||||
|
@ -1382,244 +1594,71 @@ static double deltas[256][3], map[256][3];
|
||||||
static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||||
static int RoundUp(double number);
|
static int RoundUp(double number);
|
||||||
|
|
||||||
INT32 R_CreateColormap(char *p1, char *p2, char *p3)
|
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
|
||||||
{
|
{
|
||||||
double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb;
|
double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb;
|
||||||
double r, g, b, cbrightness, maskamt = 0, othermask = 0;
|
|
||||||
int mask, fog = 0;
|
|
||||||
size_t mapnum = num_extra_colormaps;
|
|
||||||
size_t i;
|
|
||||||
UINT32 cr, cg, cb, maskcolor, fadecolor;
|
|
||||||
UINT32 fadestart = 0, fadeend = 31, fadedist = 31;
|
|
||||||
|
|
||||||
#define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0)
|
|
||||||
if (p1[0] == '#')
|
|
||||||
{
|
|
||||||
cr = ((HEX2INT(p1[1]) * 16) + HEX2INT(p1[2]));
|
|
||||||
cmaskr = cr;
|
|
||||||
cg = ((HEX2INT(p1[3]) * 16) + HEX2INT(p1[4]));
|
|
||||||
cmaskg = cg;
|
|
||||||
cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6]));
|
|
||||||
cmaskb = cb;
|
|
||||||
// Create a rough approximation of the color (a 16 bit color)
|
|
||||||
maskcolor = ((cb) >> 3) + (((cg) >> 2) << 5) + (((cr) >> 3) << 11);
|
|
||||||
if (p1[7] >= 'a' && p1[7] <= 'z')
|
|
||||||
mask = (p1[7] - 'a');
|
|
||||||
else if (p1[7] >= 'A' && p1[7] <= 'Z')
|
|
||||||
mask = (p1[7] - 'A');
|
|
||||||
else
|
|
||||||
mask = 24;
|
|
||||||
|
|
||||||
maskamt = (double)(mask/24.0l);
|
|
||||||
|
|
||||||
othermask = 1 - maskamt;
|
|
||||||
maskamt /= 0xff;
|
|
||||||
cmaskr *= maskamt;
|
|
||||||
cmaskg *= maskamt;
|
|
||||||
cmaskb *= maskamt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmaskr = cmaskg = cmaskb = 0xff;
|
|
||||||
maskamt = 0;
|
|
||||||
maskcolor = ((0xff) >> 3) + (((0xff) >> 2) << 5) + (((0xff) >> 3) << 11);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0)
|
|
||||||
if (p2[0] == '#')
|
|
||||||
{
|
|
||||||
// Get parameters like fadestart, fadeend, and the fogflag
|
|
||||||
fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10);
|
|
||||||
fadeend = NUMFROMCHAR(p2[5]) + (NUMFROMCHAR(p2[4]) * 10);
|
|
||||||
if (fadestart > 30)
|
|
||||||
fadestart = 0;
|
|
||||||
if (fadeend > 31 || fadeend < 1)
|
|
||||||
fadeend = 31;
|
|
||||||
fadedist = fadeend - fadestart;
|
|
||||||
fog = NUMFROMCHAR(p2[1]);
|
|
||||||
}
|
|
||||||
#undef getnum
|
|
||||||
|
|
||||||
if (p3[0] == '#')
|
|
||||||
{
|
|
||||||
cdestr = cr = ((HEX2INT(p3[1]) * 16) + HEX2INT(p3[2]));
|
|
||||||
cdestg = cg = ((HEX2INT(p3[3]) * 16) + HEX2INT(p3[4]));
|
|
||||||
cdestb = cb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6]));
|
|
||||||
fadecolor = (((cb) >> 3) + (((cg) >> 2) << 5) + (((cr) >> 3) << 11));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cdestr = cdestg = cdestb = fadecolor = 0;
|
|
||||||
#undef HEX2INT
|
|
||||||
|
|
||||||
for (i = 0; i < num_extra_colormaps; i++)
|
|
||||||
{
|
|
||||||
if (foundcolormaps[i] != LUMPERROR)
|
|
||||||
continue;
|
|
||||||
if (maskcolor == extra_colormaps[i].maskcolor
|
|
||||||
&& fadecolor == extra_colormaps[i].fadecolor
|
|
||||||
&& (float)maskamt == (float)extra_colormaps[i].maskamt
|
|
||||||
&& fadestart == extra_colormaps[i].fadestart
|
|
||||||
&& fadeend == extra_colormaps[i].fadeend
|
|
||||||
&& fog == extra_colormaps[i].fog)
|
|
||||||
{
|
|
||||||
return (INT32)i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_extra_colormaps == MAXCOLORMAPS)
|
|
||||||
I_Error("R_CreateColormap: Too many colormaps! the limit is %d\n", MAXCOLORMAPS);
|
|
||||||
|
|
||||||
strncpy(colormapFixingArray[num_extra_colormaps][0], p1, 8);
|
|
||||||
strncpy(colormapFixingArray[num_extra_colormaps][1], p2, 8);
|
|
||||||
strncpy(colormapFixingArray[num_extra_colormaps][2], p3, 8);
|
|
||||||
|
|
||||||
num_extra_colormaps++;
|
|
||||||
|
|
||||||
if (rendermode == render_soft)
|
|
||||||
{
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
r = pMasterPalette[i].s.red;
|
|
||||||
g = pMasterPalette[i].s.green;
|
|
||||||
b = pMasterPalette[i].s.blue;
|
|
||||||
cbrightness = sqrt((r*r) + (g*g) + (b*b));
|
|
||||||
|
|
||||||
map[i][0] = (cbrightness * cmaskr) + (r * othermask);
|
|
||||||
if (map[i][0] > 255.0l)
|
|
||||||
map[i][0] = 255.0l;
|
|
||||||
deltas[i][0] = (map[i][0] - cdestr) / (double)fadedist;
|
|
||||||
|
|
||||||
map[i][1] = (cbrightness * cmaskg) + (g * othermask);
|
|
||||||
if (map[i][1] > 255.0l)
|
|
||||||
map[i][1] = 255.0l;
|
|
||||||
deltas[i][1] = (map[i][1] - cdestg) / (double)fadedist;
|
|
||||||
|
|
||||||
map[i][2] = (cbrightness * cmaskb) + (b * othermask);
|
|
||||||
if (map[i][2] > 255.0l)
|
|
||||||
map[i][2] = 255.0l;
|
|
||||||
deltas[i][2] = (map[i][2] - cdestb) / (double)fadedist;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foundcolormaps[mapnum] = LUMPERROR;
|
|
||||||
|
|
||||||
// aligned on 8 bit for asm code
|
|
||||||
extra_colormaps[mapnum].colormap = NULL;
|
|
||||||
extra_colormaps[mapnum].maskcolor = (UINT16)maskcolor;
|
|
||||||
extra_colormaps[mapnum].fadecolor = (UINT16)fadecolor;
|
|
||||||
extra_colormaps[mapnum].maskamt = maskamt;
|
|
||||||
extra_colormaps[mapnum].fadestart = (UINT16)fadestart;
|
|
||||||
extra_colormaps[mapnum].fadeend = (UINT16)fadeend;
|
|
||||||
extra_colormaps[mapnum].fog = fog;
|
|
||||||
|
|
||||||
return (INT32)mapnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_MakeColormaps(void)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
carrayindex = num_extra_colormaps;
|
|
||||||
num_extra_colormaps = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < carrayindex; i++)
|
|
||||||
R_CreateColormap2(colormapFixingArray[i][0], colormapFixingArray[i][1],
|
|
||||||
colormapFixingArray[i][2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_CreateColormap2(char *p1, char *p2, char *p3)
|
|
||||||
{
|
|
||||||
double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb;
|
|
||||||
double r, g, b, cbrightness;
|
|
||||||
double maskamt = 0, othermask = 0;
|
double maskamt = 0, othermask = 0;
|
||||||
int mask, p, fog = 0;
|
|
||||||
size_t mapnum = num_extra_colormaps;
|
UINT8 cr = R_GetRgbaR(extra_colormap->rgba),
|
||||||
|
cg = R_GetRgbaG(extra_colormap->rgba),
|
||||||
|
cb = R_GetRgbaB(extra_colormap->rgba),
|
||||||
|
ca = R_GetRgbaA(extra_colormap->rgba),
|
||||||
|
cfr = R_GetRgbaR(extra_colormap->fadergba),
|
||||||
|
cfg = R_GetRgbaG(extra_colormap->fadergba),
|
||||||
|
cfb = R_GetRgbaB(extra_colormap->fadergba);
|
||||||
|
// cfa = R_GetRgbaA(extra_colormap->fadergba); // unused in software
|
||||||
|
|
||||||
|
UINT8 fadestart = extra_colormap->fadestart,
|
||||||
|
fadedist = extra_colormap->fadeend - extra_colormap->fadestart;
|
||||||
|
|
||||||
|
lighttable_t *lighttable = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
char *colormap_p;
|
|
||||||
UINT32 cr, cg, cb, maskcolor, fadecolor;
|
|
||||||
UINT32 fadestart = 0, fadeend = 31, fadedist = 31;
|
|
||||||
|
|
||||||
#define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0)
|
/////////////////////
|
||||||
if (p1[0] == '#')
|
// Calc the RGBA mask
|
||||||
{
|
/////////////////////
|
||||||
cr = ((HEX2INT(p1[1]) * 16) + HEX2INT(p1[2]));
|
cmaskr = cr;
|
||||||
cmaskr = cr;
|
cmaskg = cg;
|
||||||
cg = ((HEX2INT(p1[3]) * 16) + HEX2INT(p1[4]));
|
cmaskb = cb;
|
||||||
cmaskg = cg;
|
|
||||||
cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6]));
|
|
||||||
cmaskb = cb;
|
|
||||||
// Create a rough approximation of the color (a 16 bit color)
|
|
||||||
maskcolor = ((cb) >> 3) + (((cg) >> 2) << 5) + (((cr) >> 3) << 11);
|
|
||||||
if (p1[7] >= 'a' && p1[7] <= 'z')
|
|
||||||
mask = (p1[7] - 'a');
|
|
||||||
else if (p1[7] >= 'A' && p1[7] <= 'Z')
|
|
||||||
mask = (p1[7] - 'A');
|
|
||||||
else
|
|
||||||
mask = 24;
|
|
||||||
|
|
||||||
maskamt = (double)(mask/24.0l);
|
maskamt = (double)(ca/24.0l);
|
||||||
|
othermask = 1 - maskamt;
|
||||||
|
maskamt /= 0xff;
|
||||||
|
|
||||||
othermask = 1 - maskamt;
|
cmaskr *= maskamt;
|
||||||
maskamt /= 0xff;
|
cmaskg *= maskamt;
|
||||||
cmaskr *= maskamt;
|
cmaskb *= maskamt;
|
||||||
cmaskg *= maskamt;
|
|
||||||
cmaskb *= maskamt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmaskr = cmaskg = cmaskb = 0xff;
|
|
||||||
maskamt = 0;
|
|
||||||
maskcolor = ((0xff) >> 3) + (((0xff) >> 2) << 5) + (((0xff) >> 3) << 11);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0)
|
/////////////////////
|
||||||
if (p2[0] == '#')
|
// Calc the RGBA fade mask
|
||||||
{
|
/////////////////////
|
||||||
// Get parameters like fadestart, fadeend, and the fogflag
|
cdestr = cfr;
|
||||||
fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10);
|
cdestg = cfg;
|
||||||
fadeend = NUMFROMCHAR(p2[5]) + (NUMFROMCHAR(p2[4]) * 10);
|
cdestb = cfb;
|
||||||
if (fadestart > 30)
|
|
||||||
fadestart = 0;
|
|
||||||
if (fadeend > 31 || fadeend < 1)
|
|
||||||
fadeend = 31;
|
|
||||||
fadedist = fadeend - fadestart;
|
|
||||||
fog = NUMFROMCHAR(p2[1]);
|
|
||||||
}
|
|
||||||
#undef getnum
|
|
||||||
|
|
||||||
if (p3[0] == '#')
|
// fade alpha unused in software
|
||||||
{
|
// maskamt = (double)(cfa/24.0l);
|
||||||
cdestr = cr = ((HEX2INT(p3[1]) * 16) + HEX2INT(p3[2]));
|
// othermask = 1 - maskamt;
|
||||||
cdestg = cg = ((HEX2INT(p3[3]) * 16) + HEX2INT(p3[4]));
|
// maskamt /= 0xff;
|
||||||
cdestb = cb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6]));
|
|
||||||
fadecolor = (((cb) >> 3) + (((cg) >> 2) << 5) + (((cr) >> 3) << 11));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cdestr = cdestg = cdestb = fadecolor = 0;
|
|
||||||
#undef HEX2INT
|
|
||||||
|
|
||||||
for (i = 0; i < num_extra_colormaps; i++)
|
// cdestr *= maskamt;
|
||||||
{
|
// cdestg *= maskamt;
|
||||||
if (foundcolormaps[i] != LUMPERROR)
|
// cdestb *= maskamt;
|
||||||
continue;
|
|
||||||
if (maskcolor == extra_colormaps[i].maskcolor
|
|
||||||
&& fadecolor == extra_colormaps[i].fadecolor
|
|
||||||
&& (float)maskamt == (float)extra_colormaps[i].maskamt
|
|
||||||
&& fadestart == extra_colormaps[i].fadestart
|
|
||||||
&& fadeend == extra_colormaps[i].fadeend
|
|
||||||
&& fog == extra_colormaps[i].fog)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_extra_colormaps == MAXCOLORMAPS)
|
|
||||||
I_Error("R_CreateColormap: Too many colormaps! the limit is %d\n", MAXCOLORMAPS);
|
|
||||||
|
|
||||||
num_extra_colormaps++;
|
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
// This code creates the colormap array used by software renderer
|
||||||
|
/////////////////////
|
||||||
if (rendermode == render_soft)
|
if (rendermode == render_soft)
|
||||||
{
|
{
|
||||||
|
double r, g, b, cbrightness;
|
||||||
|
int p;
|
||||||
|
char *colormap_p;
|
||||||
|
|
||||||
|
// Initialise the map and delta arrays
|
||||||
|
// map[i] stores an RGB color (as double) for index i,
|
||||||
|
// which is then converted to SRB2's palette later
|
||||||
|
// deltas[i] stores a corresponding fade delta between the RGB color and the final fade color;
|
||||||
|
// map[i]'s values are decremented by after each use
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
r = pMasterPalette[i].s.red;
|
r = pMasterPalette[i].s.red;
|
||||||
|
@ -1642,25 +1681,14 @@ void R_CreateColormap2(char *p1, char *p2, char *p3)
|
||||||
map[i][2] = 255.0l;
|
map[i][2] = 255.0l;
|
||||||
deltas[i][2] = (map[i][2] - cdestb) / (double)fadedist;
|
deltas[i][2] = (map[i][2] - cdestb) / (double)fadedist;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
foundcolormaps[mapnum] = LUMPERROR;
|
// Now allocate memory for the actual colormap array itself!
|
||||||
|
// aligned on 8 bit for asm code
|
||||||
// aligned on 8 bit for asm code
|
|
||||||
extra_colormaps[mapnum].colormap = NULL;
|
|
||||||
extra_colormaps[mapnum].maskcolor = (UINT16)maskcolor;
|
|
||||||
extra_colormaps[mapnum].fadecolor = (UINT16)fadecolor;
|
|
||||||
extra_colormaps[mapnum].maskamt = maskamt;
|
|
||||||
extra_colormaps[mapnum].fadestart = (UINT16)fadestart;
|
|
||||||
extra_colormaps[mapnum].fadeend = (UINT16)fadeend;
|
|
||||||
extra_colormaps[mapnum].fog = fog;
|
|
||||||
|
|
||||||
#define ABS2(x) ((x) < 0 ? -(x) : (x))
|
|
||||||
if (rendermode == render_soft)
|
|
||||||
{
|
|
||||||
colormap_p = Z_MallocAlign((256 * 34) + 10, PU_LEVEL, NULL, 8);
|
colormap_p = Z_MallocAlign((256 * 34) + 10, PU_LEVEL, NULL, 8);
|
||||||
extra_colormaps[mapnum].colormap = (UINT8 *)colormap_p;
|
lighttable = (UINT8 *)colormap_p;
|
||||||
|
|
||||||
|
// Calculate the palette index for each palette index, for each light level
|
||||||
|
// (as well as the two unused colormap lines we inherited from Doom)
|
||||||
for (p = 0; p < 34; p++)
|
for (p = 0; p < 34; p++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
|
@ -1672,7 +1700,7 @@ void R_CreateColormap2(char *p1, char *p2, char *p3)
|
||||||
|
|
||||||
if ((UINT32)p < fadestart)
|
if ((UINT32)p < fadestart)
|
||||||
continue;
|
continue;
|
||||||
|
#define ABS2(x) ((x) < 0 ? -(x) : (x))
|
||||||
if (ABS2(map[i][0] - cdestr) > ABS2(deltas[i][0]))
|
if (ABS2(map[i][0] - cdestr) > ABS2(deltas[i][0]))
|
||||||
map[i][0] -= deltas[i][0];
|
map[i][0] -= deltas[i][0];
|
||||||
else
|
else
|
||||||
|
@ -1687,12 +1715,290 @@ void R_CreateColormap2(char *p1, char *p2, char *p3)
|
||||||
map[i][2] -= deltas[i][2];
|
map[i][2] -= deltas[i][2];
|
||||||
else
|
else
|
||||||
map[i][2] = cdestb;
|
map[i][2] = cdestb;
|
||||||
|
#undef ABS2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef ABS2
|
|
||||||
|
|
||||||
return;
|
return lighttable;
|
||||||
|
}
|
||||||
|
|
||||||
|
extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
|
||||||
|
{
|
||||||
|
extracolormap_t *extra_colormap, *exc;
|
||||||
|
|
||||||
|
// default values
|
||||||
|
UINT8 cr = 0, cg = 0, cb = 0, ca = 0, cfr = 0, cfg = 0, cfb = 0, cfa = 25;
|
||||||
|
UINT32 fadestart = 0, fadeend = 31;
|
||||||
|
UINT8 fog = 0;
|
||||||
|
INT32 rgba = 0, fadergba = 0x19000000;
|
||||||
|
|
||||||
|
#define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0)
|
||||||
|
#define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0)
|
||||||
|
|
||||||
|
// Get base colormap value
|
||||||
|
// First alpha-only, then full value
|
||||||
|
if (p1[0] >= 'a' && p1[0] <= 'z' && !p1[1])
|
||||||
|
ca = (p1[0] - 'a');
|
||||||
|
else if (p1[0] == '#' && p1[1] >= 'a' && p1[1] <= 'z' && !p1[2])
|
||||||
|
ca = (p1[1] - 'a');
|
||||||
|
else if (p1[0] >= 'A' && p1[0] <= 'Z' && !p1[1])
|
||||||
|
ca = (p1[0] - 'A');
|
||||||
|
else if (p1[0] == '#' && p1[1] >= 'A' && p1[1] <= 'Z' && !p1[2])
|
||||||
|
ca = (p1[1] - 'A');
|
||||||
|
else if (p1[0] == '#')
|
||||||
|
{
|
||||||
|
// For each subsequent value, the value before it must exist
|
||||||
|
// If we don't get every value, then set alpha to max
|
||||||
|
if (p1[1] && p1[2])
|
||||||
|
{
|
||||||
|
cr = ((HEX2INT(p1[1]) * 16) + HEX2INT(p1[2]));
|
||||||
|
if (p1[3] && p1[4])
|
||||||
|
{
|
||||||
|
cg = ((HEX2INT(p1[3]) * 16) + HEX2INT(p1[4]));
|
||||||
|
if (p1[5] && p1[6])
|
||||||
|
{
|
||||||
|
cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6]));
|
||||||
|
|
||||||
|
if (p1[7] >= 'a' && p1[7] <= 'z')
|
||||||
|
ca = (p1[7] - 'a');
|
||||||
|
else if (p1[7] >= 'A' && p1[7] <= 'Z')
|
||||||
|
ca = (p1[7] - 'A');
|
||||||
|
else
|
||||||
|
ca = 25;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ca = 25;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ca = 25;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ca = 25;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0)
|
||||||
|
|
||||||
|
// Get parameters like fadestart, fadeend, and the fogflag
|
||||||
|
if (p2[0] == '#')
|
||||||
|
{
|
||||||
|
if (p2[1])
|
||||||
|
{
|
||||||
|
fog = NUMFROMCHAR(p2[1]);
|
||||||
|
if (p2[2] && p2[3])
|
||||||
|
{
|
||||||
|
fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10);
|
||||||
|
if (p2[4] && p2[5])
|
||||||
|
fadeend = NUMFROMCHAR(p2[5]) + (NUMFROMCHAR(p2[4]) * 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fadestart > 30)
|
||||||
|
fadestart = 0;
|
||||||
|
if (fadeend > 31 || fadeend < 1)
|
||||||
|
fadeend = 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef NUMFROMCHAR
|
||||||
|
|
||||||
|
// Get fade (dark) colormap value
|
||||||
|
// First alpha-only, then full value
|
||||||
|
if (p3[0] >= 'a' && p3[0] <= 'z' && !p3[1])
|
||||||
|
cfa = (p3[0] - 'a');
|
||||||
|
else if (p3[0] == '#' && p3[1] >= 'a' && p3[1] <= 'z' && !p3[2])
|
||||||
|
cfa = (p3[1] - 'a');
|
||||||
|
else if (p3[0] >= 'A' && p3[0] <= 'Z' && !p3[1])
|
||||||
|
cfa = (p3[0] - 'A');
|
||||||
|
else if (p3[0] == '#' && p3[1] >= 'A' && p3[1] <= 'Z' && !p3[2])
|
||||||
|
cfa = (p3[1] - 'A');
|
||||||
|
else if (p3[0] == '#')
|
||||||
|
{
|
||||||
|
// For each subsequent value, the value before it must exist
|
||||||
|
// If we don't get every value, then set alpha to max
|
||||||
|
if (p3[1] && p3[2])
|
||||||
|
{
|
||||||
|
cfr = ((HEX2INT(p3[1]) * 16) + HEX2INT(p3[2]));
|
||||||
|
if (p3[3] && p3[4])
|
||||||
|
{
|
||||||
|
cfg = ((HEX2INT(p3[3]) * 16) + HEX2INT(p3[4]));
|
||||||
|
if (p3[5] && p3[6])
|
||||||
|
{
|
||||||
|
cfb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6]));
|
||||||
|
|
||||||
|
if (p3[7] >= 'a' && p3[7] <= 'z')
|
||||||
|
cfa = (p3[7] - 'a');
|
||||||
|
else if (p3[7] >= 'A' && p3[7] <= 'Z')
|
||||||
|
cfa = (p3[7] - 'A');
|
||||||
|
else
|
||||||
|
cfa = 25;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cfa = 25;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cfa = 25;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cfa = 25;
|
||||||
|
}
|
||||||
|
#undef ALPHA2INT
|
||||||
|
#undef HEX2INT
|
||||||
|
|
||||||
|
// Pack rgba values into combined var
|
||||||
|
// OpenGL also uses this instead of lighttables for rendering
|
||||||
|
rgba = R_PutRgbaRGBA(cr, cg, cb, ca);
|
||||||
|
fadergba = R_PutRgbaRGBA(cfr, cfg, cfb, cfa);
|
||||||
|
|
||||||
|
// Did we just make a default colormap?
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, fog, LUMPERROR))
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, fog))
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Look for existing colormaps
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog, LUMPERROR);
|
||||||
|
#else
|
||||||
|
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog);
|
||||||
|
#endif
|
||||||
|
if (exc)
|
||||||
|
return exc;
|
||||||
|
|
||||||
|
CONS_Debug(DBG_RENDER, "Creating Colormap: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n",
|
||||||
|
cr, cg, cb, ca, cfr, cfg, cfb, cfa);
|
||||||
|
|
||||||
|
extra_colormap = Z_Calloc(sizeof (*extra_colormap), PU_LEVEL, NULL);
|
||||||
|
|
||||||
|
extra_colormap->fadestart = (UINT16)fadestart;
|
||||||
|
extra_colormap->fadeend = (UINT16)fadeend;
|
||||||
|
extra_colormap->fog = fog;
|
||||||
|
|
||||||
|
extra_colormap->rgba = rgba;
|
||||||
|
extra_colormap->fadergba = fadergba;
|
||||||
|
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
extra_colormap->lump = LUMPERROR;
|
||||||
|
extra_colormap->lumpname[0] = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Having lighttables for alpha-only entries is kind of pointless,
|
||||||
|
// but if there happens to be a matching rgba entry that is NOT alpha-only (but has same rgb values),
|
||||||
|
// then it needs this lighttable because we share matching entries.
|
||||||
|
extra_colormap->colormap = R_CreateLightTable(extra_colormap);
|
||||||
|
|
||||||
|
R_AddColormapToList(extra_colormap);
|
||||||
|
|
||||||
|
return extra_colormap;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// R_AddColormaps()
|
||||||
|
// NOTE: The result colormap is not added to the extra_colormaps chain. You must do that yourself!
|
||||||
|
//
|
||||||
|
extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend,
|
||||||
|
boolean subR, boolean subG, boolean subB, boolean subA,
|
||||||
|
boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA,
|
||||||
|
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFog,
|
||||||
|
boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha,
|
||||||
|
boolean lighttable)
|
||||||
|
{
|
||||||
|
INT16 red, green, blue, alpha;
|
||||||
|
|
||||||
|
// exc_augend is added (or subtracted) onto by exc_addend
|
||||||
|
// In Rennaisance times, the first number was considered the augend, the second number the addend
|
||||||
|
// But since the commutative property was discovered, today they're both called addends!
|
||||||
|
// So let's be Olde English for a hot second.
|
||||||
|
|
||||||
|
exc_augend = R_CopyColormap(exc_augend, false);
|
||||||
|
if(!exc_addend)
|
||||||
|
exc_addend = R_GetDefaultColormap();
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// base rgba
|
||||||
|
///////////////////
|
||||||
|
|
||||||
|
red = max(min(
|
||||||
|
R_GetRgbaR(exc_augend->rgba)
|
||||||
|
+ (subR ? -1 : 1) // subtract R
|
||||||
|
* R_GetRgbaR(exc_addend->rgba)
|
||||||
|
, 255), 0);
|
||||||
|
|
||||||
|
green = max(min(
|
||||||
|
R_GetRgbaG(exc_augend->rgba)
|
||||||
|
+ (subG ? -1 : 1) // subtract G
|
||||||
|
* R_GetRgbaG(exc_addend->rgba)
|
||||||
|
, 255), 0);
|
||||||
|
|
||||||
|
blue = max(min(
|
||||||
|
R_GetRgbaB(exc_augend->rgba)
|
||||||
|
+ (subB ? -1 : 1) // subtract B
|
||||||
|
* R_GetRgbaB(exc_addend->rgba)
|
||||||
|
, 255), 0);
|
||||||
|
|
||||||
|
alpha = useAltAlpha ? altAlpha : R_GetRgbaA(exc_addend->rgba);
|
||||||
|
alpha = max(min(R_GetRgbaA(exc_augend->rgba) + (subA ? -1 : 1) * alpha, 25), 0);
|
||||||
|
|
||||||
|
exc_augend->rgba = R_PutRgbaRGBA(red, green, blue, alpha);
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// fade/dark rgba
|
||||||
|
///////////////////
|
||||||
|
|
||||||
|
red = max(min(
|
||||||
|
R_GetRgbaR(exc_augend->fadergba)
|
||||||
|
+ (subFadeR ? -1 : 1) // subtract R
|
||||||
|
* R_GetRgbaR(exc_addend->fadergba)
|
||||||
|
, 255), 0);
|
||||||
|
|
||||||
|
green = max(min(
|
||||||
|
R_GetRgbaG(exc_augend->fadergba)
|
||||||
|
+ (subFadeG ? -1 : 1) // subtract G
|
||||||
|
* R_GetRgbaG(exc_addend->fadergba)
|
||||||
|
, 255), 0);
|
||||||
|
|
||||||
|
blue = max(min(
|
||||||
|
R_GetRgbaB(exc_augend->fadergba)
|
||||||
|
+ (subFadeB ? -1 : 1) // subtract B
|
||||||
|
* R_GetRgbaB(exc_addend->fadergba)
|
||||||
|
, 255), 0);
|
||||||
|
|
||||||
|
alpha = useAltAlpha ? altFadeAlpha : R_GetRgbaA(exc_addend->fadergba);
|
||||||
|
if (alpha == 25 && !useAltAlpha && !R_GetRgbaRGB(exc_addend->fadergba))
|
||||||
|
alpha = 0; // HACK: fadergba A defaults at 25, so don't add anything in this case
|
||||||
|
alpha = max(min(R_GetRgbaA(exc_augend->fadergba) + (subFadeA ? -1 : 1) * alpha, 25), 0);
|
||||||
|
|
||||||
|
exc_augend->fadergba = R_PutRgbaRGBA(red, green, blue, alpha);
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// parameters
|
||||||
|
///////////////////
|
||||||
|
|
||||||
|
exc_augend->fadestart = max(min(
|
||||||
|
exc_augend->fadestart
|
||||||
|
+ (subFadeStart ? -1 : 1) // subtract fadestart
|
||||||
|
* exc_addend->fadestart
|
||||||
|
, 31), 0);
|
||||||
|
|
||||||
|
exc_augend->fadeend = max(min(
|
||||||
|
exc_augend->fadeend
|
||||||
|
+ (subFadeEnd ? -1 : 1) // subtract fadeend
|
||||||
|
* (exc_addend->fadeend == 31 && !exc_addend->fadestart ? 0 : exc_addend->fadeend)
|
||||||
|
// HACK: fadeend defaults to 31, so don't add anything in this case
|
||||||
|
, 31), 0);
|
||||||
|
|
||||||
|
if (!ignoreFog) // overwrite fog with new value
|
||||||
|
exc_augend->fog = exc_addend->fog;
|
||||||
|
|
||||||
|
///////////////////
|
||||||
|
// put it together
|
||||||
|
///////////////////
|
||||||
|
|
||||||
|
exc_augend->colormap = lighttable ? R_CreateLightTable(exc_augend) : NULL;
|
||||||
|
exc_augend->next = exc_augend->prev = NULL;
|
||||||
|
return exc_augend;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Thanks to quake2 source!
|
// Thanks to quake2 source!
|
||||||
|
@ -1735,20 +2041,18 @@ static int RoundUp(double number)
|
||||||
return (int)number;
|
return (int)number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *R_ColormapNameForNum(INT32 num)
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
const char *R_NameForColormap(extracolormap_t *extra_colormap)
|
||||||
{
|
{
|
||||||
if (num == -1)
|
if (!extra_colormap)
|
||||||
return "NONE";
|
return "NONE";
|
||||||
|
|
||||||
if (num < 0 || num > MAXCOLORMAPS)
|
if (extra_colormap->lump == LUMPERROR)
|
||||||
I_Error("R_ColormapNameForNum: num %d is invalid!\n", num);
|
|
||||||
|
|
||||||
if (foundcolormaps[num] == LUMPERROR)
|
|
||||||
return "INLEVEL";
|
return "INLEVEL";
|
||||||
|
|
||||||
return W_CheckNameForNum(foundcolormaps[num]);
|
return extra_colormap->lumpname;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// build a table for quick conversion from 8bpp to 15bpp
|
// build a table for quick conversion from 8bpp to 15bpp
|
||||||
|
|
54
src/r_data.h
54
src/r_data.h
|
@ -96,13 +96,57 @@ void R_ClearTextureNumCache(boolean btell);
|
||||||
INT32 R_TextureNumForName(const char *name);
|
INT32 R_TextureNumForName(const char *name);
|
||||||
INT32 R_CheckTextureNumForName(const char *name);
|
INT32 R_CheckTextureNumForName(const char *name);
|
||||||
|
|
||||||
|
// Extra Colormap lumps (C_START/C_END) are not used anywhere
|
||||||
|
// Uncomment to enable
|
||||||
|
//#define EXTRACOLORMAPLUMPS
|
||||||
|
|
||||||
|
// Uncomment to make extra_colormaps order Newest -> Oldest
|
||||||
|
//#define COLORMAPREVERSELIST
|
||||||
|
|
||||||
void R_ReInitColormaps(UINT16 num);
|
void R_ReInitColormaps(UINT16 num);
|
||||||
void R_ClearColormaps(void);
|
void R_ClearColormaps(void);
|
||||||
INT32 R_ColormapNumForName(char *name);
|
extracolormap_t *R_CreateDefaultColormap(boolean lighttable);
|
||||||
INT32 R_CreateColormap(char *p1, char *p2, char *p3);
|
extracolormap_t *R_GetDefaultColormap(void);
|
||||||
void R_CreateColormap2(char *p1, char *p2, char *p3);
|
extracolormap_t *R_CopyColormap(extracolormap_t *extra_colormap, boolean lighttable);
|
||||||
void R_MakeColormaps(void);
|
void R_AddColormapToList(extracolormap_t *extra_colormap);
|
||||||
const char *R_ColormapNameForNum(INT32 num);
|
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||||
|
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump);
|
||||||
|
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump);
|
||||||
|
#else
|
||||||
|
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||||
|
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog);
|
||||||
|
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog);
|
||||||
|
#endif
|
||||||
|
boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgba, boolean checkfadergba, boolean checkparams);
|
||||||
|
boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams);
|
||||||
|
extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap);
|
||||||
|
|
||||||
|
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap);
|
||||||
|
extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3);
|
||||||
|
extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend,
|
||||||
|
boolean subR, boolean subG, boolean subB, boolean subA,
|
||||||
|
boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA,
|
||||||
|
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFog,
|
||||||
|
boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha,
|
||||||
|
boolean lighttable);
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
extracolormap_t *R_ColormapForName(char *name);
|
||||||
|
const char *R_NameForColormap(extracolormap_t *extra_colormap);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define R_GetRgbaR(rgba) (rgba & 0xFF)
|
||||||
|
#define R_GetRgbaG(rgba) ((rgba >> 8) & 0xFF)
|
||||||
|
#define R_GetRgbaB(rgba) ((rgba >> 16) & 0xFF)
|
||||||
|
#define R_GetRgbaA(rgba) ((rgba >> 24) & 0xFF)
|
||||||
|
#define R_GetRgbaRGB(rgba) (rgba & 0xFFFFFF)
|
||||||
|
#define R_PutRgbaR(r) (r)
|
||||||
|
#define R_PutRgbaG(g) (g << 8)
|
||||||
|
#define R_PutRgbaB(b) (b << 16)
|
||||||
|
#define R_PutRgbaA(a) (a << 24)
|
||||||
|
#define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b))
|
||||||
|
#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
|
||||||
|
|
||||||
extern INT32 numtextures;
|
extern INT32 numtextures;
|
||||||
|
|
||||||
|
|
34
src/r_defs.h
34
src/r_defs.h
|
@ -50,18 +50,25 @@ typedef struct
|
||||||
typedef UINT8 lighttable_t;
|
typedef UINT8 lighttable_t;
|
||||||
|
|
||||||
// ExtraColormap type. Use for extra_colormaps from now on.
|
// ExtraColormap type. Use for extra_colormaps from now on.
|
||||||
typedef struct
|
typedef struct extracolormap_s
|
||||||
{
|
{
|
||||||
UINT16 maskcolor, fadecolor;
|
UINT8 fadestart, fadeend;
|
||||||
double maskamt;
|
UINT8 fog; // categorical value, not boolean
|
||||||
UINT16 fadestart, fadeend;
|
|
||||||
INT32 fog;
|
|
||||||
|
|
||||||
// rgba is used in hw mode for colored sector lighting
|
// store rgba values in combined bitwise
|
||||||
|
// also used in OpenGL instead lighttables
|
||||||
INT32 rgba; // similar to maskcolor in sw mode
|
INT32 rgba; // similar to maskcolor in sw mode
|
||||||
INT32 fadergba; // The colour the colourmaps fade to
|
INT32 fadergba; // The colour the colourmaps fade to
|
||||||
|
|
||||||
lighttable_t *colormap;
|
lighttable_t *colormap;
|
||||||
|
|
||||||
|
#ifdef EXTRACOLORMAPLUMPS
|
||||||
|
lumpnum_t lump; // for colormap lump matching, init to LUMPERROR
|
||||||
|
char lumpname[9]; // for netsyncing
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct extracolormap_s *next;
|
||||||
|
struct extracolormap_s *prev;
|
||||||
} extracolormap_t;
|
} extracolormap_t;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -177,6 +184,8 @@ typedef struct ffloor_s
|
||||||
// these are saved for netgames, so do not let Lua touch these!
|
// these are saved for netgames, so do not let Lua touch these!
|
||||||
ffloortype_e spawnflags; // flags the 3D floor spawned with
|
ffloortype_e spawnflags; // flags the 3D floor spawned with
|
||||||
INT32 spawnalpha; // alpha the 3D floor spawned with
|
INT32 spawnalpha; // alpha the 3D floor spawned with
|
||||||
|
|
||||||
|
void *fadingdata; // fading FOF thinker
|
||||||
} ffloor_t;
|
} ffloor_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -187,7 +196,7 @@ typedef struct lightlist_s
|
||||||
{
|
{
|
||||||
fixed_t height;
|
fixed_t height;
|
||||||
INT16 *lightlevel;
|
INT16 *lightlevel;
|
||||||
extracolormap_t *extra_colormap;
|
extracolormap_t **extra_colormap; // pointer-to-a-pointer, so we can react to colormap changes
|
||||||
INT32 flags;
|
INT32 flags;
|
||||||
ffloor_t *caster;
|
ffloor_t *caster;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
|
@ -308,6 +317,7 @@ typedef struct sector_s
|
||||||
void *floordata; // floor move thinker
|
void *floordata; // floor move thinker
|
||||||
void *ceilingdata; // ceiling move thinker
|
void *ceilingdata; // ceiling move thinker
|
||||||
void *lightingdata; // lighting change thinker
|
void *lightingdata; // lighting change thinker
|
||||||
|
void *fadecolormapdata; // fade colormap thinker
|
||||||
|
|
||||||
// floor and ceiling texture offsets
|
// floor and ceiling texture offsets
|
||||||
fixed_t floor_xoffs, floor_yoffs;
|
fixed_t floor_xoffs, floor_yoffs;
|
||||||
|
@ -323,8 +333,6 @@ typedef struct sector_s
|
||||||
INT32 floorlightsec, ceilinglightsec;
|
INT32 floorlightsec, ceilinglightsec;
|
||||||
INT32 crumblestate; // used for crumbling and bobbing
|
INT32 crumblestate; // used for crumbling and bobbing
|
||||||
|
|
||||||
INT32 bottommap, midmap, topmap; // dynamic colormaps
|
|
||||||
|
|
||||||
// list of mobjs that are at least partially in the sector
|
// list of mobjs that are at least partially in the sector
|
||||||
// thinglist is a subset of touching_thinglist
|
// thinglist is a subset of touching_thinglist
|
||||||
struct msecnode_s *touching_thinglist;
|
struct msecnode_s *touching_thinglist;
|
||||||
|
@ -383,6 +391,9 @@ typedef struct sector_s
|
||||||
boolean hasslope; // The sector, or one of its visible FOFs, contains a slope
|
boolean hasslope; // The sector, or one of its visible FOFs, contains a slope
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// for fade thinker
|
||||||
|
INT16 spawn_lightlevel;
|
||||||
|
|
||||||
// these are saved for netgames, so do not let Lua touch these!
|
// these are saved for netgames, so do not let Lua touch these!
|
||||||
INT32 spawn_nexttag, spawn_firsttag; // the actual nexttag/firsttag values may differ if the sector's tag was changed
|
INT32 spawn_nexttag, spawn_firsttag; // the actual nexttag/firsttag values may differ if the sector's tag was changed
|
||||||
|
|
||||||
|
@ -393,6 +404,9 @@ typedef struct sector_s
|
||||||
// flag angles sector spawned with (via linedef type 7)
|
// flag angles sector spawned with (via linedef type 7)
|
||||||
angle_t spawn_flrpic_angle;
|
angle_t spawn_flrpic_angle;
|
||||||
angle_t spawn_ceilpic_angle;
|
angle_t spawn_ceilpic_angle;
|
||||||
|
|
||||||
|
// colormap structure
|
||||||
|
extracolormap_t *spawn_extra_colormap;
|
||||||
} sector_t;
|
} sector_t;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -468,6 +482,8 @@ typedef struct
|
||||||
INT16 repeatcnt; // # of times to repeat midtexture
|
INT16 repeatcnt; // # of times to repeat midtexture
|
||||||
|
|
||||||
char *text; // a concatination of all top, bottom, and mid texture names, for linedef specials that require a string.
|
char *text; // a concatination of all top, bottom, and mid texture names, for linedef specials that require a string.
|
||||||
|
|
||||||
|
extracolormap_t *colormap_data; // storage for colormaps; not applied to sectors.
|
||||||
} side_t;
|
} side_t;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -261,7 +261,7 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
||||||
val = source[frac>>FRACBITS];
|
val = source[frac>>FRACBITS];
|
||||||
|
|
||||||
if (val != TRANSPARENTPIXEL)
|
if (val != TRANSPARENTPIXEL)
|
||||||
*dest = colormap[*(transmap + (val<<8) + (*dest))];
|
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||||
|
|
||||||
dest += vid.width;
|
dest += vid.width;
|
||||||
|
|
||||||
|
@ -281,12 +281,12 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
||||||
{
|
{
|
||||||
val = source[(frac>>FRACBITS) & heightmask];
|
val = source[(frac>>FRACBITS) & heightmask];
|
||||||
if (val != TRANSPARENTPIXEL)
|
if (val != TRANSPARENTPIXEL)
|
||||||
*dest = colormap[*(transmap + (val<<8) + (*dest))];
|
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||||
dest += vid.width;
|
dest += vid.width;
|
||||||
frac += fracstep;
|
frac += fracstep;
|
||||||
val = source[(frac>>FRACBITS) & heightmask];
|
val = source[(frac>>FRACBITS) & heightmask];
|
||||||
if (val != TRANSPARENTPIXEL)
|
if (val != TRANSPARENTPIXEL)
|
||||||
*dest = colormap[*(transmap + (val<<8) + (*dest))];
|
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||||
dest += vid.width;
|
dest += vid.width;
|
||||||
frac += fracstep;
|
frac += fracstep;
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
||||||
{
|
{
|
||||||
val = source[(frac>>FRACBITS) & heightmask];
|
val = source[(frac>>FRACBITS) & heightmask];
|
||||||
if (val != TRANSPARENTPIXEL)
|
if (val != TRANSPARENTPIXEL)
|
||||||
*dest = colormap[*(transmap + (val<<8) + (*dest))];
|
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,8 +118,7 @@ lighttable_t *scalelightfixed[MAXLIGHTSCALE];
|
||||||
lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
|
lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||||
|
|
||||||
// Hack to support extra boom colormaps.
|
// Hack to support extra boom colormaps.
|
||||||
size_t num_extra_colormaps;
|
extracolormap_t *extra_colormaps = NULL;
|
||||||
extracolormap_t extra_colormaps[MAXCOLORMAPS];
|
|
||||||
|
|
||||||
static CV_PossibleValue_t drawdist_cons_t[] = {
|
static CV_PossibleValue_t drawdist_cons_t[] = {
|
||||||
{256, "256"}, {512, "512"}, {768, "768"},
|
{256, "256"}, {512, "512"}, {768, "768"},
|
||||||
|
|
|
@ -413,7 +413,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
||||||
#endif
|
#endif
|
||||||
rlight->startheight = rlight->height; // keep starting value here to reset for each repeat
|
rlight->startheight = rlight->height; // keep starting value here to reset for each repeat
|
||||||
rlight->lightlevel = *light->lightlevel;
|
rlight->lightlevel = *light->lightlevel;
|
||||||
rlight->extra_colormap = light->extra_colormap;
|
rlight->extra_colormap = *light->extra_colormap;
|
||||||
rlight->flags = light->flags;
|
rlight->flags = light->flags;
|
||||||
|
|
||||||
if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
|
if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
|
||||||
|
@ -944,7 +944,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
}
|
}
|
||||||
|
|
||||||
rlight->lightlevel = *light->lightlevel;
|
rlight->lightlevel = *light->lightlevel;
|
||||||
rlight->extra_colormap = light->extra_colormap;
|
rlight->extra_colormap = *light->extra_colormap;
|
||||||
|
|
||||||
// Check if the current light effects the colormap/lightlevel
|
// Check if the current light effects the colormap/lightlevel
|
||||||
if (pfloor->flags & FF_FOG)
|
if (pfloor->flags & FF_FOG)
|
||||||
|
@ -2808,7 +2808,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||||
}
|
}
|
||||||
|
|
||||||
rlight->lightlevel = *light->lightlevel;
|
rlight->lightlevel = *light->lightlevel;
|
||||||
rlight->extra_colormap = light->extra_colormap;
|
rlight->extra_colormap = *light->extra_colormap;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,7 @@ extern sprcache_t *spritecachedinfo;
|
||||||
extern lighttable_t *colormaps;
|
extern lighttable_t *colormaps;
|
||||||
|
|
||||||
// Boom colormaps.
|
// Boom colormaps.
|
||||||
// Had to put a limit on colormaps :(
|
extern extracolormap_t *extra_colormaps;
|
||||||
#define MAXCOLORMAPS 60
|
|
||||||
|
|
||||||
extern size_t num_extra_colormaps;
|
|
||||||
extern extracolormap_t extra_colormaps[MAXCOLORMAPS];
|
|
||||||
|
|
||||||
// for global animation
|
// for global animation
|
||||||
extern INT32 *texturetranslation;
|
extern INT32 *texturetranslation;
|
||||||
|
|
|
@ -981,7 +981,7 @@ static void R_SplitSprite(vissprite_t *sprite)
|
||||||
else
|
else
|
||||||
spritelights = scalelight[lightnum];
|
spritelights = scalelight[lightnum];
|
||||||
|
|
||||||
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
|
newsprite->extra_colormap = *sector->lightlist[i].extra_colormap;
|
||||||
|
|
||||||
if (!((newsprite->cut & SC_FULLBRIGHT)
|
if (!((newsprite->cut & SC_FULLBRIGHT)
|
||||||
&& (!newsprite->extra_colormap || !(newsprite->extra_colormap->fog & 1))))
|
&& (!newsprite->extra_colormap || !(newsprite->extra_colormap->fog & 1))))
|
||||||
|
@ -1360,7 +1360,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS);
|
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS);
|
||||||
vis->cut = cut;
|
vis->cut = cut;
|
||||||
if (thing->subsector->sector->numlights)
|
if (thing->subsector->sector->numlights)
|
||||||
vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap;
|
vis->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap;
|
||||||
else
|
else
|
||||||
vis->extra_colormap = thing->subsector->sector->extra_colormap;
|
vis->extra_colormap = thing->subsector->sector->extra_colormap;
|
||||||
|
|
||||||
|
@ -1525,6 +1525,17 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// okay, we can't return now except for vertical clipping... this is a hack, but weather isn't networked, so it should be ok
|
||||||
|
if (!(thing->precipflags & PCF_THUNK))
|
||||||
|
{
|
||||||
|
if (thing->precipflags & PCF_RAIN)
|
||||||
|
P_RainThinker(thing);
|
||||||
|
else
|
||||||
|
P_SnowThinker(thing);
|
||||||
|
thing->precipflags |= PCF_THUNK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//SoM: 3/17/2000: Disregard sprites that are out of view..
|
//SoM: 3/17/2000: Disregard sprites that are out of view..
|
||||||
gzt = thing->z + spritecachedinfo[lump].topoffset;
|
gzt = thing->z + spritecachedinfo[lump].topoffset;
|
||||||
gz = gzt - spritecachedinfo[lump].height;
|
gz = gzt - spritecachedinfo[lump].height;
|
||||||
|
@ -1642,8 +1653,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
||||||
|
|
||||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||||
|
|
||||||
if (approx_dist <= limit_dist)
|
if (approx_dist > limit_dist)
|
||||||
R_ProjectSprite(thing);
|
continue;
|
||||||
|
|
||||||
|
R_ProjectSprite(thing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1664,8 +1677,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
||||||
|
|
||||||
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
||||||
|
|
||||||
if (approx_dist <= limit_dist)
|
if (approx_dist > limit_dist)
|
||||||
R_ProjectPrecipitationSprite(precipthing);
|
continue;
|
||||||
|
|
||||||
|
R_ProjectPrecipitationSprite(precipthing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
388
src/s_sound.c
388
src/s_sound.c
|
@ -230,7 +230,7 @@ void S_RegisterSoundStuff(void)
|
||||||
{
|
{
|
||||||
if (dedicated)
|
if (dedicated)
|
||||||
{
|
{
|
||||||
nosound = true;
|
sound_disabled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||||
mobj_t *listenmobj = players[displayplayer].mo;
|
mobj_t *listenmobj = players[displayplayer].mo;
|
||||||
mobj_t *listenmobj2 = NULL;
|
mobj_t *listenmobj2 = NULL;
|
||||||
|
|
||||||
if (sound_disabled || !sound_started || nosound)
|
if (sound_disabled || !sound_started)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Don't want a sound? Okay then...
|
// Don't want a sound? Okay then...
|
||||||
|
@ -626,7 +626,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||||
|
|
||||||
// Assigns the handle to one of the channels in the
|
// Assigns the handle to one of the channels in the
|
||||||
// mix/output buffer.
|
// mix/output buffer.
|
||||||
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
|
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
dontplay:
|
dontplay:
|
||||||
|
@ -679,7 +679,7 @@ dontplay:
|
||||||
|
|
||||||
// Assigns the handle to one of the channels in the
|
// Assigns the handle to one of the channels in the
|
||||||
// mix/output buffer.
|
// mix/output buffer.
|
||||||
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
|
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_StartSound(const void *origin, sfxenum_t sfx_id)
|
void S_StartSound(const void *origin, sfxenum_t sfx_id)
|
||||||
|
@ -824,7 +824,7 @@ void S_UpdateSounds(void)
|
||||||
goto notinlevel;
|
goto notinlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dedicated || nosound)
|
if (dedicated || sound_disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (players[displayplayer].awayviewtics)
|
if (players[displayplayer].awayviewtics)
|
||||||
|
@ -1283,6 +1283,43 @@ void S_StartSoundName(void *mo, const char *soundname)
|
||||||
S_StartSound(mo, soundnum);
|
S_StartSound(mo, soundnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initializes sound stuff, including volume
|
||||||
|
// Sets channels, SFX volume,
|
||||||
|
// allocates channel buffer, sets S_sfx lookup.
|
||||||
|
//
|
||||||
|
void S_InitSfxChannels(INT32 sfxVolume)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
if (dedicated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
S_SetSfxVolume(sfxVolume);
|
||||||
|
|
||||||
|
SetChannelsNum();
|
||||||
|
|
||||||
|
// Note that sounds have not been cached (yet).
|
||||||
|
for (i = 1; i < NUMSFX; i++)
|
||||||
|
{
|
||||||
|
S_sfx[i].usefulness = -1; // for I_GetSfx()
|
||||||
|
S_sfx[i].lumpnum = LUMPERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// precache sounds if requested by cmdline, or precachesound var true
|
||||||
|
if (!sound_disabled && (M_CheckParm("-precachesound") || precachesound.value))
|
||||||
|
{
|
||||||
|
// Initialize external data (all sounds) at start, keep static.
|
||||||
|
CONS_Printf(M_GetText("Loading sounds... "));
|
||||||
|
|
||||||
|
for (i = 1; i < NUMSFX; i++)
|
||||||
|
if (S_sfx[i].name)
|
||||||
|
S_sfx[i].data = I_GetSfx(&S_sfx[i]);
|
||||||
|
|
||||||
|
CONS_Printf(M_GetText(" pre-cached all sound data\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
/// Music
|
/// Music
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
@ -1309,31 +1346,109 @@ const char *compat_special_music_slots[16] =
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define music_playing (music_name[0]) // String is empty if no music is playing
|
|
||||||
|
|
||||||
static char music_name[7]; // up to 6-character name
|
static char music_name[7]; // up to 6-character name
|
||||||
static lumpnum_t music_lumpnum; // lump number of music (used??)
|
static void *music_data;
|
||||||
static void *music_data; // music raw data
|
static UINT16 music_flags;
|
||||||
static INT32 music_handle; // once registered, the handle for the music
|
static boolean music_looping;
|
||||||
|
|
||||||
static boolean mus_paused = 0; // whether songs are mus_paused
|
/// ------------------------
|
||||||
|
/// Music Status
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
static boolean S_MIDIMusic(const char *mname, boolean looping)
|
boolean S_DigMusicDisabled(void)
|
||||||
|
{
|
||||||
|
return digital_disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean S_MIDIMusicDisabled(void)
|
||||||
|
{
|
||||||
|
return midi_disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean S_MusicDisabled(void)
|
||||||
|
{
|
||||||
|
return (midi_disabled && digital_disabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean S_MusicPlaying(void)
|
||||||
|
{
|
||||||
|
return I_SongPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean S_MusicPaused(void)
|
||||||
|
{
|
||||||
|
return I_SongPaused();
|
||||||
|
}
|
||||||
|
|
||||||
|
musictype_t S_MusicType(void)
|
||||||
|
{
|
||||||
|
return I_SongType();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping)
|
||||||
|
{
|
||||||
|
if (!I_SongPlaying())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
strncpy(mname, music_name, 7);
|
||||||
|
mname[6] = 0;
|
||||||
|
*mflags = music_flags;
|
||||||
|
*looping = music_looping;
|
||||||
|
|
||||||
|
return (boolean)mname[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(checkDigi ? W_CheckNumForName(va("O_%s", mname)) != LUMPERROR : false)
|
||||||
|
|| (checkMIDI ? W_CheckNumForName(va("D_%s", mname)) != LUMPERROR : false)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// Music Effects
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
boolean S_SpeedMusic(float speed)
|
||||||
|
{
|
||||||
|
return I_SetSongSpeed(speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// Music Playback
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
static boolean S_LoadMusic(const char *mname)
|
||||||
{
|
{
|
||||||
lumpnum_t mlumpnum;
|
lumpnum_t mlumpnum;
|
||||||
void *mdata;
|
void *mdata;
|
||||||
INT32 mhandle;
|
|
||||||
|
|
||||||
if (nomidimusic || music_disabled)
|
if (S_MusicDisabled())
|
||||||
return false; // didn't search.
|
|
||||||
|
|
||||||
if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR)
|
|
||||||
return false;
|
return false;
|
||||||
mlumpnum = W_GetNumForName(va("d_%s", mname));
|
|
||||||
|
if (!S_DigMusicDisabled() && S_DigExists(mname))
|
||||||
|
mlumpnum = W_GetNumForName(va("o_%s", mname));
|
||||||
|
else if (!S_MIDIMusicDisabled() && S_MIDIExists(mname))
|
||||||
|
mlumpnum = W_GetNumForName(va("d_%s", mname));
|
||||||
|
else if (S_DigMusicDisabled() && S_DigExists(mname))
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_NOTICE, "Digital music is disabled!\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (S_MIDIMusicDisabled() && S_MIDIExists(mname))
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_NOTICE, "MIDI music is disabled!\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mname);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// load & register it
|
// load & register it
|
||||||
mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC);
|
mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC);
|
||||||
mhandle = I_RegisterSong(mdata, W_LumpLength(mlumpnum));
|
|
||||||
|
|
||||||
#ifdef MUSSERV
|
#ifdef MUSSERV
|
||||||
if (msg_id != -1)
|
if (msg_id != -1)
|
||||||
|
@ -1347,37 +1462,49 @@ static boolean S_MIDIMusic(const char *mname, boolean looping)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// play it
|
if (I_LoadSong(mdata, W_LumpLength(mlumpnum)))
|
||||||
if (!I_PlaySong(mhandle, looping))
|
{
|
||||||
|
strncpy(music_name, mname, 7);
|
||||||
|
music_name[6] = 0;
|
||||||
|
music_data = mdata;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
strncpy(music_name, mname, 7);
|
|
||||||
music_name[6] = 0;
|
|
||||||
music_lumpnum = mlumpnum;
|
|
||||||
music_data = mdata;
|
|
||||||
music_handle = mhandle;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean S_DigMusic(const char *mname, boolean looping)
|
static void S_UnloadMusic(void)
|
||||||
{
|
{
|
||||||
if (nodigimusic || digital_disabled)
|
I_UnloadSong();
|
||||||
return false; // try midi
|
|
||||||
|
|
||||||
if (!I_StartDigSong(mname, looping))
|
#ifndef HAVE_SDL //SDL uses RWOPS
|
||||||
|
Z_ChangeTag(music_data, PU_CACHE);
|
||||||
|
#endif
|
||||||
|
music_data = NULL;
|
||||||
|
|
||||||
|
music_name[0] = 0;
|
||||||
|
music_flags = 0;
|
||||||
|
music_looping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean S_PlayMusic(boolean looping)
|
||||||
|
{
|
||||||
|
if (S_MusicDisabled())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
strncpy(music_name, mname, 7);
|
if (!I_PlaySong(looping))
|
||||||
music_name[6] = 0;
|
{
|
||||||
music_lumpnum = LUMPERROR;
|
S_UnloadMusic();
|
||||||
music_data = NULL;
|
return false;
|
||||||
music_handle = 0;
|
}
|
||||||
|
|
||||||
|
S_InitMusicVolume(); // switch between digi and sequence volume
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
|
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
|
||||||
{
|
{
|
||||||
if ((nomidimusic || music_disabled) && (nodigimusic || digital_disabled))
|
if (S_MusicDisabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// No Music (empty string)
|
// No Music (empty string)
|
||||||
|
@ -1387,44 +1514,39 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(music_name, mmusic, 6))
|
if (strnicmp(music_name, mmusic, 6))
|
||||||
{
|
{
|
||||||
S_StopMusic(); // shutdown old music
|
S_StopMusic(); // shutdown old music
|
||||||
if (!S_DigMusic(mmusic, looping) && !S_MIDIMusic(mmusic, looping))
|
|
||||||
|
if (!S_LoadMusic(mmusic))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mmusic);
|
CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded!\n", mmusic);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
music_flags = mflags;
|
||||||
|
music_looping = looping;
|
||||||
|
|
||||||
|
if (!S_PlayMusic(looping))
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, "Music %.6s could not be played!\n", mmusic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
I_SetSongTrack(mflags & MUSIC_TRACKMASK);
|
I_SetSongTrack(mflags & MUSIC_TRACKMASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean S_SpeedMusic(float speed)
|
|
||||||
{
|
|
||||||
return I_SetSongSpeed(speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void S_StopMusic(void)
|
void S_StopMusic(void)
|
||||||
{
|
{
|
||||||
if (!music_playing)
|
if (!I_SongPlaying())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mus_paused)
|
if (I_SongPaused())
|
||||||
I_ResumeSong(music_handle);
|
I_ResumeSong();
|
||||||
|
|
||||||
if (!nodigimusic)
|
|
||||||
I_StopDigSong();
|
|
||||||
|
|
||||||
S_SpeedMusic(1.0f);
|
S_SpeedMusic(1.0f);
|
||||||
I_StopSong(music_handle);
|
I_StopSong();
|
||||||
I_UnRegisterSong(music_handle);
|
S_UnloadMusic(); // for now, stopping also means you unload the song
|
||||||
|
|
||||||
#ifndef HAVE_SDL //SDL uses RWOPS
|
|
||||||
Z_ChangeTag(music_data, PU_CACHE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
music_data = NULL;
|
|
||||||
music_name[0] = 0;
|
|
||||||
|
|
||||||
if (cv_closedcaptioning.value)
|
if (cv_closedcaptioning.value)
|
||||||
{
|
{
|
||||||
|
@ -1433,81 +1555,70 @@ void S_StopMusic(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_SetDigMusicVolume(INT32 volume)
|
//
|
||||||
|
// Stop and resume music, during game PAUSE.
|
||||||
|
//
|
||||||
|
void S_PauseAudio(void)
|
||||||
{
|
{
|
||||||
if (volume < 0 || volume > 31)
|
if (I_SongPlaying() && !I_SongPaused())
|
||||||
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
|
I_PauseSong();
|
||||||
|
|
||||||
CV_SetValue(&cv_digmusicvolume, volume&31);
|
// pause cd music
|
||||||
actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var
|
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
|
||||||
|
I_PauseCD();
|
||||||
#ifdef DJGPPDOS
|
#else
|
||||||
I_SetDigMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this.
|
I_StopCD();
|
||||||
#endif
|
#endif
|
||||||
I_SetDigMusicVolume(volume&31);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_SetMIDIMusicVolume(INT32 volume)
|
void S_ResumeAudio(void)
|
||||||
{
|
{
|
||||||
if (volume < 0 || volume > 31)
|
if (I_SongPlaying() && I_SongPaused())
|
||||||
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
|
I_ResumeSong();
|
||||||
|
|
||||||
CV_SetValue(&cv_midimusicvolume, volume&0x1f);
|
// resume cd music
|
||||||
|
I_ResumeCD();
|
||||||
|
}
|
||||||
|
|
||||||
|
void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
|
||||||
|
{
|
||||||
|
if (digvolume < 0)
|
||||||
|
digvolume = cv_digmusicvolume.value;
|
||||||
|
if (seqvolume < 0)
|
||||||
|
seqvolume = cv_midimusicvolume.value;
|
||||||
|
|
||||||
|
if (digvolume < 0 || digvolume > 31)
|
||||||
|
CONS_Alert(CONS_WARNING, "digmusicvolume should be between 0-31\n");
|
||||||
|
CV_SetValue(&cv_digmusicvolume, digvolume&31);
|
||||||
|
actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var
|
||||||
|
|
||||||
|
if (seqvolume < 0 || seqvolume > 31)
|
||||||
|
CONS_Alert(CONS_WARNING, "midimusicvolume should be between 0-31\n");
|
||||||
|
CV_SetValue(&cv_midimusicvolume, seqvolume&31);
|
||||||
actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var
|
actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var
|
||||||
|
|
||||||
#ifdef DJGPPDOS
|
#ifdef DJGPPDOS
|
||||||
I_SetMIDIMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this.
|
digvolume = seqvolume = 31;
|
||||||
#endif
|
#endif
|
||||||
I_SetMIDIMusicVolume(volume&0x1f);
|
|
||||||
|
switch(I_SongType())
|
||||||
|
{
|
||||||
|
case MU_MID:
|
||||||
|
//case MU_MOD:
|
||||||
|
//case MU_GME:
|
||||||
|
I_SetMusicVolume(seqvolume&31);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
I_SetMusicVolume(digvolume&31);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
/// Init & Others
|
/// Init & Others
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
|
||||||
//
|
|
||||||
// Initializes sound stuff, including volume
|
|
||||||
// Sets channels, SFX and music volume,
|
|
||||||
// allocates channel buffer, sets S_sfx lookup.
|
|
||||||
//
|
|
||||||
void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume)
|
|
||||||
{
|
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
if (dedicated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
S_SetSfxVolume(sfxVolume);
|
|
||||||
S_SetDigMusicVolume(digMusicVolume);
|
|
||||||
S_SetMIDIMusicVolume(midiMusicVolume);
|
|
||||||
|
|
||||||
SetChannelsNum();
|
|
||||||
|
|
||||||
// no sounds are playing, and they are not mus_paused
|
|
||||||
mus_paused = 0;
|
|
||||||
|
|
||||||
// Note that sounds have not been cached (yet).
|
|
||||||
for (i = 1; i < NUMSFX; i++)
|
|
||||||
{
|
|
||||||
S_sfx[i].usefulness = -1; // for I_GetSfx()
|
|
||||||
S_sfx[i].lumpnum = LUMPERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// precache sounds if requested by cmdline, or precachesound var true
|
|
||||||
if (!nosound && (M_CheckParm("-precachesound") || precachesound.value))
|
|
||||||
{
|
|
||||||
// Initialize external data (all sounds) at start, keep static.
|
|
||||||
CONS_Printf(M_GetText("Loading sounds... "));
|
|
||||||
|
|
||||||
for (i = 1; i < NUMSFX; i++)
|
|
||||||
if (S_sfx[i].name)
|
|
||||||
S_sfx[i].data = I_GetSfx(&S_sfx[i]);
|
|
||||||
|
|
||||||
CONS_Printf(M_GetText(" pre-cached all sound data\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Per level startup code.
|
// Per level startup code.
|
||||||
// Kills playing sounds at start of level,
|
// Kills playing sounds at start of level,
|
||||||
|
@ -1522,46 +1633,7 @@ void S_Start(void)
|
||||||
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
|
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
mus_paused = 0;
|
|
||||||
|
|
||||||
if (cv_resetmusic.value)
|
if (cv_resetmusic.value)
|
||||||
S_StopMusic();
|
S_StopMusic();
|
||||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
S_ChangeMusic(mapmusname, mapmusflags, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Stop and resume music, during game PAUSE.
|
|
||||||
//
|
|
||||||
void S_PauseAudio(void)
|
|
||||||
{
|
|
||||||
if (!nodigimusic)
|
|
||||||
I_PauseSong(0);
|
|
||||||
|
|
||||||
if (music_playing && !mus_paused)
|
|
||||||
{
|
|
||||||
I_PauseSong(music_handle);
|
|
||||||
mus_paused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pause cd music
|
|
||||||
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
|
|
||||||
I_PauseCD();
|
|
||||||
#else
|
|
||||||
I_StopCD();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void S_ResumeAudio(void)
|
|
||||||
{
|
|
||||||
if (!nodigimusic)
|
|
||||||
I_ResumeSong(0);
|
|
||||||
else
|
|
||||||
if (music_playing && mus_paused)
|
|
||||||
{
|
|
||||||
I_ResumeSong(music_handle);
|
|
||||||
mus_paused = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// resume cd music
|
|
||||||
I_ResumeCD();
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#ifndef __S_SOUND__
|
#ifndef __S_SOUND__
|
||||||
#define __S_SOUND__
|
#define __S_SOUND__
|
||||||
|
|
||||||
|
#include "i_sound.h" // musictype_t
|
||||||
#include "sounds.h"
|
#include "sounds.h"
|
||||||
#include "m_fixed.h"
|
#include "m_fixed.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
@ -97,9 +98,9 @@ void S_RegisterSoundStuff(void);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initializes sound stuff, including volume
|
// Initializes sound stuff, including volume
|
||||||
// Sets channels, SFX and music volume, allocates channel buffer, sets S_sfx lookup.
|
// Sets channels, SFX, allocates channel buffer, sets S_sfx lookup.
|
||||||
//
|
//
|
||||||
void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume);
|
void S_InitSfxChannels(INT32 sfxVolume);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Per level startup code.
|
// Per level startup code.
|
||||||
|
@ -125,6 +126,33 @@ void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume);
|
||||||
// Stop sound for thing at <origin>
|
// Stop sound for thing at <origin>
|
||||||
void S_StopSound(void *origin);
|
void S_StopSound(void *origin);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Music Status
|
||||||
|
//
|
||||||
|
|
||||||
|
boolean S_DigMusicDisabled(void);
|
||||||
|
boolean S_MIDIMusicDisabled(void);
|
||||||
|
boolean S_MusicDisabled(void);
|
||||||
|
boolean S_MusicPlaying(void);
|
||||||
|
boolean S_MusicPaused(void);
|
||||||
|
musictype_t S_MusicType(void);
|
||||||
|
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping);
|
||||||
|
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
|
||||||
|
#define S_DigExists(a) S_MusicExists(a, false, true)
|
||||||
|
#define S_MIDIExists(a) S_MusicExists(a, true, false)
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Music Properties
|
||||||
|
//
|
||||||
|
|
||||||
|
// Set Speed of Music
|
||||||
|
boolean S_SpeedMusic(float speed);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Music Routines
|
||||||
|
//
|
||||||
|
|
||||||
// Start music track, arbitrary, given its name, and set whether looping
|
// Start music track, arbitrary, given its name, and set whether looping
|
||||||
// note: music flags 12 bits for tracknum (gme, other formats with more than one track)
|
// note: music flags 12 bits for tracknum (gme, other formats with more than one track)
|
||||||
// 13-15 aren't used yet
|
// 13-15 aren't used yet
|
||||||
|
@ -132,9 +160,6 @@ void S_StopSound(void *origin);
|
||||||
#define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b)
|
#define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b)
|
||||||
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping);
|
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping);
|
||||||
|
|
||||||
// Set Speed of Music
|
|
||||||
boolean S_SpeedMusic(float speed);
|
|
||||||
|
|
||||||
// Stops the music.
|
// Stops the music.
|
||||||
void S_StopMusic(void);
|
void S_StopMusic(void);
|
||||||
|
|
||||||
|
@ -149,9 +174,11 @@ void S_UpdateSounds(void);
|
||||||
|
|
||||||
FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
|
FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
|
||||||
|
|
||||||
void S_SetDigMusicVolume(INT32 volume);
|
|
||||||
void S_SetMIDIMusicVolume(INT32 volume);
|
|
||||||
void S_SetSfxVolume(INT32 volume);
|
void S_SetSfxVolume(INT32 volume);
|
||||||
|
void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume);
|
||||||
|
#define S_SetDigMusicVolume(a) S_SetMusicVolume(a,-1)
|
||||||
|
#define S_SetMIDIMusicVolume(a) S_SetMusicVolume(-1,a)
|
||||||
|
#define S_InitMusicVolume() S_SetMusicVolume(-1,-1)
|
||||||
|
|
||||||
INT32 S_OriginPlaying(void *origin);
|
INT32 S_OriginPlaying(void *origin);
|
||||||
INT32 S_IdPlaying(sfxenum_t id);
|
INT32 S_IdPlaying(sfxenum_t id);
|
||||||
|
|
|
@ -124,6 +124,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
||||||
#include "macosx/mac_resources.h"
|
#include "macosx/mac_resources.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Locations for searching the srb2.pk3
|
// Locations for searching the srb2.pk3
|
||||||
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
|
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
|
||||||
#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2"
|
#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2"
|
||||||
|
@ -1149,6 +1153,7 @@ static void I_ShutdownJoystick2(void)
|
||||||
D_PostEvent(&event);
|
D_PostEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
joystick2_started = 0;
|
||||||
JoyReset(&JoyInfo2);
|
JoyReset(&JoyInfo2);
|
||||||
if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||||
{
|
{
|
||||||
|
@ -1678,7 +1683,7 @@ static void I_ShutdownMouse2(void)
|
||||||
EscapeCommFunction(mouse2filehandle, CLRRTS);
|
EscapeCommFunction(mouse2filehandle, CLRRTS);
|
||||||
|
|
||||||
PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT |
|
PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT |
|
||||||
PURGE_TXCLEAR | PURGE_RXCLEAR);
|
PURGE_TXCLEAR | PURGE_RXCLEAR);
|
||||||
|
|
||||||
CloseHandle(mouse2filehandle);
|
CloseHandle(mouse2filehandle);
|
||||||
|
|
||||||
|
@ -1871,11 +1876,11 @@ void I_StartupMouse2(void)
|
||||||
{
|
{
|
||||||
// COM file handle
|
// COM file handle
|
||||||
mouse2filehandle = CreateFileA(cv_mouse2port.string, GENERIC_READ | GENERIC_WRITE,
|
mouse2filehandle = CreateFileA(cv_mouse2port.string, GENERIC_READ | GENERIC_WRITE,
|
||||||
0, // exclusive access
|
0, // exclusive access
|
||||||
NULL, // no security attrs
|
NULL, // no security attrs
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL);
|
NULL);
|
||||||
if (mouse2filehandle == INVALID_HANDLE_VALUE)
|
if (mouse2filehandle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
INT32 e = GetLastError();
|
INT32 e = GetLastError();
|
||||||
|
@ -1895,7 +1900,7 @@ void I_StartupMouse2(void)
|
||||||
|
|
||||||
// purge buffers
|
// purge buffers
|
||||||
PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT
|
PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT
|
||||||
| PURGE_TXCLEAR | PURGE_RXCLEAR);
|
| PURGE_TXCLEAR | PURGE_RXCLEAR);
|
||||||
|
|
||||||
// setup port to 1200 7N1
|
// setup port to 1200 7N1
|
||||||
dcb.DCBlength = sizeof (DCB);
|
dcb.DCBlength = sizeof (DCB);
|
||||||
|
@ -2024,7 +2029,7 @@ static void I_ShutdownTimer(void)
|
||||||
tic_t I_GetTime (void)
|
tic_t I_GetTime (void)
|
||||||
{
|
{
|
||||||
static Uint32 basetime = 0;
|
static Uint32 basetime = 0;
|
||||||
Uint32 ticks = SDL_GetTicks();
|
Uint32 ticks = SDL_GetTicks();
|
||||||
|
|
||||||
if (!basetime)
|
if (!basetime)
|
||||||
basetime = ticks;
|
basetime = ticks;
|
||||||
|
@ -2090,7 +2095,6 @@ INT32 I_StartupSystem(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// I_Quit
|
// I_Quit
|
||||||
//
|
//
|
||||||
|
@ -2369,7 +2373,7 @@ void I_GetDiskFreeSpace(INT64 *freespace)
|
||||||
{
|
{
|
||||||
DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
|
DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
|
||||||
GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
|
GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
|
||||||
&NumberOfFreeClusters, &TotalNumberOfClusters);
|
&NumberOfFreeClusters, &TotalNumberOfClusters);
|
||||||
*freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters;
|
*freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters;
|
||||||
}
|
}
|
||||||
#else // Dummy for platform independent; 1GB should be enough
|
#else // Dummy for platform independent; 1GB should be enough
|
||||||
|
@ -2576,22 +2580,22 @@ static const char *locateWad(void)
|
||||||
|
|
||||||
#ifdef CMAKECONFIG
|
#ifdef CMAKECONFIG
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
I_OutputMsg(","CMAKE_ASSETS_DIR);
|
I_OutputMsg(","CMAKE_ASSETS_DIR);
|
||||||
strcpy(returnWadPath, CMAKE_ASSETS_DIR);
|
strcpy(returnWadPath, CMAKE_ASSETS_DIR);
|
||||||
if (isWadPathOk(returnWadPath))
|
if (isWadPathOk(returnWadPath))
|
||||||
{
|
{
|
||||||
return returnWadPath;
|
return returnWadPath;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
OSX_GetResourcesPath(returnWadPath);
|
OSX_GetResourcesPath(returnWadPath);
|
||||||
I_OutputMsg(",%s", returnWadPath);
|
I_OutputMsg(",%s", returnWadPath);
|
||||||
if (isWadPathOk(returnWadPath))
|
if (isWadPathOk(returnWadPath))
|
||||||
{
|
{
|
||||||
return returnWadPath;
|
return returnWadPath;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// examine default dirs
|
// examine default dirs
|
||||||
|
@ -2696,7 +2700,30 @@ const char *I_LocateWad(void)
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#define MEMINFO_FILE "/proc/meminfo"
|
#define MEMINFO_FILE "/proc/meminfo"
|
||||||
#define MEMTOTAL "MemTotal:"
|
#define MEMTOTAL "MemTotal:"
|
||||||
|
#define MEMAVAILABLE "MemAvailable:"
|
||||||
#define MEMFREE "MemFree:"
|
#define MEMFREE "MemFree:"
|
||||||
|
#define CACHED "Cached:"
|
||||||
|
#define BUFFERS "Buffers:"
|
||||||
|
#define SHMEM "Shmem:"
|
||||||
|
|
||||||
|
/* Parse the contents of /proc/meminfo (in buf), return value of "name"
|
||||||
|
* (example: MemTotal) */
|
||||||
|
static long get_entry(const char* name, const char* buf)
|
||||||
|
{
|
||||||
|
long val;
|
||||||
|
char* hit = strstr(buf, name);
|
||||||
|
if (hit == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
val = strtol(hit + strlen(name), NULL, 10);
|
||||||
|
if (errno != 0) {
|
||||||
|
CONS_Alert(CONS_ERROR, M_GetText("get_entry: strtol() failed: %s\n"), strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// quick fix for compil
|
// quick fix for compil
|
||||||
|
@ -2758,6 +2785,11 @@ UINT32 I_GetFreeMem(UINT32 *total)
|
||||||
UINT32 totalKBytes;
|
UINT32 totalKBytes;
|
||||||
INT32 n;
|
INT32 n;
|
||||||
INT32 meminfo_fd = -1;
|
INT32 meminfo_fd = -1;
|
||||||
|
long Cached;
|
||||||
|
long MemFree;
|
||||||
|
long Buffers;
|
||||||
|
long Shmem;
|
||||||
|
long MemAvailable = -1;
|
||||||
|
|
||||||
meminfo_fd = open(MEMINFO_FILE, O_RDONLY);
|
meminfo_fd = open(MEMINFO_FILE, O_RDONLY);
|
||||||
n = read(meminfo_fd, buf, 1023);
|
n = read(meminfo_fd, buf, 1023);
|
||||||
|
@ -2783,16 +2815,28 @@ UINT32 I_GetFreeMem(UINT32 *total)
|
||||||
memTag += sizeof (MEMTOTAL);
|
memTag += sizeof (MEMTOTAL);
|
||||||
totalKBytes = atoi(memTag);
|
totalKBytes = atoi(memTag);
|
||||||
|
|
||||||
if ((memTag = strstr(buf, MEMFREE)) == NULL)
|
if ((memTag = strstr(buf, MEMAVAILABLE)) == NULL)
|
||||||
{
|
{
|
||||||
// Error
|
Cached = get_entry(CACHED, buf);
|
||||||
if (total)
|
MemFree = get_entry(MEMFREE, buf);
|
||||||
*total = 0L;
|
Buffers = get_entry(BUFFERS, buf);
|
||||||
return 0;
|
Shmem = get_entry(SHMEM, buf);
|
||||||
}
|
MemAvailable = Cached + MemFree + Buffers - Shmem;
|
||||||
|
|
||||||
memTag += sizeof (MEMFREE);
|
if (MemAvailable == -1)
|
||||||
freeKBytes = atoi(memTag);
|
{
|
||||||
|
// Error
|
||||||
|
if (total)
|
||||||
|
*total = 0L;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
freeKBytes = MemAvailable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memTag += sizeof (MEMAVAILABLE);
|
||||||
|
freeKBytes = atoi(memTag);
|
||||||
|
}
|
||||||
|
|
||||||
if (total)
|
if (total)
|
||||||
*total = totalKBytes << 10;
|
*total = totalKBytes << 10;
|
||||||
|
|
|
@ -566,7 +566,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
||||||
// Tell game we got focus back, resume music if necessary
|
// Tell game we got focus back, resume music if necessary
|
||||||
window_notinfocus = false;
|
window_notinfocus = false;
|
||||||
if (!paused)
|
if (!paused)
|
||||||
I_ResumeSong(0); //resume it
|
I_ResumeSong(); //resume it
|
||||||
|
|
||||||
if (!firsttimeonmouse)
|
if (!firsttimeonmouse)
|
||||||
{
|
{
|
||||||
|
@ -578,7 +578,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
||||||
{
|
{
|
||||||
// Tell game we lost focus, pause music
|
// Tell game we lost focus, pause music
|
||||||
window_notinfocus = true;
|
window_notinfocus = true;
|
||||||
I_PauseSong(0);
|
I_PauseSong();
|
||||||
|
|
||||||
if (!disable_mouse)
|
if (!disable_mouse)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,14 +34,18 @@
|
||||||
(SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z))
|
(SDL_MIXER_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// thanks alam for making the buildbots happy!
|
||||||
|
#if SDL_MIXER_VERSION_ATLEAST(2,0,2)
|
||||||
|
#define MUS_MP3_MAD MUS_MP3_MAD_UNUSED
|
||||||
|
#define MUS_MODPLUG MUS_MODPLUG_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
#include "gme/gme.h"
|
#include "gme/gme.h"
|
||||||
#define GME_TREBLE 5.0
|
#define GME_TREBLE 5.0
|
||||||
#define GME_BASS 1.0
|
#define GME_BASS 1.0
|
||||||
#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng
|
|
||||||
|
|
||||||
#define HAVE_ZLIB
|
|
||||||
|
|
||||||
|
#ifdef HAVE_ZLIB
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#ifndef _LARGEFILE64_SOURCE
|
#ifndef _LARGEFILE64_SOURCE
|
||||||
#define _LARGEFILE64_SOURCE
|
#define _LARGEFILE64_SOURCE
|
||||||
|
@ -57,14 +61,13 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
#endif
|
#endif // HAVE_ZLIB
|
||||||
#endif
|
#endif // HAVE_LIBGME
|
||||||
|
|
||||||
UINT8 sound_started = false;
|
UINT8 sound_started = false;
|
||||||
|
|
||||||
static boolean midimode;
|
|
||||||
static Mix_Music *music;
|
static Mix_Music *music;
|
||||||
static UINT8 music_volume, midi_volume, sfx_volume;
|
static UINT8 music_volume, sfx_volume;
|
||||||
static float loop_point;
|
static float loop_point;
|
||||||
static boolean songpaused;
|
static boolean songpaused;
|
||||||
|
|
||||||
|
@ -73,13 +76,20 @@ static Music_Emu *gme;
|
||||||
static INT32 current_track;
|
static INT32 current_track;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// Audio System
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
void I_StartupSound(void)
|
void I_StartupSound(void)
|
||||||
{
|
{
|
||||||
I_Assert(!sound_started);
|
I_Assert(!sound_started);
|
||||||
|
|
||||||
// EE inits audio first so we're following along.
|
// EE inits audio first so we're following along.
|
||||||
if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO)
|
if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO)
|
||||||
CONS_Printf("SDL Audio already started\n");
|
{
|
||||||
|
CONS_Debug(DBG_DETAILED, "SDL Audio already started\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
|
else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, "Error initializing SDL Audio: %s\n", SDL_GetError());
|
CONS_Alert(CONS_ERROR, "Error initializing SDL Audio: %s\n", SDL_GetError());
|
||||||
|
@ -87,9 +97,8 @@ void I_StartupSound(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
midimode = false;
|
|
||||||
music = NULL;
|
music = NULL;
|
||||||
music_volume = midi_volume = sfx_volume = 0;
|
music_volume = sfx_volume = 0;
|
||||||
|
|
||||||
#if SDL_MIXER_VERSION_ATLEAST(1,2,11)
|
#if SDL_MIXER_VERSION_ATLEAST(1,2,11)
|
||||||
Mix_Init(MIX_INIT_FLAC|MIX_INIT_MOD|MIX_INIT_MP3|MIX_INIT_OGG);
|
Mix_Init(MIX_INIT_FLAC|MIX_INIT_MOD|MIX_INIT_MP3|MIX_INIT_OGG);
|
||||||
|
@ -130,6 +139,10 @@ FUNCMATH void I_UpdateSound(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// SFX
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
// this is as fast as I can possibly make it.
|
// this is as fast as I can possibly make it.
|
||||||
// sorry. more asm needed.
|
// sorry. more asm needed.
|
||||||
static Mix_Chunk *ds2chunk(void *stream)
|
static Mix_Chunk *ds2chunk(void *stream)
|
||||||
|
@ -178,7 +191,7 @@ static Mix_Chunk *ds2chunk(void *stream)
|
||||||
return NULL; // would and/or did wrap, can't store.
|
return NULL; // would and/or did wrap, can't store.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sound = malloc(newsamples<<2); // samples * frequency shift * bytes per sample * channels
|
sound = Z_Malloc(newsamples<<2, PU_SOUND, NULL); // samples * frequency shift * bytes per sample * channels
|
||||||
|
|
||||||
s = (SINT8 *)stream;
|
s = (SINT8 *)stream;
|
||||||
d = (INT16 *)sound;
|
d = (INT16 *)sound;
|
||||||
|
@ -246,6 +259,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
|
||||||
{
|
{
|
||||||
void *lump;
|
void *lump;
|
||||||
Mix_Chunk *chunk;
|
Mix_Chunk *chunk;
|
||||||
|
SDL_RWops *rw;
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
Music_Emu *emu;
|
Music_Emu *emu;
|
||||||
gme_info_t *info;
|
gme_info_t *info;
|
||||||
|
@ -361,7 +375,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
|
||||||
}
|
}
|
||||||
Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
|
Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
|
||||||
#else
|
#else
|
||||||
//CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
|
return NULL; // No zlib support
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// Try to read it as a GME sound
|
// Try to read it as a GME sound
|
||||||
|
@ -387,21 +401,43 @@ void *I_GetSfx(sfxinfo_t *sfx)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Try to load it as a WAVE or OGG using Mixer.
|
// Try to load it as a WAVE or OGG using Mixer.
|
||||||
return Mix_LoadWAV_RW(SDL_RWFromMem(lump, sfx->length), 1);
|
rw = SDL_RWFromMem(lump, sfx->length);
|
||||||
|
if (rw != NULL)
|
||||||
|
{
|
||||||
|
chunk = Mix_LoadWAV_RW(rw, 1);
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL; // haven't been able to get anything
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_FreeSfx(sfxinfo_t *sfx)
|
void I_FreeSfx(sfxinfo_t *sfx)
|
||||||
{
|
{
|
||||||
if (sfx->data)
|
if (sfx->data)
|
||||||
|
{
|
||||||
|
Mix_Chunk *chunk = (Mix_Chunk*)sfx->data;
|
||||||
|
UINT8 *abufdata = NULL;
|
||||||
|
if (chunk->allocated == 0)
|
||||||
|
{
|
||||||
|
// We allocated the data in this chunk, so get the abuf from mixer, then let it free the chunk, THEN we free the data
|
||||||
|
// I believe this should ensure the sound is not playing when we free it
|
||||||
|
abufdata = chunk->abuf;
|
||||||
|
}
|
||||||
Mix_FreeChunk(sfx->data);
|
Mix_FreeChunk(sfx->data);
|
||||||
|
if (abufdata)
|
||||||
|
{
|
||||||
|
// I'm going to assume we used Z_Malloc to allocate this data.
|
||||||
|
Z_Free(abufdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
sfx->data = NULL;
|
sfx->data = NULL;
|
||||||
sfx->lumpnum = LUMPERROR;
|
sfx->lumpnum = LUMPERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
|
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
|
||||||
{
|
{
|
||||||
UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
|
UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
|
||||||
INT32 handle = Mix_PlayChannel(-1, S_sfx[id].data, 0);
|
INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0);
|
||||||
Mix_Volume(handle, volume);
|
Mix_Volume(handle, volume);
|
||||||
Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
|
Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
|
||||||
(void)pitch; // Mixer can't handle pitch
|
(void)pitch; // Mixer can't handle pitch
|
||||||
|
@ -432,11 +468,10 @@ void I_SetSfxVolume(UINT8 volume)
|
||||||
sfx_volume = volume;
|
sfx_volume = volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/// ------------------------
|
||||||
// Music
|
/// Music Hooks
|
||||||
//
|
/// ------------------------
|
||||||
|
|
||||||
// Music hooks
|
|
||||||
static void music_loop(void)
|
static void music_loop(void)
|
||||||
{
|
{
|
||||||
Mix_PlayMusic(music, 0);
|
Mix_PlayMusic(music, 0);
|
||||||
|
@ -464,78 +499,101 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// Music System
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
FUNCMATH void I_InitMusic(void)
|
FUNCMATH void I_InitMusic(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_ShutdownMusic(void)
|
void I_ShutdownMusic(void)
|
||||||
{
|
{
|
||||||
I_ShutdownDigMusic();
|
I_UnloadSong();
|
||||||
I_ShutdownMIDIMusic();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_PauseSong(INT32 handle)
|
/// ------------------------
|
||||||
{
|
/// Music Properties
|
||||||
(void)handle;
|
/// ------------------------
|
||||||
Mix_PauseMusic();
|
|
||||||
songpaused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_ResumeSong(INT32 handle)
|
musictype_t I_SongType(void)
|
||||||
{
|
|
||||||
(void)handle;
|
|
||||||
Mix_ResumeMusic();
|
|
||||||
songpaused = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Digital Music
|
|
||||||
//
|
|
||||||
|
|
||||||
void I_InitDigMusic(void)
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
gme = NULL;
|
if (gme)
|
||||||
current_track = -1;
|
return MU_GME;
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
if (!music)
|
||||||
|
return MU_NONE;
|
||||||
|
else if (Mix_GetMusicType(music) == MUS_MID)
|
||||||
|
return MU_MID;
|
||||||
|
else if (Mix_GetMusicType(music) == MUS_MOD || Mix_GetMusicType(music) == MUS_MODPLUG)
|
||||||
|
return MU_MOD;
|
||||||
|
else if (Mix_GetMusicType(music) == MUS_MP3 || Mix_GetMusicType(music) == MUS_MP3_MAD)
|
||||||
|
return MU_MP3;
|
||||||
|
else
|
||||||
|
return (musictype_t)Mix_GetMusicType(music);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_ShutdownDigMusic(void)
|
boolean I_SongPlaying(void)
|
||||||
{
|
{
|
||||||
if (midimode)
|
return (
|
||||||
return;
|
#ifdef HAVE_LIBGME
|
||||||
|
(I_SongType() == MU_GME && gme) ||
|
||||||
|
#endif
|
||||||
|
(boolean)music
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SongPaused(void)
|
||||||
|
{
|
||||||
|
return songpaused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// Music Effects
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
boolean I_SetSongSpeed(float speed)
|
||||||
|
{
|
||||||
|
if (speed > 250.0f)
|
||||||
|
speed = 250.0f; //limit speed up to 250x
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
if (gme)
|
if (gme)
|
||||||
{
|
{
|
||||||
Mix_HookMusic(NULL, NULL);
|
SDL_LockAudio();
|
||||||
gme_delete(gme);
|
gme_set_tempo(gme, speed);
|
||||||
gme = NULL;
|
SDL_UnlockAudio();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void)speed;
|
||||||
#endif
|
#endif
|
||||||
if (!music)
|
return false;
|
||||||
return;
|
|
||||||
Mix_HookMusicFinished(NULL);
|
|
||||||
Mix_FreeMusic(music);
|
|
||||||
music = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean I_StartDigSong(const char *musicname, boolean looping)
|
/// ------------------------
|
||||||
|
/// Music Playback
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
boolean I_LoadSong(char *data, size_t len)
|
||||||
{
|
{
|
||||||
char *data;
|
const char *key1 = "LOOP";
|
||||||
size_t len;
|
const char *key2 = "POINT=";
|
||||||
lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname));
|
const char *key3 = "MS=";
|
||||||
|
const size_t key1len = strlen(key1);
|
||||||
|
const size_t key2len = strlen(key2);
|
||||||
|
const size_t key3len = strlen(key3);
|
||||||
|
char *p = data;
|
||||||
|
SDL_RWops *rw;
|
||||||
|
|
||||||
I_Assert(!music);
|
if (music
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
I_Assert(!gme);
|
|| gme
|
||||||
#endif
|
#endif
|
||||||
|
)
|
||||||
if (lumpnum == LUMPERROR)
|
I_UnloadSong();
|
||||||
return false;
|
|
||||||
midimode = false;
|
|
||||||
|
|
||||||
data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC);
|
|
||||||
len = W_LumpLength(lumpnum);
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
if ((UINT8)data[0] == 0x1F
|
if ((UINT8)data[0] == 0x1F
|
||||||
|
@ -621,66 +679,95 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
}
|
}
|
||||||
Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
|
Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
|
||||||
#else
|
#else
|
||||||
//CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
|
CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
|
||||||
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (!gme_open_data(data, len, &gme, 44100))
|
else if (!gme_open_data(data, len, &gme, 44100))
|
||||||
{
|
{
|
||||||
gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
|
gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
|
||||||
gme_start_track(gme, 0);
|
|
||||||
current_track = 0;
|
|
||||||
gme_set_equalizer(gme, &eq);
|
gme_set_equalizer(gme, &eq);
|
||||||
Mix_HookMusic(mix_gme, gme);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE);
|
rw = SDL_RWFromMem(data, len);
|
||||||
|
if (rw != NULL)
|
||||||
|
{
|
||||||
|
music = Mix_LoadMUS_RW(rw, 1);
|
||||||
|
}
|
||||||
if (!music)
|
if (!music)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
|
CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the OGG loop point.
|
// Find the OGG loop point.
|
||||||
loop_point = 0.0f;
|
loop_point = 0.0f;
|
||||||
if (looping)
|
|
||||||
|
while ((UINT32)(p - data) < len)
|
||||||
{
|
{
|
||||||
const char *key1 = "LOOP";
|
if (strncmp(p++, key1, key1len))
|
||||||
const char *key2 = "POINT=";
|
continue;
|
||||||
const char *key3 = "MS=";
|
p += key1len-1; // skip OOP (the L was skipped in strncmp)
|
||||||
const size_t key1len = strlen(key1);
|
if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
|
||||||
const size_t key2len = strlen(key2);
|
|
||||||
const size_t key3len = strlen(key3);
|
|
||||||
char *p = data;
|
|
||||||
while ((UINT32)(p - data) < len)
|
|
||||||
{
|
{
|
||||||
if (strncmp(p++, key1, key1len))
|
p += key2len; // skip POINT=
|
||||||
continue;
|
loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count.
|
||||||
p += key1len-1; // skip OOP (the L was skipped in strncmp)
|
// because SDL_Mixer is USELESS and can't even tell us
|
||||||
if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
|
// something simple like the frequency of the streaming music,
|
||||||
{
|
// we are unfortunately forced to assume that ALL MUSIC is 44100hz.
|
||||||
p += key2len; // skip POINT=
|
// This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly.
|
||||||
loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count.
|
|
||||||
// because SDL_Mixer is USELESS and can't even tell us
|
|
||||||
// something simple like the frequency of the streaming music,
|
|
||||||
// we are unfortunately forced to assume that ALL MUSIC is 44100hz.
|
|
||||||
// This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly.
|
|
||||||
}
|
|
||||||
else if (!strncmp(p, key3, key3len)) // is it LOOPMS=?
|
|
||||||
{
|
|
||||||
p += key3len; // skip MS=
|
|
||||||
loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds.
|
|
||||||
// Everything that uses LOOPMS will work perfectly with SDL_Mixer.
|
|
||||||
}
|
|
||||||
// Neither?! Continue searching.
|
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(p, key3, key3len)) // is it LOOPMS=?
|
||||||
|
{
|
||||||
|
p += key3len; // skip MS=
|
||||||
|
loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds.
|
||||||
|
// Everything that uses LOOPMS will work perfectly with SDL_Mixer.
|
||||||
|
}
|
||||||
|
// Neither?! Continue searching.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_UnloadSong(void)
|
||||||
|
{
|
||||||
|
I_StopSong();
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGME
|
||||||
|
if (gme)
|
||||||
|
{
|
||||||
|
gme_delete(gme);
|
||||||
|
gme = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (music)
|
||||||
|
{
|
||||||
|
Mix_FreeMusic(music);
|
||||||
|
music = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_PlaySong(boolean looping)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LIBGME
|
||||||
|
if (gme)
|
||||||
|
{
|
||||||
|
gme_start_track(gme, 0);
|
||||||
|
current_track = 0;
|
||||||
|
Mix_HookMusic(mix_gme, gme);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (!music)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1)
|
if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
|
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
Mix_VolumeMusic((UINT32)music_volume*128/31);
|
Mix_VolumeMusic((UINT32)music_volume*128/31);
|
||||||
|
|
||||||
|
@ -689,51 +776,49 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_StopDigSong(void)
|
void I_StopSong(void)
|
||||||
{
|
{
|
||||||
if (midimode)
|
|
||||||
return;
|
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
if (gme)
|
if (gme)
|
||||||
{
|
{
|
||||||
Mix_HookMusic(NULL, NULL);
|
Mix_HookMusic(NULL, NULL);
|
||||||
gme_delete(gme);
|
|
||||||
gme = NULL;
|
|
||||||
current_track = -1;
|
current_track = -1;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!music)
|
if (music)
|
||||||
return;
|
|
||||||
Mix_HookMusicFinished(NULL);
|
|
||||||
Mix_FreeMusic(music);
|
|
||||||
music = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_SetDigMusicVolume(UINT8 volume)
|
|
||||||
{
|
|
||||||
music_volume = volume;
|
|
||||||
if (midimode || !music)
|
|
||||||
return;
|
|
||||||
Mix_VolumeMusic((UINT32)volume*128/31);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_SetSongSpeed(float speed)
|
|
||||||
{
|
|
||||||
if (speed > 250.0f)
|
|
||||||
speed = 250.0f; //limit speed up to 250x
|
|
||||||
#ifdef HAVE_LIBGME
|
|
||||||
if (gme)
|
|
||||||
{
|
{
|
||||||
SDL_LockAudio();
|
Mix_HookMusicFinished(NULL);
|
||||||
gme_set_tempo(gme, speed);
|
Mix_HaltMusic();
|
||||||
SDL_UnlockAudio();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
#else
|
}
|
||||||
(void)speed;
|
|
||||||
|
void I_PauseSong(void)
|
||||||
|
{
|
||||||
|
Mix_PauseMusic();
|
||||||
|
songpaused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ResumeSong(void)
|
||||||
|
{
|
||||||
|
Mix_ResumeMusic();
|
||||||
|
songpaused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_SetMusicVolume(UINT8 volume)
|
||||||
|
{
|
||||||
|
if (!I_SongPlaying())
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (I_SongType() == MU_MID)
|
||||||
|
// HACK: Until we stop using native MIDI,
|
||||||
|
// disable volume changes
|
||||||
|
music_volume = 31;
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
return false;
|
music_volume = volume;
|
||||||
|
|
||||||
|
Mix_VolumeMusic((UINT32)music_volume*128/31);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean I_SetSongTrack(int track)
|
boolean I_SetSongTrack(int track)
|
||||||
|
@ -767,79 +852,4 @@ boolean I_SetSongTrack(int track)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
#endif
|
||||||
// MIDI Music
|
|
||||||
//
|
|
||||||
|
|
||||||
FUNCMATH void I_InitMIDIMusic(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_ShutdownMIDIMusic(void)
|
|
||||||
{
|
|
||||||
if (!midimode || !music)
|
|
||||||
return;
|
|
||||||
Mix_FreeMusic(music);
|
|
||||||
music = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_SetMIDIMusicVolume(UINT8 volume)
|
|
||||||
{
|
|
||||||
// HACK: Until we stop using native MIDI,
|
|
||||||
// disable volume changes
|
|
||||||
(void)volume;
|
|
||||||
midi_volume = 31;
|
|
||||||
//midi_volume = volume;
|
|
||||||
|
|
||||||
if (!midimode || !music)
|
|
||||||
return;
|
|
||||||
Mix_VolumeMusic((UINT32)midi_volume*128/31);
|
|
||||||
}
|
|
||||||
|
|
||||||
INT32 I_RegisterSong(void *data, size_t len)
|
|
||||||
{
|
|
||||||
music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE);
|
|
||||||
if (!music)
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1337;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_PlaySong(INT32 handle, boolean looping)
|
|
||||||
{
|
|
||||||
(void)handle;
|
|
||||||
|
|
||||||
midimode = true;
|
|
||||||
|
|
||||||
if (Mix_PlayMusic(music, looping ? -1 : 0) == -1)
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mix_VolumeMusic((UINT32)midi_volume*128/31);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_StopSong(INT32 handle)
|
|
||||||
{
|
|
||||||
if (!midimode || !music)
|
|
||||||
return;
|
|
||||||
|
|
||||||
(void)handle;
|
|
||||||
Mix_HaltMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_UnRegisterSong(INT32 handle)
|
|
||||||
{
|
|
||||||
if (!midimode || !music)
|
|
||||||
return;
|
|
||||||
|
|
||||||
(void)handle;
|
|
||||||
Mix_FreeMusic(music);
|
|
||||||
music = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -194,8 +194,8 @@ static srb2audio_t localdata;
|
||||||
static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio callback
|
static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio callback
|
||||||
{
|
{
|
||||||
if (Snd_Mutex) SDL_LockMutex(Snd_Mutex);
|
if (Snd_Mutex) SDL_LockMutex(Snd_Mutex);
|
||||||
else if (nosound) return;
|
else if (sound_disabled) return;
|
||||||
else if (nomidimusic && nodigimusic
|
else if (midi_disabled && digital_disabled
|
||||||
#ifdef HW3SOUND
|
#ifdef HW3SOUND
|
||||||
&& hws_mode == HWS_DEFAULT_MODE
|
&& hws_mode == HWS_DEFAULT_MODE
|
||||||
#endif
|
#endif
|
||||||
|
@ -208,8 +208,8 @@ static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio call
|
||||||
static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio callback
|
static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio callback
|
||||||
{
|
{
|
||||||
if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex);
|
if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex);
|
||||||
else if (nosound) return;
|
else if (sound_disabled) return;
|
||||||
else if (nomidimusic && nodigimusic
|
else if (midi_disabled && digital_disabled
|
||||||
#ifdef HW3SOUND
|
#ifdef HW3SOUND
|
||||||
&& hws_mode == HWS_DEFAULT_MODE
|
&& hws_mode == HWS_DEFAULT_MODE
|
||||||
#endif
|
#endif
|
||||||
|
@ -493,7 +493,7 @@ static inline void I_SetChannels(void)
|
||||||
|
|
||||||
INT32 *steptablemid = steptable + 128;
|
INT32 *steptablemid = steptable + 128;
|
||||||
|
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// This table provides step widths for pitch parameters.
|
// This table provides step widths for pitch parameters.
|
||||||
|
@ -604,12 +604,13 @@ void I_FreeSfx(sfxinfo_t * sfx)
|
||||||
// Pitching (that is, increased speed of playback)
|
// Pitching (that is, increased speed of playback)
|
||||||
// is set, but currently not used by mixing.
|
// is set, but currently not used by mixing.
|
||||||
//
|
//
|
||||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
|
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
|
||||||
{
|
{
|
||||||
(void)priority;
|
(void)priority;
|
||||||
(void)pitch;
|
(void)pitch;
|
||||||
|
(void)channel;
|
||||||
|
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (S_sfx[id].data == NULL) return -1;
|
if (S_sfx[id].data == NULL) return -1;
|
||||||
|
@ -989,7 +990,7 @@ FUNCINLINE static ATTRINLINE void I_UpdateStream16M(Uint8 *stream, int len)
|
||||||
if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex);
|
if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBGME
|
#if 0 //#ifdef HAVE_LIBGME
|
||||||
static void I_UpdateSteamGME(Music_Emu *emu, INT16 *stream, int len, UINT8 looping)
|
static void I_UpdateSteamGME(Music_Emu *emu, INT16 *stream, int len, UINT8 looping)
|
||||||
{
|
{
|
||||||
#define GME_BUFFER_LEN 44100*2048
|
#define GME_BUFFER_LEN 44100*2048
|
||||||
|
@ -1049,14 +1050,16 @@ static void SDLCALL I_UpdateStream(void *userdata, Uint8 *stream, int len)
|
||||||
else if (audio.channels == 2 && audio.format == AUDIO_S16SYS)
|
else if (audio.channels == 2 && audio.format == AUDIO_S16SYS)
|
||||||
{
|
{
|
||||||
I_UpdateStream16S(stream, len);
|
I_UpdateStream16S(stream, len);
|
||||||
#ifdef HAVE_LIBGME
|
|
||||||
if (userdata)
|
// Crashes! But no matter; this build doesn't play music anyway...
|
||||||
{
|
// #ifdef HAVE_LIBGME
|
||||||
srb2audio_t *sa_userdata = userdata;
|
// if (userdata)
|
||||||
if (!sa_userdata->gme_pause)
|
// {
|
||||||
I_UpdateSteamGME(sa_userdata->gme_emu, (INT16 *)stream, len/4, sa_userdata->gme_loop);
|
// srb2audio_t *sa_userdata = userdata;
|
||||||
}
|
// if (!sa_userdata->gme_pause)
|
||||||
#endif
|
// I_UpdateSteamGME(sa_userdata->gme_emu, (INT16 *)stream, len/4, sa_userdata->gme_loop);
|
||||||
|
// }
|
||||||
|
// #endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1136,7 +1139,7 @@ static INT32 Init3DSDriver(const char *soName)
|
||||||
|
|
||||||
void I_ShutdownSound(void)
|
void I_ShutdownSound(void)
|
||||||
{
|
{
|
||||||
if (nosound || !sound_started)
|
if (sound_disabled || !sound_started)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CONS_Printf("I_ShutdownSound: ");
|
CONS_Printf("I_ShutdownSound: ");
|
||||||
|
@ -1150,7 +1153,7 @@ void I_ShutdownSound(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (nomidimusic && nodigimusic)
|
if (midi_disabled && digital_disabled)
|
||||||
SDL_CloseAudio();
|
SDL_CloseAudio();
|
||||||
CONS_Printf("%s", M_GetText("shut down\n"));
|
CONS_Printf("%s", M_GetText("shut down\n"));
|
||||||
sound_started = false;
|
sound_started = false;
|
||||||
|
@ -1170,7 +1173,7 @@ void I_StartupSound(void)
|
||||||
const char *sdrv_name = NULL;
|
const char *sdrv_name = NULL;
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_MIXER
|
#ifndef HAVE_MIXER
|
||||||
nomidimusic = nodigimusic = true;
|
midi_disabled = digital_disabled = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memset(channels, 0, sizeof (channels)); //Alam: Clean it
|
memset(channels, 0, sizeof (channels)); //Alam: Clean it
|
||||||
|
@ -1213,7 +1216,7 @@ void I_StartupSound(void)
|
||||||
audio.samples /= 2;
|
audio.samples /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nosound)
|
if (sound_disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef HW3SOUND
|
#ifdef HW3SOUND
|
||||||
|
@ -1261,7 +1264,7 @@ void I_StartupSound(void)
|
||||||
{
|
{
|
||||||
snddev_t snddev;
|
snddev_t snddev;
|
||||||
|
|
||||||
//nosound = true;
|
//sound_disabled = true;
|
||||||
//I_AddExitFunc(I_ShutdownSound);
|
//I_AddExitFunc(I_ShutdownSound);
|
||||||
snddev.bps = 16;
|
snddev.bps = 16;
|
||||||
snddev.sample_rate = audio.freq;
|
snddev.sample_rate = audio.freq;
|
||||||
|
@ -1288,7 +1291,7 @@ void I_StartupSound(void)
|
||||||
if (!musicStarted && SDL_OpenAudio(&audio, &audio) < 0)
|
if (!musicStarted && SDL_OpenAudio(&audio, &audio) < 0)
|
||||||
{
|
{
|
||||||
CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n"));
|
CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n"));
|
||||||
nosound = true;
|
sound_disabled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1313,13 +1316,11 @@ void I_StartupSound(void)
|
||||||
// MUSIC API.
|
// MUSIC API.
|
||||||
//
|
//
|
||||||
|
|
||||||
void I_ShutdownMIDIMusic(void)
|
/// ------------------------
|
||||||
{
|
// MUSIC SYSTEM
|
||||||
nomidimusic = false;
|
/// ------------------------
|
||||||
if (nodigimusic) I_ShutdownMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBGME
|
#if 0 //#ifdef HAVE_LIBGME
|
||||||
static void I_ShutdownGMEMusic(void)
|
static void I_ShutdownGMEMusic(void)
|
||||||
{
|
{
|
||||||
Snd_LockAudio();
|
Snd_LockAudio();
|
||||||
|
@ -1330,390 +1331,126 @@ static void I_ShutdownGMEMusic(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void I_ShutdownDigMusic(void)
|
|
||||||
{
|
|
||||||
nodigimusic = false;
|
|
||||||
if (nomidimusic) I_ShutdownMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
static boolean LoadSong(void *data, size_t lumplength, size_t selectpos)
|
|
||||||
{
|
|
||||||
FILE *midfile;
|
|
||||||
const char *tempname;
|
|
||||||
#ifdef USE_RWOPS
|
|
||||||
if (canuseRW)
|
|
||||||
{
|
|
||||||
SDL_RWops *SDLRW;
|
|
||||||
void *olddata = Smidi[selectpos]; //quick shortcut to set
|
|
||||||
|
|
||||||
Z_Free(olddata); //free old memory
|
|
||||||
Smidi[selectpos] = NULL;
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return olddata != NULL; //was there old data?
|
|
||||||
|
|
||||||
SDLRW = SDL_RWFromConstMem(data, (int)lumplength); //new RWops from Z_zone
|
|
||||||
if (!SDLRW) //ERROR while making RWops!
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("Couldn't load music lump: %s\n"), SDL_GetError());
|
|
||||||
Z_Free(data);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
music[selectpos] = Mix_LoadMUS_RW(SDLRW); // new Mix_Chuck from RWops
|
|
||||||
if (music[selectpos])
|
|
||||||
Smidi[selectpos] = data; //all done
|
|
||||||
else //ERROR while making Mix_Chuck
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("Couldn't load music data: %s\n"), Mix_GetError());
|
|
||||||
Z_Free(data);
|
|
||||||
SDL_RWclose(SDLRW);
|
|
||||||
Smidi[selectpos] = NULL;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
tempname = va("%s/%s", MIDI_PATH, fmidi[selectpos]);
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
if (FIL_FileExists(tempname))
|
|
||||||
return unlink(tempname)+1;
|
|
||||||
#ifdef MIDI_PATH2
|
|
||||||
else if (FIL_FileExists(tempname = va("%s/%s", MIDI_PATH2, fmidi[selectpos])))
|
|
||||||
return unlink(tempname)+1;
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
midfile = fopen(tempname, "wb");
|
|
||||||
|
|
||||||
#ifdef MIDI_PATH2
|
|
||||||
if (!midfile)
|
|
||||||
{
|
|
||||||
tempname = va("%s/%s", MIDI_PATH2, fmidi[selectpos]);
|
|
||||||
midfile = fopen(tempname, "wb");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!midfile)
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("Couldn't open file %s to write music in\n"), tempname);
|
|
||||||
Z_Free(data);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fwrite(data, lumplength, 1, midfile) == 0)
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("Couldn't write music into file %s because %s\n"), tempname, strerror(ferror(midfile)));
|
|
||||||
Z_Free(data);
|
|
||||||
fclose(midfile);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(midfile);
|
|
||||||
|
|
||||||
Z_Free(data);
|
|
||||||
|
|
||||||
music[selectpos] = Mix_LoadMUS(tempname);
|
|
||||||
if (!music[selectpos]) //ERROR while making Mix_Chuck
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText("Couldn't load music file %s: %s\n"), tempname, Mix_GetError());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void I_ShutdownMusic(void)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
if ((nomidimusic && nodigimusic) || !musicStarted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CONS_Printf("%s", M_GetText("I_ShutdownMusic: "));
|
|
||||||
|
|
||||||
I_UnRegisterSong(0);
|
|
||||||
I_StopDigSong();
|
|
||||||
Mix_CloseAudio();
|
|
||||||
#ifdef MIX_INIT
|
|
||||||
Mix_Quit();
|
|
||||||
#endif
|
|
||||||
CONS_Printf("%s", M_GetText("shut down\n"));
|
|
||||||
musicStarted = SDL_FALSE;
|
|
||||||
if (Msc_Mutex)
|
|
||||||
SDL_DestroyMutex(Msc_Mutex);
|
|
||||||
Msc_Mutex = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_InitMIDIMusic(void)
|
|
||||||
{
|
|
||||||
if (nodigimusic) I_InitMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_InitDigMusic(void)
|
|
||||||
{
|
|
||||||
if (nomidimusic) I_InitMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_InitMusic(void)
|
void I_InitMusic(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_MIXER
|
#if 0 //#ifdef HAVE_LIBGME
|
||||||
char ad[100];
|
|
||||||
SDL_version MIXcompiled;
|
|
||||||
const SDL_version *MIXlinked;
|
|
||||||
#ifdef MIXER_INIT
|
|
||||||
const int mixstart = MIX_INIT_OGG;
|
|
||||||
int mixflags;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBGME
|
|
||||||
I_AddExitFunc(I_ShutdownGMEMusic);
|
I_AddExitFunc(I_ShutdownGMEMusic);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
MIX_VERSION(&MIXcompiled)
|
|
||||||
MIXlinked = Mix_Linked_Version();
|
|
||||||
I_OutputMsg("Compiled for SDL_mixer version: %d.%d.%d\n",
|
|
||||||
MIXcompiled.major, MIXcompiled.minor, MIXcompiled.patch);
|
|
||||||
#ifdef MIXER_POS
|
|
||||||
if (MIXlinked->major == 1 && MIXlinked->minor == 2 && MIXlinked->patch < 7)
|
|
||||||
canlooping = SDL_FALSE;
|
|
||||||
#endif
|
|
||||||
#ifdef USE_RWOPS
|
|
||||||
if (M_CheckParm("-noRW"))
|
|
||||||
canuseRW = SDL_FALSE;
|
|
||||||
#endif
|
|
||||||
I_OutputMsg("Linked with SDL_mixer version: %d.%d.%d\n",
|
|
||||||
MIXlinked->major, MIXlinked->minor, MIXlinked->patch);
|
|
||||||
if (audio.freq < 44100 && !M_CheckParm ("-freq")) //I want atleast 44Khz
|
|
||||||
{
|
|
||||||
audio.samples = (Uint16)(audio.samples*(INT32)(44100/audio.freq));
|
|
||||||
audio.freq = 44100; //Alam: to keep it around the same XX ms
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sound_started
|
|
||||||
#ifdef HW3SOUND
|
|
||||||
&& hws_mode == HWS_DEFAULT_MODE
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
I_OutputMsg("Temp Shutdown of SDL Audio System");
|
|
||||||
SDL_CloseAudio();
|
|
||||||
I_OutputMsg(" Done\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
CONS_Printf("%s", M_GetText("I_InitMusic:"));
|
|
||||||
|
|
||||||
#ifdef MIXER_INIT
|
|
||||||
mixflags = Mix_Init(mixstart);
|
|
||||||
if ((mixstart & MIX_INIT_FLAC) != (mixflags & MIX_INIT_FLAC))
|
|
||||||
{
|
|
||||||
CONS_Printf("%s", M_GetText(" Unable to load FLAC support\n"));
|
|
||||||
}
|
|
||||||
if ((mixstart & MIX_INIT_MOD ) != (mixflags & MIX_INIT_MOD ))
|
|
||||||
{
|
|
||||||
CONS_Printf("%s", M_GetText(" Unable to load MOD support\n"));
|
|
||||||
}
|
|
||||||
if ((mixstart & MIX_INIT_MP3 ) != (mixflags & MIX_INIT_MP3 ))
|
|
||||||
{
|
|
||||||
CONS_Printf("%s", M_GetText(" Unable to load MP3 support\n"));
|
|
||||||
}
|
|
||||||
if ((mixstart & MIX_INIT_OGG ) != (mixflags & MIX_INIT_OGG ))
|
|
||||||
{
|
|
||||||
CONS_Printf("%s", M_GetText(" Unable to load OGG support\n"));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Mix_OpenAudio(audio.freq, audio.format, audio.channels, audio.samples) < 0) //open_music(&audio)
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText(" Unable to open music: %s\n"), Mix_GetError());
|
|
||||||
nomidimusic = nodigimusic = true;
|
|
||||||
if (sound_started
|
|
||||||
#ifdef HW3SOUND
|
|
||||||
&& hws_mode == HWS_DEFAULT_MODE
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (SDL_OpenAudio(&audio, NULL) < 0) //retry
|
|
||||||
{
|
|
||||||
CONS_Printf("%s", M_GetText(" couldn't open audio with desired format\n"));
|
|
||||||
nosound = true;
|
|
||||||
sound_started = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CONS_Printf(M_GetText(" Starting with audio driver : %s\n"), SDL_AudioDriverName(ad, (int)sizeof ad));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CONS_Printf(M_GetText(" Starting up with audio driver : %s with SDL_Mixer\n"), SDL_AudioDriverName(ad, (int)sizeof ad));
|
|
||||||
|
|
||||||
samplecount = audio.samples;
|
|
||||||
CV_SetValue(&cv_samplerate, audio.freq);
|
|
||||||
if (sound_started
|
|
||||||
#ifdef HW3SOUND
|
|
||||||
&& hws_mode == HWS_DEFAULT_MODE
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
I_OutputMsg(" Reconfigured SDL Audio System");
|
|
||||||
else I_OutputMsg(" Configured SDL_Mixer System");
|
|
||||||
I_OutputMsg(" with %d samples/slice at %ikhz(%dms buffer)\n", samplecount, audio.freq/1000, (INT32) ((audio.samples * 1000.0f) / audio.freq));
|
|
||||||
Mix_SetPostMix(audio.callback, audio.userdata); // after mixing music, add sound effects
|
|
||||||
Mix_Resume(-1);
|
|
||||||
CONS_Printf("%s", M_GetText("Music initialized\n"));
|
|
||||||
musicStarted = SDL_TRUE;
|
|
||||||
Msc_Mutex = SDL_CreateMutex();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean I_PlaySong(INT32 handle, boolean looping)
|
void I_ShutdownMusic(void) { }
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC PROPERTIES
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
musictype_t I_SongType(void)
|
||||||
{
|
{
|
||||||
(void)handle;
|
return MU_NONE;
|
||||||
#ifdef HAVE_MIXER
|
}
|
||||||
if (nomidimusic || !musicStarted || !music[handle])
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef MIXER_POS
|
boolean I_SongPlaying(void)
|
||||||
if (canlooping)
|
{
|
||||||
Mix_HookMusicFinished(NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Mix_FadeInMusic(music[handle], looping ? -1 : 0, MIDIfade) == -1)
|
|
||||||
CONS_Printf(M_GetText("Couldn't play song because %s\n"), Mix_GetError());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Mix_VolumeMusic(musicvol);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
(void)looping;
|
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean I_SongPaused(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC EFFECTS
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
boolean I_SetSongSpeed(float speed)
|
||||||
|
{
|
||||||
|
(void)speed;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC PLAYBACK
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
#if 0 //#ifdef HAVE_LIBGME
|
||||||
|
static void I_StopGME(void)
|
||||||
|
{
|
||||||
|
Snd_LockAudio();
|
||||||
|
gme_seek(localdata.gme_emu, 0);
|
||||||
|
Snd_UnlockAudio();
|
||||||
|
}
|
||||||
|
|
||||||
static void I_PauseGME(void)
|
static void I_PauseGME(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBGME
|
|
||||||
localdata.gme_pause = true;
|
localdata.gme_pause = true;
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_PauseSong(INT32 handle)
|
|
||||||
{
|
|
||||||
(void)handle;
|
|
||||||
I_PauseGME();
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
if ((nomidimusic && nodigimusic) || !musicStarted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Mix_PauseMusic();
|
|
||||||
//I_StopSong(handle);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void I_ResumeGME(void)
|
static void I_ResumeGME(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBGME
|
|
||||||
localdata.gme_pause = false;
|
localdata.gme_pause = false;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_ResumeSong(INT32 handle)
|
|
||||||
{
|
|
||||||
(void)handle;
|
|
||||||
I_ResumeGME();
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
if ((nomidimusic && nodigimusic) || !musicStarted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Mix_VolumeMusic(musicvol);
|
|
||||||
Mix_ResumeMusic();
|
|
||||||
//I_PlaySong(handle, true);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
void I_StopSong(INT32 handle)
|
boolean I_LoadSong(char *data, size_t len)
|
||||||
{
|
{
|
||||||
(void)handle;
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
if (nomidimusic || !musicStarted)
|
|
||||||
return;
|
|
||||||
Mix_FadeOutMusic(MIDIfade);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_UnRegisterSong(INT32 handle)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
|
|
||||||
if (nomidimusic || !musicStarted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Mix_HaltMusic();
|
|
||||||
while (Mix_PlayingMusic())
|
|
||||||
;
|
|
||||||
|
|
||||||
if (music[handle])
|
|
||||||
Mix_FreeMusic(music[handle]);
|
|
||||||
music[handle] = NULL;
|
|
||||||
LoadSong(NULL, 0, handle);
|
|
||||||
#else
|
|
||||||
(void)handle;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
INT32 I_RegisterSong(void *data, size_t len)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
if (nomidimusic || !musicStarted)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!LoadSong(data, len, 0))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (music[0])
|
|
||||||
return true;
|
|
||||||
|
|
||||||
CONS_Printf(M_GetText("Couldn't load MIDI: %s\n"), Mix_GetError());
|
|
||||||
#else
|
|
||||||
(void)len;
|
|
||||||
(void)data;
|
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_SetMIDIMusicVolume(UINT8 volume)
|
void I_UnloadSong(void) { }
|
||||||
{
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
if ((nomidimusic && nodigimusic) || !musicStarted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Msc_Mutex) SDL_LockMutex(Msc_Mutex);
|
boolean I_PlaySong(boolean looping)
|
||||||
musicvol = volume * 2;
|
{
|
||||||
if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex);
|
(void)looping;
|
||||||
Mix_VolumeMusic(musicvol);
|
return false;
|
||||||
#else
|
}
|
||||||
(void)volume;
|
|
||||||
|
void I_StopSong(void)
|
||||||
|
{
|
||||||
|
#if 0 //#ifdef HAVE_LIBGME
|
||||||
|
I_StopGME();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBGME
|
void I_PauseSong(void)
|
||||||
|
{
|
||||||
|
#if 0 //#ifdef HAVE_LIBGME
|
||||||
|
I_PauseGME();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ResumeSong(void)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
I_ResumeGME();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_SetMusicVolume(UINT8 volume)
|
||||||
|
{
|
||||||
|
(void)volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongTrack(int track)
|
||||||
|
{
|
||||||
|
(void)track;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC LOADING AND CLEANUP
|
||||||
|
// \todo Split logic between loading and playing,
|
||||||
|
// then move to Playback section
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
#if 0 //#ifdef HAVE_LIBGME
|
||||||
static void I_CleanupGME(void *userdata)
|
static void I_CleanupGME(void *userdata)
|
||||||
{
|
{
|
||||||
Z_Free(userdata);
|
Z_Free(userdata);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static boolean I_StartGMESong(const char *musicname, boolean looping)
|
static boolean I_StartGMESong(const char *musicname, boolean looping)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBGME
|
|
||||||
char filename[9];
|
char filename[9];
|
||||||
void *data;
|
void *data;
|
||||||
lumpnum_t lumpnum;
|
lumpnum_t lumpnum;
|
||||||
|
@ -1759,240 +1496,7 @@ static boolean I_StartGMESong(const char *musicname, boolean looping)
|
||||||
Snd_UnlockAudio();
|
Snd_UnlockAudio();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
(void)musicname;
|
|
||||||
(void)looping;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_StartDigSong(const char *musicname, boolean looping)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
char filename[9];
|
|
||||||
void *data;
|
|
||||||
lumpnum_t lumpnum;
|
|
||||||
size_t lumplength;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(I_StartGMESong(musicname, looping))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
if (nodigimusic)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
snprintf(filename, sizeof filename, "o_%s", musicname);
|
|
||||||
|
|
||||||
lumpnum = W_CheckNumForName(filename);
|
|
||||||
|
|
||||||
I_StopDigSong();
|
|
||||||
|
|
||||||
if (lumpnum == LUMPERROR)
|
|
||||||
{
|
|
||||||
// Alam_GBC: like in win32/win_snd.c: Graue 02-29-2004: don't worry about missing music, there might still be a MIDI
|
|
||||||
//I_OutputMsg("Music lump %s not found!\n", filename);
|
|
||||||
return false; // No music found. Oh well!
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lumplength = W_LumpLength(lumpnum);
|
|
||||||
|
|
||||||
data = W_CacheLumpNum(lumpnum, PU_MUSIC);
|
|
||||||
|
|
||||||
if (Msc_Mutex) SDL_LockMutex(Msc_Mutex);
|
|
||||||
|
|
||||||
#ifdef MIXER_POS
|
|
||||||
if (canlooping && (loopingDig = looping) == SDL_TRUE && strcmp(data, "OggS") == 0)
|
|
||||||
looping = false; // Only on looping Ogg files, will we will do our own looping
|
|
||||||
|
|
||||||
// Scan the Ogg Vorbis file for the COMMENT= field for a custom
|
|
||||||
// loop point
|
|
||||||
if (!looping && loopingDig)
|
|
||||||
{
|
|
||||||
size_t scan;
|
|
||||||
const char *dataum = data;
|
|
||||||
char looplength[64];
|
|
||||||
UINT32 loopstart = 0;
|
|
||||||
UINT8 newcount = 0;
|
|
||||||
|
|
||||||
Mix_HookMusicFinished(I_FinishMusic);
|
|
||||||
|
|
||||||
for (scan = 0; scan < lumplength; scan++)
|
|
||||||
{
|
|
||||||
if (*dataum++ == 'C'){
|
|
||||||
if (*dataum++ == 'O'){
|
|
||||||
if (*dataum++ == 'M'){
|
|
||||||
if (*dataum++ == 'M'){
|
|
||||||
if (*dataum++ == 'E'){
|
|
||||||
if (*dataum++ == 'N'){
|
|
||||||
if (*dataum++ == 'T'){
|
|
||||||
if (*dataum++ == '='){
|
|
||||||
if (*dataum++ == 'L'){
|
|
||||||
if (*dataum++ == 'O'){
|
|
||||||
if (*dataum++ == 'O'){
|
|
||||||
if (*dataum++ == 'P'){
|
|
||||||
if (*dataum++ == 'P'){
|
|
||||||
if (*dataum++ == 'O'){
|
|
||||||
if (*dataum++ == 'I'){
|
|
||||||
if (*dataum++ == 'N'){
|
|
||||||
if (*dataum++ == 'T'){
|
|
||||||
if (*dataum++ == '=')
|
|
||||||
{
|
|
||||||
|
|
||||||
while (*dataum != 1 && newcount != 63)
|
|
||||||
looplength[newcount++] = *dataum++;
|
|
||||||
|
|
||||||
looplength[newcount] = '\0';
|
|
||||||
|
|
||||||
loopstart = atoi(looplength);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
else
|
|
||||||
dataum--;}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loopstart > 0)
|
|
||||||
{
|
|
||||||
loopstartDig = (double)((44.1l+loopstart) / 44100.0l); //8 PCM chucks off and PCM to secs
|
|
||||||
//#ifdef PARANOIA
|
|
||||||
//I_OutputMsg("I_StartDigSong: setting looping point to %ul PCMs(%f seconds)\n", loopstart, loopstartDig);
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
looping = true; // loopingDig true, but couldn't find start loop point
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
loopstartDig = 0.0l;
|
|
||||||
#else
|
|
||||||
if (looping && strcmp(data, "OggS") == 0)
|
|
||||||
I_OutputMsg("I_StartDigSong: SRB2 was not compiled with looping music support(no Mix_FadeInMusicPos)\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!LoadSong(data, lumplength, 1))
|
|
||||||
{
|
|
||||||
if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: LoadSong() frees the data. Let's make sure
|
|
||||||
// we don't try to use the data again.
|
|
||||||
data = NULL;
|
|
||||||
|
|
||||||
if (Mix_FadeInMusic(music[1], looping ? -1 : 0, Digfade) == -1)
|
|
||||||
{
|
|
||||||
if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex);
|
|
||||||
I_OutputMsg("I_StartDigSong: Couldn't play song %s because %s\n", musicname, Mix_GetError());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Mix_VolumeMusic(musicvol);
|
|
||||||
|
|
||||||
if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex);
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
(void)looping;
|
|
||||||
(void)musicname;
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void I_StopGME(void)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_LIBGME
|
|
||||||
Snd_LockAudio();
|
|
||||||
gme_seek(localdata.gme_emu, 0);
|
|
||||||
Snd_UnlockAudio();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_StopDigSong(void)
|
|
||||||
{
|
|
||||||
I_StopGME();
|
|
||||||
#ifdef HAVE_MIXER
|
|
||||||
if (nodigimusic)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef MIXER_POS
|
|
||||||
if (canlooping)
|
|
||||||
Mix_HookMusicFinished(NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Mix_HaltMusic();
|
|
||||||
while (Mix_PlayingMusic())
|
|
||||||
;
|
|
||||||
|
|
||||||
if (music[1])
|
|
||||||
Mix_FreeMusic(music[1]);
|
|
||||||
music[1] = NULL;
|
|
||||||
LoadSong(NULL, 0, 1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_SetDigMusicVolume(UINT8 volume)
|
|
||||||
{
|
|
||||||
I_SetMIDIMusicVolume(volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_SetSongSpeed(float speed)
|
|
||||||
{
|
|
||||||
|
|
||||||
(void)speed;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_SetSongTrack(int track)
|
|
||||||
{
|
|
||||||
(void)track;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MIXER_POS
|
|
||||||
static void SDLCALL I_FinishMusic(void)
|
|
||||||
{
|
|
||||||
if (!music[1])
|
|
||||||
return;
|
|
||||||
else if (Msc_Mutex) SDL_LockMutex(Msc_Mutex);
|
|
||||||
// I_OutputMsg("I_FinishMusic: Loopping song to %g seconds\n", loopstartDig);
|
|
||||||
|
|
||||||
if (Mix_FadeInMusicPos(music[1], loopstartDig ? 0 : -1, Digfade, loopstartDig) == 0)
|
|
||||||
Mix_VolumeMusic(musicvol);
|
|
||||||
else
|
|
||||||
I_OutputMsg("I_FinishMusic: Couldn't loop song because %s\n", Mix_GetError());
|
|
||||||
|
|
||||||
if (Msc_Mutex) SDL_UnlockMutex(Msc_Mutex);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif //HAVE_SDL
|
#endif //HAVE_SDL
|
||||||
|
|
|
@ -1045,7 +1045,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
|
||||||
//
|
//
|
||||||
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
|
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
|
||||||
{
|
{
|
||||||
if (skins[skinnum].flags & SF_HIRES)
|
if (skinnum < 0 || skinnum >= numskins || (skins[skinnum].flags & SF_HIRES))
|
||||||
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
|
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -234,10 +234,10 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum)
|
||||||
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
|
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
|
||||||
if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
|
if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
|
||||||
{ // shameless copy+paste of code from LUA_LoadLump
|
{ // shameless copy+paste of code from LUA_LoadLump
|
||||||
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
size_t len = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
||||||
char *name = malloc(length + 1);
|
char *name = malloc(len+1);
|
||||||
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
|
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
|
||||||
name[length] = '\0';
|
name[len] = '\0';
|
||||||
|
|
||||||
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
|
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
|
||||||
DEH_LoadDehackedLumpPwad(wadnum, lump);
|
DEH_LoadDehackedLumpPwad(wadnum, lump);
|
||||||
|
|
|
@ -471,7 +471,7 @@ void I_PlayCD(UINT8 nTrack, UINT8 bLooping)
|
||||||
//faB: stop MIDI music, MIDI music will restart if volume is upped later
|
//faB: stop MIDI music, MIDI music will restart if volume is upped later
|
||||||
cv_digmusicvolume.value = 0;
|
cv_digmusicvolume.value = 0;
|
||||||
cv_midimusicvolume.value = 0;
|
cv_midimusicvolume.value = 0;
|
||||||
I_StopSong (0);
|
I_StopSong();
|
||||||
|
|
||||||
//faB: I don't use the notify message, I'm trying to minimize the delay
|
//faB: I don't use the notify message, I'm trying to minimize the delay
|
||||||
mciPlay.dwCallback = (DWORD)((size_t)hWndMain);
|
mciPlay.dwCallback = (DWORD)((size_t)hWndMain);
|
||||||
|
|
|
@ -110,9 +110,9 @@ static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPAR
|
||||||
|
|
||||||
// pause music when alt-tab
|
// pause music when alt-tab
|
||||||
if (appActive && !paused)
|
if (appActive && !paused)
|
||||||
I_ResumeSong(0);
|
I_ResumeSong();
|
||||||
else if (!paused)
|
else if (!paused)
|
||||||
I_PauseSong(0);
|
I_PauseSong();
|
||||||
{
|
{
|
||||||
HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
|
HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
DWORD mode;
|
DWORD mode;
|
||||||
|
|
|
@ -17,10 +17,8 @@
|
||||||
#include "gme/gme.h"
|
#include "gme/gme.h"
|
||||||
#define GME_TREBLE 5.0
|
#define GME_TREBLE 5.0
|
||||||
#define GME_BASS 1.0
|
#define GME_BASS 1.0
|
||||||
#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng
|
|
||||||
|
|
||||||
#define HAVE_ZLIB
|
|
||||||
|
|
||||||
|
#ifdef HAVE_ZLIB
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#ifndef _LARGEFILE64_SOURCE
|
#ifndef _LARGEFILE64_SOURCE
|
||||||
#define _LARGEFILE64_SOURCE
|
#define _LARGEFILE64_SOURCE
|
||||||
|
@ -36,13 +34,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
#endif
|
#endif // HAVE_ZLIB
|
||||||
#endif
|
#endif // HAVE_LIBGME
|
||||||
|
|
||||||
static FMOD_SYSTEM *fsys;
|
static FMOD_SYSTEM *fsys;
|
||||||
static FMOD_SOUND *music_stream;
|
static FMOD_SOUND *music_stream;
|
||||||
static FMOD_CHANNEL *music_channel;
|
static FMOD_CHANNEL *music_channel;
|
||||||
static boolean midimode;
|
|
||||||
|
|
||||||
static UINT8 music_volume, midi_volume, sfx_volume;
|
static UINT8 music_volume, midi_volume, sfx_volume;
|
||||||
static INT32 current_track;
|
static INT32 current_track;
|
||||||
|
@ -355,12 +352,13 @@ void I_FreeSfx(sfxinfo_t *sfx)
|
||||||
sfx->data = NULL;
|
sfx->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
|
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
|
||||||
{
|
{
|
||||||
FMOD_SOUND *sound;
|
FMOD_SOUND *sound;
|
||||||
FMOD_CHANNEL *chan;
|
FMOD_CHANNEL *chan;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
float frequency;
|
float frequency;
|
||||||
|
(void)channel;
|
||||||
|
|
||||||
sound = (FMOD_SOUND *)S_sfx[id].data;
|
sound = (FMOD_SOUND *)S_sfx[id].data;
|
||||||
I_Assert(sound != NULL);
|
I_Assert(sound != NULL);
|
||||||
|
@ -440,9 +438,9 @@ void I_SetSfxVolume(UINT8 volume)
|
||||||
sfx_volume = volume;
|
sfx_volume = volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/// ------------------------
|
||||||
// MUSIC
|
// MUSIC SYSTEM
|
||||||
//
|
/// ------------------------
|
||||||
|
|
||||||
void I_InitMusic(void)
|
void I_InitMusic(void)
|
||||||
{
|
{
|
||||||
|
@ -450,53 +448,111 @@ void I_InitMusic(void)
|
||||||
|
|
||||||
void I_ShutdownMusic(void)
|
void I_ShutdownMusic(void)
|
||||||
{
|
{
|
||||||
I_ShutdownDigMusic();
|
I_StopSong();
|
||||||
I_ShutdownMIDIMusic();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_PauseSong(INT32 handle)
|
/// ------------------------
|
||||||
{
|
// MUSIC PROPERTIES
|
||||||
UNREFERENCED_PARAMETER(handle);
|
/// ------------------------
|
||||||
if (music_stream)
|
|
||||||
FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_ResumeSong(INT32 handle)
|
musictype_t I_SongType(void)
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(handle);
|
#ifdef HAVE_LIBGME
|
||||||
if (music_stream)
|
if (gme)
|
||||||
FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, false));
|
return MU_GME;
|
||||||
}
|
#endif
|
||||||
|
|
||||||
void I_InitDigMusic(void)
|
if (!music_stream)
|
||||||
{
|
return MU_NONE;
|
||||||
}
|
|
||||||
|
|
||||||
void I_ShutdownDigMusic(void)
|
FMOD_SOUND_TYPE type;
|
||||||
{
|
if (FMOD_Sound_GetFormat(music_stream, &type, NULL, NULL, NULL) == FMOD_OK)
|
||||||
if (!midimode)
|
|
||||||
I_StopDigSong();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_StartDigSong(const char *musicname, boolean looping)
|
|
||||||
{
|
|
||||||
char *data;
|
|
||||||
size_t len;
|
|
||||||
FMOD_CREATESOUNDEXINFO fmt;
|
|
||||||
lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname));
|
|
||||||
|
|
||||||
if (lumpnum == LUMPERROR)
|
|
||||||
{
|
{
|
||||||
lumpnum = W_CheckNumForName(va("D_%s",musicname));
|
switch(type)
|
||||||
if (lumpnum == LUMPERROR)
|
{
|
||||||
return false;
|
case FMOD_SOUND_TYPE_WAV:
|
||||||
midimode = true;
|
return MU_WAV;
|
||||||
|
case FMOD_SOUND_TYPE_MOD:
|
||||||
|
return MU_MOD;
|
||||||
|
case FMOD_SOUND_TYPE_MIDI:
|
||||||
|
return MU_MID;
|
||||||
|
case FMOD_SOUND_TYPE_OGGVORBIS:
|
||||||
|
return MU_OGG;
|
||||||
|
case FMOD_SOUND_TYPE_MPEG:
|
||||||
|
return MU_MP3;
|
||||||
|
case FMOD_SOUND_TYPE_FLAC:
|
||||||
|
return MU_FLAC;
|
||||||
|
default:
|
||||||
|
return MU_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
midimode = false;
|
return MU_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC);
|
boolean I_SongPlaying(void)
|
||||||
len = W_LumpLength(lumpnum);
|
{
|
||||||
|
return (boolean)music_stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SongPaused(void)
|
||||||
|
{
|
||||||
|
boolean fmpaused = false;
|
||||||
|
if (music_stream)
|
||||||
|
FMOD_Channel_GetPaused(music_channel, &fmpaused);
|
||||||
|
return fmpaused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC EFFECTS
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
boolean I_SetSongSpeed(float speed)
|
||||||
|
{
|
||||||
|
FMOD_RESULT e;
|
||||||
|
float frequency;
|
||||||
|
if (!music_stream)
|
||||||
|
return false;
|
||||||
|
if (speed > 250.0f)
|
||||||
|
speed = 250.0f; //limit speed up to 250x
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGME
|
||||||
|
// Try to set GME speed
|
||||||
|
if (gme)
|
||||||
|
{
|
||||||
|
gme_set_tempo(gme, speed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Try to set Mod/Midi speed
|
||||||
|
e = FMOD_Sound_SetMusicSpeed(music_stream, speed);
|
||||||
|
|
||||||
|
if (e == FMOD_ERR_FORMAT)
|
||||||
|
{
|
||||||
|
// Just change pitch instead for Ogg/etc.
|
||||||
|
FMR(FMOD_Sound_GetDefaults(music_stream, &frequency, NULL, NULL, NULL));
|
||||||
|
FMR_MUSIC(FMOD_Channel_SetFrequency(music_channel, speed*frequency));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FMR_MUSIC(e);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC PLAYBACK
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
boolean I_LoadSong(char *data, size_t len)
|
||||||
|
{
|
||||||
|
FMOD_CREATESOUNDEXINFO fmt;
|
||||||
|
FMOD_RESULT e;
|
||||||
|
FMOD_TAG tag;
|
||||||
|
unsigned int loopstart, loopend;
|
||||||
|
|
||||||
|
if (gme || music_stream)
|
||||||
|
I_UnloadSong();
|
||||||
|
|
||||||
memset(&fmt, 0, sizeof(FMOD_CREATESOUNDEXINFO));
|
memset(&fmt, 0, sizeof(FMOD_CREATESOUNDEXINFO));
|
||||||
fmt.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
|
fmt.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
|
||||||
|
@ -531,8 +587,6 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
gme_equalizer_t gmeq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
|
gme_equalizer_t gmeq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
|
||||||
Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around
|
Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around
|
||||||
Z_Free(data); // We don't need this, either.
|
Z_Free(data); // We don't need this, either.
|
||||||
gme_start_track(gme, 0);
|
|
||||||
current_track = 0;
|
|
||||||
gme_set_equalizer(gme,&gmeq);
|
gme_set_equalizer(gme,&gmeq);
|
||||||
fmt.format = FMOD_SOUND_FORMAT_PCM16;
|
fmt.format = FMOD_SOUND_FORMAT_PCM16;
|
||||||
fmt.defaultfrequency = 44100;
|
fmt.defaultfrequency = 44100;
|
||||||
|
@ -541,10 +595,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
fmt.decodebuffersize = (44100 * 2) / 35;
|
fmt.decodebuffersize = (44100 * 2) / 35;
|
||||||
fmt.pcmreadcallback = GMEReadCallback;
|
fmt.pcmreadcallback = GMEReadCallback;
|
||||||
fmt.userdata = gme;
|
fmt.userdata = gme;
|
||||||
FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER | (looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream));
|
FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER, &fmt, &music_stream));
|
||||||
FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel));
|
|
||||||
FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
|
|
||||||
FMR(FMOD_Channel_SetPriority(music_channel, 0));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -603,8 +654,6 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
{
|
{
|
||||||
gme_equalizer_t gmeq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
|
gme_equalizer_t gmeq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
|
||||||
Z_Free(data); // We don't need this anymore.
|
Z_Free(data); // We don't need this anymore.
|
||||||
gme_start_track(gme, 0);
|
|
||||||
current_track = 0;
|
|
||||||
gme_set_equalizer(gme,&gmeq);
|
gme_set_equalizer(gme,&gmeq);
|
||||||
fmt.format = FMOD_SOUND_FORMAT_PCM16;
|
fmt.format = FMOD_SOUND_FORMAT_PCM16;
|
||||||
fmt.defaultfrequency = 44100;
|
fmt.defaultfrequency = 44100;
|
||||||
|
@ -613,7 +662,102 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
fmt.decodebuffersize = (44100 * 2) / 35;
|
fmt.decodebuffersize = (44100 * 2) / 35;
|
||||||
fmt.pcmreadcallback = GMEReadCallback;
|
fmt.pcmreadcallback = GMEReadCallback;
|
||||||
fmt.userdata = gme;
|
fmt.userdata = gme;
|
||||||
FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER | (looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream));
|
FMR(FMOD_System_CreateStream(fsys, NULL, FMOD_OPENUSER, &fmt, &music_stream));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fmt.length = len;
|
||||||
|
|
||||||
|
e = FMOD_System_CreateStream(fsys, data, FMOD_OPENMEMORY_POINT, &fmt, &music_stream);
|
||||||
|
if (e != FMOD_OK)
|
||||||
|
{
|
||||||
|
if (e == FMOD_ERR_FORMAT)
|
||||||
|
CONS_Alert(CONS_WARNING, "Failed to play music lump due to invalid format.\n");
|
||||||
|
else
|
||||||
|
FMR(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find a loop point in streaming music formats (ogg, mp3)
|
||||||
|
|
||||||
|
// A proper LOOPPOINT is its own tag, stupid.
|
||||||
|
e = FMOD_Sound_GetTag(music_stream, "LOOPPOINT", 0, &tag);
|
||||||
|
if (e != FMOD_ERR_TAGNOTFOUND)
|
||||||
|
{
|
||||||
|
FMR(e);
|
||||||
|
loopstart = atoi((char *)tag.data); // assumed to be a string data tag.
|
||||||
|
FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM));
|
||||||
|
if (loopstart > 0)
|
||||||
|
FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use LOOPMS for time in miliseconds.
|
||||||
|
e = FMOD_Sound_GetTag(music_stream, "LOOPMS", 0, &tag);
|
||||||
|
if (e != FMOD_ERR_TAGNOTFOUND)
|
||||||
|
{
|
||||||
|
FMR(e);
|
||||||
|
loopstart = atoi((char *)tag.data); // assumed to be a string data tag.
|
||||||
|
FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_MS, &loopend, FMOD_TIMEUNIT_PCM));
|
||||||
|
if (loopstart > 0)
|
||||||
|
FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_MS, loopend, FMOD_TIMEUNIT_PCM));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to fetch it from the COMMENT tag, like A.J. Freda
|
||||||
|
e = FMOD_Sound_GetTag(music_stream, "COMMENT", 0, &tag);
|
||||||
|
if (e != FMOD_ERR_TAGNOTFOUND)
|
||||||
|
{
|
||||||
|
char *loopText;
|
||||||
|
// Handle any errors that arose, first
|
||||||
|
FMR(e);
|
||||||
|
// Figure out where the number starts
|
||||||
|
loopText = strstr((char *)tag.data,"LOOPPOINT=");
|
||||||
|
if (loopText != NULL)
|
||||||
|
{
|
||||||
|
// Skip the "LOOPPOINT=" part.
|
||||||
|
loopText += 10;
|
||||||
|
// Convert it to our looppoint
|
||||||
|
// FMOD seems to ensure the tag is properly NULL-terminated.
|
||||||
|
// atoi will stop when it reaches anything that's not a number.
|
||||||
|
loopstart = atoi(loopText);
|
||||||
|
// Now do the rest like above
|
||||||
|
FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM));
|
||||||
|
if (loopstart > 0)
|
||||||
|
FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No special loop point
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_UnloadSong(void)
|
||||||
|
{
|
||||||
|
I_StopSong();
|
||||||
|
#ifdef HAVE_LIBGME
|
||||||
|
if (gme)
|
||||||
|
{
|
||||||
|
gme_delete(gme);
|
||||||
|
gme = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (music_stream)
|
||||||
|
{
|
||||||
|
FMR(FMOD_Sound_Release(music_stream));
|
||||||
|
music_stream = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_PlaySong(boolean looping)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LIBGME
|
||||||
|
if (gme)
|
||||||
|
{
|
||||||
|
gme_start_track(gme, 0);
|
||||||
|
current_track = 0;
|
||||||
FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel));
|
FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel));
|
||||||
FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
|
FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
|
||||||
FMR(FMOD_Channel_SetPriority(music_channel, 0));
|
FMR(FMOD_Channel_SetPriority(music_channel, 0));
|
||||||
|
@ -621,139 +765,48 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fmt.length = len;
|
FMR(FMOD_Sound_SetMode(music_stream, (looping ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF)));
|
||||||
{
|
|
||||||
FMOD_RESULT e = FMOD_System_CreateStream(fsys, data, FMOD_OPENMEMORY_POINT|(looping ? FMOD_LOOP_NORMAL : 0), &fmt, &music_stream);
|
|
||||||
if (e != FMOD_OK)
|
|
||||||
{
|
|
||||||
if (e == FMOD_ERR_FORMAT)
|
|
||||||
CONS_Alert(CONS_WARNING, "Failed to play music lump %s due to invalid format.\n", W_CheckNameForNum(lumpnum));
|
|
||||||
else
|
|
||||||
FMR(e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel));
|
FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel));
|
||||||
if (midimode)
|
if (I_SongType() != MU_MID)
|
||||||
FMR(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0));
|
FMR(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0));
|
||||||
else
|
else
|
||||||
FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
|
FMR(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
|
||||||
FMR(FMOD_Channel_SetPriority(music_channel, 0));
|
FMR(FMOD_Channel_SetPriority(music_channel, 0));
|
||||||
current_track = 0;
|
current_track = 0;
|
||||||
|
|
||||||
// Try to find a loop point in streaming music formats (ogg, mp3)
|
|
||||||
if (looping)
|
|
||||||
{
|
|
||||||
FMOD_RESULT e;
|
|
||||||
FMOD_TAG tag;
|
|
||||||
unsigned int loopstart, loopend;
|
|
||||||
|
|
||||||
// A proper LOOPPOINT is its own tag, stupid.
|
|
||||||
e = FMOD_Sound_GetTag(music_stream, "LOOPPOINT", 0, &tag);
|
|
||||||
if (e != FMOD_ERR_TAGNOTFOUND)
|
|
||||||
{
|
|
||||||
FMR(e);
|
|
||||||
loopstart = atoi((char *)tag.data); // assumed to be a string data tag.
|
|
||||||
FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM));
|
|
||||||
if (loopstart > 0)
|
|
||||||
FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use LOOPMS for time in miliseconds.
|
|
||||||
e = FMOD_Sound_GetTag(music_stream, "LOOPMS", 0, &tag);
|
|
||||||
if (e != FMOD_ERR_TAGNOTFOUND)
|
|
||||||
{
|
|
||||||
FMR(e);
|
|
||||||
loopstart = atoi((char *)tag.data); // assumed to be a string data tag.
|
|
||||||
FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_MS, &loopend, FMOD_TIMEUNIT_PCM));
|
|
||||||
if (loopstart > 0)
|
|
||||||
FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_MS, loopend, FMOD_TIMEUNIT_PCM));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to fetch it from the COMMENT tag, like A.J. Freda
|
|
||||||
e = FMOD_Sound_GetTag(music_stream, "COMMENT", 0, &tag);
|
|
||||||
if (e != FMOD_ERR_TAGNOTFOUND)
|
|
||||||
{
|
|
||||||
char *loopText;
|
|
||||||
// Handle any errors that arose, first
|
|
||||||
FMR(e);
|
|
||||||
// Figure out where the number starts
|
|
||||||
loopText = strstr((char *)tag.data,"LOOPPOINT=");
|
|
||||||
if (loopText != NULL)
|
|
||||||
{
|
|
||||||
// Skip the "LOOPPOINT=" part.
|
|
||||||
loopText += 10;
|
|
||||||
// Convert it to our looppoint
|
|
||||||
// FMOD seems to ensure the tag is properly NULL-terminated.
|
|
||||||
// atoi will stop when it reaches anything that's not a number.
|
|
||||||
loopstart = atoi(loopText);
|
|
||||||
// Now do the rest like above
|
|
||||||
FMR(FMOD_Sound_GetLoopPoints(music_stream, NULL, FMOD_TIMEUNIT_PCM, &loopend, FMOD_TIMEUNIT_PCM));
|
|
||||||
if (loopstart > 0)
|
|
||||||
FMR(FMOD_Sound_SetLoopPoints(music_stream, loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No special loop point, but we're playing so it's all good.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_StopDigSong(void)
|
void I_StopSong(void)
|
||||||
{
|
{
|
||||||
if (music_stream)
|
if (music_channel)
|
||||||
FMR(FMOD_Sound_Release(music_stream));
|
FMR_MUSIC(FMOD_Channel_Stop(music_channel));
|
||||||
music_stream = NULL;
|
|
||||||
#ifdef HAVE_LIBGME
|
|
||||||
if (gme)
|
|
||||||
gme_delete(gme);
|
|
||||||
gme = NULL;
|
|
||||||
#endif
|
|
||||||
current_track = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_SetDigMusicVolume(UINT8 volume)
|
void I_PauseSong(void)
|
||||||
{
|
{
|
||||||
|
if (music_channel)
|
||||||
|
FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_ResumeSong(void)
|
||||||
|
{
|
||||||
|
if (music_channel)
|
||||||
|
FMR_MUSIC(FMOD_Channel_SetPaused(music_channel, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_SetMusicVolume(UINT8 volume)
|
||||||
|
{
|
||||||
|
if (!music_channel)
|
||||||
|
return;
|
||||||
|
|
||||||
// volume is 0 to 31.
|
// volume is 0 to 31.
|
||||||
music_volume = volume;
|
if (I_SongType() == MU_MID)
|
||||||
if (!midimode && music_stream)
|
music_volume = 31; // windows bug hack
|
||||||
FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, volume / 31.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_SetSongSpeed(float speed)
|
|
||||||
{
|
|
||||||
FMOD_RESULT e;
|
|
||||||
float frequency;
|
|
||||||
if (!music_stream)
|
|
||||||
return false;
|
|
||||||
if (speed > 250.0f)
|
|
||||||
speed = 250.0f; //limit speed up to 250x
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBGME
|
|
||||||
// Try to set GME speed
|
|
||||||
if (gme)
|
|
||||||
{
|
|
||||||
gme_set_tempo(gme, speed);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Try to set Mod/Midi speed
|
|
||||||
e = FMOD_Sound_SetMusicSpeed(music_stream, speed);
|
|
||||||
|
|
||||||
if (e == FMOD_ERR_FORMAT)
|
|
||||||
{
|
|
||||||
// Just change pitch instead for Ogg/etc.
|
|
||||||
FMR(FMOD_Sound_GetDefaults(music_stream, &frequency, NULL, NULL, NULL));
|
|
||||||
FMR_MUSIC(FMOD_Channel_SetFrequency(music_channel, speed*frequency));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
FMR_MUSIC(e);
|
music_volume = volume;
|
||||||
|
|
||||||
return true;
|
FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean I_SetSongTrack(INT32 track)
|
boolean I_SetSongTrack(INT32 track)
|
||||||
|
@ -800,62 +853,3 @@ boolean I_SetSongTrack(INT32 track)
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Fuck MIDI. ... Okay fine, you can have your silly D_-only mode.
|
|
||||||
//
|
|
||||||
|
|
||||||
void I_InitMIDIMusic(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_ShutdownMIDIMusic(void)
|
|
||||||
{
|
|
||||||
if (midimode)
|
|
||||||
I_StopSong(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_SetMIDIMusicVolume(UINT8 volume)
|
|
||||||
{
|
|
||||||
// volume is 0 to 31.
|
|
||||||
midi_volume = volume;
|
|
||||||
if (midimode && music_stream)
|
|
||||||
FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, volume / 31.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
INT32 I_RegisterSong(void *data, size_t len)
|
|
||||||
{
|
|
||||||
FMOD_CREATESOUNDEXINFO fmt;
|
|
||||||
memset(&fmt, 0, sizeof(FMOD_CREATESOUNDEXINFO));
|
|
||||||
fmt.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
|
|
||||||
fmt.length = len;
|
|
||||||
FMR(FMOD_System_CreateStream(fsys, (char *)data, FMOD_OPENMEMORY_POINT, &fmt, &music_stream));
|
|
||||||
return 1337;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean I_PlaySong(INT32 handle, boolean looping)
|
|
||||||
{
|
|
||||||
if (1337 == handle)
|
|
||||||
{
|
|
||||||
midimode = true;
|
|
||||||
if (looping)
|
|
||||||
FMR(FMOD_Sound_SetMode(music_stream, FMOD_LOOP_NORMAL));
|
|
||||||
FMR(FMOD_System_PlaySound(fsys, FMOD_CHANNEL_FREE, music_stream, false, &music_channel));
|
|
||||||
FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, midi_volume / 31.0));
|
|
||||||
FMR_MUSIC(FMOD_Channel_SetPriority(music_channel, 0));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_StopSong(INT32 handle)
|
|
||||||
{
|
|
||||||
I_UnRegisterSong(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_UnRegisterSong(INT32 handle)
|
|
||||||
{
|
|
||||||
UNREFERENCED_PARAMETER(handle);
|
|
||||||
if (music_stream)
|
|
||||||
FMR(FMOD_Sound_Release(music_stream));
|
|
||||||
music_stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1750,6 +1750,26 @@ static void Y_SetRingBonus(player_t *player, y_bonus_t *bstruct)
|
||||||
bstruct->points = max(0, (player->rings) * 100);
|
bstruct->points = max(0, (player->rings) * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Y_SetNightsBonus
|
||||||
|
//
|
||||||
|
static void Y_SetNightsBonus(player_t *player, y_bonus_t *bstruct)
|
||||||
|
{
|
||||||
|
strncpy(bstruct->patch, "YB_NIGHT", sizeof(bstruct->patch));
|
||||||
|
bstruct->display = true;
|
||||||
|
bstruct->points = player->totalmarescore;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Y_SetLapBonus
|
||||||
|
//
|
||||||
|
static void Y_SetLapBonus(player_t *player, y_bonus_t *bstruct)
|
||||||
|
{
|
||||||
|
strncpy(bstruct->patch, "YB_LAP", sizeof(bstruct->patch));
|
||||||
|
bstruct->display = true;
|
||||||
|
bstruct->points = max(0, player->totalmarebonuslap * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Y_SetLinkBonus
|
// Y_SetLinkBonus
|
||||||
//
|
//
|
||||||
|
@ -1811,7 +1831,7 @@ static void Y_SetPerfectBonus(player_t *player, y_bonus_t *bstruct)
|
||||||
|
|
||||||
// This list can be extended in the future with SOC/Lua, perhaps.
|
// This list can be extended in the future with SOC/Lua, perhaps.
|
||||||
typedef void (*bonus_f)(player_t *, y_bonus_t *);
|
typedef void (*bonus_f)(player_t *, y_bonus_t *);
|
||||||
bonus_f bonuses_list[4][4] = {
|
bonus_f bonuses_list[6][4] = {
|
||||||
{
|
{
|
||||||
Y_SetNullBonus,
|
Y_SetNullBonus,
|
||||||
Y_SetNullBonus,
|
Y_SetNullBonus,
|
||||||
|
@ -1836,6 +1856,18 @@ bonus_f bonuses_list[4][4] = {
|
||||||
Y_SetRingBonus,
|
Y_SetRingBonus,
|
||||||
Y_SetPerfectBonus,
|
Y_SetPerfectBonus,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Y_SetNullBonus,
|
||||||
|
Y_SetNightsBonus,
|
||||||
|
Y_SetLapBonus,
|
||||||
|
Y_SetNullBonus,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Y_SetNullBonus,
|
||||||
|
Y_SetLinkBonus,
|
||||||
|
Y_SetLapBonus,
|
||||||
|
Y_SetNullBonus,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1911,8 +1943,8 @@ static void Y_AwardSpecialStageBonus(void)
|
||||||
|
|
||||||
if (!playeringame[i] || players[i].lives < 1) // not active or game over
|
if (!playeringame[i] || players[i].lives < 1) // not active or game over
|
||||||
Y_SetNullBonus(&players[i], &localbonus);
|
Y_SetNullBonus(&players[i], &localbonus);
|
||||||
else if (maptol & TOL_NIGHTS) // Link instead of Rings
|
else if (maptol & TOL_NIGHTS) // Mare score instead of Rings
|
||||||
Y_SetLinkBonus(&players[i], &localbonus);
|
Y_SetNightsBonus(&players[i], &localbonus);
|
||||||
else
|
else
|
||||||
Y_SetRingBonus(&players[i], &localbonus);
|
Y_SetRingBonus(&players[i], &localbonus);
|
||||||
players[i].score += localbonus.points;
|
players[i].score += localbonus.points;
|
||||||
|
|
Loading…
Reference in a new issue