Merge branch 'master' into analog-flipcam-synch-fix

This commit is contained in:
LJSonik 2018-10-29 19:52:08 +01:00 committed by GitHub
commit b52158eb48
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
74 changed files with 4036 additions and 3584 deletions

View file

@ -57,49 +57,6 @@ matrix:
- gcc-4.8 - gcc-4.8
compiler: gcc-4.8 compiler: gcc-4.8
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- p7zip-full
- gcc-4.9
compiler: gcc-4.9
#gcc-4.9 (Ubuntu 4.9.3-8ubuntu2~14.04) 4.9.3
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- p7zip-full
- gcc-5
compiler: gcc-5
#gcc-5 (Ubuntu 5.3.0-3ubuntu1~14.04) 5.3.0 20151204
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- libsdl2-mixer-dev
- libpng-dev
- libgl1-mesa-dev
- libgme-dev
- p7zip-full
- gcc-6
compiler: gcc-6
env: WFLAGS="-Wno-tautological-compare"
#gcc-6 (Ubuntu 6.1.1-3ubuntu11~14.04.1) 6.1.1 20160511
- os: linux - os: linux
addons: addons:
apt: apt:

View file

@ -1,3 +1,4 @@
# GNU Make makefile for SRB2 # GNU Make makefile for SRB2
############################################################################# #############################################################################
# Copyright (C) 1998-2000 by DooM Legacy Team. # Copyright (C) 1998-2000 by DooM Legacy Team.
@ -65,6 +66,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'
@ -118,6 +120,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
@ -198,6 +201,7 @@ endif
ifdef NDS ifdef NDS
NOPNG=1 NOPNG=1
NOZLIB=1
NONET=1 NONET=1
#NOHW=1 #NOHW=1
NOHS=1 NOHS=1
@ -324,13 +328,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
@ -342,6 +339,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
@ -421,7 +430,8 @@ endif
ifdef PROFILEMODE ifdef PROFILEMODE
# build with profiling information # build with profiling information
CFLAGS:=-pg $(CFLAGS) CFLAGS+=-pg
LDFLAGS+=-pg
endif endif
ifdef ZDEBUG ifdef ZDEBUG

View file

@ -8,7 +8,7 @@
UINT8 cdaudio_started = 0; UINT8 cdaudio_started = 0;
consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cd_volume = {"cd_volume","18",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};

View file

@ -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;
}

View file

@ -401,8 +401,7 @@ static void ExtraDataTicker(void)
DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic)); DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic));
} }
CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]); CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]);
D_FreeTextcmd(gametic); break;
return;
} }
} }
} }
@ -1569,8 +1568,6 @@ static void CL_LoadReceivedSavegame(void)
automapactive = false; automapactive = false;
// load a base level // load a base level
playerdeadview = false;
if (P_LoadNetGame()) if (P_LoadNetGame())
{ {
const INT32 actnum = mapheaderinfo[gamemap-1]->actnum; const INT32 actnum = mapheaderinfo[gamemap-1]->actnum;
@ -2244,7 +2241,7 @@ static void Command_connect(void)
// Assume we connect directly. // Assume we connect directly.
boolean viams = false; boolean viams = false;
if (COM_Argc() < 2) if (COM_Argc() < 2 || *COM_Argv(1) == 0)
{ {
CONS_Printf(M_GetText( CONS_Printf(M_GetText(
"Connect <serveraddress> (port): connect to a server\n" "Connect <serveraddress> (port): connect to a server\n"
@ -3296,7 +3293,7 @@ void SV_StopServer(void)
localtextcmd[0] = 0; localtextcmd[0] = 0;
localtextcmd2[0] = 0; localtextcmd2[0] = 0;
for (i = 0; i < BACKUPTICS; i++) for (i = firstticstosend; i < firstticstosend + BACKUPTICS; i++)
D_Clearticcmd(i); D_Clearticcmd(i);
consoleplayer = 0; consoleplayer = 0;

View file

@ -121,20 +121,17 @@ INT32 postimgparam;
postimg_t postimgtype2 = postimg_none; postimg_t postimgtype2 = postimg_none;
INT32 postimgparam2; INT32 postimgparam2;
#ifdef _XBOX
boolean nomidimusic = true, nosound = true;
boolean nodigimusic = true;
#else
boolean nomidimusic = false, nosound = false;
boolean nodigimusic = false; // No fmod-based music
#endif
// 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; #ifdef _XBOX
boolean midi_disabled = true, sound_disabled = true;
boolean digital_disabled = true;
#else
boolean midi_disabled = false;
boolean sound_disabled = false; boolean sound_disabled = false;
boolean digital_disabled = false; boolean digital_disabled = false;
#endif
boolean advancedemo; boolean advancedemo;
#ifdef DEBUGFILE #ifdef DEBUGFILE
@ -720,7 +717,6 @@ void D_StartTitle(void)
maptol = 0; maptol = 0;
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
displayplayer = consoleplayer = 0; displayplayer = consoleplayer = 0;
//demosequence = -1; //demosequence = -1;
gametype = GT_COOP; gametype = GT_COOP;
@ -730,11 +726,6 @@ void D_StartTitle(void)
CON_ToggleOff(); CON_ToggleOff();
// Reset the palette // Reset the palette
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_SetPaletteColor(0);
else
#endif
if (rendermode != render_none) if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL"); V_SetPaletteLump("PLAYPAL");
} }
@ -1056,19 +1047,10 @@ void D_SRB2Main(void)
if (M_CheckParm("-password") && M_IsNextParm()) if (M_CheckParm("-password") && M_IsNextParm())
D_SetPassword(M_GetNextParm()); D_SetPassword(M_GetNextParm());
else
{
size_t z;
char junkpw[25];
for (z = 0; z < 24; z++)
junkpw[z] = (char)(rand() & 64)+32;
junkpw[24] = '\0';
D_SetPassword(junkpw);
}
// add any files specified on the command line with -file wadfile // add any files specified on the command line with -file wadfile
// to the wad list // to the wad list
if (!(M_CheckParm("-connect"))) if (!(M_CheckParm("-connect") && !M_CheckParm("-server")))
{ {
if (M_CheckParm("-file")) if (M_CheckParm("-file"))
{ {
@ -1224,21 +1206,29 @@ void D_SRB2Main(void)
R_Init(); R_Init();
// setting up sound // setting up sound
CONS_Printf("S_Init(): Setting up sound.\n"); if (dedicated)
{
sound_disabled = true;
midi_disabled = digital_disabled = true;
}
else
{
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();
@ -1323,7 +1313,7 @@ void D_SRB2Main(void)
ultimatemode = true; ultimatemode = true;
} }
if (autostart || netgame || M_CheckParm("+connect") || M_CheckParm("-connect")) if (autostart || netgame)
{ {
gameaction = ga_nothing; gameaction = ga_nothing;
@ -1361,8 +1351,7 @@ void D_SRB2Main(void)
} }
} }
if (server && !M_CheckParm("+map") && !M_CheckParm("+connect") if (server && !M_CheckParm("+map"))
&& !M_CheckParm("-connect"))
{ {
// Prevent warping to nonexistent levels // Prevent warping to nonexistent levels
if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR) if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR)

View file

@ -34,7 +34,7 @@ void D_SRB2Loop(void) FUNCNORETURN;
// D_SRB2Main() // D_SRB2Main()
// Not a globally visible function, just included for source reference, // Not a globally visible function, just included for source reference,
// calls all startup code, parses command line options. // calls all startup code, parses command line options.
// If not overrided by user input, calls N_AdvanceDemo. // If not overrided by user input, calls D_AdvanceDemo.
// //
void D_SRB2Main(void); void D_SRB2Main(void);
@ -51,9 +51,6 @@ const char *D_Home(void);
// //
// BASE LEVEL // BASE LEVEL
// //
void D_PageTicker(void);
// pagename is lumpname of a 320x200 patch to fill the screen
void D_PageDrawer(const char *pagename);
void D_AdvanceDemo(void); void D_AdvanceDemo(void);
void D_StartTitle(void); void D_StartTitle(void);

View file

@ -49,7 +49,9 @@ doomcom_t *doomcom = NULL;
/// \brief network packet data, points inside doomcom /// \brief network packet data, points inside doomcom
doomdata_t *netbuffer = NULL; doomdata_t *netbuffer = NULL;
#ifdef DEBUGFILE
FILE *debugfile = NULL; // put some net info in a file during the game FILE *debugfile = NULL; // put some net info in a file during the game
#endif
#define MAXREBOUND 8 #define MAXREBOUND 8
static doomdata_t reboundstore[MAXREBOUND]; static doomdata_t reboundstore[MAXREBOUND];

View file

@ -2656,10 +2656,12 @@ static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt,
#define BASESALT "basepasswordstorage" #define BASESALT "basepasswordstorage"
static UINT8 adminpassmd5[16]; static UINT8 adminpassmd5[16];
static boolean adminpasswordset = false;
void D_SetPassword(const char *pw) void D_SetPassword(const char *pw)
{ {
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5); D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &adminpassmd5);
adminpasswordset = true;
} }
// Remote Administration // Remote Administration
@ -2731,6 +2733,12 @@ static void Got_Login(UINT8 **cp, INT32 playernum)
if (client) if (client)
return; return;
if (!adminpasswordset)
{
CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[playernum]);
return;
}
// Do the final pass to compare with the sent md5 // Do the final pass to compare with the sent md5
D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", playernum), &finalmd5); D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", playernum), &finalmd5);
@ -3947,19 +3955,18 @@ 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();
I_InitMusic(); I_InitMusic();
// 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.

View file

@ -212,7 +212,6 @@ void Command_ExitGame_f(void);
void Command_Retry_f(void); void Command_Retry_f(void);
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect);
void ObjectPlace_OnChange(void);
void ItemFinder_OnChange(void); void ItemFinder_OnChange(void);
void D_SetPassword(const char *pw); void D_SetPassword(const char *pw);

View file

@ -990,19 +990,41 @@ filestatus_t checkfilemd5(char *filename, const UINT8 *wantedmd5sum)
return FS_FOUND; // will never happen, but makes the compiler shut up return FS_FOUND; // will never happen, but makes the compiler shut up
} }
// Rewritten by Monster Iestyn to be less stupid
// Note: if completepath is true, "filename" is modified, but only if FS_FOUND is going to be returned
// (Don't worry about WinCE's version of filesearch, nobody cares about that OS anymore)
filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean completepath) filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean completepath)
{ {
filestatus_t homecheck = filesearch(filename, srb2home, wantedmd5sum, false, 10); filestatus_t homecheck; // store result of last file search
if (homecheck == FS_FOUND) boolean badmd5 = false; // store whether md5 was bad from either of the first two searches (if nothing was found in the third)
return filesearch(filename, srb2home, wantedmd5sum, completepath, 10);
homecheck = filesearch(filename, srb2path, wantedmd5sum, false, 10); // first, check SRB2's "home" directory
if (homecheck == FS_FOUND) homecheck = filesearch(filename, srb2home, wantedmd5sum, completepath, 10);
return filesearch(filename, srb2path, wantedmd5sum, completepath, 10);
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
return FS_FOUND;
else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5
badmd5 = true;
// if not found at all, just move on without doing anything
// next, check SRB2's "path" directory
homecheck = filesearch(filename, srb2path, wantedmd5sum, completepath, 10);
if (homecheck == FS_FOUND) // we found the file, so return that we have :)
return FS_FOUND;
else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5
badmd5 = true;
// if not found at all, just move on without doing anything
// finally check "." directory
#ifdef _arch_dreamcast #ifdef _arch_dreamcast
return filesearch(filename, "/cd", wantedmd5sum, completepath, 10); homecheck = filesearch(filename, "/cd", wantedmd5sum, completepath, 10);
#else #else
return filesearch(filename, ".", wantedmd5sum, completepath, 10); homecheck = filesearch(filename, ".", wantedmd5sum, completepath, 10);
#endif #endif
if (homecheck != FS_NOTFOUND) // if not found this time, fall back on the below return statement
return homecheck; // otherwise return the result we got
return (badmd5 ? FS_MD5SUMBAD : FS_NOTFOUND); // md5 sum bad or file not found
} }

View file

@ -50,7 +50,7 @@ static boolean wasPlaying;
static int cdVolume=0; // current cd volume (0-31) static int cdVolume=0; // current cd volume (0-31)
// 0-31 like Music & Sfx, though CD hardware volume is 0-255. // 0-31 like Music & Sfx, though CD hardware volume is 0-255.
consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cd_volume = {"cd_volume","18",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// allow Update for next/loop track // allow Update for next/loop track
// some crap cd drivers take up to // some crap cd drivers take up to

View file

@ -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

View file

@ -85,10 +85,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;
@ -445,19 +442,17 @@ extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF
#if defined (macintosh) #if defined (macintosh)
#define DEBFILE(msg) I_OutputMsg(msg) #define DEBFILE(msg) I_OutputMsg(msg)
extern FILE *debugfile;
#else #else
#define DEBUGFILE #define DEBUGFILE
#ifdef DEBUGFILE #ifdef DEBUGFILE
#define DEBFILE(msg) { if (debugfile) { fputs(msg, debugfile); fflush(debugfile); } } #define DEBFILE(msg) { if (debugfile) { fputs(msg, debugfile); fflush(debugfile); } }
extern FILE *debugfile;
#else #else
#define DEBFILE(msg) {} #define DEBFILE(msg) {}
extern FILE *debugfile;
#endif #endif
#endif #endif
#ifdef DEBUGFILE #ifdef DEBUGFILE
extern FILE *debugfile;
extern INT32 debugload; extern INT32 debugload;
#endif #endif

View file

@ -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;
} }

View file

@ -233,11 +233,19 @@ static void F_SkyScroll(INT32 scrollspeed)
#ifdef HWRENDER #ifdef HWRENDER
else if (rendermode != render_none) else if (rendermode != render_none)
{ // if only software rendering could be this simple and retarded { // if only software rendering could be this simple and retarded
scrolled = animtimer; INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
if (scrolled > 0) INT32 y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz;
V_DrawScaledPatch(scrolled - SHORT(pat->width), 0, 0, pat); scrolled = animtimer * dupz;
for (x = 0; x < fakedwidth; x += SHORT(pat->width)) for (x = 0; x < vid.width; x += pw)
V_DrawScaledPatch(x + scrolled, 0, 0, pat); {
for (y = 0; y < vid.height; y += ph)
{
if (scrolled > 0)
V_DrawScaledPatch(scrolled - pw, y, V_NOSCALESTART, pat);
V_DrawScaledPatch(x + scrolled, y, V_NOSCALESTART, pat);
}
}
} }
#endif #endif
@ -434,7 +442,6 @@ void F_StartIntro(void)
G_SetGamestate(GS_INTRO); G_SetGamestate(GS_INTRO);
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();
CON_ClearHUD(); CON_ClearHUD();
@ -969,7 +976,6 @@ static const char *credits[] = {
"\1Programming", "\1Programming",
"Alam \"GBC\" Arias", "Alam \"GBC\" Arias",
"Logan \"GBA\" Arias", "Logan \"GBA\" Arias",
"Tim \"RedEnchilada\" Bordelon",
"Callum Dickinson", "Callum Dickinson",
"Scott \"Graue\" Feeney", "Scott \"Graue\" Feeney",
"Nathan \"Jazz\" Giroux", "Nathan \"Jazz\" Giroux",
@ -978,12 +984,12 @@ static const char *credits[] = {
"Ronald \"Furyhunter\" Kinard", // The SDL2 port "Ronald \"Furyhunter\" Kinard", // The SDL2 port
"John \"JTE\" Muniz", "John \"JTE\" Muniz",
"Ehab \"Wolfy\" Saeed", "Ehab \"Wolfy\" Saeed",
"\"Kaito Sinclaire\"",
"\"SSNTails\"", "\"SSNTails\"",
"Matthew \"Inuyasha\" Walsh",
"", "",
"\1Programming", "\1Programming",
"\1Assistance", "\1Assistance",
"\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom) "\"chi.miru\"", // helped port slope drawing code from ZDoom
"Andrew \"orospakr\" Clunis", "Andrew \"orospakr\" Clunis",
"Gregor \"Oogaland\" Dick", "Gregor \"Oogaland\" Dick",
"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol) "Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
@ -999,7 +1005,7 @@ static const char *credits[] = {
"", "",
"\1Sprite Artists", "\1Sprite Artists",
"Odi \"Iceman404\" Atunzu", "Odi \"Iceman404\" Atunzu",
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
"Jim \"MotorRoach\" DeMello", "Jim \"MotorRoach\" DeMello",
"Desmond \"Blade\" DesJardins", "Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins", "Sherman \"CoatRack\" DesJardins",
@ -1017,7 +1023,7 @@ static const char *credits[] = {
"\1Music and Sound", "\1Music and Sound",
"\1Production", "\1Production",
"Malcolm \"RedXVI\" Brown", "Malcolm \"RedXVI\" Brown",
"David \"Bulmybag\" Bulmer", "Dave \"DemonTomatoDave\" Bulmer",
"Paul \"Boinciel\" Clempson", "Paul \"Boinciel\" Clempson",
"Cyan Helkaraxe", "Cyan Helkaraxe",
"Kepa \"Nev3r\" Iceta", "Kepa \"Nev3r\" Iceta",
@ -1041,13 +1047,13 @@ static const char *credits[] = {
"Kepa \"Nev3r\" Iceta", "Kepa \"Nev3r\" Iceta",
"Thomas \"Shadow Hog\" Igoe", "Thomas \"Shadow Hog\" Igoe",
"Erik \"Torgo\" Nielsen", "Erik \"Torgo\" Nielsen",
"\"Kaito Sinclaire\"",
"Wessel \"Spherallic\" Smit", "Wessel \"Spherallic\" Smit",
"\"Spazzo\"", "\"Spazzo\"",
"\"SSNTails\"", "\"SSNTails\"",
"Rob Tisdell", "Rob Tisdell",
"Jarrett \"JEV3\" Voight", "Jarrett \"JEV3\" Voight",
"Johnny \"Sonikku\" Wallbank", "Johnny \"Sonikku\" Wallbank",
"Matthew \"Inuyasha\" Walsh",
"Marco \"Digiku\" Zafra", "Marco \"Digiku\" Zafra",
"", "",
"\1Boss Design", "\1Boss Design",
@ -1123,7 +1129,6 @@ void F_StartCredits(void)
} }
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();
CON_ClearHUD(); CON_ClearHUD();
@ -1270,7 +1275,6 @@ void F_StartGameEvaluation(void)
G_SaveGame((UINT32)cursaveslot); G_SaveGame((UINT32)cursaveslot);
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();
CON_ClearHUD(); CON_ClearHUD();
@ -1381,7 +1385,6 @@ void F_StartGameEnd(void)
G_SetGamestate(GS_GAMEEND); G_SetGamestate(GS_GAMEEND);
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();
CON_ClearHUD(); CON_ClearHUD();
@ -1584,7 +1587,6 @@ void F_StartContinue(void)
gameaction = ga_nothing; gameaction = ga_nothing;
keypressed = false; keypressed = false;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();
CON_ClearHUD(); CON_ClearHUD();
@ -1753,7 +1755,6 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
G_SetGamestate(GS_CUTSCENE); G_SetGamestate(GS_CUTSCENE);
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();

View file

@ -3578,7 +3578,8 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
unlocktriggers = 0; unlocktriggers = 0;
// clear itemfinder, just in case // clear itemfinder, just in case
CV_StealthSetValue(&cv_itemfinder, 0); if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds
CV_StealthSetValue(&cv_itemfinder, 0);
} }
// internal game map // internal game map
@ -3605,7 +3606,6 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
mapmusflags |= MUSIC_RELOADRESET; mapmusflags |= MUSIC_RELOADRESET;
ultimatemode = pultmode; ultimatemode = pultmode;
playerdeadview = false;
automapactive = false; automapactive = false;
imcontinuing = false; imcontinuing = false;
@ -4351,6 +4351,7 @@ void G_GhostTicker(void)
p->next = g->next; p->next = g->next;
else else
ghosts = g->next; ghosts = g->next;
Z_Free(g);
continue; continue;
} }
p = g; p = g;
@ -5303,29 +5304,28 @@ void G_AddGhost(char *defdemoname)
mthing = playerstarts[0]; mthing = playerstarts[0];
I_Assert(mthing); I_Assert(mthing);
{ // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling. { // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling.
fixed_t x,y,z; fixed_t z,f,c;
sector_t *sector; gh->mo = P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST);
x = mthing->x << FRACBITS; gh->mo->angle = FixedAngle(mthing->angle*FRACUNIT);
y = mthing->y << FRACBITS; f = gh->mo->floorz;
sector = R_PointInSubsector(x, y)->sector; c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height;
if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP)) if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP))
{ {
z = sector->ceilingheight - mobjinfo[MT_PLAYER].height; z = c;
if (mthing->options >> ZSHIFT) if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS); z -= ((mthing->options >> ZSHIFT) << FRACBITS);
if (z < sector->floorheight) if (z < f)
z = sector->floorheight; z = f;
} }
else else
{ {
z = sector->floorheight; z = f;
if (mthing->options >> ZSHIFT) if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS); z += ((mthing->options >> ZSHIFT) << FRACBITS);
if (z > sector->ceilingheight - mobjinfo[MT_PLAYER].height) if (z > c)
z = sector->ceilingheight - mobjinfo[MT_PLAYER].height; z = c;
} }
gh->mo = P_SpawnMobj(x, y, z, MT_GHOST); gh->mo->z = z;
gh->mo->angle = FixedAngle(mthing->angle*FRACUNIT);
} }
gh->mo->state = states+S_PLAY_STND; gh->mo->state = states+S_PLAY_STND;
gh->mo->sprite = gh->mo->state->sprite; gh->mo->sprite = gh->mo->state->sprite;
@ -5523,8 +5523,14 @@ boolean G_CheckDemoStatus(void)
{ {
boolean saved; boolean saved;
if(ghosts) // ... ... ... while (ghosts)
ghosts = NULL; // :) {
demoghost *next = ghosts->next;
Z_Free(ghosts);
ghosts = next;
}
ghosts = NULL;
// DO NOT end metal sonic demos here // DO NOT end metal sonic demos here

View file

@ -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];

View file

@ -564,8 +564,6 @@ static inline void HWR_SubsecPoly(INT32 num, poly_t *poly)
subsector_t *sub; subsector_t *sub;
seg_t *lseg; seg_t *lseg;
sscount++;
sub = &subsectors[num]; sub = &subsectors[num];
count = sub->numlines; count = sub->numlines;
lseg = &segs[sub->firstline]; lseg = &segs[sub->firstline];

View file

@ -20,8 +20,8 @@
#define _HWR_DEFS_ #define _HWR_DEFS_
#include "../doomtype.h" #include "../doomtype.h"
#define ZCLIP_PLANE 4.0f #define ZCLIP_PLANE 4.0f // Used for the actual game drawing
#define NZCLIP_PLANE 0.9f #define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures
// ========================================================================== // ==========================================================================
// SIMPLE TYPES // SIMPLE TYPES
@ -133,12 +133,13 @@ enum EPolyFlags
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture) PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture)
PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency
PF_Additive = 0x00000024, // Poly is added to the frame buffer PF_Additive = 0x00000004, // Poly is added to the frame buffer
PF_Environment = 0x00000008, // Poly should be drawn environment mapped. PF_Environment = 0x00000008, // Poly should be drawn environment mapped.
// Hurdler: used for text drawing // Hurdler: used for text drawing
PF_Substractive = 0x00000010, // for splat PF_Substractive = 0x00000010, // for splat
PF_NoAlphaTest = 0x00000020, // hiden param PF_NoAlphaTest = 0x00000020, // hiden param
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive)&~PF_NoAlphaTest, PF_Fog = 0x00000040, // Fog blocks
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest,
// other flag bits // other flag bits

View file

@ -147,10 +147,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; float dupx, dupy, fscale, fwidth, fheight;
float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale);
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale);
if (alphalevel >= 10 && alphalevel < 13) if (alphalevel >= 10 && alphalevel < 13)
return; return;
@ -161,40 +158,108 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
else else
HWR_GetMappedPatch(gpatch, colormap); HWR_GetMappedPatch(gpatch, colormap);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
switch (option & V_SCALEPATCHMASK) switch (option & V_SCALEPATCHMASK)
{ {
case V_NOSCALEPATCH: case V_NOSCALEPATCH:
pdupx = pdupy = 2.0f; dupx = dupy = 1.0f;
break; break;
case V_SMALLSCALEPATCH: case V_SMALLSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); dupx = (float)vid.smalldupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); dupy = (float)vid.smalldupy;
break; break;
case V_MEDSCALEPATCH: case V_MEDSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); dupx = (float)vid.meddupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); dupy = (float)vid.meddupy;
break; break;
} }
if (option & V_NOSCALESTART) dupx = dupy = (dupx < dupy ? dupx : dupy);
sdupx = sdupy = 2.0f; fscale = FIXED_TO_FLOAT(pscale);
if (option & V_SPLITSCREEN) if (option & V_OFFSET)
sdupy /= 2.0f;
if (option & V_FLIP) // Need to flip both this and sow
{ {
v[0].x = v[3].x = (cx*sdupx-(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; cx -= (float)gpatch->leftoffset * dupx * fscale;
v[2].x = v[1].x = (cx*sdupx+gpatch->leftoffset*pdupx)/vid.width - 1; cy -= (float)gpatch->topoffset * dupy * fscale;
} }
else else
{ {
v[0].x = v[3].x = (cx*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1; cy -= (float)gpatch->topoffset * fscale;
v[2].x = v[1].x = (cx*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; if (option & V_FLIP)
cx -= ((float)gpatch->width - (float)gpatch->leftoffset) * fscale;
else
cx -= (float)gpatch->leftoffset * fscale;
} }
v[0].y = v[1].y = 1-(cy*sdupy-gpatch->topoffset*pdupy)/vid.height; if (option & V_SPLITSCREEN)
v[2].y = v[3].y = 1-(cy*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height; cy /= 2;
if (!(option & V_NOSCALESTART))
{
cx = cx * dupx;
cy = cy * dupy;
if (!(option & V_SCALEPATCHMASK))
{
// if it's meant to cover the whole screen, black out the rest
// cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
Z_Free(realpatch);
}
// centre screen
if (vid.width != BASEVIDWIDTH * vid.dupx)
{
if (option & V_SNAPTORIGHT)
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
if (vid.height != BASEVIDHEIGHT * vid.dupy)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
else if (option & V_SNAPTOBOTTOM)
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
}
}
}
if (pscale != FRACUNIT)
{
fwidth = (float)gpatch->width * fscale * dupx;
fheight = (float)gpatch->height * fscale * dupy;
}
else
{
fwidth = (float)gpatch->width * dupx;
fheight = (float)gpatch->height * dupy;
}
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
cx = -1 + (cx / (vid.width/2));
cy = 1 - (cy / (vid.height/2));
// fwidth and fheight are similar
fwidth /= vid.width / 2;
fheight /= vid.height / 2;
// set the polygon vertices to the right positions
v[0].x = v[3].x = cx;
v[2].x = v[1].x = cx + fwidth;
v[0].y = v[1].y = cy;
v[2].y = v[3].y = cy - fheight;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
@ -247,10 +312,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; float dupx, dupy, fscale, fwidth, fheight;
float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale);
float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale);
if (alphalevel >= 10 && alphalevel < 13) if (alphalevel >= 10 && alphalevel < 13)
return; return;
@ -258,28 +320,109 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
// make patch ready in hardware cache // make patch ready in hardware cache
HWR_GetPatch(gpatch); HWR_GetPatch(gpatch);
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
switch (option & V_SCALEPATCHMASK) switch (option & V_SCALEPATCHMASK)
{ {
case V_NOSCALEPATCH: case V_NOSCALEPATCH:
pdupx = pdupy = 2.0f; dupx = dupy = 1.0f;
break; break;
case V_SMALLSCALEPATCH: case V_SMALLSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); dupx = (float)vid.smalldupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); dupy = (float)vid.smalldupy;
break; break;
case V_MEDSCALEPATCH: case V_MEDSCALEPATCH:
pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); dupx = (float)vid.meddupx;
pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); dupy = (float)vid.meddupy;
break; break;
} }
if (option & V_NOSCALESTART) dupx = dupy = (dupx < dupy ? dupx : dupy);
sdupx = sdupy = 2.0f; fscale = FIXED_TO_FLOAT(pscale);
v[0].x = v[3].x = (cx*sdupx - gpatch->leftoffset * pdupx) / vid.width - 1; cy -= (float)gpatch->topoffset * fscale;
v[2].x = v[1].x = (cx*sdupx + ((w-sx) - gpatch->leftoffset) * pdupx) / vid.width - 1; cx -= (float)gpatch->leftoffset * fscale;
v[0].y = v[1].y = 1 - (cy*sdupy - gpatch->topoffset * pdupy) / vid.height;
v[2].y = v[3].y = 1 - (cy*sdupy + ((h-sy) - gpatch->topoffset) * pdupy) / vid.height; if (!(option & V_NOSCALESTART))
{
cx = cx * dupx;
cy = cy * dupy;
if (!(option & V_SCALEPATCHMASK))
{
// if it's meant to cover the whole screen, black out the rest
// cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
Z_Free(realpatch);
}
// centre screen
if (vid.width != BASEVIDWIDTH * vid.dupx)
{
if (option & V_SNAPTORIGHT)
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
if (vid.height != BASEVIDHEIGHT * vid.dupy)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
else if (option & V_SNAPTOBOTTOM)
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(option & V_SNAPTOTOP))
cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2;
}
}
}
fwidth = w;
fheight = h;
if (fwidth > w - sx)
fwidth = w - sx;
if (fheight > h - sy)
fheight = h - sy;
if (fwidth > gpatch->width)
fwidth = gpatch->width;
if (fheight > gpatch->height)
fheight = gpatch->height;
if (pscale != FRACUNIT)
{
fwidth *= fscale * dupx;
fheight *= fscale * dupy;
}
else
{
fwidth *= dupx;
fheight *= dupy;
}
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
cx = -1 + (cx / (vid.width/2));
cy = 1 - (cy / (vid.height/2));
// fwidth and fheight are similar
fwidth /= vid.width / 2;
fheight /= vid.height / 2;
// set the polygon vertices to the right positions
v[0].x = v[3].x = cx;
v[2].x = v[1].x = cx + fwidth;
v[0].y = v[1].y = cy;
v[2].y = v[3].y = cy - fheight;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
@ -656,7 +799,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
{ {
FOutVector v[4]; FOutVector v[4];
FSurfaceInfo Surf; FSurfaceInfo Surf;
float sdupx, sdupy; float fx, fy, fw, fh;
if (w < 0 || h < 0) if (w < 0 || h < 0)
return; // consistency w/ software return; // consistency w/ software
@ -665,16 +808,79 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
// | /| // | /|
// |/ | // |/ |
// 0--1 // 0--1
sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f;
sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f;
if (color & V_NOSCALESTART) fx = (float)x;
sdupx = sdupy = 2.0f; fy = (float)y;
fw = (float)w;
fh = (float)h;
v[0].x = v[3].x = (x*sdupx)/vid.width - 1; if (!(color & V_NOSCALESTART))
v[2].x = v[1].x = (x*sdupx + w*sdupx)/vid.width - 1; {
v[0].y = v[1].y = 1-(y*sdupy)/vid.height; float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
v[2].y = v[3].y = 1-(y*sdupy + h*sdupy)/vid.height;
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{
RGBA_t rgbaColour = V_GetColor(color);
FRGBAFloat clearColour;
clearColour.red = (float)rgbaColour.s.red / 255;
clearColour.green = (float)rgbaColour.s.green / 255;
clearColour.blue = (float)rgbaColour.s.blue / 255;
clearColour.alpha = 1;
HWD.pfnClearBuffer(true, false, &clearColour);
return;
}
fx *= dupx;
fy *= dupy;
fw *= dupx;
fh *= dupy;
if (vid.width != BASEVIDWIDTH * vid.dupx)
{
if (color & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (vid.height != BASEVIDHEIGHT * dupy)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(color & V_SNAPTOTOP))
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
}
if (fx >= vid.width || fy >= vid.height)
return;
if (fx < 0)
{
fw += fx;
fx = 0;
}
if (fy < 0)
{
fh += fy;
fy = 0;
}
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = (float)vid.height - fy;
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
v[0].y = v[1].y = fy;
v[2].y = v[3].y = fy - fh;
//Hurdler: do we still use this argb color? if not, we should remove it //Hurdler: do we still use this argb color? if not, we should remove it
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;

View file

@ -79,6 +79,7 @@ EXPORT char *HWRAPI(GetRenderer) (void);
#define SCREENVERTS 10 #define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
#endif #endif
EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(StartScreenWipe) (void);
EXPORT void HWRAPI(EndScreenWipe) (void); EXPORT void HWRAPI(EndScreenWipe) (void);
EXPORT void HWRAPI(DoScreenWipe) (float alpha); EXPORT void HWRAPI(DoScreenWipe) (float alpha);
@ -124,6 +125,7 @@ struct hwdriver_s
#ifdef SHUFFLE #ifdef SHUFFLE
PostImgRedraw pfnPostImgRedraw; PostImgRedraw pfnPostImgRedraw;
#endif #endif
FlushScreenTextures pfnFlushScreenTextures;
StartScreenWipe pfnStartScreenWipe; StartScreenWipe pfnStartScreenWipe;
EndScreenWipe pfnEndScreenWipe; EndScreenWipe pfnEndScreenWipe;
DoScreenWipe pfnDoScreenWipe; DoScreenWipe pfnDoScreenWipe;

View file

@ -68,6 +68,7 @@ typedef struct gr_vissprite_s
struct gr_vissprite_s *prev; struct gr_vissprite_s *prev;
struct gr_vissprite_s *next; struct gr_vissprite_s *next;
float x1, x2; float x1, x2;
float z1, z2;
float tz, ty; float tz, ty;
lumpnum_t patchlumpnum; lumpnum_t patchlumpnum;
boolean flip; boolean flip;

File diff suppressed because it is too large Load diff

View file

@ -33,6 +33,7 @@
#include "hw_drv.h" #include "hw_drv.h"
#include "hw_light.h" #include "hw_light.h"
#include "hw_md2.h" #include "hw_md2.h"
#include "../d_main.h"
#include "../r_bsp.h" #include "../r_bsp.h"
#include "../r_main.h" #include "../r_main.h"
#include "../m_misc.h" #include "../m_misc.h"
@ -67,6 +68,10 @@
#endif #endif
#endif #endif
#ifndef errno
#include "errno.h"
#endif
#define NUMVERTEXNORMALS 162 #define NUMVERTEXNORMALS 162
float avertexnormals[NUMVERTEXNORMALS][3] = { float avertexnormals[NUMVERTEXNORMALS][3] = {
{-0.525731f, 0.000000f, 0.850651f}, {-0.525731f, 0.000000f, 0.850651f},
@ -288,7 +293,8 @@ static md2_model_t *md2_readModel(const char *filename)
if (model == NULL) if (model == NULL)
return 0; return 0;
file = fopen(filename, "rb"); //Filename checking fixed ~Monster Iestyn and Golden
file = fopen(va("%s"PATHSEP"%s", srb2home, filename), "rb");
if (!file) if (!file)
{ {
free(model); free(model);
@ -477,7 +483,8 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
#endif #endif
#endif #endif
png_FILE_p png_FILE; png_FILE_p png_FILE;
char *pngfilename = va("md2/%s", filename); //Filename checking fixed ~Monster Iestyn and Golden
char *pngfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename);
FIL_ForceExtension(pngfilename, ".png"); FIL_ForceExtension(pngfilename, ".png");
png_FILE = fopen(pngfilename, "rb"); png_FILE = fopen(pngfilename, "rb");
@ -605,7 +612,8 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
size_t pw, ph, size, ptr = 0; size_t pw, ph, size, ptr = 0;
INT32 ch, rep; INT32 ch, rep;
FILE *file; FILE *file;
char *pcxfilename = va("md2/%s", filename); //Filename checking fixed ~Monster Iestyn and Golden
char *pcxfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename);
FIL_ForceExtension(pcxfilename, ".pcx"); FIL_ForceExtension(pcxfilename, ".pcx");
file = fopen(pcxfilename, "rb"); file = fopen(pcxfilename, "rb");
@ -795,11 +803,12 @@ void HWR_InitMD2(void)
} }
// read the md2.dat file // read the md2.dat file
f = fopen("md2.dat", "rt"); //Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt");
if (!f) if (!f)
{ {
CONS_Printf("%s", M_GetText("Error while loading md2.dat\n")); CONS_Printf("%s %s\n", M_GetText("Error while loading md2.dat:"), strerror(errno));
nomd2s = true; nomd2s = true;
return; return;
} }
@ -861,7 +870,8 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup
CONS_Printf("AddPlayerMD2()...\n"); CONS_Printf("AddPlayerMD2()...\n");
// read the md2.dat file // read the md2.dat file
f = fopen("md2.dat", "rt"); //Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt");
if (!f) if (!f)
{ {
@ -906,7 +916,8 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu
return; return;
// Read the md2.dat file // Read the md2.dat file
f = fopen("md2.dat", "rt"); //Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "md2.dat"), "rt");
if (!f) if (!f)
{ {
@ -1347,7 +1358,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames; frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
buff = md2->model->glCommandBuffer; buff = md2->model->glCommandBuffer;
curr = &md2->model->frames[frame]; curr = &md2->model->frames[frame];
if (cv_grmd2.value == 1) if (cv_grmd2.value == 1 && tics <= durs)
{ {
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
if (spr->mobj->frame & FF_ANIMATE) if (spr->mobj->frame & FF_ANIMATE)

View file

@ -59,7 +59,7 @@ typedef struct GLRGBAFloat GLRGBAFloat;
#define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f)
#define ASPECT_RATIO (1.0f) //(320.0f/200.0f) #define ASPECT_RATIO (1.0f) //(320.0f/200.0f)
#define FAR_CLIPPING_PLANE 150000.0f // Draw further! Tails 01-21-2001 #define FAR_CLIPPING_PLANE 32768.0f // Draw further! Tails 01-21-2001
static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE;
// ************************************************************************** // **************************************************************************
@ -107,10 +107,19 @@ static GLint viewport[4];
#endif #endif
// Yay for arbitrary numbers! NextTexAvail is buggy for some reason. // Yay for arbitrary numbers! NextTexAvail is buggy for some reason.
static GLuint screentexture = 60000; // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing
static GLuint startScreenWipe = 60001; // flush all of the stored textures, leaving them unavailable at times such as between levels
static GLuint endScreenWipe = 60002; // These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs
static GLuint finalScreenTexture = 60003; // can know when the textures aren't there, as textures are always considered resident in their virtual memory
// TODO: Store them in a more normal way
#define SCRTEX_SCREENTEXTURE 65535
#define SCRTEX_STARTSCREENWIPE 65534
#define SCRTEX_ENDSCREENWIPE 65533
#define SCRTEX_FINALSCREENTEXTURE 65532
static GLuint screentexture = 0;
static GLuint startScreenWipe = 0;
static GLuint endScreenWipe = 0;
static GLuint finalScreenTexture = 0;
#if 0 #if 0
GLuint screentexture = FIRST_TEX_AVAIL; GLuint screentexture = FIRST_TEX_AVAIL;
#endif #endif
@ -263,6 +272,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
/* texture mapping */ //GL_EXT_copy_texture /* texture mapping */ //GL_EXT_copy_texture
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
#define pglCopyTexImage2D glCopyTexImage2D #define pglCopyTexImage2D glCopyTexImage2D
#define pglCopyTexSubImage2D glCopyTexSubImage2D
#endif #endif
#else //!STATIC_OPENGL #else //!STATIC_OPENGL
@ -387,6 +397,8 @@ static PFNglBindTexture pglBindTexture;
/* texture mapping */ //GL_EXT_copy_texture /* texture mapping */ //GL_EXT_copy_texture
typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
static PFNglCopyTexImage2D pglCopyTexImage2D; static PFNglCopyTexImage2D pglCopyTexImage2D;
typedef void (APIENTRY * PFNglCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
static PFNglCopyTexSubImage2D pglCopyTexSubImage2D;
#endif #endif
/* GLU functions */ /* GLU functions */
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data); typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
@ -503,6 +515,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglBindTexture , glBindTexture) GETOPENGLFUNC(pglBindTexture , glBindTexture)
GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D) GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D)
GETOPENGLFUNC(pglCopyTexSubImage2D , glCopyTexSubImage2D)
#undef GETOPENGLFUNC #undef GETOPENGLFUNC
@ -654,6 +667,10 @@ void SetModelView(GLint w, GLint h)
{ {
// DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); // DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h);
// The screen textures need to be flushed if the width or height change so that they be remade for the correct size
if (screen_width != w || screen_height != h)
FlushScreenTextures();
screen_width = w; screen_width = w;
screen_height = h; screen_height = h;
@ -801,6 +818,7 @@ void Flush(void)
screentexture = FIRST_TEX_AVAIL; screentexture = FIRST_TEX_AVAIL;
} }
#endif #endif
tex_downloaded = 0; tex_downloaded = 0;
} }
@ -1056,30 +1074,56 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
switch (PolyFlags & PF_Blending) { switch (PolyFlags & PF_Blending) {
case PF_Translucent & PF_Blending: case PF_Translucent & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break; break;
case PF_Masked & PF_Blending: case PF_Masked & PF_Blending:
// Hurdler: does that mean lighting is only made by alpha src? // Hurdler: does that mean lighting is only made by alpha src?
// it sounds ok, but not for polygonsmooth // it sounds ok, but not for polygonsmooth
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_GREATER, 0.5f);
#endif
break; break;
case PF_Additive & PF_Blending: case PF_Additive & PF_Blending:
#ifdef ATI_RAGE_PRO_COMPATIBILITY #ifdef ATI_RAGE_PRO_COMPATIBILITY
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
#else #else
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
#endif
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif #endif
break; break;
case PF_Environment & PF_Blending: case PF_Environment & PF_Blending:
pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break; break;
case PF_Substractive & PF_Blending: case PF_Substractive & PF_Blending:
// good for shadow // good for shadow
// not realy but what else ? // not realy but what else ?
pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break;
case PF_Fog & PF_Fog:
// Sryder: Fog
// multiplies input colour by input alpha, and destination colour by input colour, then adds them
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
#endif
break; break;
default : // must be 0, otherwise it's an error default : // must be 0, otherwise it's an error
// No blending // No blending
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
#ifndef KOS_GL_COMPATIBILITY
pglAlphaFunc(GL_GREATER, 0.5f);
#endif
break; break;
} }
} }
@ -1339,6 +1383,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
tex[w*j+i].s.green = 0; tex[w*j+i].s.green = 0;
tex[w*j+i].s.blue = 0; tex[w*j+i].s.blue = 0;
tex[w*j+i].s.alpha = 0; tex[w*j+i].s.alpha = 0;
pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it
} }
else else
{ {
@ -1409,8 +1454,22 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
tex_downloaded = pTexInfo->downloaded; tex_downloaded = pTexInfo->downloaded;
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); if (pTexInfo->flags & TF_TRANSPARENT)
{
#ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NONE);
#else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif
}
else
{
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
}
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexImage2D(GL_TEXTURE_2D, 0, GL_ARGB4444, w, h, 0, GL_ARGB4444, GL_UNSIGNED_BYTE, ptex); pglTexImage2D(GL_TEXTURE_2D, 0, GL_ARGB4444, w, h, 0, GL_ARGB4444, GL_UNSIGNED_BYTE, ptex);
@ -1864,12 +1923,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
ambient[1] = 0.75f; ambient[1] = 0.75f;
if (ambient[2] > 0.75f) if (ambient[2] > 0.75f)
ambient[2] = 0.75f; ambient[2] = 0.75f;
if (color[3] < 255)
{
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
pglDepthMask(GL_FALSE);
}
} }
pglEnable(GL_CULL_FACE); pglEnable(GL_CULL_FACE);
@ -1896,10 +1949,12 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
#endif #endif
if (color[3] < 255)
SetBlend(PF_Translucent|PF_Modulated|PF_Clip);
else
SetBlend(PF_Masked|PF_Modulated|PF_Occlude|PF_Clip);
} }
DrawPolygon(NULL, NULL, 0, PF_Masked|PF_Modulated|PF_Occlude|PF_Clip);
pglPushMatrix(); // should be the same as glLoadIdentity pglPushMatrix(); // should be the same as glLoadIdentity
//Hurdler: now it seems to work //Hurdler: now it seems to work
pglTranslatef(pos->x, pos->z, pos->y); pglTranslatef(pos->x, pos->z, pos->y);
@ -1907,14 +1962,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
scaley = -scaley; scaley = -scaley;
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f); pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
//pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
// Remove depth mask when the model is transparent so it doesn't cut thorugh sprites // SRB2CBTODO: For all stuff too?!
if (color && color[3] < 255)
{
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
pglDepthMask(GL_FALSE);
}
val = *gl_cmd_buffer++; val = *gl_cmd_buffer++;
@ -1982,7 +2029,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
if (color) if (color)
pglDisable(GL_LIGHTING); pglDisable(GL_LIGHTING);
pglShadeModel(GL_FLAT); pglShadeModel(GL_FLAT);
pglDepthMask(GL_TRUE);
pglDisable(GL_CULL_FACE); pglDisable(GL_CULL_FACE);
} }
@ -2135,10 +2181,25 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2])
} }
#endif //SHUFFLE #endif //SHUFFLE
// Sryder: This needs to be called whenever the screen changes resolution in order to reset the screen textures to use
// a new size
EXPORT void HWRAPI(FlushScreenTextures) (void)
{
pglDeleteTextures(1, &screentexture);
pglDeleteTextures(1, &startScreenWipe);
pglDeleteTextures(1, &endScreenWipe);
pglDeleteTextures(1, &finalScreenTexture);
screentexture = 0;
startScreenWipe = 0;
endScreenWipe = 0;
finalScreenTexture = 0;
}
// Create Screen to fade from // Create Screen to fade from
EXPORT void HWRAPI(StartScreenWipe) (void) EXPORT void HWRAPI(StartScreenWipe) (void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (startScreenWipe == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -2147,27 +2208,38 @@ EXPORT void HWRAPI(StartScreenWipe) (void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
startScreenWipe = SCRTEX_STARTSCREENWIPE;
pglBindTexture(GL_TEXTURE_2D, startScreenWipe); pglBindTexture(GL_TEXTURE_2D, startScreenWipe);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else #else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif #endif
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = startScreenWipe;
} }
// Create Screen to fade to // Create Screen to fade to
EXPORT void HWRAPI(EndScreenWipe)(void) EXPORT void HWRAPI(EndScreenWipe)(void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (endScreenWipe == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -2176,21 +2248,32 @@ EXPORT void HWRAPI(EndScreenWipe)(void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
endScreenWipe = SCRTEX_ENDSCREENWIPE;
pglBindTexture(GL_TEXTURE_2D, endScreenWipe); pglBindTexture(GL_TEXTURE_2D, endScreenWipe);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else #else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif #endif
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
tex_downloaded = endScreenWipe;
} }
@ -2232,7 +2315,7 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void)
pglEnd(); pglEnd();
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = screentexture;
} }
// Do screen fades! // Do screen fades!
@ -2323,6 +2406,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit
pglActiveTexture(GL_TEXTURE0); pglActiveTexture(GL_TEXTURE0);
tex_downloaded = endScreenWipe;
} }
else else
{ {
@ -2348,11 +2432,10 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
pglTexCoord2f(xfix, 0.0f); pglTexCoord2f(xfix, 0.0f);
pglVertex3f(1.0f, -1.0f, 1.0f); pglVertex3f(1.0f, -1.0f, 1.0f);
pglEnd(); pglEnd();
tex_downloaded = endScreenWipe;
#ifndef MINI_GL_COMPATIBILITY #ifndef MINI_GL_COMPATIBILITY
} }
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
} }
@ -2360,6 +2443,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
EXPORT void HWRAPI(MakeScreenTexture) (void) EXPORT void HWRAPI(MakeScreenTexture) (void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (screentexture == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -2368,26 +2452,37 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
screentexture = SCRTEX_SCREENTEXTURE;
pglBindTexture(GL_TEXTURE_2D, screentexture); pglBindTexture(GL_TEXTURE_2D, screentexture);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else #else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif #endif
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = screentexture;
} }
EXPORT void HWRAPI(MakeScreenFinalTexture) (void) EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
{ {
INT32 texsize = 2048; INT32 texsize = 2048;
boolean firstTime = (finalScreenTexture == 0);
// Use a power of two texture, dammit // Use a power of two texture, dammit
if(screen_width <= 512) if(screen_width <= 512)
@ -2396,27 +2491,40 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
texsize = 1024; texsize = 1024;
// Create screen texture // Create screen texture
if (firstTime)
finalScreenTexture = SCRTEX_FINALSCREENTEXTURE;
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
if (firstTime)
{
#ifdef KOS_GL_COMPATIBILITY #ifdef KOS_GL_COMPATIBILITY
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE);
#else #else
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
#endif #endif
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
}
else
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
#endif #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = finalScreenTexture;
} }
EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
{ {
float xfix, yfix; float xfix, yfix;
float origaspect, newaspect;
float xoff = 1, yoff = 1; // xoffset and yoffset for the polygon to have black bars around the screen
FRGBAFloat clearColour;
INT32 texsize = 2048; INT32 texsize = 2048;
if(screen_width <= 1024) if(screen_width <= 1024)
@ -2427,35 +2535,47 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height)
xfix = 1/((float)(texsize)/((float)((screen_width)))); xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height)))); yfix = 1/((float)(texsize)/((float)((screen_height))));
//pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); origaspect = (float)screen_width / screen_height;
newaspect = (float)width / height;
if (origaspect < newaspect)
{
xoff = origaspect / newaspect;
yoff = 1;
}
else if (origaspect > newaspect)
{
xoff = 1;
yoff = newaspect / origaspect;
}
pglViewport(0, 0, width, height); pglViewport(0, 0, width, height);
clearColour.red = clearColour.green = clearColour.blue = 0;
clearColour.alpha = 1;
ClearBuffer(true, false, &clearColour);
pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture);
pglBegin(GL_QUADS); pglBegin(GL_QUADS);
pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Bottom left // Bottom left
pglTexCoord2f(0.0f, 0.0f); pglTexCoord2f(0.0f, 0.0f);
pglVertex3f(-1, -1, 1.0f); pglVertex3f(-xoff, -yoff, 1.0f);
// Top left // Top left
pglTexCoord2f(0.0f, yfix); pglTexCoord2f(0.0f, yfix);
pglVertex3f(-1, 1, 1.0f); pglVertex3f(-xoff, yoff, 1.0f);
// Top right // Top right
pglTexCoord2f(xfix, yfix); pglTexCoord2f(xfix, yfix);
pglVertex3f(1, 1, 1.0f); pglVertex3f(xoff, yoff, 1.0f);
// Bottom right // Bottom right
pglTexCoord2f(xfix, 0.0f); pglTexCoord2f(xfix, 0.0f);
pglVertex3f(1, -1, 1.0f); pglVertex3f(xoff, -yoff, 1.0f);
pglEnd(); pglEnd();
SetModelView(screen_width, screen_height); tex_downloaded = finalScreenTexture;
SetStates();
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
} }
#endif //HWRENDER #endif //HWRENDER

View file

@ -78,9 +78,6 @@ extern boolean chat_on;
// set true whenever the tab rankings are being shown for any reason // set true whenever the tab rankings are being shown for any reason
extern boolean hu_showscores; extern boolean hu_showscores;
// P_DeathThink sets this true to show scores while dead, in multiplayer
extern boolean playerdeadview;
// init heads up data at game startup. // init heads up data at game startup.
void HU_Init(void); void HU_Init(void);

View file

@ -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

View file

@ -77,7 +77,9 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
deny: deny:
//must be hacked/buggy client //must be hacked/buggy client
lua_settop(gL, 0); // clear stack if (gL) // check if Lua is actually turned on first, you dummmy -- Monster Iestyn 04/07/18
lua_settop(gL, 0); // clear stack
CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]);
if (server) if (server)
{ {

View file

@ -182,19 +182,21 @@ 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;
name = malloc(strlen(wadfiles[wad]->filename)+10); len = strlen(wadfiles[wad]->filename);
name = malloc(len+10);
strcpy(name, wadfiles[wad]->filename); strcpy(name, wadfiles[wad]->filename);
if (!fasticmp(&name[strlen(name) - 4], ".lua")) { if (!fasticmp(&name[len - 4], ".lua")) {
// If it's not a .lua file, copy the lump name in too. // If it's not a .lua file, copy the lump name in too.
name[strlen(wadfiles[wad]->filename)] = '|'; name[len] = '|';
M_Memcpy(name+strlen(wadfiles[wad]->filename)+1, wadfiles[wad]->lumpinfo[lump].name, 8); M_Memcpy(name+len+1, wadfiles[wad]->lumpinfo[lump].name, 8);
name[strlen(wadfiles[wad]->filename)+9] = '\0'; name[len+9] = '\0';
} }
LUA_LoadFile(&f, name); LUA_LoadFile(&f, name);
@ -851,7 +853,7 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
LUA_PushUserdata(gL, &sectors[READUINT16(save_p)], META_SECTOR); LUA_PushUserdata(gL, &sectors[READUINT16(save_p)], META_SECTOR);
break; break;
case ARCH_MAPHEADER: case ARCH_MAPHEADER:
LUA_PushUserdata(gL, &sectors[READUINT16(save_p)], META_MAPHEADER); LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
break; break;
case ARCH_TEND: case ARCH_TEND:
return 1; return 1;

View file

@ -492,7 +492,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);

View file

@ -33,7 +33,9 @@
*/ */
fixed_t FixedMul(fixed_t a, fixed_t b) fixed_t FixedMul(fixed_t a, fixed_t b)
{ {
return (fixed_t)((((INT64)a * b) ) / FRACUNIT); // Need to cast to unsigned before shifting to avoid undefined behaviour
// for negative integers
return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS);
} }
#endif //__USE_C_FIXEDMUL__ #endif //__USE_C_FIXEDMUL__

View file

@ -6295,6 +6295,13 @@ static void M_DrawConnectIPMenu(void)
static void M_ConnectIP(INT32 choice) static void M_ConnectIP(INT32 choice)
{ {
(void)choice; (void)choice;
if (*setupm_ip == 0)
{
M_StartMessage("You must specify an IP address.\n", NULL, MM_NOTHING);
return;
}
COM_BufAddText(va("connect \"%s\"\n", setupm_ip)); COM_BufAddText(va("connect \"%s\"\n", setupm_ip));
// A little "please wait" message. // A little "please wait" message.
@ -6536,7 +6543,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
if (choice < 32 || choice > 127 || itemOn != 0) if (choice < 32 || choice > 127 || itemOn != 0)
break; break;
l = strlen(setupm_name); l = strlen(setupm_name);
if (l < MAXPLAYERNAME-1) if (l < MAXPLAYERNAME)
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_name[l] =(char)choice; setupm_name[l] =(char)choice;
@ -6943,82 +6950,95 @@ static void M_ChangeControl(INT32 choice)
// Toggles sound systems in-game. // Toggles sound systems in-game.
static void M_ToggleSFX(void) static void M_ToggleSFX(void)
{ {
if (nosound) if (sound_disabled)
{ {
nosound = false; sound_disabled = false;
I_StartupSound(); S_InitSfxChannels(cv_soundvolume.value);
if (nosound) return; S_StartSound(NULL, sfx_strpst);
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
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; M_StartMessage(M_GetText("SFX Disabled\n"), NULL, MM_NOTHING);
M_StartMessage(M_GetText("SFX Enabled\n"), NULL, MM_NOTHING);
}
else
{
sound_disabled = true;
S_StopSounds();
M_StartMessage(M_GetText("SFX Disabled\n"), NULL, MM_NOTHING);
}
} }
} }
static void M_ToggleDigital(void) static void M_ToggleDigital(void)
{ {
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();
S_ChangeMusicInternal("lclear", false); if (Playing())
P_RestoreMusic(&players[consoleplayer]);
else
S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING);
} }
else else
{ {
if (digital_disabled) digital_disabled = true;
if (S_MusicType() != MU_MID)
{ {
digital_disabled = false; if (midi_disabled)
M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); S_StopMusic();
} else
else {
{ char mmusic[7];
digital_disabled = true; UINT16 mflags;
S_StopMusic(); boolean looping;
M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING);
if (S_MusicInfo(mmusic, &mflags, &looping) && S_MIDIExists(mmusic))
{
S_StopMusic();
S_ChangeMusic(mmusic, mflags, looping);
}
else
S_StopMusic();
}
} }
M_StartMessage(M_GetText("Digital Music Disabled\n"), NULL, MM_NOTHING);
} }
} }
static void M_ToggleMIDI(void) static void M_ToggleMIDI(void)
{ {
if (nomidimusic) if (midi_disabled)
{ {
nomidimusic = false; midi_disabled = false;
I_InitMIDIMusic(); I_InitMusic();
if (nomidimusic) return; if (Playing())
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); P_RestoreMusic(&players[consoleplayer]);
S_ChangeMusicInternal("lclear", false); else
S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING);
} }
else else
{ {
if (music_disabled) midi_disabled = true;
if (S_MusicType() == MU_MID)
{ {
music_disabled = false; if (digital_disabled)
M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); S_StopMusic();
} else
else {
{ char mmusic[7];
music_disabled = true; UINT16 mflags;
S_StopMusic(); boolean looping;
M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING);
if (S_MusicInfo(mmusic, &mflags, &looping) && S_DigExists(mmusic))
{
S_StopMusic();
S_ChangeMusic(mmusic, mflags, looping);
}
else
S_StopMusic();
}
} }
M_StartMessage(M_GetText("MIDI Music Disabled\n"), NULL, MM_NOTHING);
} }
} }

View file

@ -56,7 +56,9 @@ typedef off_t off64_t;
#endif #endif
#endif #endif
#if defined (_WIN32) #if defined(__MINGW32__) && ((__GNUC__ > 7) || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3))
#define PRIdS "u"
#elif defined (_WIN32)
#define PRIdS "Iu" #define PRIdS "Iu"
#elif defined (_PSP) || defined (_arch_dreamcast) || defined (DJGPP) || defined (_WII) || defined (_NDS) || defined (_PS3) #elif defined (_PSP) || defined (_arch_dreamcast) || defined (DJGPP) || defined (_WII) || defined (_NDS) || defined (_PS3)
#define PRIdS "u" #define PRIdS "u"

View file

@ -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;
} }

View file

@ -68,7 +68,6 @@
// both the head and tail of the thinker list // both the head and tail of the thinker list
extern thinker_t thinkercap; extern thinker_t thinkercap;
extern INT32 runcount;
void P_InitThinkers(void); void P_InitThinkers(void);
void P_AddThinker(thinker_t *thinker); void P_AddThinker(thinker_t *thinker);

View file

@ -3840,7 +3840,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)
@ -3860,25 +3861,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)
@ -7926,14 +7928,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;
} }
@ -8228,7 +8231,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)

View file

@ -252,6 +252,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

View file

@ -1661,8 +1661,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)
@ -1671,8 +1670,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)
{ {

View file

@ -2503,11 +2503,6 @@ boolean P_SetupLevel(boolean skipprecip)
// Reset the palette // Reset the palette
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_SetPaletteColor(0);
else
#endif
if (rendermode != render_none) if (rendermode != render_none)
V_SetPaletteLump("PLAYPAL"); V_SetPaletteLump("PLAYPAL");
@ -2565,6 +2560,7 @@ boolean P_SetupLevel(boolean skipprecip)
{ {
tic_t starttime = I_GetTime(); tic_t starttime = I_GetTime();
tic_t endtime = starttime + (3*TICRATE)/2; tic_t endtime = starttime + (3*TICRATE)/2;
tic_t nowtime;
S_StartSound(NULL, sfx_s3kaf); S_StartSound(NULL, sfx_s3kaf);
@ -2574,9 +2570,17 @@ boolean P_SetupLevel(boolean skipprecip)
F_WipeEndScreen(); F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_speclevel_towhite], false); F_RunWipe(wipedefs[wipe_speclevel_towhite], false);
nowtime = lastwipetic;
// Hold on white for extra effect. // Hold on white for extra effect.
while (I_GetTime() < endtime) while (nowtime < endtime)
I_Sleep(); {
// wait loop
while (!((nowtime = I_GetTime()) - lastwipetic))
I_Sleep();
lastwipetic = nowtime;
if (moviemode) // make sure we save frames for the white hold too
M_SaveFrame();
}
ranspecialwipe = 1; ranspecialwipe = 1;
} }
@ -2669,7 +2673,6 @@ boolean P_SetupLevel(boolean skipprecip)
P_CreateBlockMap(); // Graue 02-29-2004 P_CreateBlockMap(); // Graue 02-29-2004
P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS); P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS);
R_MakeColormaps();
P_LoadLineDefs2(); P_LoadLineDefs2();
P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS); P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS);
P_LoadNodes(lastloadedmaplumpnum + ML_NODES); P_LoadNodes(lastloadedmaplumpnum + ML_NODES);
@ -2994,7 +2997,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX) if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX)
{ {
CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename); CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename);
return false; return false;
} }
else wadnum = (UINT16)(numwadfiles-1); else wadnum = (UINT16)(numwadfiles-1);

View file

@ -2039,8 +2039,7 @@ void P_SwitchWeather(INT32 weathernum)
for (think = thinkercap.next; think != &thinkercap; think = think->next) for (think = thinkercap.next; think != &thinkercap; think = think->next)
{ {
if ((think->function.acp1 != (actionf_p1)P_SnowThinker) if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
&& (think->function.acp1 != (actionf_p1)P_RainThinker))
continue; // not a precipmobj thinker continue; // not a precipmobj thinker
precipmobj = (precipmobj_t *)think; precipmobj = (precipmobj_t *)think;
@ -2056,14 +2055,12 @@ void P_SwitchWeather(INT32 weathernum)
for (think = thinkercap.next; think != &thinkercap; think = think->next) for (think = thinkercap.next; think != &thinkercap; think = think->next)
{ {
if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
continue; // not a precipmobj thinker
precipmobj = (precipmobj_t *)think;
if (swap == PRECIP_RAIN) // Snow To Rain if (swap == PRECIP_RAIN) // Snow To Rain
{ {
if (!(think->function.acp1 == (actionf_p1)P_SnowThinker
|| think->function.acp1 == (actionf_p1)P_NullPrecipThinker))
continue; // not a precipmobj thinker
precipmobj = (precipmobj_t *)think;
precipmobj->flags = mobjinfo[MT_RAIN].flags; precipmobj->flags = mobjinfo[MT_RAIN].flags;
st = &states[mobjinfo[MT_RAIN].spawnstate]; st = &states[mobjinfo[MT_RAIN].spawnstate];
precipmobj->state = st; precipmobj->state = st;
@ -2074,18 +2071,13 @@ void P_SwitchWeather(INT32 weathernum)
precipmobj->precipflags &= ~PCF_INVISIBLE; precipmobj->precipflags &= ~PCF_INVISIBLE;
think->function.acp1 = (actionf_p1)P_RainThinker; precipmobj->precipflags |= PCF_RAIN;
//think->function.acp1 = (actionf_p1)P_RainThinker;
} }
else if (swap == PRECIP_SNOW) // Rain To Snow else if (swap == PRECIP_SNOW) // Rain To Snow
{ {
INT32 z; INT32 z;
if (!(think->function.acp1 == (actionf_p1)P_RainThinker
|| think->function.acp1 == (actionf_p1)P_NullPrecipThinker))
continue; // not a precipmobj thinker
precipmobj = (precipmobj_t *)think;
precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags; precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags;
z = M_RandomByte(); z = M_RandomByte();
@ -2103,19 +2095,13 @@ void P_SwitchWeather(INT32 weathernum)
precipmobj->frame = st->frame; precipmobj->frame = st->frame;
precipmobj->momz = mobjinfo[MT_SNOWFLAKE].speed; precipmobj->momz = mobjinfo[MT_SNOWFLAKE].speed;
precipmobj->precipflags &= ~PCF_INVISIBLE; precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_RAIN);
think->function.acp1 = (actionf_p1)P_SnowThinker; //think->function.acp1 = (actionf_p1)P_SnowThinker;
} }
else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse. else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse.
{ {
if (!(think->function.acp1 == (actionf_p1)P_RainThinker //think->function.acp1 = (actionf_p1)P_NullPrecipThinker;
|| think->function.acp1 == (actionf_p1)P_SnowThinker))
continue;
precipmobj = (precipmobj_t *)think;
think->function.acp1 = (actionf_p1)P_NullPrecipThinker;
precipmobj->precipflags |= PCF_INVISIBLE; precipmobj->precipflags |= PCF_INVISIBLE;
} }

View file

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

View file

@ -8648,8 +8648,6 @@ void P_DoPityCheck(player_t *player)
// P_PlayerThink // P_PlayerThink
// //
boolean playerdeadview; // show match/chaos/tag/capture the flag rankings while in death view
void P_PlayerThink(player_t *player) void P_PlayerThink(player_t *player)
{ {
ticcmd_t *cmd; ticcmd_t *cmd;
@ -8838,10 +8836,6 @@ void P_PlayerThink(player_t *player)
if (player->playerstate == PST_DEAD) if (player->playerstate == PST_DEAD)
{ {
player->mo->flags2 &= ~MF2_SHADOW; player->mo->flags2 &= ~MF2_SHADOW;
// show the multiplayer rankings while dead
if (player == &players[displayplayer])
playerdeadview = true;
P_DeathThink(player); P_DeathThink(player);
return; return;
@ -8862,9 +8856,6 @@ void P_PlayerThink(player_t *player)
player->lives = cv_startinglives.value; player->lives = cv_startinglives.value;
} }
if (player == &players[displayplayer])
playerdeadview = false;
if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)
{ {
cmd->buttons &= BT_USE; // Remove all buttons except BT_USE cmd->buttons &= BT_USE; // Remove all buttons except BT_USE

View file

@ -1038,9 +1038,6 @@ void R_ReInitColormaps(UINT16 num)
static lumpnum_t foundcolormaps[MAXCOLORMAPS]; static lumpnum_t foundcolormaps[MAXCOLORMAPS];
static char colormapFixingArray[MAXCOLORMAPS][3][9];
static size_t carrayindex;
// //
// R_ClearColormaps // R_ClearColormaps
// //
@ -1052,8 +1049,6 @@ void R_ClearColormaps(void)
num_extra_colormaps = 0; num_extra_colormaps = 0;
carrayindex = 0;
for (i = 0; i < MAXCOLORMAPS; i++) for (i = 0; i < MAXCOLORMAPS; i++)
foundcolormaps[i] = LUMPERROR; foundcolormaps[i] = LUMPERROR;
@ -1087,7 +1082,7 @@ INT32 R_ColormapNumForName(char *name)
extra_colormaps[num_extra_colormaps].fadecolor = 0x0; extra_colormaps[num_extra_colormaps].fadecolor = 0x0;
extra_colormaps[num_extra_colormaps].maskamt = 0x0; extra_colormaps[num_extra_colormaps].maskamt = 0x0;
extra_colormaps[num_extra_colormaps].fadestart = 0; extra_colormaps[num_extra_colormaps].fadestart = 0;
extra_colormaps[num_extra_colormaps].fadeend = 33; extra_colormaps[num_extra_colormaps].fadeend = 31;
extra_colormaps[num_extra_colormaps].fog = 0; extra_colormaps[num_extra_colormaps].fog = 0;
num_extra_colormaps++; num_extra_colormaps++;
@ -1110,12 +1105,12 @@ static int RoundUp(double number);
INT32 R_CreateColormap(char *p1, char *p2, char *p3) INT32 R_CreateColormap(char *p1, char *p2, char *p3)
{ {
double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb; double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb;
double r, g, b, cbrightness, maskamt = 0, othermask = 0; double maskamt = 0, othermask = 0;
int mask, fog = 0; int mask, fog = 0;
size_t mapnum = num_extra_colormaps; size_t mapnum = num_extra_colormaps;
size_t i; size_t i;
UINT32 cr, cg, cb, maskcolor, fadecolor; UINT32 cr, cg, cb, maskcolor, fadecolor;
UINT32 fadestart = 0, fadeend = 33, fadedist = 33; 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) #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] == '#') if (p1[0] == '#')
@ -1156,14 +1151,14 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
// Get parameters like fadestart, fadeend, and the fogflag // Get parameters like fadestart, fadeend, and the fogflag
fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10); fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10);
fadeend = NUMFROMCHAR(p2[5]) + (NUMFROMCHAR(p2[4]) * 10); fadeend = NUMFROMCHAR(p2[5]) + (NUMFROMCHAR(p2[4]) * 10);
if (fadestart > 32) if (fadestart > 30)
fadestart = 0; fadestart = 0;
if (fadeend > 33 || fadeend < 1) if (fadeend > 31 || fadeend < 1)
fadeend = 33; fadeend = 31;
fadedist = fadeend - fadestart; fadedist = fadeend - fadestart;
fog = NUMFROMCHAR(p2[1]) ? 1 : 0; fog = NUMFROMCHAR(p2[1]);
} }
#undef getnum #undef NUMFROMCHAR
if (p3[0] == '#') if (p3[0] == '#')
{ {
@ -1194,14 +1189,31 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
if (num_extra_colormaps == MAXCOLORMAPS) if (num_extra_colormaps == MAXCOLORMAPS)
I_Error("R_CreateColormap: Too many colormaps! the limit is %d\n", 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++; num_extra_colormaps++;
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;
// 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 = pLocalPalette[i].s.red; r = pLocalPalette[i].s.red;
@ -1224,168 +1236,13 @@ INT32 R_CreateColormap(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
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;
int mask, p, fog = 0;
size_t mapnum = num_extra_colormaps;
size_t i;
char *colormap_p;
UINT32 cr, cg, cb, maskcolor, fadecolor;
UINT32 fadestart = 0, fadeend = 33, fadedist = 33;
#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 > 32)
fadestart = 0;
if (fadeend > 33 || fadeend < 1)
fadeend = 33;
fadedist = fadeend - fadestart;
fog = NUMFROMCHAR(p2[1]) ? 1 : 0;
}
#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;
}
}
if (num_extra_colormaps == MAXCOLORMAPS)
I_Error("R_CreateColormap: Too many colormaps! the limit is %d\n", MAXCOLORMAPS);
num_extra_colormaps++;
if (rendermode == render_soft)
{
for (i = 0; i < 256; i++)
{
r = pLocalPalette[i].s.red;
g = pLocalPalette[i].s.green;
b = pLocalPalette[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;
#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; extra_colormaps[mapnum].colormap = (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++)
@ -1397,7 +1254,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
@ -1412,12 +1269,12 @@ 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 (INT32)mapnum;
} }
// Thanks to quake2 source! // Thanks to quake2 source!

View file

@ -93,8 +93,6 @@ void R_ReInitColormaps(UINT16 num);
void R_ClearColormaps(void); void R_ClearColormaps(void);
INT32 R_ColormapNumForName(char *name); INT32 R_ColormapNumForName(char *name);
INT32 R_CreateColormap(char *p1, char *p2, char *p3); INT32 R_CreateColormap(char *p1, char *p2, char *p3);
void R_CreateColormap2(char *p1, char *p2, char *p3);
void R_MakeColormaps(void);
const char *R_ColormapNameForNum(INT32 num); const char *R_ColormapNameForNum(INT32 num);
extern INT32 numtextures; extern INT32 numtextures;

View file

@ -297,7 +297,7 @@ void R_DrawTranslucentColumn_8(void)
// Re-map color indices from wall texture column // Re-map color indices from wall texture column
// using a lighting/special effects LUT. // using a lighting/special effects LUT.
// heightmask is the Tutti-Frutti fix // heightmask is the Tutti-Frutti fix
*dest = colormap[*(transmap + (source[frac>>FRACBITS]<<8) + (*dest))]; *dest = *(transmap + (colormap[source[frac>>FRACBITS]]<<8) + (*dest));
dest += vid.width; dest += vid.width;
if ((frac += fracstep) >= heightmask) if ((frac += fracstep) >= heightmask)
frac -= heightmask; frac -= heightmask;
@ -308,15 +308,15 @@ void R_DrawTranslucentColumn_8(void)
{ {
while ((count -= 2) >= 0) // texture height is a power of 2 while ((count -= 2) >= 0) // texture height is a power of 2
{ {
*dest = colormap[*(transmap + ((source[(frac>>FRACBITS)&heightmask]<<8)) + (*dest))]; *dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest));
dest += vid.width; dest += vid.width;
frac += fracstep; frac += fracstep;
*dest = colormap[*(transmap + ((source[(frac>>FRACBITS)&heightmask]<<8)) + (*dest))]; *dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest));
dest += vid.width; dest += vid.width;
frac += fracstep; frac += fracstep;
} }
if (count & 1) if (count & 1)
*dest = colormap[*(transmap + ((source[(frac>>FRACBITS)&heightmask]<<8)) + (*dest))]; *dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest));
} }
} }
} }
@ -367,8 +367,7 @@ void R_DrawTranslatedTranslucentColumn_8(void)
// using a lighting/special effects LUT. // using a lighting/special effects LUT.
// heightmask is the Tutti-Frutti fix // heightmask is the Tutti-Frutti fix
*dest = dc_colormap[*(dc_transmap *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest));
+ (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest))];
dest += vid.width; dest += vid.width;
if ((frac += fracstep) >= heightmask) if ((frac += fracstep) >= heightmask)
@ -380,17 +379,15 @@ void R_DrawTranslatedTranslucentColumn_8(void)
{ {
while ((count -= 2) >= 0) // texture height is a power of 2 while ((count -= 2) >= 0) // texture height is a power of 2
{ {
*dest = dc_colormap[*(dc_transmap *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest));
+ (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest))];
dest += vid.width; dest += vid.width;
frac += fracstep; frac += fracstep;
*dest = dc_colormap[*(dc_transmap *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest));
+ (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest))];
dest += vid.width; dest += vid.width;
frac += fracstep; frac += fracstep;
} }
if (count & 1) if (count & 1)
*dest = dc_colormap[*(dc_transmap + (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]] <<8) + (*dest))]; *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest));
} }
} }
} }
@ -738,8 +735,7 @@ void R_DrawTiltedTranslucentSpan_8(void)
v = (INT64)(vz*z) + viewy; v = (INT64)(vz*z) + viewy;
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
dest++; dest++;
iz += ds_sz.x; iz += ds_sz.x;
uz += ds_su.x; uz += ds_su.x;
@ -776,7 +772,7 @@ void R_DrawTiltedTranslucentSpan_8(void)
for (i = SPANSIZE-1; i >= 0; i--) for (i = SPANSIZE-1; i >= 0; i--)
{ {
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
dest++; dest++;
u += stepu; u += stepu;
v += stepv; v += stepv;
@ -792,7 +788,7 @@ void R_DrawTiltedTranslucentSpan_8(void)
u = (INT64)(startu); u = (INT64)(startu);
v = (INT64)(startv); v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
} }
else else
{ {
@ -813,7 +809,7 @@ void R_DrawTiltedTranslucentSpan_8(void)
for (; width != 0; width--) for (; width != 0; width--)
{ {
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
dest++; dest++;
u += stepu; u += stepu;
v += stepv; v += stepv;
@ -1124,49 +1120,49 @@ void R_DrawTranslucentSplat_8 (void)
// need! // need!
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[0] = colormap[*(ds_transmap + (val << 8) + dest[0])]; dest[0] = *(ds_transmap + (colormap[val] << 8) + dest[0]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[1] = colormap[*(ds_transmap + (val << 8) + dest[1])]; dest[1] = *(ds_transmap + (colormap[val] << 8) + dest[1]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[2] = colormap[*(ds_transmap + (val << 8) + dest[2])]; dest[2] = *(ds_transmap + (colormap[val] << 8) + dest[2]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[3] = colormap[*(ds_transmap + (val << 8) + dest[3])]; dest[3] = *(ds_transmap + (colormap[val] << 8) + dest[3]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[4] = colormap[*(ds_transmap + (val << 8) + dest[4])]; dest[4] = *(ds_transmap + (colormap[val] << 8) + dest[4]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[5] = colormap[*(ds_transmap + (val << 8) + dest[5])]; dest[5] = *(ds_transmap + (colormap[val] << 8) + dest[5]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[6] = colormap[*(ds_transmap + (val << 8) + dest[6])]; dest[6] = *(ds_transmap + (colormap[val] << 8) + dest[6]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[7] = colormap[*(ds_transmap + (val << 8) + dest[7])]; dest[7] = *(ds_transmap + (colormap[val] << 8) + dest[7]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
@ -1177,7 +1173,7 @@ void R_DrawTranslucentSplat_8 (void)
{ {
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
*dest = colormap[*(ds_transmap + (val << 8) + *dest)]; *dest = *(ds_transmap + (colormap[val] << 8) + *dest);
dest++; dest++;
xposition += xstep; xposition += xstep;
@ -1220,35 +1216,35 @@ void R_DrawTranslucentSpan_8 (void)
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
// have the uber complicated math to calculate it now, so that was a memory write we didn't // have the uber complicated math to calculate it now, so that was a memory write we didn't
// need! // need!
dest[0] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[0])]; dest[0] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[0]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
dest[1] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[1])]; dest[1] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[1]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
dest[2] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[2])]; dest[2] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[2]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
dest[3] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[3])]; dest[3] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[3]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
dest[4] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[4])]; dest[4] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[4]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
dest[5] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[5])]; dest[5] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[5]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
dest[6] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[6])]; dest[6] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[6]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
dest[7] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[7])]; dest[7] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[7]);
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
@ -1257,7 +1253,7 @@ void R_DrawTranslucentSpan_8 (void)
} }
while (count--) while (count--)
{ {
*dest = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dest)]; *dest = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + *dest);
dest++; dest++;
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;

View file

@ -60,7 +60,6 @@ fixed_t projectiony; // aspect ratio
// just for profiling purposes // just for profiling purposes
size_t framecount; size_t framecount;
size_t sscount;
size_t loopcount; size_t loopcount;
fixed_t viewx, viewy, viewz; fixed_t viewx, viewy, viewz;
@ -482,9 +481,6 @@ static void R_InitTextureMapping(void)
// Take out the fencepost cases from viewangletox. // Take out the fencepost cases from viewangletox.
for (i = 0; i < FINEANGLES/2; i++) for (i = 0; i < FINEANGLES/2; i++)
{ {
t = FixedMul(FINETANGENT(i), focallength);
t = centerx - t;
if (viewangletox[i] == -1) if (viewangletox[i] == -1)
viewangletox[i] = 0; viewangletox[i] = 0;
else if (viewangletox[i] == viewwidth+1) else if (viewangletox[i] == viewwidth+1)
@ -954,8 +950,6 @@ void R_SkyboxFrame(player_t *player)
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
sscount = 0;
// recalc necessary stuff for mouseaiming // recalc necessary stuff for mouseaiming
// slopes are already calculated for the full possible view (which is 4*viewheight). // slopes are already calculated for the full possible view (which is 4*viewheight).
@ -1079,8 +1073,6 @@ void R_SetupFrame(player_t *player, boolean skybox)
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
sscount = 0;
// recalc necessary stuff for mouseaiming // recalc necessary stuff for mouseaiming
// slopes are already calculated for the full possible view (which is 4*viewheight). // slopes are already calculated for the full possible view (which is 4*viewheight).
@ -1225,9 +1217,9 @@ void R_RenderPlayerView(player_t *player)
if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1 if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1
{ {
if (cv_homremoval.value == 1) if (cv_homremoval.value == 1)
V_DrawFill(0, 0, vid.width, vid.height, 31); // No HOM effect! V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // No HOM effect!
else //'development' HOM removal -- makes it blindingly obvious if HOM is spotted. else //'development' HOM removal -- makes it blindingly obvious if HOM is spotted.
V_DrawFill(0, 0, vid.width, vid.height, 128+(timeinmap&15)); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 128+(timeinmap&15));
} }
// load previous saved value of skyVisible for the player // load previous saved value of skyVisible for the player

View file

@ -37,6 +37,9 @@
// Quincunx antialiasing of flats! // Quincunx antialiasing of flats!
//#define QUINCUNX //#define QUINCUNX
// good night sweet prince
#define SHITPLANESPARENCY
//SoM: 3/23/2000: Use Boom visplane hashing. //SoM: 3/23/2000: Use Boom visplane hashing.
#define MAXVISPLANES 512 #define MAXVISPLANES 512
@ -768,7 +771,11 @@ void R_DrawSinglePlane(visplane_t *pl)
else // Opaque, but allow transparent flat pixels else // Opaque, but allow transparent flat pixels
spanfunc = splatfunc; spanfunc = splatfunc;
if (pl->extra_colormap && pl->extra_colormap->fog) #ifdef SHITPLANESPARENCY
if (spanfunc == splatfunc || (pl->extra_colormap && pl->extra_colormap->fog))
#else
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
#endif
light = (pl->lightlevel >> LIGHTSEGSHIFT); light = (pl->lightlevel >> LIGHTSEGSHIFT);
else else
light = LIGHTLEVELS-1; light = LIGHTLEVELS-1;
@ -822,7 +829,11 @@ void R_DrawSinglePlane(visplane_t *pl)
else // Opaque, but allow transparent flat pixels else // Opaque, but allow transparent flat pixels
spanfunc = splatfunc; spanfunc = splatfunc;
if (pl->extra_colormap && pl->extra_colormap->fog) #ifdef SHITPLANESPARENCY
if (spanfunc == splatfunc || (pl->extra_colormap && pl->extra_colormap->fog))
#else
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
#endif
light = (pl->lightlevel >> LIGHTSEGSHIFT); light = (pl->lightlevel >> LIGHTSEGSHIFT);
else else
light = LIGHTLEVELS-1; light = LIGHTLEVELS-1;

View file

@ -108,7 +108,4 @@ extern angle_t rw_normalangle;
// angle to line origin // angle to line origin
extern angle_t rw_angle1; extern angle_t rw_angle1;
// Segs count?
extern size_t sscount;
#endif #endif

View file

@ -1023,7 +1023,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
else else
*/ */
if (!((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK) || thing->flags2 & MF2_SHADOW) if (!((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK) || thing->flags2 & MF2_SHADOW)
&& (!newsprite->extra_colormap || !newsprite->extra_colormap->fog))) && (!newsprite->extra_colormap || !(newsprite->extra_colormap->fog & 1))))
{ {
lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT); lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
@ -1324,7 +1324,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->transmap = transtables + (thing->frame & FF_TRANSMASK) - 0x10000; vis->transmap = transtables + (thing->frame & FF_TRANSMASK) - 0x10000;
if (((thing->frame & FF_FULLBRIGHT) || (thing->flags2 & MF2_SHADOW)) if (((thing->frame & FF_FULLBRIGHT) || (thing->flags2 & MF2_SHADOW))
&& (!vis->extra_colormap || !vis->extra_colormap->fog)) && (!vis->extra_colormap || !(vis->extra_colormap->fog & 1)))
{ {
// full bright: goggles // full bright: goggles
vis->colormap = colormaps; vis->colormap = colormaps;
@ -1451,6 +1451,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;
@ -1569,8 +1580,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
@ -1591,8 +1604,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

View file

@ -78,7 +78,7 @@ consvar_t stereoreverse = {"stereoreverse", "Off", CV_SAVE, CV_OnOff, NULL, 0, N
static consvar_t precachesound = {"precachesound", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t precachesound = {"precachesound", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
// actual general (maximum) sound & music volume, saved into the config // actual general (maximum) sound & music volume, saved into the config
consvar_t cv_soundvolume = {"soundvolume", "31", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_soundvolume = {"soundvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_digmusicvolume = {"digmusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_digmusicvolume = {"digmusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_midimusicvolume = {"midimusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_midimusicvolume = {"midimusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// number of channels available // number of channels available
@ -226,7 +226,7 @@ void S_RegisterSoundStuff(void)
{ {
if (dedicated) if (dedicated)
{ {
nosound = true; sound_disabled = true;
return; return;
} }
@ -400,7 +400,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...
@ -529,7 +529,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:
@ -579,7 +579,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)
@ -716,7 +716,7 @@ void S_UpdateSounds(void)
return; return;
} }
if (dedicated || nosound) if (dedicated || sound_disabled)
return; return;
if (players[displayplayer].awayviewtics) if (players[displayplayer].awayviewtics)
@ -1151,6 +1151,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
/// ------------------------ /// ------------------------
@ -1177,31 +1214,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)
@ -1215,31 +1330,43 @@ 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;
} }
@ -1249,7 +1376,7 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
S_ClearSfx(); S_ClearSfx();
#endif #endif
if ((nomidimusic || music_disabled) && (nodigimusic || digital_disabled)) if (S_MusicDisabled())
return; return;
// No Music (empty string) // No Music (empty string)
@ -1259,121 +1386,105 @@ 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;
} }
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
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
I_PauseCD();
#else
I_StopCD();
#endif
}
void S_ResumeAudio(void)
{
if (I_SongPlaying() && I_SongPaused())
I_ResumeSong();
// 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 actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var
#ifdef DJGPPDOS if (seqvolume < 0 || seqvolume > 31)
I_SetDigMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this. CONS_Alert(CONS_WARNING, "midimusicvolume should be between 0-31\n");
#endif CV_SetValue(&cv_midimusicvolume, seqvolume&31);
I_SetDigMusicVolume(volume&31);
}
void S_SetMIDIMusicVolume(INT32 volume)
{
if (volume < 0 || volume > 31)
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
CV_SetValue(&cv_midimusicvolume, volume&0x1f);
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,
@ -1388,46 +1499,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();
}

View file

@ -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"
@ -69,9 +70,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.
@ -97,6 +98,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
@ -104,9 +132,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);
@ -121,9 +146,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);

File diff suppressed because it is too large Load diff

View file

@ -1,425 +1,213 @@
/* XPM */ /* XPM */
static char * C:\Repo\srb2\src\sdl\SDL_icon_xpm[] = { static const char *SDL_icon_xpm[] = {
"32 32 390 2", /* columns rows colors chars-per-pixel */
" c None", "32 32 175 2 ",
". c #4F4F70", " c None",
"+ c #4D4D87", ". c #2E2E2E",
"@ c #4D4D84", "X c #3C3C3C",
"# c #4E4E6C", "o c #493939",
"$ c #6C6C95", "O c #4E473F",
"% c #5E5EB2", "+ c #161658",
"& c #6B6BE7", "@ c #131369",
"* c #7373F9", "# c #06067B",
"= c #7C7CFF", "$ c #111173",
"- c #6F70E7", "% c #16167F",
"; c #494BB2", "& c #252567",
"> c #4F4FA3", "* c #372B7C",
", c #6464D4", "= c #3D3679",
"' c #7979F5", "- c #41414A",
") c #5F5FCA", "; c #575655",
"! c #5D5D93", ": c #6A5841",
"~ c #3A3A9F", "> c #5B4B72",
"{ c #6060AC", ", c #616160",
"] c #777793", "< c #7B7B7B",
"^ c #5C5CB3", "1 c #906E49",
"/ c #7373EA", "2 c #89685D",
"( c #7A7AFF", "3 c #A67B4A",
"_ c #7575FF", "4 c #AA7F50",
": c #7979FF", "5 c #9B7560",
"< c #6264DD", "6 c #856C78",
"[ c #47478C", "7 c #997B7D",
"} c #564567", "8 c #B48552",
"| c #4647D0", "9 c #BA8A55",
"1 c #5C5CAE", "0 c #A48665",
"2 c #5E5EFF", "q c #B98F67",
"3 c #2929FF", "w c #B9946A",
"4 c #1D1DFF", "e c #B7937A",
"5 c #1919D1", "r c #C8955C",
"6 c #4F4F90", "t c #CA9966",
"7 c #1E1ECE", "y c #DAA469",
"8 c #5858FF", "u c #C9A37B",
"9 c #6767A8", "i c #D7AB7B",
"0 c #4949A0", "p c #DFB07D",
"a c #7070FB", "a c #EBAE6A",
"b c #7D7DFF", "s c #E5B27A",
"c c #7777FF", "d c #F1B779",
"d c #7373FF", "f c #0A0A83",
"e c #7272FF", "g c #05058B",
"f c #7878FF", "h c #060687",
"g c #6465D8", "j c #101089",
"h c #363886", "k c #131382",
"i c #9F7655", "l c #040494",
"j c #C89B5C", "z c #02029D",
"k c #1D1CB7", "x c #0C0B9C",
"l c #3031B1", "c c #120F9E",
"m c #1919F4", "v c #19199B",
"n c #1111FF", "b c #382D84",
"o c #1818FF", "n c #39398D",
"p c #1B1BFF", "m c #222296",
"q c #1C1CFF", "M c #0101A6",
"r c #2626B3", "N c #0A0AA2",
"s c #1E1EC8", "B c #0202AC",
"t c #1A1AE8", "V c #1919A2",
"u c #24249F", "C c #1616AD",
"v c #2F2FD2", "Z c #0000B5",
"w c #7676FF", "A c #0202BC",
"x c #6869E2", "S c #0C0CB6",
"y c #414290", "D c #1313B3",
"z c #8C6751", "F c #1011BD",
"A c #FCBA68", "G c #1B1BBE",
"B c #E9BD7D", "H c #2B2BAC",
"C c #201EB8", "J c #3737A1",
"D c #090AB8", "K c #2A26BE",
"E c #1616EB", "L c #2A29B4",
"F c #1818FD", "P c #3B3BB8",
"G c #1414EE", "I c #48478B",
"H c #1010E1", "U c #57578A",
"I c #0E0EE2", "Y c #4A499A",
"J c #0E0EF4", "T c #524F95",
"K c #0606B2", "R c #565399",
"L c #7A7A89", "E c #4C4CA8",
"M c #0C0C9A", "W c #524DA7",
"N c #0A0AA7", "Q c #5353A4",
"O c #2424E4", "! c #5555A9",
"P c #6669E6", "~ c #5555B4",
"Q c #4F4A8F", "^ c #5656B7",
"R c #BF853B", "/ c #6464A6",
"S c #FFD98D", "( c #6F67B5",
"T c #CDAB76", ") c #0404C3",
"U c #1717C4", "_ c #0707CA",
"V c #0F10BA", "` c #1414CB",
"W c #0909B6", "' c #1A1AC6",
"X c #0505C3", "] c #0A0AD3",
"Y c #0000B6", "[ c #0D0DDC",
"Z c #0000BE", "{ c #1A1AD4",
"` c #0000AD", "} c #1010DF",
" . c #1D1D83", "| c #1E1EDE",
".. c #63638E", " . c #1817DE",
"+. c #090975", ".. c #221FCA",
"@. c #1414F3", "X. c #2B2BCC",
"#. c #5B5BFF", "o. c #2727C9",
"$. c #7B7BFF", "O. c #3434C3",
"%. c #7070FF", "+. c #3434D4",
"&. c #6E6EFF", "@. c #0F0FE2",
"*. c #7172F6", "#. c #1313E5",
"=. c #625DAF", "$. c #1515ED",
"-. c #BA9E6C", "%. c #1B1BEA",
";. c #887167", "&. c #1C1CE4",
">. c #090DF2", "*. c #1515F4",
",. c #1313BE", "=. c #1818F3",
"'. c #000085", "-. c #1717FD",
"). c #0000AC", ";. c #1818FF",
"!. c #0202AA", ":. c #2B2BE9",
"~. c #242488", ">. c #2424FF",
"{. c #1414C7", ",. c #2A2AFF",
"]. c #1717FF", "<. c #2222F1",
"^. c #5959FF", "1. c #3737FF",
"/. c #7F7FFF", "2. c #5D5DC3",
"(. c #7474FF", "3. c #5F5FC9",
"_. c #7171FF", "4. c #5655C2",
":. c #8686FF", "5. c #4747D1",
"<. c #7574FF", "6. c #5B5BD4",
"[. c #797CFF", "7. c #6565C8",
"}. c #5756B8", "8. c #6363DA",
"|. c #1C19A4", "9. c #4545FF",
"1. c #1617FF", "0. c #4D4DFC",
"2. c #1212BD", "q. c #5454FF",
"3. c #040485", "w. c #5959FF",
"4. c #0707A4", "e. c #6969E5",
"5. c #1B1B71", "r. c #6B6CEA",
"6. c #373797", "t. c #6666E7",
"7. c #1616FF", "y. c #6B6BFE",
"8. c #5050FF", "u. c #6767F8",
"9. c #8080FF", "i. c #7070F6",
"0. c #AAAAFF", "p. c #7373FF",
"a. c #AEAEF6", "a. c #7C7CFF",
"b. c #8A8AEF", "s. c #91918F",
"c. c #6969FB", "d. c #8F9090",
"d. c #2728FF", "f. c #979797",
"e. c #1314FF", "g. c #9C9C9C",
"f. c #1919FF", "h. c #8585A1",
"g. c #1313E8", "j. c #9C9CA7",
"h. c #1F1FF4", "k. c #9292B6",
"i. c #5454FF", "l. c #A4A4A4",
"j. c #6D6DF0", "z. c #BDB2A4",
"k. c #6868B5", "x. c #A4A4B1",
"l. c #0B0BB8", "c. c #BFBFBD",
"m. c #1212C5", "v. c #BABAB7",
"n. c #1616FC", "b. c #C8AA87",
"o. c #1515FF", "n. c #DAAE82",
"p. c #1212FF", "m. c #DBB081",
"q. c #2323FF", "M. c #EBBA85",
"r. c #3636FF", "N. c #F3BF84",
"s. c #4040FF", "B. c #F2BE88",
"t. c #4343F9", "V. c #C2B3A3",
"u. c #5D5DB8", "C. c #FBC386",
"v. c #7F7F92", "Z. c #FCC68C",
"w. c #878793", "A. c #FFC88F",
"x. c #4B4B94", "S. c #F4C387",
"y. c #0B0CE2", "D. c #FFC990",
"z. c #1313FF", "F. c #C3C1BF",
"A. c #4C4CFF", "G. c #8F8FCB",
"B. c #8282FF", "H. c #BDBDC2",
"C. c #7171ED", "J. c #BDBDD1",
"D. c #636394", "K. c #8888F9",
"E. c #575785", "L. c #A4A4FB",
"F. c #A9A99C", "P. c #CDCDCC",
"G. c #1414BC", "I. c #CECAC6",
"H. c #1414FF", "U. c #D3CFCA",
"I. c #0707FD", "Y. c #D3D0CC",
"J. c #2525AA", "T. c #C0C0D5",
"K. c #A8A8A4", "R. c #D6D5D4",
"L. c #EBEBE2", "E. c #D7D7DD",
"M. c #F9F9F2", "W. c #E1E1DF",
"N. c #E1E1CC", "Q. c #DEDEE1",
"O. c #4D4D9F", "!. c #E4E4E4",
"P. c #0B0BF7", "~. c #E8E8E8",
"Q. c #2121FF", "^. c #F0F0EE",
"R. c #3232FF", "/. c #F5F5F2",
"S. c #5555FF", "(. c #FFFFFF",
"T. c #6161B4", /* pixels */
"U. c #B5B5B2",
"V. c #FFFFF8",
"W. c #4F4F9A",
"X. c #0B0BF5",
"Y. c #1616C5",
"Z. c #A8A8A1",
"`. c #FFFFFC",
" + c #FFFFFF",
".+ c #C0C0C4",
"++ c #1212D4",
"@+ c #4444FF",
"#+ c #6464FF",
"$+ c #8383FF",
"%+ c #6767C3",
"&+ c #E4E4E4",
"*+ c #9494AE",
"=+ c #0808DF",
"-+ c #0D0DF2",
";+ c #61619A",
">+ c #F1F1E0",
",+ c #E8E8DD",
"'+ c #2424BB",
")+ c #1010FF",
"!+ c #3434FF",
"~+ c #6161FF",
"{+ c #6969D2",
"]+ c #EFEFF0",
"^+ c #C2C2BA",
"/+ c #1010B6",
"(+ c #0909AC",
"_+ c #A4A49A",
":+ c #EAEADE",
"<+ c #2525B8",
"[+ c #2F2FFF",
"}+ c #3C3CB5",
"|+ c #EEEEEE",
"1+ c #BBBBAD",
"2+ c #0B0B56",
"3+ c #0B0BFC",
"4+ c #1212EF",
"5+ c #0C0C3E",
"6+ c #919187",
"7+ c #DEDED6",
"8+ c #1F1FC0",
"9+ c #1A1AFF",
"0+ c #1717FA",
"a+ c #1515F8",
"b+ c #1111FC",
"c+ c #494992",
"d+ c #999998",
"e+ c #3E3E3B",
"f+ c #3C3C99",
"g+ c #535397",
"h+ c #5A5A4D",
"i+ c #6F6F70",
"j+ c #BFBFC9",
"k+ c #1111D6",
"l+ c #1515F1",
"m+ c #0F0FE2",
"n+ c #0D0DD9",
"o+ c #0909CD",
"p+ c #0808C7",
"q+ c #0505C7",
"r+ c #0303CB",
"s+ c #0101C0",
"t+ c #0202AF",
"u+ c #0606AC",
"v+ c #121283",
"w+ c #BBBBBB",
"x+ c #BEBEBE",
"y+ c #2F2F2E",
"z+ c #C7C8BB",
"A+ c #D8DAD1",
"B+ c #272828",
"C+ c #929292",
"D+ c #8688C7",
"E+ c #0506F6",
"F+ c #1616F5",
"G+ c #0B0BD3",
"H+ c #0202B6",
"I+ c #0000AF",
"J+ c #0000B4",
"K+ c #0000BD",
"L+ c #0000BB",
"M+ c #00009E",
"N+ c #2C2C7E",
"O+ c #6A6A8B",
"P+ c #959595",
"Q+ c #F0F0F1",
"R+ c #E1E1E1",
"S+ c #8C8E90",
"T+ c #BEBEBF",
"U+ c #C9C7C5",
"V+ c #939699",
"W+ c #E7EAED",
"X+ c #CBCBC7",
"Y+ c #413B9B",
"Z+ c #0607DD",
"`+ c #0C0CE2",
" @ c #0303B9",
".@ c #0000A8",
"+@ c #181888",
"@@ c #6A6A6A",
"#@ c #626263",
"$@ c #4B4B4C",
"%@ c #3E3B36",
"&@ c #9B805C",
"*@ c #D9B07D",
"=@ c #C9AE89",
"-@ c #B9AF9E",
";@ c #C7C5C4",
">@ c #CBCCCF",
",@ c #C7C6C6",
"'@ c #AEA59A",
")@ c #B69974",
"!@ c #D8B87F",
"~@ c #9B8272",
"{@ c #0E0B9B",
"]@ c #0000B7",
"^@ c #0000B8",
"/@ c #000082",
"(@ c #00007A",
"_@ c #636379",
":@ c #62533E",
"<@ c #B59B6C",
"[@ c #DEB07B",
"}@ c #FECC90",
"|@ c #FFCE92",
"1@ c #FEC98C",
"2@ c #F1BD82",
"3@ c #D1A979",
"4@ c #BC9E73",
"5@ c #CCA777",
"6@ c #EAB980",
"7@ c #FFCD90",
"8@ c #FFD595",
"9@ c #FDD782",
"0@ c #413678",
"a@ c #0000AE",
"b@ c #000077",
"c@ c #010193",
"d@ c #0C0CE4",
"e@ c #38389E",
"f@ c #EEC585",
"g@ c #FFDA9D",
"h@ c #FFC992",
"i@ c #FFC88F",
"j@ c #FFC990",
"k@ c #FFCE93",
"l@ c #FFD094",
"m@ c #FFCC92",
"n@ c #C9A174",
"o@ c #EDBD88",
"p@ c #FAD287",
"q@ c #3A2F7F",
"r@ c #0000BA",
"s@ c #0000B0",
"t@ c #0101B2",
"u@ c #1111ED",
"v@ c #1919C1",
"w@ c #95887C",
"x@ c #DCAC6E",
"y@ c #FFD393",
"z@ c #FFCD94",
"A@ c #FFCA93",
"B@ c #FFC991",
"C@ c #FFC78E",
"D@ c #FFCB91",
"E@ c #E0B581",
"F@ c #BB9A6F",
"G@ c #FFDC97",
"H@ c #C1A173",
"I@ c #0E0B9A",
"J@ c #0000B5",
"K@ c #0101B6",
"L@ c #1010E0",
"M@ c #1616EC",
"N@ c #A68156",
"O@ c #E7AC6B",
"P@ c #FFC582",
"Q@ c #FFCF8F",
"R@ c #FFD195",
"S@ c #FFD296",
"T@ c #FFD396",
"U@ c #FFD193",
"V@ c #FFD28F",
"W@ c #D2A96B",
"X@ c #2F2482",
"Y@ c #0000C1",
"Z@ c #0000C0",
"`@ c #0000BF",
" # c #0101BF",
".# c #1212F0",
"+# c #767698",
"@# c #9C866E",
"## c #A9865D",
"$# c #C0915D",
"%# c #C89760",
"&# c #C29360",
"*# c #AD8A61",
"=# c #9D8971",
"-# c #7F7A7A",
";# c #70708F",
"># c #6F6F91",
",# c #575788",
"'# c #464687",
")# c #2F2F87",
"!# c #15158F",
"~# c #0101A8",
"{# c #1313FB",
"]# c #57579F",
"^# c #343487",
"/# c #434388",
" ", " ",
" ", " ",
" ", " ",
" . + @ # ", " I Q T = ",
" $ % & * = - ; > , ' ) ! ", " Q 7.e.r.i.8.E E 3.r.6.J ",
" ~ { ] ^ / = ( _ : < [ } | 1 2 3 4 5 6 ", " H ~ n 4.r.p.p.p.p.8.R > 5.^ w.,.-.{ v ",
" 7 8 9 0 a b c d e f g h i j k l m n o p q r ", " { 9.^ & P t.p.p.p.p.p.8.I 5 q K L <.;.;.;.-.' ",
" s t u v _ f d d d w x y z A B C D E F G H I J K L ", " { %.H +.y.p.p.p.p.p.e.Y 2 a n.K F $.*.$.@.} ] N ",
" M N O _ c e d d d _ P Q R S T U V W X Y Z ` ... ", " x D :.y.p.p.p.p.p.p.r.R 8 C.u ..F A ) A Z M h $ ",
" +.@.#.$.d d d d %.&._ *.=.-.;.>.,.'.).!.~. ", " f =.q.p.p.p.p.p.p.p.p.i.( e 6 $.` l B M g ",
" {.].^./.(.d d _.$.:._ <.[.}.|.1.2.3.4.5. ", " ` ;.q.p.p.p.p.p.a.K.a.p.p.4.L -.` l N % ",
" 6.7.7.4 8.e : w 9.0.a.b.c.2 d.e.f.g.h.i.j.k. ", " V =.-.>.q.y.p.p.p.L.L.K.i.w.,.-.;.$.<.q.u.2. ",
" l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.o o z.A.B./.b C.D. ", " D { =.-.;.>.1.1.9.( h.h.Q &.-.-.-.;.9.p.p.p.r.! ",
" E.F.G.].o H.z.I.J.K.L.M.N.O.P.o o o Q.R.S._.b B.T. ", " U j.o.-.;.-.;.-.P x.Q.^.R.~ *.-.;.;.>.1.q.y.p.i.2. ",
" U.V.W.X.f.f.7.Y.Z.`. + + +.+++].o o o.n z.q.@+#+$+%+ ", " H./.! *.;.;.;.o.x./.(.(.(.J.| -.-.;.-.-.;.,.9.u.p.7. ",
" &+ +*+=+].o -+;+>+ + + + +,+'+H.o o o o o H.)+o !+~+{+ ", " !.(.k.#.;.-.=./ !.(.(.(.(.Q.X.-.;.;.;.;.-.-.;.;.1.w.6. ",
" ]+ +^+/+H.o.(+_+ + + + + +:+<+z.o o o o o o o 7.n H.[+}+ ", " ~.(.H.G ;.-.D j.(.(.(.(.(.!.O.-.-.;.;.;.-.;.-.;.-.;.,.O. ",
" |+ +1+2+3+4+5+6+ + + + + +7+8+H.o o f.9+f.9+f.F 0+a+b+o.c+ ", " ~.(.v.@ *.$.+ d.(.(.(.(.(.E.o.-.-.;.;.-.;.;.;.*.=.=.*.$.v ",
" &+ +d+e+f+g+h+i+ + + + + +j+k+].f.9+l+m+n+o+p+q+r+s+t+u+v+ ", " ~.(.l.- Y T ; < (.(.(.(.(.J.&.-.;.;.$.@.[ ] _ ) ) Z B B f ",
" w+ +x+y+z+A+B+C+ + + + + +D+E+9+F+G+H+I+J+K+L+M+N+O+ ", " P.(.F.X c.I.X f.(.(.(.(.(.G.=.-.=.] A Z Z Z Z z f $ ",
" P+Q+R+S+T+U+V+W+ + + + +X+Y+Z+`+ @I+J+Z .@+@E. ", " l.!.R.s.F.I.g.W.(.(.(.(.R.E .[ A Z Z Z B g $ ",
" @@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@I+/@(@_@ ", " . , ; - 0 M.b.V.U.R.Y.z.u n.7 c Z Z B g # + ",
" :@<@[@}@|@1@2@3@4@5@6@7@8@9@0@L+a@b@c@d@e@ ", " : w p Z.D.A.S.p u i M.A.A.S.* Z B h z ] C ",
" f@g@h@i@i@j@k@l@|@m@n@o@p@q@r@s@t@u@p v@ ", " s D.D.A.A.A.A.A.A.A.i B.B.b A Z Z @.-.` ",
" w@x@y@z@A@B@i@C@D@E@F@G@H@I@L+J@K@L@p M@ ", " 1 y C.D.A.A.A.A.A.M.u Z.e c A Z Z [ ;.&. ",
" N@O@P@Q@R@S@T@U@V@W@X@Y@Z@Y@`@ #.#p +# ", " 8 y d C.A.A.A.C.B.t * B Z Z Z A #.=.m ",
" @###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]# ", " 3 9 r t r 9 8 o @ $ # f j l B #.V ",
" ^#/# ", " j k ",
" ", " ",
" ", " ",
" ", " ",
" "}; " "
};

View file

@ -94,6 +94,7 @@ void *hwSym(const char *funcName,void *handle)
#ifdef SHUFFLE #ifdef SHUFFLE
GETFUNC(PostImgRedraw); GETFUNC(PostImgRedraw);
#endif //SHUFFLE #endif //SHUFFLE
GETFUNC(FlushScreenTextures);
GETFUNC(StartScreenWipe); GETFUNC(StartScreenWipe);
GETFUNC(EndScreenWipe); GETFUNC(EndScreenWipe);
GETFUNC(DoScreenWipe); GETFUNC(DoScreenWipe);

View file

@ -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.srb // Locations for searching the srb2.srb
#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"
@ -1150,6 +1154,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)
{ {
@ -1679,7 +1684,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);
@ -1872,11 +1877,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();
@ -1896,7 +1901,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);
@ -2025,7 +2030,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;
@ -2091,7 +2096,6 @@ INT32 I_StartupSystem(void)
return 0; return 0;
} }
// //
// I_Quit // I_Quit
// //
@ -2370,7 +2374,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
@ -2592,22 +2596,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
@ -2712,7 +2716,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
@ -2784,6 +2811,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);
@ -2809,16 +2841,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;

View file

@ -39,6 +39,10 @@
#ifdef HAVE_IMAGE #ifdef HAVE_IMAGE
#include "SDL_image.h" #include "SDL_image.h"
#elif 1
#define LOAD_XPM //I want XPM!
#include "IMG_xpm.c" //Alam: I don't want to add SDL_Image.dll/so
#define HAVE_IMAGE //I have SDL_Image, sortof
#endif #endif
#ifdef HAVE_IMAGE #ifdef HAVE_IMAGE
@ -562,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)
{ {
@ -574,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)
{ {
@ -658,6 +662,14 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type)
SDL_memset(&event, 0, sizeof(event_t)); SDL_memset(&event, 0, sizeof(event_t));
// Ignore the event if the mouse is not actually focused on the window.
// This can happen if you used the mouse to restore keyboard focus;
// this apparently makes a mouse button down event but not a mouse button up event,
// resulting in whatever key was pressed down getting "stuck" if we don't ignore it.
// -- Monster Iestyn (28/05/18)
if (SDL_GetMouseFocus() != window)
return;
/// \todo inputEvent.button.which /// \todo inputEvent.button.which
if (USE_MOUSEINPUT) if (USE_MOUSEINPUT)
{ {
@ -1442,6 +1454,7 @@ void I_StartupGraphics(void)
#ifdef SHUFFLE #ifdef SHUFFLE
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
#endif #endif
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);

View file

@ -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,28 +61,35 @@
#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;
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
static Music_Emu *gme; 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());
@ -86,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);
@ -102,6 +112,7 @@ void I_StartupSound(void)
} }
sound_started = true; sound_started = true;
songpaused = false;
Mix_AllocateChannels(256); Mix_AllocateChannels(256);
} }
@ -128,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)
@ -244,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;
@ -304,7 +320,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
gme_track_info(emu, &info, 0); gme_track_info(emu, &info, 0);
len = (info->play_length * 441 / 10) << 2; len = (info->play_length * 441 / 10) << 2;
mem = Z_Malloc(len, PU_SOUND, NULL); mem = malloc(len);
gme_play(emu, len >> 1, mem); gme_play(emu, len >> 1, mem);
gme_delete(emu); gme_delete(emu);
@ -359,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
@ -376,7 +392,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
gme_track_info(emu, &info, 0); gme_track_info(emu, &info, 0);
len = (info->play_length * 441 / 10) << 2; len = (info->play_length * 441 / 10) << 2;
mem = Z_Malloc(len, PU_SOUND, NULL); mem = malloc(len);
gme_play(emu, len >> 1, mem); gme_play(emu, len >> 1, mem);
gme_delete(emu); gme_delete(emu);
@ -385,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
@ -430,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);
@ -450,7 +487,7 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
(void)udata; (void)udata;
// no gme? no music. // no gme? no music.
if (!gme || gme_track_ended(gme)) if (!gme || gme_track_ended(gme) || songpaused)
return; return;
// play gme into stream // play gme into stream
@ -458,80 +495,105 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
// apply volume to stream // apply volume to stream
for (i = 0, p = (short *)stream; i < len/2; i++, p++) for (i = 0, p = (short *)stream; i < len/2; i++, p++)
*p = ((INT32)*p) * music_volume / 31; *p = ((INT32)*p) * music_volume*2 / 42;
} }
#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();
}
void I_ResumeSong(INT32 handle) musictype_t I_SongType(void)
{
(void)handle;
Mix_ResumeMusic();
}
//
// 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
@ -617,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);
@ -685,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)
@ -763,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

View file

@ -214,8 +214,11 @@ void OglSdlFinishUpdate(boolean waitvbl)
HWR_DrawScreenFinalTexture(sdlw, sdlh); HWR_DrawScreenFinalTexture(sdlw, sdlh);
SDL_GL_SwapWindow(window); SDL_GL_SwapWindow(window);
SetModelView(realwidth, realheight); GClipRect(0, 0, realwidth, realheight, NZCLIP_PLANE);
SetStates();
// Sryder: We need to draw the final screen texture again into the other buffer in the original position so that
// effects that want to take the old screen can do so after this
HWR_DrawScreenFinalTexture(realwidth, realheight);
} }
EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma)

View file

@ -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
@ -1180,12 +1183,6 @@ void I_StartupSound(void)
audio.callback = I_UpdateStream; audio.callback = I_UpdateStream;
audio.userdata = &localdata; audio.userdata = &localdata;
if (dedicated)
{
nosound = nomidimusic = nodigimusic = true;
return;
}
// Configure sound device // Configure sound device
CONS_Printf("I_StartupSound:\n"); CONS_Printf("I_StartupSound:\n");
@ -1219,7 +1216,7 @@ void I_StartupSound(void)
audio.samples /= 2; audio.samples /= 2;
} }
if (nosound) if (sound_disabled)
return; return;
#ifdef HW3SOUND #ifdef HW3SOUND
@ -1267,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;
@ -1294,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
@ -1319,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();
@ -1336,394 +1331,127 @@ 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
if ((nomidimusic && nodigimusic) || dedicated)
return;
#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];
XBOXSTATIC char filename[9];
void *data; void *data;
lumpnum_t lumpnum; lumpnum_t lumpnum;
size_t lumplength; size_t lumplength;
@ -1768,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
XBOXSTATIC 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;
XBOXSTATIC 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

View file

@ -100,6 +100,7 @@ void *hwSym(const char *funcName,void *handle)
#ifdef SHUFFLE #ifdef SHUFFLE
GETFUNC(PostImgRedraw); GETFUNC(PostImgRedraw);
#endif //SHUFFLE #endif //SHUFFLE
GETFUNC(FlushScreenTextures);
GETFUNC(StartScreenWipe); GETFUNC(StartScreenWipe);
GETFUNC(EndScreenWipe); GETFUNC(EndScreenWipe);
GETFUNC(DoScreenWipe); GETFUNC(DoScreenWipe);

View file

@ -60,7 +60,7 @@ void SDL_SYS_CDQuit(void)
UINT8 cdaudio_started = 0; // for system startup/shutdown UINT8 cdaudio_started = 0; // for system startup/shutdown
consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cd_volume = {"cd_volume","18",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
#ifndef NOSDLCD #ifndef NOSDLCD

View file

@ -1972,6 +1972,7 @@ void I_StartupGraphics(void)
#ifdef SHUFFLE #ifdef SHUFFLE
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
#endif #endif
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);

View file

@ -376,10 +376,10 @@ 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)
{ {
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

View file

@ -621,10 +621,11 @@ 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 (nosound)
return 0; return 0;

View file

@ -210,17 +210,17 @@ void ST_doPaletteStuff(void)
else else
palette = 0; palette = 0;
#ifdef HWRENDER
if (rendermode == render_opengl)
palette = 0; // No flashpals here in OpenGL
#endif
palette = min(max(palette, 0), 13); palette = min(max(palette, 0), 13);
if (palette != st_palette) if (palette != st_palette)
{ {
st_palette = palette; st_palette = palette;
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_SetPaletteColor(0);
else
#endif
if (rendermode != render_none) if (rendermode != render_none)
{ {
V_SetPaletteLump(GetPalette()); // Reset the palette V_SetPaletteLump(GetPalette()); // Reset the palette

View file

@ -418,7 +418,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
if (scrn & V_FLIP) if (scrn & V_FLIP)
{ {
flip = true; flip = true;
x -= FixedMul((SHORT(patch->width) - SHORT(patch->leftoffset))<<FRACBITS, pscale); x -= FixedMul((SHORT(patch->width) - SHORT(patch->leftoffset))<<FRACBITS, pscale) + 1;
} }
else else
x -= FixedMul(SHORT(patch->leftoffset)<<FRACBITS, pscale); x -= FixedMul(SHORT(patch->leftoffset)<<FRACBITS, pscale);
@ -446,30 +446,10 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
y = FixedMul(y,dupy<<FRACBITS); y = FixedMul(y,dupy<<FRACBITS);
x >>= FRACBITS; x >>= FRACBITS;
y >>= FRACBITS; y >>= FRACBITS;
desttop += (y*vid.width) + x;
// Center it if necessary // Center it if necessary
if (!(scrn & V_SCALEPATCHMASK)) if (!(scrn & V_SCALEPATCHMASK))
{ {
if (vid.width != BASEVIDWIDTH * dupx)
{
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
// so center this imaginary screen
if (scrn & V_SNAPTORIGHT)
desttop += (vid.width - (BASEVIDWIDTH * dupx));
else if (!(scrn & V_SNAPTOLEFT))
desttop += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
}
if (vid.height != BASEVIDHEIGHT * dupy)
{
// same thing here
if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
desttop += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)) * vid.width;
else if (scrn & V_SNAPTOBOTTOM)
desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width;
else if (!(scrn & V_SNAPTOTOP))
desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2;
}
// if it's meant to cover the whole screen, black out the rest // if it's meant to cover the whole screen, black out the rest
if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT) if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT)
{ {
@ -477,6 +457,27 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
source = (const UINT8 *)(column) + 3; source = (const UINT8 *)(column) + 3;
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
} }
if (vid.width != BASEVIDWIDTH * dupx)
{
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
// so center this imaginary screen
if (scrn & V_SNAPTORIGHT)
x += (vid.width - (BASEVIDWIDTH * dupx));
else if (!(scrn & V_SNAPTOLEFT))
x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
}
if (vid.height != BASEVIDHEIGHT * dupy)
{
// same thing here
if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy));
else if (scrn & V_SNAPTOBOTTOM)
y += (vid.height - (BASEVIDHEIGHT * dupy));
else if (!(scrn & V_SNAPTOTOP))
y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
}
desttop += (y*vid.width) + x;
} }
} }
@ -583,28 +584,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
y = FixedMul(y,dupy<<FRACBITS); y = FixedMul(y,dupy<<FRACBITS);
x >>= FRACBITS; x >>= FRACBITS;
y >>= FRACBITS; y >>= FRACBITS;
desttop += (y*vid.width) + x;
// Center it if necessary // Center it if necessary
if (!(scrn & V_SCALEPATCHMASK)) if (!(scrn & V_SCALEPATCHMASK))
{ {
if (vid.width != BASEVIDWIDTH * dupx)
{
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
// so center this imaginary screen
if (scrn & V_SNAPTORIGHT)
desttop += (vid.width - (BASEVIDWIDTH * dupx));
else if (!(scrn & V_SNAPTOLEFT))
desttop += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
}
if (vid.height != BASEVIDHEIGHT * dupy)
{
// same thing here
if (scrn & V_SNAPTOBOTTOM)
desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width;
else if (!(scrn & V_SNAPTOTOP))
desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2;
}
// if it's meant to cover the whole screen, black out the rest // if it's meant to cover the whole screen, black out the rest
if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT) if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT)
{ {
@ -612,7 +595,26 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
source = (const UINT8 *)(column) + 3; source = (const UINT8 *)(column) + 3;
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
} }
if (vid.width != BASEVIDWIDTH * dupx)
{
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
// so center this imaginary screen
if (scrn & V_SNAPTORIGHT)
x += (vid.width - (BASEVIDWIDTH * dupx));
else if (!(scrn & V_SNAPTOLEFT))
x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
}
if (vid.height != BASEVIDHEIGHT * dupy)
{
// same thing here
if (scrn & V_SNAPTOBOTTOM)
y += (vid.height - (BASEVIDHEIGHT * dupy));
else if (!(scrn & V_SNAPTOTOP))
y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
}
} }
desttop += (y*vid.width) + x;
} }
for (col = sx<<FRACBITS; (col>>FRACBITS) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, ++x, desttop++) for (col = sx<<FRACBITS; (col>>FRACBITS) < SHORT(patch->width) && (col>>FRACBITS) < w; col += colfrac, ++x, desttop++)
@ -651,14 +653,10 @@ 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))
#ifdef HWRENDER V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE)); // Draw a star
// || (rendermode != render_soft && rendermode != render_none)
#endif
)
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
else else
{ { // Find front angle of the first waiting frame of the character's actual sprites
spriteframe_t *sprframe = &skins[skinnum].spritedef.spriteframes[2 & FF_FRAMEMASK]; spriteframe_t *sprframe = &skins[skinnum].spritedef.spriteframes[2 & FF_FRAMEMASK];
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE); const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
@ -776,7 +774,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{ // Clear the entire screen, from dest to deststop. Yes, this really works. { // Clear the entire screen, from dest to deststop. Yes, this really works.
memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp); memset(screens[0], (c&255), vid.width * vid.height * vid.bpp);
return; return;
} }
@ -831,7 +829,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
c &= 255; c &= 255;
for (;(--h >= 0) && dest < deststop; dest += vid.width) for (;(--h >= 0) && dest < deststop; dest += vid.width)
memset(dest, (UINT8)(c&255), w * vid.bpp); memset(dest, c, w * vid.bpp);
} }
// //
@ -937,14 +935,6 @@ void V_DrawPatchFill(patch_t *pat)
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz;
#ifdef HWRENDER
if (rendermode == render_opengl)
{
pw = FixedMul(SHORT(pat->width)*FRACUNIT, vid.fdupx)>>FRACBITS;
ph = FixedMul(SHORT(pat->height)*FRACUNIT, vid.fdupy)>>FRACBITS;
}
#endif
for (x = 0; x < vid.width; x += pw) for (x = 0; x < vid.width; x += pw)
{ {
for (y = 0; y < vid.height; y += ph) for (y = 0; y < vid.height; y += ph)
@ -1137,7 +1127,7 @@ char *V_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
// //
void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string) void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
{ {
INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0; INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, center = 0, left = 0;
const char *ch = string; const char *ch = string;
INT32 charflags = 0; INT32 charflags = 0;
const UINT8 *colormap = NULL; const UINT8 *colormap = NULL;
@ -1153,7 +1143,12 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
scrwidth = vid.width; scrwidth = vid.width;
} }
else else
{
dupx = dupy = 1; dupx = dupy = 1;
scrwidth = vid.width/vid.dupx;
left = (scrwidth - BASEVIDWIDTH)/2;
scrwidth -= left;
}
charflags = (option & V_CHARCOLORMASK); charflags = (option & V_CHARCOLORMASK);
@ -1214,9 +1209,9 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
else else
w = SHORT(hu_font[c]->width) * dupx; w = SHORT(hu_font[c]->width) * dupx;
if (cx + w > scrwidth) if (cx > scrwidth)
break; break;
if (cx < 0) //left boundary check if (cx+left + w < 0) //left boundary check
{ {
cx += w; cx += w;
continue; continue;
@ -1247,7 +1242,7 @@ void V_DrawRightAlignedString(INT32 x, INT32 y, INT32 option, const char *string
// //
void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string) void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string)
{ {
INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0; INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, center = 0, left = 0;
const char *ch = string; const char *ch = string;
INT32 charflags = 0; INT32 charflags = 0;
const UINT8 *colormap = NULL; const UINT8 *colormap = NULL;
@ -1263,7 +1258,12 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string)
scrwidth = vid.width; scrwidth = vid.width;
} }
else else
{
dupx = dupy = 1; dupx = dupy = 1;
scrwidth = vid.width/vid.dupx;
left = (scrwidth - BASEVIDWIDTH)/2;
scrwidth -= left;
}
charflags = (option & V_CHARCOLORMASK); charflags = (option & V_CHARCOLORMASK);
@ -1322,9 +1322,9 @@ void V_DrawSmallString(INT32 x, INT32 y, INT32 option, const char *string)
} }
else else
w = SHORT(hu_font[c]->width) * dupx / 2; w = SHORT(hu_font[c]->width) * dupx / 2;
if (cx + w > scrwidth) if (cx > scrwidth)
break; break;
if (cx < 0) //left boundary check if (cx+left + w < 0) //left boundary check
{ {
cx += w; cx += w;
continue; continue;
@ -1349,7 +1349,7 @@ void V_DrawRightAlignedSmallString(INT32 x, INT32 y, INT32 option, const char *s
// //
void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string) void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
{ {
INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH; INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0;
const char *ch = string; const char *ch = string;
INT32 charflags = 0; INT32 charflags = 0;
const UINT8 *colormap = NULL; const UINT8 *colormap = NULL;
@ -1365,7 +1365,12 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
scrwidth = vid.width; scrwidth = vid.width;
} }
else else
{
dupx = dupy = 1; dupx = dupy = 1;
scrwidth = vid.width/vid.dupx;
left = (scrwidth - BASEVIDWIDTH)/2;
scrwidth -= left;
}
charflags = (option & V_CHARCOLORMASK); charflags = (option & V_CHARCOLORMASK);
@ -1422,9 +1427,9 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
else else
w = (SHORT(tny_font[c]->width) * dupx); w = (SHORT(tny_font[c]->width) * dupx);
if (cx + w > scrwidth) if (cx > scrwidth)
break; break;
if (cx < 0) //left boundary check if (cx+left + w < 0) //left boundary check
{ {
cx += w; cx += w;
continue; continue;
@ -1447,7 +1452,7 @@ void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *st
void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string) void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
{ {
fixed_t cx = x, cy = y; fixed_t cx = x, cy = y;
INT32 w, c, dupx, dupy, scrwidth = BASEVIDWIDTH, center = 0; INT32 w, c, dupx, dupy, scrwidth, center = 0, left = 0;
const char *ch = string; const char *ch = string;
INT32 spacewidth = 4, charwidth = 0; INT32 spacewidth = 4, charwidth = 0;
@ -1461,7 +1466,12 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
scrwidth = vid.width; scrwidth = vid.width;
} }
else else
{
dupx = dupy = 1; dupx = dupy = 1;
scrwidth = vid.width/vid.dupx;
left = (scrwidth - BASEVIDWIDTH)/2;
scrwidth -= left;
}
switch (option & V_SPACINGMASK) switch (option & V_SPACINGMASK)
{ {
@ -1515,9 +1525,9 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
else else
w = SHORT(hu_font[c]->width) * dupx; w = SHORT(hu_font[c]->width) * dupx;
if ((cx>>FRACBITS) + w > scrwidth) if ((cx>>FRACBITS) > scrwidth)
break; break;
if (cx < 0) //left boundary check if ((cx>>FRACBITS)+left + w < 0) //left boundary check
{ {
cx += w<<FRACBITS; cx += w<<FRACBITS;
continue; continue;
@ -1617,7 +1627,7 @@ void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string)
} }
w = SHORT(cred_font[c]->width) * dupx; w = SHORT(cred_font[c]->width) * dupx;
if ((cx>>FRACBITS) + w > scrwidth) if ((cx>>FRACBITS) > scrwidth)
break; break;
V_DrawSciencePatch(cx, cy, option, cred_font[c], FRACUNIT); V_DrawSciencePatch(cx, cy, option, cred_font[c], FRACUNIT);
@ -1653,7 +1663,7 @@ INT32 V_CreditStringWidth(const char *string)
// //
void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string) void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string)
{ {
INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth = BASEVIDWIDTH; INT32 w, c, cx = x, cy = y, dupx, dupy, scrwidth, left = 0;
const char *ch = string; const char *ch = string;
if (option & V_NOSCALESTART) if (option & V_NOSCALESTART)
@ -1663,7 +1673,12 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string)
scrwidth = vid.width; scrwidth = vid.width;
} }
else else
{
dupx = dupy = 1; dupx = dupy = 1;
scrwidth = vid.width/vid.dupx;
left = (scrwidth - BASEVIDWIDTH)/2;
scrwidth -= left;
}
for (;;) for (;;)
{ {
@ -1685,11 +1700,10 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string)
} }
w = SHORT(lt_font[c]->width) * dupx; w = SHORT(lt_font[c]->width) * dupx;
if (cx + w > scrwidth) if (cx > scrwidth)
break; break;
if (cx+left + w < 0) //left boundary check
//left boundary check
if (cx < 0)
{ {
cx += w; cx += w;
continue; continue;

View file

@ -194,16 +194,21 @@ 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
char *name = malloc(strlen(wadfiles[wadnum]->filename)+10); size_t len = strlen(wadfiles[wadnum]->filename);
char *name = malloc(len+10);
strcpy(name, wadfiles[wadnum]->filename); strcpy(name, wadfiles[wadnum]->filename);
if (!fasticmp(&name[strlen(name) - 4], ".soc")) { if (!fasticmp(&name[len - 4], ".soc")) {
// If it's not a .soc file, copy the lump name in too. // If it's not a .soc file, copy the lump name in too.
name[strlen(wadfiles[wadnum]->filename)] = '|'; name[len] = '|';
M_Memcpy(name+strlen(wadfiles[wadnum]->filename)+1, lump_p->name, 8); M_Memcpy(name+len+1, lump_p->name, 8);
name[strlen(wadfiles[wadnum]->filename)+9] = '\0'; name[len+9] = '\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);
free(name);
} }
else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG
{ {

View file

@ -161,7 +161,7 @@ static BOOL wasPlaying;
//static INT cdVolume = 0; // current cd volume (0-31) //static INT cdVolume = 0; // current cd volume (0-31)
// 0-31 like Music & Sfx, though CD hardware volume is 0-255. // 0-31 like Music & Sfx, though CD hardware volume is 0-255.
consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cd_volume = {"cd_volume","18",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// allow Update for next/loop track // allow Update for next/loop track
// some crap cd drivers take up to // some crap cd drivers take up to
@ -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);

View file

@ -117,6 +117,7 @@ static loadfunc_t hwdFuncTable[] = {
#ifdef SHUFFLE #ifdef SHUFFLE
{"PostImgRedraw@4", &hwdriver.pfnPostImgRedraw}, {"PostImgRedraw@4", &hwdriver.pfnPostImgRedraw},
#endif #endif
{"FlushScreenTextures@0",&hwdriver.pfnFlushScreenTextures},
{"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe}, {"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe},
{"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe}, {"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe},
{"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe}, {"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe},
@ -147,6 +148,7 @@ static loadfunc_t hwdFuncTable[] = {
#ifdef SHUFFLE #ifdef SHUFFLE
{"PostImgRedraw", &hwdriver.pfnPostImgRedraw}, {"PostImgRedraw", &hwdriver.pfnPostImgRedraw},
#endif #endif
{"FlushScreenTextures"},&hwdriver.pfnFlushScreenTextures},
{"StartScreenWipe", &hwdriver.pfnStartScreenWipe}, {"StartScreenWipe", &hwdriver.pfnStartScreenWipe},
{"EndScreenWipe", &hwdriver.pfnEndScreenWipe}, {"EndScreenWipe", &hwdriver.pfnEndScreenWipe},
{"DoScreenWipe", &hwdriver.pfnDoScreenWipe}, {"DoScreenWipe", &hwdriver.pfnDoScreenWipe},

View file

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

View file

@ -17,17 +17,13 @@
#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 _WII
#ifndef _LARGEFILE64_SOURCE #ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE
#endif #endif
#endif #endif
#endif
#ifndef _LFS64_LARGEFILE #ifndef _LFS64_LARGEFILE
#define _LFS64_LARGEFILE #define _LFS64_LARGEFILE
@ -38,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;
@ -357,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);
@ -442,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)
{ {
@ -452,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);
@ -533,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;
@ -543,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;
} }
} }
@ -605,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;
@ -615,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));
@ -623,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)
@ -802,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;
}

View file

@ -159,7 +159,7 @@ static boolean wasPlaying;
//static int cdVolume = 0; // current cd volume (0-31) //static int cdVolume = 0; // current cd volume (0-31)
// 0-31 like Music & Sfx, though CD hardware volume is 0-255. // 0-31 like Music & Sfx, though CD hardware volume is 0-255.
consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cd_volume = {"cd_volume","18",CV_SAVE,soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// allow Update for next/loop track // allow Update for next/loop track
// some crap cd drivers take up to // some crap cd drivers take up to

View file

@ -538,7 +538,8 @@ INT32 I_StartSound (sfxenum_t id,
INT32 vol, INT32 vol,
INT32 sep, INT32 sep,
INT32 pitch, INT32 pitch,
INT32 priority) INT32 priority,
INT32 channel)
{ {
HRESULT hr; HRESULT hr;
LPDIRECTSOUNDBUFFER dsbuffer; LPDIRECTSOUNDBUFFER dsbuffer;
@ -549,6 +550,7 @@ INT32 I_StartSound (sfxenum_t id,
#ifdef SURROUND #ifdef SURROUND
LPDIRECTSOUNDBUFFER dssurround; LPDIRECTSOUNDBUFFER dssurround;
#endif #endif
(void)channel;
if (nosound) if (nosound)
return -1; return -1;