mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2025-01-26 19:20:55 +00:00
Merge branch 'next' into jimita-unfuck-awayview
This commit is contained in:
commit
34ce368895
46 changed files with 1821 additions and 356 deletions
|
@ -3,7 +3,7 @@ jobs:
|
|||
build:
|
||||
working_directory: /root/SRB2
|
||||
docker:
|
||||
- image: debian:jessie
|
||||
- image: debian:stretch
|
||||
environment:
|
||||
CC: ccache gcc -m32
|
||||
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
|
||||
|
@ -36,17 +36,20 @@ jobs:
|
|||
- v1-SRB2-APT
|
||||
- run:
|
||||
name: Install SDK
|
||||
command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng12-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx openssh-client
|
||||
command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx openssh-client
|
||||
- save_cache:
|
||||
key: v1-SRB2-APT
|
||||
paths:
|
||||
- /var/cache/apt/archives
|
||||
- checkout
|
||||
- run:
|
||||
name: Compile without network support
|
||||
command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1
|
||||
name: Compile without network support and BLUA
|
||||
command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1 NO_LUA=1
|
||||
- run:
|
||||
name: Clean build
|
||||
name: wipe build
|
||||
command: make -C src LINUX=1 cleandep
|
||||
- run:
|
||||
name: rebuild depend
|
||||
command: make -C src LINUX=1 clean
|
||||
- restore_cache:
|
||||
keys:
|
||||
|
|
28
.travis.yml
28
.travis.yml
|
@ -15,6 +15,7 @@ matrix:
|
|||
- p7zip-full
|
||||
- gcc-4.4
|
||||
compiler: gcc-4.4
|
||||
env: GCC44=1
|
||||
#gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
|
||||
- os: linux
|
||||
addons:
|
||||
|
@ -27,6 +28,7 @@ matrix:
|
|||
- p7zip-full
|
||||
- gcc-4.6
|
||||
compiler: gcc-4.6
|
||||
env: GCC46=1
|
||||
#gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
|
||||
- os: linux
|
||||
addons:
|
||||
|
@ -39,9 +41,11 @@ matrix:
|
|||
- p7zip-full
|
||||
- gcc-4.7
|
||||
compiler: gcc-4.7
|
||||
env: GCC47=1
|
||||
#gcc-4.7
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: GCC48=1
|
||||
#gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
|
||||
- os: linux
|
||||
addons:
|
||||
|
@ -56,6 +60,7 @@ matrix:
|
|||
- p7zip-full
|
||||
- gcc-4.8
|
||||
compiler: gcc-4.8
|
||||
env: GCC48=1
|
||||
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
|
||||
- os: linux
|
||||
addons:
|
||||
|
@ -70,7 +75,7 @@ matrix:
|
|||
- p7zip-full
|
||||
- gcc-7
|
||||
compiler: gcc-7
|
||||
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough"
|
||||
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough" GCC72=1
|
||||
#gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802
|
||||
- os: linux
|
||||
addons:
|
||||
|
@ -85,7 +90,7 @@ matrix:
|
|||
- p7zip-full
|
||||
- gcc-8
|
||||
compiler: gcc-8
|
||||
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow"
|
||||
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow" GCC81=1
|
||||
#gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0
|
||||
- os: linux
|
||||
compiler: clang
|
||||
|
@ -216,9 +221,11 @@ matrix:
|
|||
# - os: osx
|
||||
# osx_image: xcode7.2
|
||||
# #Apple LLVM version 7.0.2 (clang-700.1.81)
|
||||
# - os: osx
|
||||
# osx_image: xcode7.3
|
||||
# #Apple LLVM version 7.3.0 (clang-703.0.31)
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
#Apple LLVM version 7.3.0 (clang-703.0.31)
|
||||
#Default: macOS 10.13 and Xcode 9.4.1
|
||||
allow_failures:
|
||||
- compiler: clang-3.5
|
||||
- compiler: clang-3.6
|
||||
|
@ -242,6 +249,16 @@ addons:
|
|||
- libgl1-mesa-dev
|
||||
- libgme-dev
|
||||
- p7zip-full
|
||||
homebrew:
|
||||
taps:
|
||||
- mazmazz/srb2
|
||||
packages:
|
||||
- sdl2_mixer
|
||||
- game-music-emu
|
||||
- p7zip
|
||||
- cmake
|
||||
update: true
|
||||
|
||||
|
||||
before_script:
|
||||
- wget --verbose --server-response -c http://rosenthalcastle.org/srb2/SRB2-v2115-assets-2.7z -O $HOME/srb2_cache/SRB2-v2115-assets-2.7z
|
||||
|
@ -253,9 +270,6 @@ before_script:
|
|||
- cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
before_install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install sdl2 sdl2_mixer game-music-emu p7zip; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cmake||true; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/release/SDL2-2.0.6.dmg; hdiutil attach SDL2-2.0.6.dmg; sudo cp -a /Volumes/SDL2/SDL2.framework /Library/Frameworks/; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.dmg; hdiutil attach SDL2_mixer-2.0.1.dmg; sudo cp -a /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks/; fi
|
||||
- mkdir -p $HOME/srb2_cache
|
||||
|
|
|
@ -54,13 +54,19 @@ macro(copy_files_to_build_dir target dlllist_var)
|
|||
endif()
|
||||
endmacro()
|
||||
|
||||
# 64-bit check
|
||||
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
|
||||
# bitness check
|
||||
set(SRB2_SYSTEM_BITS 0)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
message(STATUS "Target is 64-bit")
|
||||
set(SRB2_SYSTEM_BITS 64)
|
||||
else()
|
||||
endif()
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
message(STATUS "Target is 32-bit")
|
||||
set(SRB2_SYSTEM_BITS 32)
|
||||
endif()
|
||||
if(${SRB2_SYSTEM_BITS} EQUAL 0)
|
||||
message(STATUS "Target bitness is unknown")
|
||||
endif()
|
||||
|
||||
# OS macros
|
||||
if (UNIX)
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
# and other things
|
||||
#
|
||||
|
||||
ifdef GCC81
|
||||
GCC80=1
|
||||
endif
|
||||
|
||||
ifdef GCC80
|
||||
GCC72=1
|
||||
endif
|
||||
|
|
|
@ -96,6 +96,37 @@ boolean I_SetSongSpeed(float speed)
|
|||
return false;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC SEEKING
|
||||
/// ------------------------
|
||||
|
||||
UINT32 I_GetSongLength(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||
{
|
||||
(void)looppoint;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 I_GetSongLoopPoint(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean I_SetSongPosition(UINT32 position)
|
||||
{
|
||||
(void)position;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 I_GetSongPosition(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC PLAYBACK
|
||||
/// ------------------------
|
||||
|
@ -140,3 +171,44 @@ void I_SetMusicVolume(INT32 volume)
|
|||
{
|
||||
(void)volume;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC FADING
|
||||
/// ------------------------
|
||||
|
||||
void I_SetInternalMusicVolume(UINT8 volume)
|
||||
{
|
||||
(void)volume;
|
||||
}
|
||||
|
||||
void I_StopFadingSong(void)
|
||||
{
|
||||
}
|
||||
|
||||
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
|
||||
{
|
||||
(void)target_volume;
|
||||
(void)source_volume;
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
|
||||
{
|
||||
(void)target_volume;
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeOutStopSong(UINT32 ms)
|
||||
{
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||
{
|
||||
(void)ms;
|
||||
(void)looping;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -148,6 +148,20 @@ void COM_BufInsertText(const char *ptext)
|
|||
}
|
||||
}
|
||||
|
||||
/** Progress the wait timer and flush waiting console commands when ready.
|
||||
*/
|
||||
void
|
||||
COM_BufTicker(void)
|
||||
{
|
||||
if (com_wait)
|
||||
{
|
||||
com_wait--;
|
||||
return;
|
||||
}
|
||||
|
||||
COM_BufExecute();
|
||||
}
|
||||
|
||||
/** Flushes (executes) console commands in the buffer.
|
||||
*/
|
||||
void COM_BufExecute(void)
|
||||
|
@ -157,12 +171,6 @@ void COM_BufExecute(void)
|
|||
char line[1024] = "";
|
||||
INT32 quotes;
|
||||
|
||||
if (com_wait)
|
||||
{
|
||||
com_wait--;
|
||||
return;
|
||||
}
|
||||
|
||||
while (com_text.cursize)
|
||||
{
|
||||
// find a '\n' or; line break
|
||||
|
@ -514,7 +522,6 @@ static void COM_ExecuteString(char *ptext)
|
|||
{
|
||||
if (!stricmp(com_argv[0], cmd->name)) //case insensitive now that we have lower and uppercase!
|
||||
{
|
||||
recursion = 0;
|
||||
cmd->function();
|
||||
return;
|
||||
}
|
||||
|
@ -526,19 +533,17 @@ static void COM_ExecuteString(char *ptext)
|
|||
if (!stricmp(com_argv[0], a->name))
|
||||
{
|
||||
if (recursion > MAX_ALIAS_RECURSION)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Alias recursion cycle detected!\n"));
|
||||
recursion = 0;
|
||||
return;
|
||||
else
|
||||
{ // Monster Iestyn: keep track of how many levels of recursion we're in
|
||||
recursion++;
|
||||
COM_BufInsertText(a->value);
|
||||
recursion--;
|
||||
}
|
||||
recursion++;
|
||||
COM_BufInsertText(a->value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
recursion = 0;
|
||||
|
||||
// check cvars
|
||||
// Hurdler: added at Ebola's request ;)
|
||||
// (don't flood the console in software mode with bad gr_xxx command)
|
||||
|
|
|
@ -45,6 +45,9 @@ void COM_ImmedExecute(const char *ptext);
|
|||
// Execute commands in buffer, flush them
|
||||
void COM_BufExecute(void);
|
||||
|
||||
// As above; and progress the wait timer.
|
||||
void COM_BufTicker(void);
|
||||
|
||||
// setup command buffer, at game tartup
|
||||
void COM_Init(void);
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ static size_t input_len; // length of current line, used to bound cursor and suc
|
|||
// protos.
|
||||
static void CON_InputInit(void);
|
||||
static void CON_RecalcSize(void);
|
||||
static void CON_ChangeHeight(void);
|
||||
|
||||
static void CONS_hudlines_Change(void);
|
||||
static void CONS_backcolor_Change(void);
|
||||
|
@ -447,6 +448,12 @@ static void CON_RecalcSize(void)
|
|||
con_destlines = vid.height;
|
||||
}
|
||||
|
||||
if (con_destlines > 0) // Resize console if already open
|
||||
{
|
||||
CON_ChangeHeight();
|
||||
con_curlines = con_destlines;
|
||||
}
|
||||
|
||||
// check for change of video width
|
||||
if (conw == con_width)
|
||||
return; // didn't change
|
||||
|
@ -496,6 +503,20 @@ static void CON_RecalcSize(void)
|
|||
Z_Free(tmp_buffer);
|
||||
}
|
||||
|
||||
static void CON_ChangeHeight(void)
|
||||
{
|
||||
INT32 minheight = 20 * con_scalefactor; // 20 = 8+8+4
|
||||
|
||||
// toggle console in
|
||||
con_destlines = (cons_height.value*vid.height)/100;
|
||||
if (con_destlines < minheight)
|
||||
con_destlines = minheight;
|
||||
else if (con_destlines > vid.height)
|
||||
con_destlines = vid.height;
|
||||
|
||||
con_destlines &= ~0x3; // multiple of text row height
|
||||
}
|
||||
|
||||
// Handles Console moves in/out of screen (per frame)
|
||||
//
|
||||
static void CON_MoveConsole(void)
|
||||
|
@ -584,16 +605,7 @@ void CON_Ticker(void)
|
|||
CON_ClearHUD();
|
||||
}
|
||||
else
|
||||
{
|
||||
// toggle console in
|
||||
con_destlines = (cons_height.value*vid.height)/100;
|
||||
if (con_destlines < minheight)
|
||||
con_destlines = minheight;
|
||||
else if (con_destlines > vid.height)
|
||||
con_destlines = vid.height;
|
||||
|
||||
con_destlines &= ~0x3; // multiple of text row height
|
||||
}
|
||||
CON_ChangeHeight();
|
||||
}
|
||||
|
||||
// console movement
|
||||
|
@ -1051,16 +1063,6 @@ boolean CON_Responder(event_t *ev)
|
|||
else if (key == KEY_KPADSLASH)
|
||||
key = '/';
|
||||
|
||||
// capslock
|
||||
if (key == KEY_CAPSLOCK) // it's a toggle.
|
||||
{
|
||||
if (capslock)
|
||||
capslock = false;
|
||||
else
|
||||
capslock = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key >= 'a' && key <= 'z')
|
||||
{
|
||||
if (capslock ^ shiftdown)
|
||||
|
@ -1106,6 +1108,7 @@ static void CON_Print(char *msg)
|
|||
{
|
||||
size_t l;
|
||||
INT32 controlchars = 0; // for color changing
|
||||
char color = '\x80'; // keep color across lines
|
||||
|
||||
if (msg == NULL)
|
||||
return;
|
||||
|
@ -1131,7 +1134,7 @@ static void CON_Print(char *msg)
|
|||
{
|
||||
if (*msg & 0x80)
|
||||
{
|
||||
con_line[con_cx++] = *(msg++);
|
||||
color = con_line[con_cx++] = *(msg++);
|
||||
controlchars++;
|
||||
continue;
|
||||
}
|
||||
|
@ -1139,12 +1142,14 @@ static void CON_Print(char *msg)
|
|||
{
|
||||
con_cy--;
|
||||
CON_Linefeed();
|
||||
color = '\x80';
|
||||
controlchars = 0;
|
||||
}
|
||||
else if (*msg == '\n') // linefeed
|
||||
{
|
||||
CON_Linefeed();
|
||||
controlchars = 0;
|
||||
con_line[con_cx++] = color;
|
||||
controlchars = 1;
|
||||
}
|
||||
else if (*msg == ' ') // space
|
||||
{
|
||||
|
@ -1152,7 +1157,8 @@ static void CON_Print(char *msg)
|
|||
if (con_cx - controlchars >= con_width-11)
|
||||
{
|
||||
CON_Linefeed();
|
||||
controlchars = 0;
|
||||
con_line[con_cx++] = color;
|
||||
controlchars = 1;
|
||||
}
|
||||
}
|
||||
else if (*msg == '\t')
|
||||
|
@ -1167,7 +1173,8 @@ static void CON_Print(char *msg)
|
|||
if (con_cx - controlchars >= con_width-11)
|
||||
{
|
||||
CON_Linefeed();
|
||||
controlchars = 0;
|
||||
con_line[con_cx++] = color;
|
||||
controlchars = 1;
|
||||
}
|
||||
}
|
||||
msg++;
|
||||
|
@ -1184,7 +1191,8 @@ static void CON_Print(char *msg)
|
|||
if ((con_cx - controlchars) + l > con_width-11)
|
||||
{
|
||||
CON_Linefeed();
|
||||
controlchars = 0;
|
||||
con_line[con_cx++] = color;
|
||||
controlchars = 1;
|
||||
}
|
||||
|
||||
// a word at a time
|
||||
|
@ -1539,8 +1547,7 @@ static void CON_DrawConsole(void)
|
|||
i = con_cy - con_scrollup;
|
||||
|
||||
// skip the last empty line due to the cursor being at the start of a new line
|
||||
if (!con_scrollup && !con_cx)
|
||||
i--;
|
||||
i--;
|
||||
|
||||
i -= (con_curlines - minheight) / charheight;
|
||||
|
||||
|
|
|
@ -2056,17 +2056,11 @@ static void CL_ConnectToServer(boolean viams)
|
|||
|
||||
if (i != -1)
|
||||
{
|
||||
INT32 j;
|
||||
UINT8 num = serverlist[i].info.gametype;
|
||||
const char *gametypestr = NULL;
|
||||
CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername);
|
||||
for (j = 0; gametype_cons_t[j].strvalue; j++)
|
||||
{
|
||||
if (gametype_cons_t[j].value == serverlist[i].info.gametype)
|
||||
{
|
||||
gametypestr = gametype_cons_t[j].strvalue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num < NUMGAMETYPES)
|
||||
gametypestr = Gametype_Names[num];
|
||||
if (gametypestr)
|
||||
CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr);
|
||||
CONS_Printf(M_GetText("Version: %d.%d.%u\n"), serverlist[i].info.version/100,
|
||||
|
@ -2598,7 +2592,10 @@ static void Command_Ban(void)
|
|||
else
|
||||
{
|
||||
if (server) // only the server is allowed to do this right now
|
||||
{
|
||||
Ban_Add(COM_Argv(2));
|
||||
D_SaveBan(); // save the ban list
|
||||
}
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
{
|
||||
|
@ -2629,6 +2626,42 @@ static void Command_Ban(void)
|
|||
|
||||
}
|
||||
|
||||
static void Command_BanIP(void)
|
||||
{
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("banip <ip> <reason>: ban an ip address\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (server) // Only the server can use this, otherwise does nothing.
|
||||
{
|
||||
const char *address = (COM_Argv(1));
|
||||
const char *reason;
|
||||
|
||||
if (COM_Argc() == 2)
|
||||
reason = NULL;
|
||||
else
|
||||
reason = COM_Argv(2);
|
||||
|
||||
|
||||
if (I_SetBanAddress && I_SetBanAddress(address, NULL))
|
||||
{
|
||||
if (reason)
|
||||
CONS_Printf("Banned IP address %s for: %s\n", address, reason);
|
||||
else
|
||||
CONS_Printf("Banned IP address %s\n", address);
|
||||
|
||||
Ban_Add(reason);
|
||||
D_SaveBan();
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Command_Kick(void)
|
||||
{
|
||||
if (COM_Argc() < 2)
|
||||
|
@ -2908,6 +2941,7 @@ void D_ClientServerInit(void)
|
|||
COM_AddCommand("getplayernum", Command_GetPlayerNum);
|
||||
COM_AddCommand("kick", Command_Kick);
|
||||
COM_AddCommand("ban", Command_Ban);
|
||||
COM_AddCommand("banip", Command_BanIP);
|
||||
COM_AddCommand("clearbans", Command_ClearBans);
|
||||
COM_AddCommand("showbanlist", Command_ShowBan);
|
||||
COM_AddCommand("reloadbans", Command_ReloadBan);
|
||||
|
@ -4563,7 +4597,7 @@ void TryRunTics(tic_t realtics)
|
|||
|
||||
if (realtics >= 1)
|
||||
{
|
||||
COM_BufExecute();
|
||||
COM_BufTicker();
|
||||
if (mapchangepending)
|
||||
D_MapChange(-1, 0, ultimatemode, false, 2, false, fromlevelselect); // finish the map change
|
||||
}
|
||||
|
|
46
src/d_main.c
46
src/d_main.c
|
@ -176,37 +176,11 @@ void D_PostEvent_end(void) {};
|
|||
#endif
|
||||
|
||||
// modifier keys
|
||||
// Now handled in I_OsPolling
|
||||
UINT8 shiftdown = 0; // 0x1 left, 0x2 right
|
||||
UINT8 ctrldown = 0; // 0x1 left, 0x2 right
|
||||
UINT8 altdown = 0; // 0x1 left, 0x2 right
|
||||
boolean capslock = 0; // gee i wonder what this does.
|
||||
//
|
||||
// D_ModifierKeyResponder
|
||||
// Sets global shift/ctrl/alt variables, never actually eats events
|
||||
//
|
||||
static inline void D_ModifierKeyResponder(event_t *ev)
|
||||
{
|
||||
if (ev->type == ev_keydown || ev->type == ev_console) switch (ev->data1)
|
||||
{
|
||||
case KEY_LSHIFT: shiftdown |= 0x1; return;
|
||||
case KEY_RSHIFT: shiftdown |= 0x2; return;
|
||||
case KEY_LCTRL: ctrldown |= 0x1; return;
|
||||
case KEY_RCTRL: ctrldown |= 0x2; return;
|
||||
case KEY_LALT: altdown |= 0x1; return;
|
||||
case KEY_RALT: altdown |= 0x2; return;
|
||||
default: return;
|
||||
}
|
||||
else if (ev->type == ev_keyup) switch (ev->data1)
|
||||
{
|
||||
case KEY_LSHIFT: shiftdown &= ~0x1; return;
|
||||
case KEY_RSHIFT: shiftdown &= ~0x2; return;
|
||||
case KEY_LCTRL: ctrldown &= ~0x1; return;
|
||||
case KEY_RCTRL: ctrldown &= ~0x2; return;
|
||||
case KEY_LALT: altdown &= ~0x1; return;
|
||||
case KEY_RALT: altdown &= ~0x2; return;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// D_ProcessEvents
|
||||
|
@ -220,9 +194,6 @@ void D_ProcessEvents(void)
|
|||
{
|
||||
ev = &events[eventtail];
|
||||
|
||||
// Set global shift/ctrl/alt down variables
|
||||
D_ModifierKeyResponder(ev); // never eats events
|
||||
|
||||
// Screenshots over everything so that they can be taken anywhere.
|
||||
if (M_ScreenshotResponder(ev))
|
||||
continue; // ate the event
|
||||
|
@ -726,7 +697,6 @@ void D_StartTitle(void)
|
|||
paused = false;
|
||||
advancedemo = false;
|
||||
F_StartTitleScreen();
|
||||
CON_ToggleOff();
|
||||
|
||||
// Reset the palette
|
||||
if (rendermode != render_none)
|
||||
|
@ -1362,13 +1332,9 @@ void D_SRB2Main(void)
|
|||
INT16 newgametype = -1;
|
||||
const char *sgametype = M_GetNextParm();
|
||||
|
||||
for (j = 0; gametype_cons_t[j].strvalue; j++)
|
||||
if (!strcasecmp(gametype_cons_t[j].strvalue, sgametype))
|
||||
{
|
||||
newgametype = (INT16)gametype_cons_t[j].value;
|
||||
break;
|
||||
}
|
||||
if (!gametype_cons_t[j].strvalue) // reached end of the list with no match
|
||||
newgametype = G_GetGametypeByName(sgametype);
|
||||
|
||||
if (newgametype == -1) // reached end of the list with no match
|
||||
{
|
||||
j = atoi(sgametype); // assume they gave us a gametype number, which is okay too
|
||||
if (j >= 0 && j < NUMGAMETYPES)
|
||||
|
@ -1400,13 +1366,13 @@ void D_SRB2Main(void)
|
|||
}
|
||||
else if (M_CheckParm("-skipintro"))
|
||||
{
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
F_StartTitleScreen();
|
||||
}
|
||||
else
|
||||
F_StartIntro(); // Tails 03-03-2002
|
||||
|
||||
CON_ToggleOff();
|
||||
|
||||
if (dedicated && server)
|
||||
{
|
||||
pagename = "TITLESKY";
|
||||
|
|
|
@ -409,6 +409,16 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
|||
*/
|
||||
void D_RegisterServerCommands(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < NUMGAMETYPES; i++)
|
||||
{
|
||||
gametype_cons_t[i].value = i;
|
||||
gametype_cons_t[i].strvalue = Gametype_Names[i];
|
||||
}
|
||||
gametype_cons_t[NUMGAMETYPES].value = 0;
|
||||
gametype_cons_t[NUMGAMETYPES].strvalue = NULL;
|
||||
|
||||
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
|
||||
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
|
||||
RegisterNetXCmd(XD_MAP, Got_Mapcmd);
|
||||
|
@ -1639,7 +1649,7 @@ static void Command_Map_f(void)
|
|||
{
|
||||
const char *mapname;
|
||||
size_t i;
|
||||
INT32 j, newmapnum;
|
||||
INT32 newmapnum;
|
||||
boolean newresetplayers;
|
||||
INT32 newgametype = gametype;
|
||||
|
||||
|
@ -1707,27 +1717,13 @@ static void Command_Map_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
for (j = 0; gametype_cons_t[j].strvalue; j++)
|
||||
if (!strcasecmp(gametype_cons_t[j].strvalue, COM_Argv(i+1)))
|
||||
{
|
||||
// Don't do any variable setting here. Wait until you get your
|
||||
// map packet first to avoid sending the same info twice!
|
||||
newgametype = gametype_cons_t[j].value;
|
||||
newgametype = G_GetGametypeByName(COM_Argv(i+1));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gametype_cons_t[j].strvalue) // reached end of the list with no match
|
||||
if (newgametype == -1) // reached end of the list with no match
|
||||
{
|
||||
// assume they gave us a gametype number, which is okay too
|
||||
for (j = 0; gametype_cons_t[j].strvalue != NULL; j++)
|
||||
{
|
||||
if (atoi(COM_Argv(i+1)) == gametype_cons_t[j].value)
|
||||
{
|
||||
newgametype = gametype_cons_t[j].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
INT32 j = atoi(COM_Argv(i+1)); // assume they gave us a gametype number, which is okay too
|
||||
if (j >= 0 && j < NUMGAMETYPES)
|
||||
newgametype = (INT16)j;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1742,12 +1738,11 @@ static void Command_Map_f(void)
|
|||
char gametypestring[32] = "Single Player";
|
||||
|
||||
if (multiplayer)
|
||||
for (i = 0; gametype_cons_t[i].strvalue != NULL; i++)
|
||||
if (gametype_cons_t[i].value == newgametype)
|
||||
{
|
||||
strcpy(gametypestring, gametype_cons_t[i].strvalue);
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (newgametype >= 0 && newgametype < NUMGAMETYPES
|
||||
&& Gametype_Names[newgametype])
|
||||
strcpy(gametypestring, Gametype_Names[newgametype]);
|
||||
}
|
||||
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname, gametypestring);
|
||||
return;
|
||||
|
@ -1831,9 +1826,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
CONS_Printf(M_GetText("Speeding off to level...\n"));
|
||||
}
|
||||
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
|
||||
if (demoplayback && !timingdemo)
|
||||
precache = false;
|
||||
|
||||
|
@ -3486,7 +3478,6 @@ static void Command_ModDetails_f(void)
|
|||
//
|
||||
static void Command_ShowGametype_f(void)
|
||||
{
|
||||
INT32 j;
|
||||
const char *gametypestr = NULL;
|
||||
|
||||
if (!(netgame || multiplayer)) // print "Single player" instead of "Co-op"
|
||||
|
@ -3494,15 +3485,11 @@ static void Command_ShowGametype_f(void)
|
|||
CONS_Printf(M_GetText("Current gametype is %s\n"), M_GetText("Single player"));
|
||||
return;
|
||||
}
|
||||
// find name string for current gametype
|
||||
for (j = 0; gametype_cons_t[j].strvalue; j++)
|
||||
{
|
||||
if (gametype_cons_t[j].value == gametype)
|
||||
{
|
||||
gametypestr = gametype_cons_t[j].strvalue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// get name string for current gametype
|
||||
if (gametype >= 0 && gametype < NUMGAMETYPES)
|
||||
gametypestr = Gametype_Names[gametype];
|
||||
|
||||
if (gametypestr)
|
||||
CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr);
|
||||
else // string for current gametype was not found above (should never happen)
|
||||
|
@ -3644,15 +3631,13 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
{
|
||||
if (netgame)
|
||||
{
|
||||
INT32 j;
|
||||
const char *oldgt = NULL, *newgt = NULL;
|
||||
for (j = 0; gametype_cons_t[j].strvalue; j++)
|
||||
{
|
||||
if (gametype_cons_t[j].value == lastgametype)
|
||||
oldgt = gametype_cons_t[j].strvalue;
|
||||
if (gametype_cons_t[j].value == gametype)
|
||||
newgt = gametype_cons_t[j].strvalue;
|
||||
}
|
||||
|
||||
if (lastgametype >= 0 && lastgametype < NUMGAMETYPES)
|
||||
oldgt = Gametype_Names[lastgametype];
|
||||
if (gametype >= 0 && lastgametype < NUMGAMETYPES)
|
||||
newgt = Gametype_Names[gametype];
|
||||
|
||||
if (oldgt && newgt)
|
||||
CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), oldgt, newgt);
|
||||
}
|
||||
|
|
|
@ -1196,6 +1196,13 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
#endif
|
||||
else if (fastcmp(word, "MUSICTRACK"))
|
||||
mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1);
|
||||
else if (fastcmp(word, "MUSICPOS"))
|
||||
mapheaderinfo[num-1]->muspos = (UINT32)get_number(word2);
|
||||
else if (fastcmp(word, "MUSICINTERFADEOUT"))
|
||||
mapheaderinfo[num-1]->musinterfadeout = (UINT32)get_number(word2);
|
||||
else if (fastcmp(word, "MUSICINTER"))
|
||||
deh_strlcpy(mapheaderinfo[num-1]->musintername, word2,
|
||||
sizeof(mapheaderinfo[num-1]->musintername), va("Level header %d: intermission music", num));
|
||||
else if (fastcmp(word, "FORCECHARACTER"))
|
||||
{
|
||||
strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1);
|
||||
|
@ -1499,6 +1506,11 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
|||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchflags), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK;
|
||||
}
|
||||
else if (fastcmp(word, "MUSICPOS"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchposition), UNDO_NONE);
|
||||
cutscenes[num]->scene[scenenum].musswitchposition = (UINT32)get_number(word2);
|
||||
}
|
||||
else if (fastcmp(word, "MUSICLOOP"))
|
||||
{
|
||||
DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musicloop), UNDO_NONE);
|
||||
|
@ -7003,6 +7015,7 @@ struct {
|
|||
|
||||
// doomdef.h constants
|
||||
{"TICRATE",TICRATE},
|
||||
{"MUSICRATE",MUSICRATE},
|
||||
{"RING_DIST",RING_DIST},
|
||||
{"PUSHACCEL",PUSHACCEL},
|
||||
{"MODID",MODID}, // I don't know, I just thought it would be cool for a wad to potentially know what mod it was loaded into.
|
||||
|
@ -8314,6 +8327,9 @@ static inline int lib_getenum(lua_State *L)
|
|||
} else if (fastcmp(word,"mapmusflags")) {
|
||||
lua_pushinteger(L, mapmusflags);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mapmusposition")) {
|
||||
lua_pushinteger(L, mapmusposition);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"server")) {
|
||||
if ((!multiplayer || !netgame) && !playeringame[serverplayer])
|
||||
return 0;
|
||||
|
|
|
@ -438,6 +438,37 @@ boolean I_SetSongSpeed(float speed)
|
|||
return false;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC SEEKING
|
||||
/// ------------------------
|
||||
|
||||
UINT32 I_GetSongLength(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||
{
|
||||
(void)looppoint;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 I_GetSongLoopPoint(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean I_SetSongPosition(UINT32 position)
|
||||
{
|
||||
(void)position;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 I_GetSongPosition(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC PLAYBACK
|
||||
/// ------------------------
|
||||
|
@ -545,3 +576,44 @@ int I_QrySongPlaying(int handle)
|
|||
return (midi_pos==-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC FADING
|
||||
/// ------------------------
|
||||
|
||||
void I_SetInternalMusicVolume(UINT8 volume)
|
||||
{
|
||||
(void)volume;
|
||||
}
|
||||
|
||||
void I_StopFadingSong(void)
|
||||
{
|
||||
}
|
||||
|
||||
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
|
||||
{
|
||||
(void)target_volume;
|
||||
(void)source_volume;
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
|
||||
{
|
||||
(void)target_volume;
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeOutStopSong(UINT32 ms)
|
||||
{
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||
{
|
||||
(void)ms;
|
||||
(void)looping;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -305,6 +305,8 @@ typedef enum
|
|||
#define NEWTICRATERATIO 1 // try 4 for 140 fps :)
|
||||
#define NEWTICRATE (TICRATE*NEWTICRATERATIO)
|
||||
|
||||
#define MUSICRATE 1000 // sound timing is calculated by milliseconds
|
||||
|
||||
#define RING_DIST 512*FRACUNIT // how close you need to be to a ring to attract it
|
||||
|
||||
#define PUSHACCEL (2*FRACUNIT) // Acceleration for MF2_SLIDEPUSH items.
|
||||
|
|
|
@ -33,8 +33,10 @@
|
|||
extern INT16 gamemap;
|
||||
extern char mapmusname[7];
|
||||
extern UINT16 mapmusflags;
|
||||
extern UINT32 mapmusposition;
|
||||
#define MUSIC_TRACKMASK 0x0FFF // ----************
|
||||
#define MUSIC_RELOADRESET 0x8000 // *---------------
|
||||
#define MUSIC_FORCERESET 0x4000 // -*--------------
|
||||
// Use other bits if necessary.
|
||||
|
||||
extern INT16 maptol;
|
||||
|
@ -145,6 +147,7 @@ typedef struct
|
|||
|
||||
char musswitch[7];
|
||||
UINT16 musswitchflags;
|
||||
UINT32 musswitchposition;
|
||||
|
||||
UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade
|
||||
UINT8 fadeinid; // ID of the first fade, to a color -- ignored if fadecolor is 0
|
||||
|
@ -215,6 +218,7 @@ typedef struct
|
|||
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
|
||||
char musname[7]; ///< Music track to play. "" for no music.
|
||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||
UINT32 muspos; ///< Music position to jump to.
|
||||
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable.
|
||||
UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave.
|
||||
INT16 skynum; ///< Sky number to use.
|
||||
|
@ -243,6 +247,10 @@ typedef struct
|
|||
UINT8 numGradedMares; ///< Internal. For grade support.
|
||||
nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful.
|
||||
|
||||
// Music stuff.
|
||||
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
|
||||
char musintername[7]; ///< Intermission screen music.
|
||||
|
||||
// Lua stuff.
|
||||
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
|
||||
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
|
||||
|
@ -310,7 +318,10 @@ enum GameType
|
|||
|
||||
NUMGAMETYPES
|
||||
};
|
||||
// If you alter this list, update gametype_cons_t in m_menu.c
|
||||
// If you alter this list, update dehacked.c, and Gametype_Names in g_game.c
|
||||
|
||||
// String names for gametypes
|
||||
extern const char *Gametype_Names[NUMGAMETYPES];
|
||||
|
||||
extern tic_t totalplaytime;
|
||||
|
||||
|
|
|
@ -95,6 +95,37 @@ boolean I_SetSongSpeed(float speed)
|
|||
return false;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC SEEKING
|
||||
/// ------------------------
|
||||
|
||||
UINT32 I_GetSongLength(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||
{
|
||||
(void)looppoint;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 I_GetSongLoopPoint(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean I_SetSongPosition(UINT32 position)
|
||||
{
|
||||
(void)position;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 I_GetSongPosition(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC PLAYBACK
|
||||
/// ------------------------
|
||||
|
@ -142,4 +173,45 @@ boolean I_SetSongTrack(int track)
|
|||
{
|
||||
(void)track;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC FADING
|
||||
/// ------------------------
|
||||
|
||||
void I_SetInternalMusicVolume(UINT8 volume)
|
||||
{
|
||||
(void)volume;
|
||||
}
|
||||
|
||||
void I_StopFadingSong(void)
|
||||
{
|
||||
}
|
||||
|
||||
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
|
||||
{
|
||||
(void)target_volume;
|
||||
(void)source_volume;
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
|
||||
{
|
||||
(void)target_volume;
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeOutStopSong(UINT32 ms)
|
||||
{
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||
{
|
||||
(void)ms;
|
||||
(void)looping;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -444,7 +444,6 @@ void F_StartIntro(void)
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
F_NewCutscene(introtext[0]);
|
||||
|
||||
intro_scenenum = 0;
|
||||
|
@ -1146,7 +1145,6 @@ void F_StartCredits(void)
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
S_StopMusic();
|
||||
|
||||
S_ChangeMusicInternal("credit", false);
|
||||
|
@ -1192,16 +1190,34 @@ void F_CreditDrawer(void)
|
|||
if (FixedMul(y,vid.dupy) > vid.height)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void F_CreditTicker(void)
|
||||
{
|
||||
// "Simulate" the drawing of the credits so that dedicated mode doesn't get stuck
|
||||
UINT16 i;
|
||||
fixed_t y = (80<<FRACBITS) - 5*(animtimer<<FRACBITS)/8;
|
||||
|
||||
// Draw credits text on top
|
||||
for (i = 0; credits[i]; i++)
|
||||
{
|
||||
switch(credits[i][0])
|
||||
{
|
||||
case 0: y += 80<<FRACBITS; break;
|
||||
case 1: y += 30<<FRACBITS; break;
|
||||
default: y += 12<<FRACBITS; break;
|
||||
}
|
||||
if (FixedMul(y,vid.dupy) > vid.height)
|
||||
break;
|
||||
}
|
||||
|
||||
// Do this here rather than in the drawer you doofus! (this is why dedicated mode broke at credits)
|
||||
if (!credits[i] && y <= 120<<FRACBITS && !finalecount)
|
||||
{
|
||||
timetonext = 5*TICRATE+1;
|
||||
finalecount = 5*TICRATE;
|
||||
}
|
||||
}
|
||||
|
||||
void F_CreditTicker(void)
|
||||
{
|
||||
if (timetonext)
|
||||
timetonext--;
|
||||
else
|
||||
|
@ -1295,7 +1311,6 @@ void F_StartGameEvaluation(void)
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
|
||||
finalecount = 0;
|
||||
}
|
||||
|
@ -1405,7 +1420,6 @@ void F_StartGameEnd(void)
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
S_StopMusic();
|
||||
|
||||
// In case menus are still up?!!
|
||||
|
@ -1608,7 +1622,6 @@ void F_StartContinue(void)
|
|||
keypressed = false;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
CON_ClearHUD();
|
||||
|
||||
// In case menus are still up?!!
|
||||
M_ClearMenus(true);
|
||||
|
@ -1728,9 +1741,10 @@ static void F_AdvanceToNextScene(void)
|
|||
picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum];
|
||||
|
||||
if (cutscenes[cutnum]->scene[scenenum].musswitch[0])
|
||||
S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musswitch,
|
||||
S_ChangeMusicEx(cutscenes[cutnum]->scene[scenenum].musswitch,
|
||||
cutscenes[cutnum]->scene[scenenum].musswitchflags,
|
||||
cutscenes[cutnum]->scene[scenenum].musicloop);
|
||||
cutscenes[cutnum]->scene[scenenum].musicloop,
|
||||
cutscenes[cutnum]->scene[scenenum].musswitchposition, 0, 0);
|
||||
|
||||
// Fade to the next
|
||||
dofadenow = true;
|
||||
|
@ -1779,8 +1793,6 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
|||
|
||||
F_NewCutscene(cutscenes[cutscenenum]->scene[0].text);
|
||||
|
||||
CON_ClearHUD();
|
||||
|
||||
cutsceneover = false;
|
||||
runningprecutscene = precutscene;
|
||||
precutresetplayer = resetplayer;
|
||||
|
@ -1801,9 +1813,10 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
|||
stoptimer = 0;
|
||||
|
||||
if (cutscenes[cutnum]->scene[0].musswitch[0])
|
||||
S_ChangeMusic(cutscenes[cutnum]->scene[0].musswitch,
|
||||
S_ChangeMusicEx(cutscenes[cutnum]->scene[0].musswitch,
|
||||
cutscenes[cutnum]->scene[0].musswitchflags,
|
||||
cutscenes[cutnum]->scene[0].musicloop);
|
||||
cutscenes[cutnum]->scene[0].musicloop,
|
||||
cutscenes[cutnum]->scene[scenenum].musswitchposition, 0, 0);
|
||||
else
|
||||
S_StopMusic();
|
||||
}
|
||||
|
|
42
src/g_game.c
42
src/g_game.c
|
@ -71,6 +71,7 @@ static void G_DoWorldDone(void);
|
|||
|
||||
char mapmusname[7]; // Music name
|
||||
UINT16 mapmusflags; // Track and reset bit
|
||||
UINT32 mapmusposition; // Position to jump to
|
||||
|
||||
INT16 gamemap = 1;
|
||||
INT16 maptol;
|
||||
|
@ -2268,9 +2269,14 @@ void G_PlayerReborn(INT32 player)
|
|||
{
|
||||
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
|
||||
mapmusname[6] = 0;
|
||||
mapmusflags = mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK;
|
||||
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
|
||||
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
|
||||
}
|
||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
||||
|
||||
// This is in S_Start, but this was not here previously.
|
||||
// if (cv_resetmusic.value)
|
||||
// S_StopMusic();
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||
}
|
||||
|
||||
if (gametype == GT_COOP)
|
||||
|
@ -2692,6 +2698,38 @@ void G_ExitLevel(void)
|
|||
}
|
||||
}
|
||||
|
||||
// See also the enum GameType in doomstat.h
|
||||
const char *Gametype_Names[NUMGAMETYPES] =
|
||||
{
|
||||
"Co-op", // GT_COOP
|
||||
"Competition", // GT_COMPETITION
|
||||
"Race", // GT_RACE
|
||||
|
||||
"Match", // GT_MATCH
|
||||
"Team Match", // GT_TEAMMATCH
|
||||
|
||||
"Tag", // GT_TAG
|
||||
"Hide and Seek", // GT_HIDEANDSEEK
|
||||
|
||||
"CTF" // GT_CTF
|
||||
};
|
||||
|
||||
//
|
||||
// G_GetGametypeByName
|
||||
//
|
||||
// Returns the number for the given gametype name string, or -1 if not valid.
|
||||
//
|
||||
INT32 G_GetGametypeByName(const char *gametypestr)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < NUMGAMETYPES; i++)
|
||||
if (!stricmp(gametypestr, Gametype_Names[i]))
|
||||
return i;
|
||||
|
||||
return -1; // unknown gametype
|
||||
}
|
||||
|
||||
//
|
||||
// G_IsSpecialStage
|
||||
//
|
||||
|
|
|
@ -163,6 +163,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void);
|
|||
void G_StopDemo(void);
|
||||
boolean G_CheckDemoStatus(void);
|
||||
|
||||
INT32 G_GetGametypeByName(const char *gametypestr);
|
||||
boolean G_IsSpecialStage(INT32 mapnum);
|
||||
boolean G_GametypeUsesLives(void);
|
||||
boolean G_GametypeHasTeams(void);
|
||||
|
|
|
@ -4246,10 +4246,43 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t
|
|||
}
|
||||
}
|
||||
|
||||
// This is expecting a pointer to an array containing 4 wallVerts for a sprite
|
||||
static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts)
|
||||
{
|
||||
if (cv_grspritebillboarding.value && spr && spr->mobj && wallVerts)
|
||||
{
|
||||
float basey = FIXED_TO_FLOAT(spr->mobj->z);
|
||||
float lowy = wallVerts[0].y;
|
||||
if (P_MobjFlip(spr->mobj) == -1)
|
||||
{
|
||||
basey = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height);
|
||||
}
|
||||
// Rotate sprites to fully billboard with the camera
|
||||
// X, Y, AND Z need to be manipulated for the polys to rotate around the
|
||||
// origin, because of how the origin setting works I believe that should
|
||||
// be mobj->z or mobj->z + mobj->height
|
||||
wallVerts[2].y = wallVerts[3].y = (spr->ty - basey) * gr_viewludsin + basey;
|
||||
wallVerts[0].y = wallVerts[1].y = (lowy - basey) * gr_viewludsin + basey;
|
||||
// translate back to be around 0 before translating back
|
||||
wallVerts[3].x += ((spr->ty - basey) * gr_viewludcos) * gr_viewcos;
|
||||
wallVerts[2].x += ((spr->ty - basey) * gr_viewludcos) * gr_viewcos;
|
||||
|
||||
wallVerts[0].x += ((lowy - basey) * gr_viewludcos) * gr_viewcos;
|
||||
wallVerts[1].x += ((lowy - basey) * gr_viewludcos) * gr_viewcos;
|
||||
|
||||
wallVerts[3].z += ((spr->ty - basey) * gr_viewludcos) * gr_viewsin;
|
||||
wallVerts[2].z += ((spr->ty - basey) * gr_viewludcos) * gr_viewsin;
|
||||
|
||||
wallVerts[0].z += ((lowy - basey) * gr_viewludcos) * gr_viewsin;
|
||||
wallVerts[1].z += ((lowy - basey) * gr_viewludcos) * gr_viewsin;
|
||||
}
|
||||
}
|
||||
|
||||
static void HWR_SplitSprite(gr_vissprite_t *spr)
|
||||
{
|
||||
float this_scale = 1.0f;
|
||||
FOutVector wallVerts[4];
|
||||
FOutVector baseWallVerts[4]; // This is what the verts should end up as
|
||||
GLPatch_t *gpatch;
|
||||
FSurfaceInfo Surf;
|
||||
const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES);
|
||||
|
@ -4262,11 +4295,13 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
float realtop, realbot, top, bot;
|
||||
float towtop, towbot, towmult;
|
||||
float bheight;
|
||||
float realheight, heightmult;
|
||||
const sector_t *sector = spr->mobj->subsector->sector;
|
||||
const lightlist_t *list = sector->lightlist;
|
||||
#ifdef ESLOPE
|
||||
float endrealtop, endrealbot, endtop, endbot;
|
||||
float endbheight;
|
||||
float endrealheight;
|
||||
fixed_t temp;
|
||||
fixed_t v1x, v1y, v2x, v2y;
|
||||
#endif
|
||||
|
@ -4299,16 +4334,16 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
HWR_DrawSpriteShadow(spr, gpatch, this_scale);
|
||||
}
|
||||
|
||||
wallVerts[0].x = wallVerts[3].x = spr->x1;
|
||||
wallVerts[2].x = wallVerts[1].x = spr->x2;
|
||||
wallVerts[0].z = wallVerts[3].z = spr->z1;
|
||||
wallVerts[1].z = wallVerts[2].z = spr->z2;
|
||||
baseWallVerts[0].x = baseWallVerts[3].x = spr->x1;
|
||||
baseWallVerts[2].x = baseWallVerts[1].x = spr->x2;
|
||||
baseWallVerts[0].z = baseWallVerts[3].z = spr->z1;
|
||||
baseWallVerts[1].z = baseWallVerts[2].z = spr->z2;
|
||||
|
||||
wallVerts[2].y = wallVerts[3].y = spr->ty;
|
||||
baseWallVerts[2].y = baseWallVerts[3].y = spr->ty;
|
||||
if (spr->mobj && fabsf(this_scale - 1.0f) > 1.0E-36f)
|
||||
wallVerts[0].y = wallVerts[1].y = spr->ty - gpatch->height * this_scale;
|
||||
baseWallVerts[0].y = baseWallVerts[1].y = spr->ty - gpatch->height * this_scale;
|
||||
else
|
||||
wallVerts[0].y = wallVerts[1].y = spr->ty - gpatch->height;
|
||||
baseWallVerts[0].y = baseWallVerts[1].y = spr->ty - gpatch->height;
|
||||
|
||||
v1x = FLOAT_TO_FIXED(spr->x1);
|
||||
v1y = FLOAT_TO_FIXED(spr->z1);
|
||||
|
@ -4317,44 +4352,56 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
|
||||
if (spr->flip)
|
||||
{
|
||||
wallVerts[0].sow = wallVerts[3].sow = gpatch->max_s;
|
||||
wallVerts[2].sow = wallVerts[1].sow = 0;
|
||||
}else{
|
||||
wallVerts[0].sow = wallVerts[3].sow = 0;
|
||||
wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s;
|
||||
baseWallVerts[0].sow = baseWallVerts[3].sow = gpatch->max_s;
|
||||
baseWallVerts[2].sow = baseWallVerts[1].sow = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseWallVerts[0].sow = baseWallVerts[3].sow = 0;
|
||||
baseWallVerts[2].sow = baseWallVerts[1].sow = gpatch->max_s;
|
||||
}
|
||||
|
||||
// flip the texture coords (look familiar?)
|
||||
if (spr->vflip)
|
||||
{
|
||||
wallVerts[3].tow = wallVerts[2].tow = gpatch->max_t;
|
||||
wallVerts[0].tow = wallVerts[1].tow = 0;
|
||||
}else{
|
||||
wallVerts[3].tow = wallVerts[2].tow = 0;
|
||||
wallVerts[0].tow = wallVerts[1].tow = gpatch->max_t;
|
||||
baseWallVerts[3].tow = baseWallVerts[2].tow = gpatch->max_t;
|
||||
baseWallVerts[0].tow = baseWallVerts[1].tow = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseWallVerts[3].tow = baseWallVerts[2].tow = 0;
|
||||
baseWallVerts[0].tow = baseWallVerts[1].tow = gpatch->max_t;
|
||||
}
|
||||
|
||||
// if it has a dispoffset, push it a little towards the camera
|
||||
if (spr->dispoffset) {
|
||||
float co = -gr_viewcos*(0.05f*spr->dispoffset);
|
||||
float si = -gr_viewsin*(0.05f*spr->dispoffset);
|
||||
wallVerts[0].z = wallVerts[3].z = wallVerts[0].z+si;
|
||||
wallVerts[1].z = wallVerts[2].z = wallVerts[1].z+si;
|
||||
wallVerts[0].x = wallVerts[3].x = wallVerts[0].x+co;
|
||||
wallVerts[1].x = wallVerts[2].x = wallVerts[1].x+co;
|
||||
baseWallVerts[0].z = baseWallVerts[3].z = baseWallVerts[0].z+si;
|
||||
baseWallVerts[1].z = baseWallVerts[2].z = baseWallVerts[1].z+si;
|
||||
baseWallVerts[0].x = baseWallVerts[3].x = baseWallVerts[0].x+co;
|
||||
baseWallVerts[1].x = baseWallVerts[2].x = baseWallVerts[1].x+co;
|
||||
}
|
||||
|
||||
realtop = top = wallVerts[3].y;
|
||||
realbot = bot = wallVerts[0].y;
|
||||
towtop = wallVerts[3].tow;
|
||||
towbot = wallVerts[0].tow;
|
||||
// Let dispoffset work first since this adjust each vertex
|
||||
HWR_RotateSpritePolyToAim(spr, baseWallVerts);
|
||||
|
||||
realtop = top = baseWallVerts[3].y;
|
||||
realbot = bot = baseWallVerts[0].y;
|
||||
towtop = baseWallVerts[3].tow;
|
||||
towbot = baseWallVerts[0].tow;
|
||||
towmult = (towbot - towtop) / (top - bot);
|
||||
|
||||
#ifdef ESLOPE
|
||||
endrealtop = endtop = wallVerts[2].y;
|
||||
endrealbot = endbot = wallVerts[1].y;
|
||||
endrealtop = endtop = baseWallVerts[2].y;
|
||||
endrealbot = endbot = baseWallVerts[1].y;
|
||||
#endif
|
||||
|
||||
// copy the contents of baseWallVerts into the drawn wallVerts array
|
||||
// baseWallVerts is used to know the final shape to easily get the vertex
|
||||
// co-ordinates
|
||||
memcpy(wallVerts, baseWallVerts, sizeof(baseWallVerts));
|
||||
|
||||
if (!cv_translucency.value) // translucency disabled
|
||||
{
|
||||
Surf.FlatColor.s.alpha = 0xFF;
|
||||
|
@ -4481,12 +4528,53 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
wallVerts[2].y = endtop;
|
||||
wallVerts[0].y = bot;
|
||||
wallVerts[1].y = endbot;
|
||||
|
||||
// The x and y only need to be adjusted in the case that it's not a papersprite
|
||||
if (cv_grspritebillboarding.value && spr->mobj)
|
||||
{
|
||||
// Get the x and z of the vertices so billboarding draws correctly
|
||||
realheight = realbot - realtop;
|
||||
endrealheight = endrealbot - endrealtop;
|
||||
heightmult = (realtop - top) / realheight;
|
||||
wallVerts[3].x = baseWallVerts[3].x + (baseWallVerts[3].x - baseWallVerts[0].x) * heightmult;
|
||||
wallVerts[3].z = baseWallVerts[3].z + (baseWallVerts[3].z - baseWallVerts[0].z) * heightmult;
|
||||
|
||||
heightmult = (endrealtop - endtop) / endrealheight;
|
||||
wallVerts[2].x = baseWallVerts[2].x + (baseWallVerts[2].x - baseWallVerts[1].x) * heightmult;
|
||||
wallVerts[2].z = baseWallVerts[2].z + (baseWallVerts[2].z - baseWallVerts[1].z) * heightmult;
|
||||
|
||||
heightmult = (realtop - bot) / realheight;
|
||||
wallVerts[0].x = baseWallVerts[3].x + (baseWallVerts[3].x - baseWallVerts[0].x) * heightmult;
|
||||
wallVerts[0].z = baseWallVerts[3].z + (baseWallVerts[3].z - baseWallVerts[0].z) * heightmult;
|
||||
|
||||
heightmult = (endrealtop - endbot) / endrealheight;
|
||||
wallVerts[1].x = baseWallVerts[2].x + (baseWallVerts[2].x - baseWallVerts[1].x) * heightmult;
|
||||
wallVerts[1].z = baseWallVerts[2].z + (baseWallVerts[2].z - baseWallVerts[1].z) * heightmult;
|
||||
}
|
||||
#else
|
||||
wallVerts[3].tow = wallVerts[2].tow = towtop + ((realtop - top) * towmult);
|
||||
wallVerts[0].tow = wallVerts[1].tow = towtop + ((realtop - bot) * towmult);
|
||||
|
||||
wallVerts[2].y = wallVerts[3].y = top;
|
||||
wallVerts[0].y = wallVerts[1].y = bot;
|
||||
|
||||
// The x and y only need to be adjusted in the case that it's not a papersprite
|
||||
if (cv_grspritebillboarding.value && spr->mobj)
|
||||
{
|
||||
// Get the x and z of the vertices so billboarding draws correctly
|
||||
realheight = realbot - realtop;
|
||||
heightmult = (realtop - top) / realheight;
|
||||
wallVerts[3].x = baseWallVerts[3].x + (baseWallVerts[3].x - baseWallVerts[0].x) * heightmult;
|
||||
wallVerts[3].z = baseWallVerts[3].z + (baseWallVerts[3].z - baseWallVerts[0].z) * heightmult;
|
||||
wallVerts[2].x = baseWallVerts[2].x + (baseWallVerts[2].x - baseWallVerts[1].x) * heightmult;
|
||||
wallVerts[2].z = baseWallVerts[2].z + (baseWallVerts[2].z - baseWallVerts[1].z) * heightmult;
|
||||
|
||||
heightmult = (realtop - bot) / realheight;
|
||||
wallVerts[0].x = baseWallVerts[3].x + (baseWallVerts[3].x - baseWallVerts[0].x) * heightmult;
|
||||
wallVerts[0].z = baseWallVerts[3].z + (baseWallVerts[3].z - baseWallVerts[0].z) * heightmult;
|
||||
wallVerts[1].x = baseWallVerts[2].x + (baseWallVerts[2].x - baseWallVerts[1].x) * heightmult;
|
||||
wallVerts[1].z = baseWallVerts[2].z + (baseWallVerts[2].z - baseWallVerts[1].z) * heightmult;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (colormap)
|
||||
|
@ -4655,6 +4743,9 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
wallVerts[1].x = wallVerts[2].x = wallVerts[1].x+co;
|
||||
}
|
||||
|
||||
// Let dispoffset work first since this adjust each vertex
|
||||
HWR_RotateSpritePolyToAim(spr, wallVerts);
|
||||
|
||||
// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
|
||||
// sprite lighting by modulating the RGB components
|
||||
/// \todo coloured
|
||||
|
@ -4736,6 +4827,9 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
|
|||
wallVerts[0].z = wallVerts[3].z = spr->z1;
|
||||
wallVerts[1].z = wallVerts[2].z = spr->z2;
|
||||
|
||||
// Let dispoffset work first since this adjust each vertex
|
||||
HWR_RotateSpritePolyToAim(spr, wallVerts);
|
||||
|
||||
wallVerts[0].sow = wallVerts[3].sow = 0;
|
||||
wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s;
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ extern consvar_t cv_grcorrecttricks;
|
|||
extern consvar_t cv_voodoocompatibility;
|
||||
extern consvar_t cv_grfovchange;
|
||||
extern consvar_t cv_grsolvetjoin;
|
||||
extern consvar_t cv_grspritebillboarding;
|
||||
|
||||
extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy;
|
||||
|
||||
|
|
|
@ -1072,7 +1072,9 @@ static INT16 typelines = 1; // number of drawfill lines we need when drawing the
|
|||
//
|
||||
boolean HU_Responder(event_t *ev)
|
||||
{
|
||||
#ifndef NONET
|
||||
INT32 c=0;
|
||||
#endif
|
||||
|
||||
if (ev->type != ev_keydown)
|
||||
return false;
|
||||
|
@ -1099,19 +1101,9 @@ boolean HU_Responder(event_t *ev)
|
|||
return false;
|
||||
}*/ //We don't actually care about that unless we get splitscreen netgames. :V
|
||||
|
||||
#ifndef NONET
|
||||
c = (INT32)ev->data1;
|
||||
|
||||
// capslock (now handled outside of chat on so that it works everytime......)
|
||||
if (c && c == KEY_CAPSLOCK) // it's a toggle.
|
||||
{
|
||||
if (capslock)
|
||||
capslock = false;
|
||||
else
|
||||
capslock = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef NONET
|
||||
if (!chat_on)
|
||||
{
|
||||
// enter chat mode
|
||||
|
@ -1952,19 +1944,17 @@ static void HU_DrawCEcho(void)
|
|||
|
||||
static void HU_drawGametype(void)
|
||||
{
|
||||
INT32 i = 0;
|
||||
const char *strvalue = NULL;
|
||||
|
||||
for (i = 0; gametype_cons_t[i].strvalue; i++)
|
||||
{
|
||||
if (gametype_cons_t[i].value == gametype)
|
||||
{
|
||||
if (splitscreen)
|
||||
V_DrawString(4, 184, 0, gametype_cons_t[i].strvalue);
|
||||
else
|
||||
V_DrawString(4, 192, 0, gametype_cons_t[i].strvalue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (gametype < 0 || gametype >= NUMGAMETYPES)
|
||||
return; // not a valid gametype???
|
||||
|
||||
strvalue = Gametype_Names[gametype];
|
||||
|
||||
if (splitscreen)
|
||||
V_DrawString(4, 184, 0, strvalue);
|
||||
else
|
||||
V_DrawString(4, 192, 0, strvalue);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -146,6 +146,18 @@ boolean I_SongPaused(void);
|
|||
|
||||
boolean I_SetSongSpeed(float speed);
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC SEEKING
|
||||
/// ------------------------
|
||||
|
||||
UINT32 I_GetSongLength(void);
|
||||
|
||||
boolean I_SetSongLoopPoint(UINT32 looppoint);
|
||||
UINT32 I_GetSongLoopPoint(void);
|
||||
|
||||
boolean I_SetSongPosition(UINT32 position);
|
||||
UINT32 I_GetSongPosition(void);
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC PLAYBACK
|
||||
/// ------------------------
|
||||
|
@ -216,6 +228,17 @@ void I_SetMusicVolume(UINT8 volume);
|
|||
|
||||
boolean I_SetSongTrack(INT32 track);
|
||||
|
||||
/// ------------------------
|
||||
/// MUSIC FADING
|
||||
/// ------------------------
|
||||
|
||||
void I_SetInternalMusicVolume(UINT8 volume);
|
||||
void I_StopFadingSong(void);
|
||||
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
|
||||
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
|
||||
boolean I_FadeOutStopSong(UINT32 ms);
|
||||
boolean I_FadeInPlaySong(UINT32 ms, boolean looping);
|
||||
|
||||
/// ------------------------
|
||||
// CD MUSIC I/O
|
||||
/// ------------------------
|
||||
|
|
10
src/i_tcp.c
10
src/i_tcp.c
|
@ -612,7 +612,7 @@ static boolean SOCK_Get(void)
|
|||
if (c != ERRSOCKET)
|
||||
{
|
||||
// find remote node number
|
||||
for (j = 0; j <= MAXNETNODES; j++) //include LAN
|
||||
for (j = 1; j <= MAXNETNODES; j++) //include LAN
|
||||
{
|
||||
if (SOCK_cmpaddr(&fromaddress, &clientaddress[j], 0))
|
||||
{
|
||||
|
@ -1340,8 +1340,12 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
|||
while (runp != NULL)
|
||||
{
|
||||
// find ip of the server
|
||||
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
||||
runp = NULL;
|
||||
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
|
||||
{
|
||||
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
||||
break;
|
||||
}
|
||||
runp = runp->ai_next;
|
||||
}
|
||||
I_freeaddrinfo(ai);
|
||||
return newnode;
|
||||
|
|
|
@ -780,7 +780,8 @@ static int lib_pRestoreMusic(lua_State *L)
|
|||
NOHUD
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
P_RestoreMusic(player);
|
||||
if (P_IsLocalPlayer(player))
|
||||
P_RestoreMusic(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1820,7 +1821,7 @@ static int lib_sChangeMusic(lua_State *L)
|
|||
{
|
||||
#ifdef MUSICSLOT_COMPATIBILITY
|
||||
const char *music_name;
|
||||
UINT32 music_num;
|
||||
UINT32 music_num, position, prefadems, fadeinms;
|
||||
char music_compat_name[7];
|
||||
|
||||
boolean looping;
|
||||
|
@ -1848,7 +1849,6 @@ static int lib_sChangeMusic(lua_State *L)
|
|||
music_name = luaL_checkstring(L, 1);
|
||||
}
|
||||
|
||||
|
||||
looping = (boolean)lua_opttrueboolean(L, 2);
|
||||
|
||||
#else
|
||||
|
@ -1873,8 +1873,12 @@ static int lib_sChangeMusic(lua_State *L)
|
|||
#endif
|
||||
music_flags = (UINT16)luaL_optinteger(L, 4, 0);
|
||||
|
||||
position = (UINT32)luaL_optinteger(L, 5, 0);
|
||||
prefadems = (UINT32)luaL_optinteger(L, 6, 0);
|
||||
fadeinms = (UINT32)luaL_optinteger(L, 7, 0);
|
||||
|
||||
if (!player || P_IsLocalPlayer(player))
|
||||
S_ChangeMusic(music_name, music_flags, looping);
|
||||
S_ChangeMusicEx(music_name, music_flags, looping, position, prefadems, fadeinms);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1891,10 +1895,8 @@ static int lib_sSpeedMusic(lua_State *L)
|
|||
return LUA_ErrInvalid(L, "player_t");
|
||||
}
|
||||
if (!player || P_IsLocalPlayer(player))
|
||||
lua_pushboolean(L, S_SpeedMusic(speed));
|
||||
else
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
S_SpeedMusic(speed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_sStopMusic(lua_State *L)
|
||||
|
@ -1912,6 +1914,110 @@ static int lib_sStopMusic(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_sSetInternalMusicVolume(lua_State *L)
|
||||
{
|
||||
UINT32 volume = (UINT32)luaL_checkinteger(L, 1);
|
||||
player_t *player = NULL;
|
||||
NOHUD
|
||||
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
|
||||
{
|
||||
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
}
|
||||
if (!player || P_IsLocalPlayer(player))
|
||||
{
|
||||
S_SetInternalMusicVolume(volume);
|
||||
lua_pushboolean(L, true);
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_sStopFadingMusic(lua_State *L)
|
||||
{
|
||||
player_t *player = NULL;
|
||||
NOHUD
|
||||
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
|
||||
{
|
||||
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
}
|
||||
if (!player || P_IsLocalPlayer(player))
|
||||
{
|
||||
S_StopFadingMusic();
|
||||
lua_pushboolean(L, true);
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_sFadeMusic(lua_State *L)
|
||||
{
|
||||
UINT32 target_volume = (UINT32)luaL_checkinteger(L, 1);
|
||||
UINT32 ms;
|
||||
INT32 source_volume;
|
||||
player_t *player = NULL;
|
||||
NOHUD
|
||||
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
|
||||
{
|
||||
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
ms = (UINT32)luaL_checkinteger(L, 2);
|
||||
source_volume = -1;
|
||||
}
|
||||
else if (!lua_isnone(L, 4) && lua_isuserdata(L, 4))
|
||||
{
|
||||
player = *((player_t **)luaL_checkudata(L, 4, META_PLAYER));
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
source_volume = (INT32)luaL_checkinteger(L, 2);
|
||||
ms = (UINT32)luaL_checkinteger(L, 3);
|
||||
}
|
||||
else if (luaL_optinteger(L, 3, INT32_MAX) == INT32_MAX)
|
||||
{
|
||||
ms = (UINT32)luaL_checkinteger(L, 2);
|
||||
source_volume = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
source_volume = (INT32)luaL_checkinteger(L, 2);
|
||||
ms = (UINT32)luaL_checkinteger(L, 3);
|
||||
}
|
||||
|
||||
NOHUD
|
||||
|
||||
if (!player || P_IsLocalPlayer(player))
|
||||
lua_pushboolean(L, S_FadeMusicFromVolume(target_volume, source_volume, ms));
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_sFadeOutStopMusic(lua_State *L)
|
||||
{
|
||||
UINT32 ms = (UINT32)luaL_checkinteger(L, 1);
|
||||
player_t *player = NULL;
|
||||
NOHUD
|
||||
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
|
||||
{
|
||||
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
}
|
||||
if (!player || P_IsLocalPlayer(player))
|
||||
{
|
||||
lua_pushboolean(L, S_FadeOutStopMusic(ms));
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_sOriginPlaying(lua_State *L)
|
||||
{
|
||||
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
@ -2264,6 +2370,10 @@ static luaL_Reg lib[] = {
|
|||
{"S_ChangeMusic",lib_sChangeMusic},
|
||||
{"S_SpeedMusic",lib_sSpeedMusic},
|
||||
{"S_StopMusic",lib_sStopMusic},
|
||||
{"S_SetInternalMusicVolume", lib_sSetInternalMusicVolume},
|
||||
{"S_StopFadingMusic",lib_sStopFadingMusic},
|
||||
{"S_FadeMusic",lib_sFadeMusic},
|
||||
{"S_FadeOutStopMusic",lib_sFadeOutStopMusic},
|
||||
{"S_OriginPlaying",lib_sOriginPlaying},
|
||||
{"S_IdPlaying",lib_sIdPlaying},
|
||||
{"S_SoundPlaying",lib_sSoundPlaying},
|
||||
|
|
|
@ -1468,6 +1468,12 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushstring(L, header->musname);
|
||||
else if (fastcmp(field,"mustrack"))
|
||||
lua_pushinteger(L, header->mustrack);
|
||||
else if (fastcmp(field,"muspos"))
|
||||
lua_pushinteger(L, header->muspos);
|
||||
else if (fastcmp(field,"musinterfadeout"))
|
||||
lua_pushinteger(L, header->musinterfadeout);
|
||||
else if (fastcmp(field,"musintername"))
|
||||
lua_pushstring(L, header->musintername);
|
||||
else if (fastcmp(field,"forcecharacter"))
|
||||
lua_pushstring(L, header->forcecharacter);
|
||||
else if (fastcmp(field,"weather"))
|
||||
|
|
27
src/m_menu.c
27
src/m_menu.c
|
@ -347,23 +347,9 @@ static CV_PossibleValue_t skins_cons_t[MAXSKINS+1] = {{1, DEFAULTSKIN}};
|
|||
consvar_t cv_chooseskin = {"chooseskin", DEFAULTSKIN, CV_HIDEN|CV_CALL, skins_cons_t, Nextmap_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// This gametype list is integral for many different reasons.
|
||||
// When you add gametypes here, don't forget to update them in CV_AddValue!
|
||||
CV_PossibleValue_t gametype_cons_t[] =
|
||||
{
|
||||
{GT_COOP, "Co-op"},
|
||||
// When you add gametypes here, don't forget to update them in dehacked.c and doomstat.h!
|
||||
CV_PossibleValue_t gametype_cons_t[NUMGAMETYPES+1];
|
||||
|
||||
{GT_COMPETITION, "Competition"},
|
||||
{GT_RACE, "Race"},
|
||||
|
||||
{GT_MATCH, "Match"},
|
||||
{GT_TEAMMATCH, "Team Match"},
|
||||
|
||||
{GT_TAG, "Tag"},
|
||||
{GT_HIDEANDSEEK, "Hide and Seek"},
|
||||
|
||||
{GT_CTF, "CTF"},
|
||||
{0, NULL}
|
||||
};
|
||||
consvar_t cv_newgametype = {"newgametype", "Co-op", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t serversort_cons_t[] = {
|
||||
|
@ -6545,7 +6531,7 @@ static void M_DrawRoomMenu(void)
|
|||
|
||||
static void M_DrawConnectMenu(void)
|
||||
{
|
||||
UINT16 i, j;
|
||||
UINT16 i;
|
||||
const char *gt = "Unknown";
|
||||
INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE;
|
||||
|
||||
|
@ -6591,11 +6577,8 @@ static void M_DrawConnectMenu(void)
|
|||
va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time)));
|
||||
|
||||
gt = "Unknown";
|
||||
for (j = 0; gametype_cons_t[j].strvalue; j++)
|
||||
{
|
||||
if (gametype_cons_t[j].value == serverlist[slindex].info.gametype)
|
||||
gt = gametype_cons_t[j].strvalue;
|
||||
}
|
||||
if (serverlist[slindex].info.gametype < NUMGAMETYPES)
|
||||
gt = Gametype_Names[serverlist[slindex].info.gametype];
|
||||
|
||||
V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags,
|
||||
va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer));
|
||||
|
|
|
@ -2643,7 +2643,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
static void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||
{
|
||||
fixed_t fallbackspeed;
|
||||
angle_t ang;
|
||||
|
|
|
@ -647,8 +647,6 @@ static void P_NetArchiveWorld(void)
|
|||
|
||||
WRITEUINT16(put, 0xffff);
|
||||
|
||||
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
|
||||
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
|
||||
// do lines
|
||||
for (i = 0; i < numlines; i++, mld++, li++)
|
||||
{
|
||||
|
|
|
@ -187,6 +187,12 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
mapheaderinfo[num]->musname[6] = 0;
|
||||
DEH_WriteUndoline("MUSICTRACK", va("%d", mapheaderinfo[num]->mustrack), UNDO_NONE);
|
||||
mapheaderinfo[num]->mustrack = 0;
|
||||
DEH_WriteUndoline("MUSICPOS", va("%d", mapheaderinfo[num]->muspos), UNDO_NONE);
|
||||
mapheaderinfo[num]->muspos = 0;
|
||||
DEH_WriteUndoline("MUSICINTERFADEOUT", va("%d", mapheaderinfo[num]->musinterfadeout), UNDO_NONE);
|
||||
mapheaderinfo[num]->musinterfadeout = 0;
|
||||
DEH_WriteUndoline("MUSICINTER", mapheaderinfo[num]->musintername, UNDO_NONE);
|
||||
mapheaderinfo[num]->musintername[0] = '\0';
|
||||
DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE);
|
||||
mapheaderinfo[num]->forcecharacter[0] = '\0';
|
||||
DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE);
|
||||
|
@ -1527,19 +1533,33 @@ static void P_LoadRawSideDefs2(void *data)
|
|||
{
|
||||
M_Memcpy(process,msd->bottomtexture,8);
|
||||
process[8] = '\0';
|
||||
sd->bottomtexture = get_number(process)-1;
|
||||
sd->bottomtexture = get_number(process);
|
||||
}
|
||||
M_Memcpy(process,msd->toptexture,8);
|
||||
process[8] = '\0';
|
||||
sd->text = Z_Malloc(7, PU_LEVEL, NULL);
|
||||
|
||||
// If they type in O_ or D_ and their music name, just shrug,
|
||||
// then copy the rest instead.
|
||||
if ((process[0] == 'O' || process[0] == 'D') && process[7])
|
||||
M_Memcpy(sd->text, process+2, 6);
|
||||
else // Assume it's a proper music name.
|
||||
M_Memcpy(sd->text, process, 6);
|
||||
sd->text[6] = 0;
|
||||
if (!(msd->midtexture[0] == '-' && msd->midtexture[1] == '\0') || msd->midtexture[1] != '\0')
|
||||
{
|
||||
M_Memcpy(process,msd->midtexture,8);
|
||||
process[8] = '\0';
|
||||
sd->midtexture = get_number(process);
|
||||
}
|
||||
|
||||
// always process if back sidedef, because we need that - symbol
|
||||
sd->text = Z_Malloc(7, PU_LEVEL, NULL);
|
||||
if (i == 1 || msd->toptexture[0] != '-' || msd->toptexture[1] != '\0')
|
||||
{
|
||||
M_Memcpy(process,msd->toptexture,8);
|
||||
process[8] = '\0';
|
||||
|
||||
// If they type in O_ or D_ and their music name, just shrug,
|
||||
// then copy the rest instead.
|
||||
if ((process[0] == 'O' || process[0] == 'D') && process[7])
|
||||
M_Memcpy(sd->text, process+2, 6);
|
||||
else // Assume it's a proper music name.
|
||||
M_Memcpy(sd->text, process, 6);
|
||||
sd->text[6] = 0;
|
||||
}
|
||||
else
|
||||
sd->text[0] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
66
src/p_spec.c
66
src/p_spec.c
|
@ -2408,16 +2408,68 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
// console player only unless NOCLIMB is set
|
||||
if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)))
|
||||
{
|
||||
UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture;
|
||||
boolean musicsame = (!sides[line->sidenum[0]].text[0] || !strnicmp(sides[line->sidenum[0]].text, S_MusicName(), 7));
|
||||
UINT16 tracknum = (UINT16)max(sides[line->sidenum[0]].bottomtexture, 0);
|
||||
INT32 position = (INT32)max(sides[line->sidenum[0]].midtexture, 0);
|
||||
UINT32 prefadems = (UINT32)max(sides[line->sidenum[0]].textureoffset >> FRACBITS, 0);
|
||||
UINT32 postfadems = (UINT32)max(sides[line->sidenum[0]].rowoffset >> FRACBITS, 0);
|
||||
UINT8 fadetarget = (UINT8)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].textureoffset >> FRACBITS : 0, 0);
|
||||
INT16 fadesource = (INT16)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].rowoffset >> FRACBITS : -1, -1);
|
||||
|
||||
strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
|
||||
mapmusname[6] = 0;
|
||||
// Seek offset from current song position
|
||||
if (line->flags & ML_EFFECT1)
|
||||
{
|
||||
// adjust for loop point if subtracting
|
||||
if (position < 0 && S_GetMusicLength() &&
|
||||
S_GetMusicPosition() > S_GetMusicLoopPoint() &&
|
||||
S_GetMusicPosition() + position < S_GetMusicLoopPoint())
|
||||
position = max(S_GetMusicLength() - (S_GetMusicLoopPoint() - (S_GetMusicPosition() + position)), 0);
|
||||
else
|
||||
position = max(S_GetMusicPosition() + position, 0);
|
||||
}
|
||||
|
||||
mapmusflags = tracknum & MUSIC_TRACKMASK;
|
||||
if (!(line->flags & ML_BLOCKMONSTERS))
|
||||
mapmusflags |= MUSIC_RELOADRESET;
|
||||
// Fade current music to target volume (if music won't be changed)
|
||||
if ((line->flags & ML_EFFECT2) && fadetarget && musicsame)
|
||||
{
|
||||
// 0 fadesource means fade from current volume.
|
||||
// meaning that we can't specify volume 0 as the source volume -- this starts at 1.
|
||||
if (!fadesource)
|
||||
fadesource = -1;
|
||||
|
||||
S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4));
|
||||
if (!postfadems)
|
||||
S_SetInternalMusicVolume(fadetarget);
|
||||
else
|
||||
S_FadeMusicFromVolume(fadetarget, fadesource, postfadems);
|
||||
|
||||
if (position)
|
||||
S_SetMusicPosition(position);
|
||||
}
|
||||
// Change the music and apply position/fade operations
|
||||
else
|
||||
{
|
||||
strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
|
||||
mapmusname[6] = 0;
|
||||
|
||||
mapmusflags = tracknum & MUSIC_TRACKMASK;
|
||||
if (!(line->flags & ML_BLOCKMONSTERS))
|
||||
mapmusflags |= MUSIC_RELOADRESET;
|
||||
if (line->flags & ML_BOUNCY)
|
||||
mapmusflags |= MUSIC_FORCERESET;
|
||||
|
||||
mapmusposition = position;
|
||||
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4), position,
|
||||
!(line->flags & ML_EFFECT2) ? prefadems : 0,
|
||||
!(line->flags & ML_EFFECT2) ? postfadems : 0);
|
||||
|
||||
if ((line->flags & ML_EFFECT2) && fadetarget)
|
||||
{
|
||||
if (!postfadems)
|
||||
S_SetInternalMusicVolume(fadetarget);
|
||||
else
|
||||
S_FadeMusicFromVolume(fadetarget, fadesource, postfadems);
|
||||
}
|
||||
}
|
||||
|
||||
// Except, you can use the ML_BLOCKMONSTERS flag to change this behavior.
|
||||
// if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.
|
||||
|
|
|
@ -1124,13 +1124,13 @@ void P_RestoreMusic(player_t *player)
|
|||
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
|
||||
{
|
||||
S_SpeedMusic(1.4f);
|
||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||
}
|
||||
else
|
||||
S_ChangeMusicInternal("shoes", true);
|
||||
}
|
||||
else
|
||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -1407,6 +1407,7 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_grcoronasize);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_grmd2);
|
||||
CV_RegisterVar(&cv_grspritebillboarding);
|
||||
#endif
|
||||
|
||||
#ifdef HWRENDER
|
||||
|
|
41
src/r_segs.c
41
src/r_segs.c
|
@ -854,24 +854,26 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights)
|
||||
{
|
||||
lightlist_t *nextlight = &frontsector->lightlist[i+1];
|
||||
if (nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height > pfloorleft
|
||||
&& nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height > pfloorright)
|
||||
if ((nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height) > pfloorleft
|
||||
&& (nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height) > pfloorright)
|
||||
continue;
|
||||
}
|
||||
|
||||
leftheight -= viewz;
|
||||
rightheight -= viewz;
|
||||
|
||||
#define OVERFLOWTEST(height, scale) \
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)height*scale)>>FRACBITS); \
|
||||
if (overflow_test < 0) overflow_test = -overflow_test; \
|
||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue;
|
||||
#define CLAMPMAX INT32_MAX
|
||||
#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out.
|
||||
// Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave.
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS);
|
||||
if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX;
|
||||
else if (overflow_test > (INT64)CLAMPMIN) rlight->height = (fixed_t)overflow_test;
|
||||
else rlight->height = CLAMPMIN;
|
||||
|
||||
OVERFLOWTEST(leftheight, ds->scale1)
|
||||
OVERFLOWTEST(rightheight, ds->scale2)
|
||||
|
||||
rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1);
|
||||
rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
|
||||
if (overflow_test > (INT64)CLAMPMAX) rlight->heightstep = CLAMPMAX;
|
||||
else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test;
|
||||
else rlight->heightstep = CLAMPMIN;
|
||||
rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
|
||||
#else
|
||||
if (light->height < *pfloor->bottomheight)
|
||||
|
@ -893,12 +895,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
leftheight -= viewz;
|
||||
rightheight -= viewz;
|
||||
|
||||
OVERFLOWTEST(leftheight, ds->scale1)
|
||||
OVERFLOWTEST(rightheight, ds->scale2)
|
||||
#undef OVERFLOWTEST
|
||||
// Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave.
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS);
|
||||
if (overflow_test > (INT64)CLAMPMAX) rlight->botheight = CLAMPMAX;
|
||||
else if (overflow_test > (INT64)CLAMPMIN) rlight->botheight = (fixed_t)overflow_test;
|
||||
else rlight->botheight = CLAMPMIN;
|
||||
|
||||
rlight->botheight = (centeryfrac) - FixedMul(leftheight, ds->scale1);
|
||||
rlight->botheightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
|
||||
if (overflow_test > (INT64)CLAMPMAX) rlight->botheightstep = CLAMPMAX;
|
||||
else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test;
|
||||
else rlight->botheightstep = CLAMPMIN;
|
||||
rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range);
|
||||
#else
|
||||
lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight;
|
||||
|
@ -1071,9 +1077,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
}
|
||||
#endif
|
||||
|
||||
#define CLAMPMAX INT32_MAX
|
||||
#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out.
|
||||
|
||||
// draw the columns
|
||||
for (dc_x = x1; dc_x <= x2; dc_x++)
|
||||
{
|
||||
|
|
169
src/s_sound.c
169
src/s_sound.c
|
@ -38,6 +38,10 @@ extern INT32 msg_id;
|
|||
#include "p_local.h" // camera info
|
||||
#include "m_misc.h" // for tunes command
|
||||
|
||||
#if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS)
|
||||
#include "lua_hook.h" // MusicChange hook
|
||||
#endif
|
||||
|
||||
#ifdef HW3SOUND
|
||||
// 3D Sound Interface
|
||||
#include "hardware/hw3sound.h"
|
||||
|
@ -1241,6 +1245,12 @@ static void *music_data;
|
|||
static UINT16 music_flags;
|
||||
static boolean music_looping;
|
||||
|
||||
static char queue_name[7];
|
||||
static UINT16 queue_flags;
|
||||
static boolean queue_looping;
|
||||
static UINT32 queue_position;
|
||||
static UINT32 queue_fadeinms;
|
||||
|
||||
/// ------------------------
|
||||
/// Music Status
|
||||
/// ------------------------
|
||||
|
@ -1275,6 +1285,11 @@ musictype_t S_MusicType(void)
|
|||
return I_SongType();
|
||||
}
|
||||
|
||||
const char *S_MusicName(void)
|
||||
{
|
||||
return music_name;
|
||||
}
|
||||
|
||||
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping)
|
||||
{
|
||||
if (!I_SongPlaying())
|
||||
|
@ -1305,6 +1320,35 @@ boolean S_SpeedMusic(float speed)
|
|||
return I_SetSongSpeed(speed);
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// Music Seeking
|
||||
/// ------------------------
|
||||
|
||||
UINT32 S_GetMusicLength(void)
|
||||
{
|
||||
return I_GetSongLength();
|
||||
}
|
||||
|
||||
boolean S_SetMusicLoopPoint(UINT32 looppoint)
|
||||
{
|
||||
return I_SetSongLoopPoint(looppoint);
|
||||
}
|
||||
|
||||
UINT32 S_GetMusicLoopPoint(void)
|
||||
{
|
||||
return I_GetSongLoopPoint();
|
||||
}
|
||||
|
||||
boolean S_SetMusicPosition(UINT32 position)
|
||||
{
|
||||
return I_SetSongPosition(position);
|
||||
}
|
||||
|
||||
UINT32 S_GetMusicPosition(void)
|
||||
{
|
||||
return I_GetSongPosition();
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// Music Playback
|
||||
/// ------------------------
|
||||
|
@ -1377,12 +1421,13 @@ static void S_UnloadMusic(void)
|
|||
music_looping = false;
|
||||
}
|
||||
|
||||
static boolean S_PlayMusic(boolean looping)
|
||||
static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
|
||||
{
|
||||
if (S_MusicDisabled())
|
||||
return false;
|
||||
|
||||
if (!I_PlaySong(looping))
|
||||
if ((!fadeinms && !I_PlaySong(looping)) ||
|
||||
(fadeinms && !I_FadeInPlaySong(fadeinms, looping)))
|
||||
{
|
||||
S_UnloadMusic();
|
||||
return false;
|
||||
|
@ -1392,8 +1437,30 @@ static boolean S_PlayMusic(boolean looping)
|
|||
return true;
|
||||
}
|
||||
|
||||
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
|
||||
static void S_QueueMusic(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 fadeinms)
|
||||
{
|
||||
strncpy(queue_name, mmusic, 7);
|
||||
queue_flags = mflags;
|
||||
queue_looping = looping;
|
||||
queue_position = position;
|
||||
queue_fadeinms = fadeinms;
|
||||
}
|
||||
|
||||
static void S_ClearQueue(void)
|
||||
{
|
||||
queue_name[0] = queue_flags = queue_looping = queue_position = queue_fadeinms = 0;
|
||||
}
|
||||
|
||||
static void S_ChangeMusicToQueue(void)
|
||||
{
|
||||
S_ChangeMusicEx(queue_name, queue_flags, queue_looping, queue_position, 0, queue_fadeinms);
|
||||
S_ClearQueue();
|
||||
}
|
||||
|
||||
void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 prefadems, UINT32 fadeinms)
|
||||
{
|
||||
char newmusic[7];
|
||||
|
||||
#if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X)
|
||||
S_ClearSfx();
|
||||
#endif
|
||||
|
@ -1401,33 +1468,66 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
|
|||
if (S_MusicDisabled())
|
||||
return;
|
||||
|
||||
// No Music (empty string)
|
||||
if (mmusic[0] == 0)
|
||||
{
|
||||
S_StopMusic();
|
||||
strncpy(newmusic, mmusic, 7);
|
||||
#if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS)
|
||||
if(LUAh_MusicChange(music_name, newmusic, &mflags, &looping, &position, &prefadems, &fadeinms))
|
||||
return;
|
||||
#endif
|
||||
newmusic[6] = 0;
|
||||
|
||||
// No Music (empty string)
|
||||
if (newmusic[0] == 0)
|
||||
{
|
||||
if (prefadems)
|
||||
I_FadeSong(0, prefadems, &S_StopMusic);
|
||||
else
|
||||
S_StopMusic();
|
||||
return;
|
||||
}
|
||||
|
||||
if (strnicmp(music_name, mmusic, 6))
|
||||
if (prefadems && S_MusicPlaying()) // queue music change for after fade // allow even if the music is the same
|
||||
{
|
||||
S_StopMusic(); // shutdown old music
|
||||
CONS_Debug(DBG_DETAILED, "Now fading out song %s\n", music_name);
|
||||
S_QueueMusic(newmusic, mflags, looping, position, fadeinms);
|
||||
I_FadeSong(0, prefadems, S_ChangeMusicToQueue);
|
||||
return;
|
||||
}
|
||||
else if (strnicmp(music_name, newmusic, 6) || (mflags & MUSIC_FORCERESET))
|
||||
{
|
||||
CONS_Debug(DBG_DETAILED, "Now playing song %s\n", newmusic);
|
||||
|
||||
if (!S_LoadMusic(mmusic))
|
||||
S_StopMusic();
|
||||
|
||||
if (!S_LoadMusic(newmusic))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded!\n", mmusic);
|
||||
CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded!\n", newmusic);
|
||||
return;
|
||||
}
|
||||
|
||||
music_flags = mflags;
|
||||
music_looping = looping;
|
||||
|
||||
if (!S_PlayMusic(looping))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Music %.6s could not be played!\n", mmusic);
|
||||
if (!S_PlayMusic(looping, fadeinms))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Music %.6s could not be played!\n", newmusic);
|
||||
return;
|
||||
}
|
||||
|
||||
if (position)
|
||||
I_SetSongPosition(position);
|
||||
|
||||
I_SetSongTrack(mflags & MUSIC_TRACKMASK);
|
||||
}
|
||||
else if (fadeinms) // let fades happen with same music
|
||||
{
|
||||
I_SetSongPosition(position);
|
||||
I_FadeSong(100, fadeinms, NULL);
|
||||
}
|
||||
else // reset volume to 100 with same music
|
||||
{
|
||||
I_StopFadingSong();
|
||||
I_FadeSong(100, 500, NULL);
|
||||
}
|
||||
I_SetSongTrack(mflags & MUSIC_TRACKMASK);
|
||||
}
|
||||
|
||||
void S_StopMusic(void)
|
||||
|
@ -1502,6 +1602,32 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
|
|||
}
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// Music Fading
|
||||
/// ------------------------
|
||||
|
||||
void S_SetInternalMusicVolume(INT32 volume)
|
||||
{
|
||||
I_SetInternalMusicVolume(min(max(volume, 0), 100));
|
||||
}
|
||||
|
||||
void S_StopFadingMusic(void)
|
||||
{
|
||||
I_StopFadingSong();
|
||||
}
|
||||
|
||||
boolean S_FadeMusicFromVolume(UINT8 target_volume, INT16 source_volume, UINT32 ms)
|
||||
{
|
||||
if (source_volume < 0)
|
||||
return I_FadeSong(target_volume, ms, NULL);
|
||||
else
|
||||
return I_FadeSongFromVolume(target_volume, source_volume, ms, NULL);
|
||||
}
|
||||
|
||||
boolean S_FadeOutStopMusic(UINT32 ms)
|
||||
{
|
||||
return I_FadeSong(0, ms, &S_StopMusic);
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// Init & Others
|
||||
|
@ -1519,22 +1645,24 @@ void S_Start(void)
|
|||
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
|
||||
mapmusname[6] = 0;
|
||||
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
|
||||
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
|
||||
}
|
||||
|
||||
if (cv_resetmusic.value)
|
||||
S_StopMusic();
|
||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||
}
|
||||
|
||||
static void Command_Tunes_f(void)
|
||||
{
|
||||
const char *tunearg;
|
||||
UINT16 tunenum, track = 0;
|
||||
UINT32 position = 0;
|
||||
const size_t argc = COM_Argc();
|
||||
|
||||
if (argc < 2) //tunes slot ...
|
||||
{
|
||||
CONS_Printf("tunes <name/num> [track] [speed] / <-show> / <-default> / <-none>:\n");
|
||||
CONS_Printf("tunes <name/num> [track] [speed] [position] / <-show> / <-default> / <-none>:\n");
|
||||
CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n"));
|
||||
CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n"));
|
||||
CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n"));
|
||||
|
@ -1581,10 +1709,15 @@ static void Command_Tunes_f(void)
|
|||
snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum));
|
||||
else
|
||||
strncpy(mapmusname, tunearg, 7);
|
||||
|
||||
if (argc > 4)
|
||||
position = (UINT32)atoi(COM_Argv(4));
|
||||
|
||||
mapmusname[6] = 0;
|
||||
mapmusflags = (track & MUSIC_TRACKMASK);
|
||||
mapmusposition = position;
|
||||
|
||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||
|
||||
if (argc > 3)
|
||||
{
|
||||
|
|
|
@ -112,29 +112,49 @@ boolean S_MusicDisabled(void);
|
|||
boolean S_MusicPlaying(void);
|
||||
boolean S_MusicPaused(void);
|
||||
musictype_t S_MusicType(void);
|
||||
const char *S_MusicName(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
|
||||
// Music Effects
|
||||
//
|
||||
|
||||
// Set Speed of Music
|
||||
boolean S_SpeedMusic(float speed);
|
||||
|
||||
//
|
||||
// Music Routines
|
||||
// Music Seeking
|
||||
//
|
||||
|
||||
// Get Length of Music
|
||||
UINT32 S_GetMusicLength(void);
|
||||
|
||||
// Set LoopPoint of Music
|
||||
boolean S_SetMusicLoopPoint(UINT32 looppoint);
|
||||
|
||||
// Get LoopPoint of Music
|
||||
UINT32 S_GetMusicLoopPoint(void);
|
||||
|
||||
// Set Position of Music
|
||||
boolean S_SetMusicPosition(UINT32 position);
|
||||
|
||||
// Get Position of Music
|
||||
UINT32 S_GetMusicPosition(void);
|
||||
|
||||
//
|
||||
// Music Playback
|
||||
//
|
||||
|
||||
// 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)
|
||||
// 13-15 aren't used yet
|
||||
// and the last bit we ignore (internal game flag for resetting music on reload)
|
||||
#define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b)
|
||||
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping);
|
||||
void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 prefadems, UINT32 fadeinms);
|
||||
#define S_ChangeMusicInternal(a,b) S_ChangeMusicEx(a,0,b,0,0,0)
|
||||
#define S_ChangeMusic(a,b,c) S_ChangeMusicEx(a,b,c,0,0,0)
|
||||
|
||||
// Stops the music.
|
||||
void S_StopMusic(void);
|
||||
|
@ -143,6 +163,17 @@ void S_StopMusic(void);
|
|||
void S_PauseAudio(void);
|
||||
void S_ResumeAudio(void);
|
||||
|
||||
//
|
||||
// Music Fading
|
||||
//
|
||||
|
||||
void S_SetInternalMusicVolume(INT32 volume);
|
||||
void S_StopFadingMusic(void);
|
||||
boolean S_FadeMusicFromVolume(UINT8 target_volume, INT16 source_volume, UINT32 ms);
|
||||
#define S_FadeMusic(a, b) S_FadeMusicFromVolume(a, -1, b)
|
||||
#define S_FadeInChangeMusic(a,b,c,d) S_ChangeMusicEx(a,b,c,0,0,d)
|
||||
boolean S_FadeOutStopMusic(UINT32 ms);
|
||||
|
||||
//
|
||||
// Updates music & sounds
|
||||
//
|
||||
|
|
|
@ -1402,7 +1402,13 @@ static int joy_open2(const char *fname)
|
|||
void I_InitJoystick(void)
|
||||
{
|
||||
I_ShutdownJoystick();
|
||||
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (M_CheckParm("-noxinput"))
|
||||
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (M_CheckParm("-nohidapi"))
|
||||
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (!strcmp(cv_usejoystick.string, "0") || M_CheckParm("-nojoy"))
|
||||
return;
|
||||
if (joy_open(cv_usejoystick.string) != -1)
|
||||
|
@ -1418,7 +1424,13 @@ void I_InitJoystick(void)
|
|||
void I_InitJoystick2(void)
|
||||
{
|
||||
I_ShutdownJoystick2();
|
||||
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (M_CheckParm("-noxinput"))
|
||||
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (M_CheckParm("-nohidapi"))
|
||||
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (!strcmp(cv_usejoystick2.string, "0") || M_CheckParm("-nojoy"))
|
||||
return;
|
||||
if (joy_open2(cv_usejoystick2.string) != -1)
|
||||
|
|
|
@ -580,8 +580,6 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
|||
if (cv_usemouse.value) I_StartupMouse();
|
||||
}
|
||||
//else firsttimeonmouse = SDL_FALSE;
|
||||
|
||||
capslock = !!( SDL_GetModState() & KMOD_CAPS );// in case CL changes
|
||||
}
|
||||
else if (!mousefocus && !kbfocus)
|
||||
{
|
||||
|
@ -939,6 +937,8 @@ void I_StartupMouse(void)
|
|||
//
|
||||
void I_OsPolling(void)
|
||||
{
|
||||
SDL_Keymod mod;
|
||||
|
||||
if (consolevent)
|
||||
I_GetConsoleEvents();
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||
|
@ -951,6 +951,18 @@ void I_OsPolling(void)
|
|||
I_GetMouseEvents();
|
||||
|
||||
I_GetEvent();
|
||||
|
||||
mod = SDL_GetModState();
|
||||
/* Handle here so that our state is always synched with the system. */
|
||||
shiftdown = ctrldown = altdown = 0;
|
||||
capslock = false;
|
||||
if (mod & KMOD_LSHIFT) shiftdown |= 1;
|
||||
if (mod & KMOD_RSHIFT) shiftdown |= 2;
|
||||
if (mod & KMOD_LCTRL) ctrldown |= 1;
|
||||
if (mod & KMOD_RCTRL) ctrldown |= 2;
|
||||
if (mod & KMOD_LALT) altdown |= 1;
|
||||
if (mod & KMOD_RALT) altdown |= 2;
|
||||
if (mod & KMOD_CAPS) capslock = true;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -984,6 +996,7 @@ void I_UpdateNoBlit(void)
|
|||
// from PrBoom's src/SDL/i_video.c
|
||||
static inline boolean I_SkipFrame(void)
|
||||
{
|
||||
#if 0
|
||||
static boolean skip = false;
|
||||
|
||||
if (rendermode != render_soft)
|
||||
|
@ -1003,6 +1016,8 @@ static inline boolean I_SkipFrame(void)
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -75,15 +75,41 @@
|
|||
UINT8 sound_started = false;
|
||||
|
||||
static Mix_Music *music;
|
||||
static UINT8 music_volume, sfx_volume;
|
||||
static UINT8 music_volume, sfx_volume, internal_volume;
|
||||
static float loop_point;
|
||||
static float song_length; // length in seconds
|
||||
static boolean songpaused;
|
||||
static UINT32 music_bytes;
|
||||
static boolean is_looping;
|
||||
|
||||
// fading
|
||||
static boolean is_fading;
|
||||
static UINT8 fading_source;
|
||||
static UINT8 fading_target;
|
||||
static UINT32 fading_timer;
|
||||
static UINT32 fading_duration;
|
||||
static INT32 fading_id;
|
||||
static void (*fading_callback)(void);
|
||||
|
||||
#ifdef HAVE_LIBGME
|
||||
static Music_Emu *gme;
|
||||
static INT32 current_track;
|
||||
#endif
|
||||
|
||||
static void var_cleanup(void)
|
||||
{
|
||||
loop_point = song_length =\
|
||||
music_bytes = fading_source = fading_target =\
|
||||
fading_timer = fading_duration = 0;
|
||||
|
||||
songpaused = is_looping =\
|
||||
is_fading = false;
|
||||
|
||||
fading_callback = NULL;
|
||||
|
||||
internal_volume = 100;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// Audio System
|
||||
/// ------------------------
|
||||
|
@ -111,6 +137,8 @@ void I_StartupSound(void)
|
|||
return;
|
||||
}
|
||||
|
||||
var_cleanup();
|
||||
|
||||
music = NULL;
|
||||
music_volume = sfx_volume = 0;
|
||||
|
||||
|
@ -336,6 +364,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
|
|||
len = (info->play_length * 441 / 10) << 2;
|
||||
mem = malloc(len);
|
||||
gme_play(emu, len >> 1, mem);
|
||||
gme_free_info(info);
|
||||
gme_delete(emu);
|
||||
|
||||
return Mix_QuickLoad_RAW((Uint8 *)mem, len);
|
||||
|
@ -408,6 +437,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
|
|||
len = (info->play_length * 441 / 10) << 2;
|
||||
mem = malloc(len);
|
||||
gme_play(emu, len >> 1, mem);
|
||||
gme_free_info(info);
|
||||
gme_delete(emu);
|
||||
|
||||
return Mix_QuickLoad_RAW((Uint8 *)mem, len);
|
||||
|
@ -482,14 +512,102 @@ void I_SetSfxVolume(UINT8 volume)
|
|||
sfx_volume = volume;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// Music Utilities
|
||||
/// ------------------------
|
||||
|
||||
static UINT32 get_real_volume(UINT8 volume)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (I_SongType() == MU_MID)
|
||||
// HACK: Until we stop using native MIDI,
|
||||
// disable volume changes
|
||||
return ((UINT32)31*128/31); // volume = 31
|
||||
else
|
||||
#endif
|
||||
// convert volume to mixer's 128 scale
|
||||
// then apply internal_volume as a percentage
|
||||
return ((UINT32)volume*128/31) * (UINT32)internal_volume / 100;
|
||||
}
|
||||
|
||||
static UINT32 get_adjusted_position(UINT32 position)
|
||||
{
|
||||
// all in milliseconds
|
||||
UINT32 length = I_GetSongLength();
|
||||
UINT32 looppoint = I_GetSongLoopPoint();
|
||||
if (length)
|
||||
return position >= length ? (position % (length-looppoint)) : position;
|
||||
else
|
||||
return position;
|
||||
}
|
||||
|
||||
static void do_fading_callback(void)
|
||||
{
|
||||
if (fading_callback)
|
||||
(*fading_callback)();
|
||||
fading_callback = NULL;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// Music Hooks
|
||||
/// ------------------------
|
||||
|
||||
static void count_music_bytes(int chan, void *stream, int len, void *udata)
|
||||
{
|
||||
(void)chan;
|
||||
(void)stream;
|
||||
(void)udata;
|
||||
|
||||
if (!music || I_SongType() == MU_GME || I_SongType() == MU_MOD || I_SongType() == MU_MID)
|
||||
return;
|
||||
music_bytes += len;
|
||||
}
|
||||
|
||||
static void music_loop(void)
|
||||
{
|
||||
Mix_PlayMusic(music, 0);
|
||||
Mix_SetMusicPosition(loop_point);
|
||||
if (is_looping)
|
||||
{
|
||||
Mix_PlayMusic(music, 0);
|
||||
Mix_SetMusicPosition(loop_point);
|
||||
music_bytes = loop_point*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetSongPosition)
|
||||
}
|
||||
else
|
||||
I_StopSong();
|
||||
}
|
||||
|
||||
static UINT32 music_fade(UINT32 interval, void *param)
|
||||
{
|
||||
(void)param;
|
||||
|
||||
if (!is_fading ||
|
||||
internal_volume == fading_target ||
|
||||
fading_duration == 0)
|
||||
{
|
||||
I_StopFadingSong();
|
||||
do_fading_callback();
|
||||
return 0;
|
||||
}
|
||||
else if (songpaused) // don't decrement timer
|
||||
return interval;
|
||||
else if ((fading_timer -= 10) <= 0)
|
||||
{
|
||||
internal_volume = fading_target;
|
||||
Mix_VolumeMusic(get_real_volume(music_volume));
|
||||
I_StopFadingSong();
|
||||
do_fading_callback();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 delta = abs(fading_target - fading_source);
|
||||
fixed_t factor = FixedDiv(fading_duration - fading_timer, fading_duration);
|
||||
if (fading_target < fading_source)
|
||||
internal_volume = max(min(internal_volume, fading_source - FixedMul(delta, factor)), fading_target);
|
||||
else if (fading_target > fading_source)
|
||||
internal_volume = min(max(internal_volume, fading_source + FixedMul(delta, factor)), fading_target);
|
||||
Mix_VolumeMusic(get_real_volume(music_volume));
|
||||
return interval;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBGME
|
||||
|
@ -509,7 +627,7 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
|
|||
|
||||
// apply volume to stream
|
||||
for (i = 0, p = (short *)stream; i < len/2; i++, p++)
|
||||
*p = ((INT32)*p) * music_volume*2 / 42;
|
||||
*p = ((INT32)*p) * (music_volume*internal_volume/100)*2 / 42;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -587,6 +705,194 @@ boolean I_SetSongSpeed(float speed)
|
|||
return false;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// MUSIC SEEKING
|
||||
/// ------------------------
|
||||
|
||||
UINT32 I_GetSongLength(void)
|
||||
{
|
||||
INT32 length;
|
||||
|
||||
#ifdef HAVE_LIBGME
|
||||
if (gme)
|
||||
{
|
||||
gme_info_t *info;
|
||||
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
|
||||
|
||||
if (gme_e != NULL)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
|
||||
length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// reconstruct info->play_length, from GME source
|
||||
// we only want intro + 1 loop, not 2
|
||||
length = info->length;
|
||||
if (length <= 0)
|
||||
{
|
||||
length = info->intro_length + info->loop_length; // intro + 1 loop
|
||||
if (length <= 0)
|
||||
length = 150 * 1000; // 2.5 minutes
|
||||
}
|
||||
}
|
||||
|
||||
gme_free_info(info);
|
||||
return max(length, 0);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!music || I_SongType() == MU_MOD || I_SongType() == MU_MID)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
// VERY IMPORTANT to set your LENGTHMS= in your song files, folks!
|
||||
// SDL mixer can't read music length itself.
|
||||
length = (UINT32)(song_length*1000);
|
||||
if (!length)
|
||||
CONS_Debug(DBG_DETAILED, "Getting music length: music is missing LENGTHMS= tag. Needed for seeking.\n");
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||
{
|
||||
if (!music || I_SongType() == MU_GME || I_SongType() == MU_MOD || I_SongType() == MU_MID || !is_looping)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
UINT32 length = I_GetSongLength();
|
||||
|
||||
if (length > 0)
|
||||
looppoint %= length;
|
||||
|
||||
loop_point = max((float)(looppoint / 1000.0L), 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 I_GetSongLoopPoint(void)
|
||||
{
|
||||
#ifdef HAVE_LIBGME
|
||||
if (gme)
|
||||
{
|
||||
INT32 looppoint;
|
||||
gme_info_t *info;
|
||||
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
|
||||
|
||||
if (gme_e != NULL)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
|
||||
looppoint = 0;
|
||||
}
|
||||
else
|
||||
looppoint = info->intro_length > 0 ? info->intro_length : 0;
|
||||
|
||||
gme_free_info(info);
|
||||
return max(looppoint, 0);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!music || I_SongType() == MU_MOD || I_SongType() == MU_MID)
|
||||
return 0;
|
||||
else
|
||||
return (UINT32)(loop_point * 1000);
|
||||
}
|
||||
|
||||
boolean I_SetSongPosition(UINT32 position)
|
||||
{
|
||||
UINT32 length;
|
||||
#ifdef HAVE_LIBGME
|
||||
if (gme)
|
||||
{
|
||||
// this is unstable, so fail silently
|
||||
return true;
|
||||
// this isn't required technically, but GME thread-locks for a second
|
||||
// if you seek too high from the counter
|
||||
// length = I_GetSongLength();
|
||||
// if (length)
|
||||
// position = get_adjusted_position(position);
|
||||
|
||||
// SDL_LockAudio();
|
||||
// gme_err_t gme_e = gme_seek(gme, position);
|
||||
// SDL_UnlockAudio();
|
||||
|
||||
// if (gme_e != NULL)
|
||||
// {
|
||||
// CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// return true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!music || I_SongType() == MU_MID)
|
||||
return false;
|
||||
else if (I_SongType() == MU_MOD)
|
||||
return Mix_SetMusicPosition(position); // Goes by channels
|
||||
else
|
||||
{
|
||||
// Because SDL mixer can't identify song length, if you have
|
||||
// a position input greater than the real length, then
|
||||
// music_bytes becomes inaccurate.
|
||||
|
||||
length = I_GetSongLength(); // get it in MS
|
||||
if (length)
|
||||
position = get_adjusted_position(position);
|
||||
|
||||
Mix_RewindMusic(); // needed for mp3
|
||||
if(Mix_SetMusicPosition((float)(position/1000.0L)) == 0)
|
||||
music_bytes = position/1000.0L*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetSongPosition)
|
||||
else
|
||||
// NOTE: This block fires on incorrect song format,
|
||||
// NOT if position input is greater than song length.
|
||||
music_bytes = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 I_GetSongPosition(void)
|
||||
{
|
||||
#ifdef HAVE_LIBGME
|
||||
if (gme)
|
||||
{
|
||||
INT32 position = gme_tell(gme);
|
||||
|
||||
gme_info_t *info;
|
||||
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
|
||||
|
||||
if (gme_e != NULL)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
|
||||
return position;
|
||||
}
|
||||
else
|
||||
{
|
||||
// adjust position, since GME's counter keeps going past loop
|
||||
if (info->length > 0)
|
||||
position %= info->length;
|
||||
else if (info->intro_length + info->loop_length > 0)
|
||||
position = position >= (info->intro_length + info->loop_length) ? (position % info->loop_length) : position;
|
||||
else
|
||||
position %= 150 * 1000; // 2.5 minutes
|
||||
}
|
||||
|
||||
gme_free_info(info);
|
||||
return max(position, 0);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!music || I_SongType() == MU_MID)
|
||||
return 0;
|
||||
else
|
||||
return music_bytes/44100.0L*1000.0L/4; //assume 44.1khz
|
||||
// 4 = byte length for 16-bit samples (AUDIO_S16SYS), stereo (2-channel)
|
||||
// This is hardcoded in I_StartupSound. Other formats for factor:
|
||||
// 8M: 1 | 8S: 2 | 16M: 2 | 16S: 4
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// Music Playback
|
||||
/// ------------------------
|
||||
|
@ -599,6 +905,7 @@ boolean I_LoadSong(char *data, size_t len)
|
|||
const size_t key1len = strlen(key1);
|
||||
const size_t key2len = strlen(key2);
|
||||
const size_t key3len = strlen(key3);
|
||||
|
||||
char *p = data;
|
||||
SDL_RWops *rw;
|
||||
|
||||
|
@ -609,6 +916,9 @@ boolean I_LoadSong(char *data, size_t len)
|
|||
)
|
||||
I_UnloadSong();
|
||||
|
||||
// always do this whether or not a music already exists
|
||||
var_cleanup();
|
||||
|
||||
#ifdef HAVE_LIBGME
|
||||
if ((UINT8)data[0] == 0x1F
|
||||
&& (UINT8)data[1] == 0x8B)
|
||||
|
@ -718,30 +1028,35 @@ boolean I_LoadSong(char *data, size_t len)
|
|||
|
||||
// Find the OGG loop point.
|
||||
loop_point = 0.0f;
|
||||
song_length = 0.0f;
|
||||
|
||||
while ((UINT32)(p - data) < len)
|
||||
{
|
||||
if (strncmp(p++, key1, key1len))
|
||||
continue;
|
||||
p += key1len-1; // skip OOP (the L was skipped in strncmp)
|
||||
if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
|
||||
if (fpclassify(loop_point) == FP_ZERO && !strncmp(p, key1, key1len))
|
||||
{
|
||||
p += key2len; // skip POINT=
|
||||
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.
|
||||
p += key1len; // skip LOOP
|
||||
if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
|
||||
{
|
||||
p += key2len; // skip POINT=
|
||||
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.
|
||||
}
|
||||
}
|
||||
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.
|
||||
}
|
||||
|
||||
if (fpclassify(loop_point) != FP_ZERO) // Got what we needed
|
||||
break;
|
||||
else // continue searching
|
||||
p++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -765,7 +1080,6 @@ void I_UnloadSong(void)
|
|||
|
||||
boolean I_PlaySong(boolean looping)
|
||||
{
|
||||
boolean lpz = fpclassify(loop_point) == FP_ZERO;
|
||||
#ifdef HAVE_LIBGME
|
||||
if (gme)
|
||||
{
|
||||
|
@ -779,21 +1093,37 @@ boolean I_PlaySong(boolean looping)
|
|||
if (!music)
|
||||
return false;
|
||||
|
||||
if (fpclassify(song_length) == FP_ZERO && (I_SongType() == MU_OGG || I_SongType() == MU_MP3 || I_SongType() == MU_FLAC))
|
||||
CONS_Debug(DBG_DETAILED, "This song is missing a LENGTHMS= tag! Required to make seeking work properly.\n");
|
||||
|
||||
if (Mix_PlayMusic(music, looping && lpz ? -1 : 0) == -1)
|
||||
if (I_SongType() != MU_MOD && I_SongType() != MU_MID && Mix_PlayMusic(music, 0) == -1)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
|
||||
return false;
|
||||
}
|
||||
else if ((I_SongType() == MU_MOD || I_SongType() == MU_MID) && Mix_PlayMusic(music, looping ? -1 : 0) == -1) // if MOD, loop forever
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
|
||||
return false;
|
||||
}
|
||||
Mix_VolumeMusic((UINT32)music_volume*128/31);
|
||||
|
||||
if (!lpz)
|
||||
Mix_HookMusicFinished(music_loop);
|
||||
is_looping = looping;
|
||||
|
||||
I_SetMusicVolume(music_volume);
|
||||
|
||||
if (I_SongType() != MU_MOD && I_SongType() != MU_MID)
|
||||
Mix_HookMusicFinished(music_loop); // don't bother counting if MOD
|
||||
|
||||
if(I_SongType() != MU_MOD && I_SongType() != MU_MID && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
|
||||
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void I_StopSong(void)
|
||||
{
|
||||
I_StopFadingSong();
|
||||
|
||||
#ifdef HAVE_LIBGME
|
||||
if (gme)
|
||||
{
|
||||
|
@ -803,19 +1133,40 @@ void I_StopSong(void)
|
|||
#endif
|
||||
if (music)
|
||||
{
|
||||
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||
Mix_HookMusicFinished(NULL);
|
||||
Mix_HaltMusic();
|
||||
}
|
||||
|
||||
var_cleanup();
|
||||
}
|
||||
|
||||
void I_PauseSong(void)
|
||||
{
|
||||
if(I_SongType() == MU_MID) // really, SDL Mixer? why can't you pause MIDI???
|
||||
return;
|
||||
|
||||
if(I_SongType() != MU_GME && I_SongType() != MU_MOD && I_SongType() != MU_MID)
|
||||
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||
|
||||
Mix_PauseMusic();
|
||||
songpaused = true;
|
||||
}
|
||||
|
||||
void I_ResumeSong(void)
|
||||
{
|
||||
if (I_SongType() == MU_MID)
|
||||
return;
|
||||
|
||||
if (I_SongType() != MU_GME && I_SongType() != MU_MOD && I_SongType() != MU_MID)
|
||||
{
|
||||
while(Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes) != 0) { }
|
||||
// HACK: fixes issue of multiple effect callbacks being registered
|
||||
|
||||
if(music && I_SongType() != MU_MOD && I_SongType() != MU_MID && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
|
||||
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
|
||||
}
|
||||
|
||||
Mix_ResumeMusic();
|
||||
songpaused = false;
|
||||
}
|
||||
|
@ -834,7 +1185,7 @@ void I_SetMusicVolume(UINT8 volume)
|
|||
#endif
|
||||
music_volume = volume;
|
||||
|
||||
Mix_VolumeMusic((UINT32)music_volume*128/31);
|
||||
Mix_VolumeMusic(get_real_volume(music_volume));
|
||||
}
|
||||
|
||||
boolean I_SetSongTrack(int track)
|
||||
|
@ -863,9 +1214,100 @@ boolean I_SetSongTrack(int track)
|
|||
SDL_UnlockAudio();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (I_SongType() == MU_MOD)
|
||||
return !Mix_SetMusicPosition(track);
|
||||
(void)track;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// MUSIC FADING
|
||||
/// ------------------------
|
||||
|
||||
void I_SetInternalMusicVolume(UINT8 volume)
|
||||
{
|
||||
internal_volume = volume;
|
||||
if (!I_SongPlaying())
|
||||
return;
|
||||
Mix_VolumeMusic(get_real_volume(music_volume));
|
||||
}
|
||||
|
||||
void I_StopFadingSong(void)
|
||||
{
|
||||
if (fading_id)
|
||||
SDL_RemoveTimer(fading_id);
|
||||
is_fading = false;
|
||||
fading_source = fading_target = fading_timer = fading_duration = fading_id = 0;
|
||||
}
|
||||
|
||||
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void))
|
||||
{
|
||||
INT16 volume_delta;
|
||||
|
||||
source_volume = min(source_volume, 100);
|
||||
volume_delta = (INT16)(target_volume - source_volume);
|
||||
|
||||
I_StopFadingSong();
|
||||
|
||||
if (!ms && volume_delta)
|
||||
{
|
||||
I_SetInternalMusicVolume(target_volume);
|
||||
if (callback)
|
||||
(*callback)();
|
||||
return true;
|
||||
|
||||
}
|
||||
else if (!volume_delta)
|
||||
{
|
||||
if (callback)
|
||||
(*callback)();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Round MS to nearest 10
|
||||
// If n - lower > higher - n, then round up
|
||||
ms = (ms - ((ms / 10) * 10) > (((ms / 10) * 10) + 10) - ms) ?
|
||||
(((ms / 10) * 10) + 10) // higher
|
||||
: ((ms / 10) * 10); // lower
|
||||
|
||||
if (!ms)
|
||||
I_SetInternalMusicVolume(target_volume);
|
||||
else if (source_volume != target_volume)
|
||||
{
|
||||
fading_id = SDL_AddTimer(10, music_fade, NULL);
|
||||
if (fading_id)
|
||||
{
|
||||
is_fading = true;
|
||||
fading_timer = fading_duration = ms;
|
||||
fading_source = source_volume;
|
||||
fading_target = target_volume;
|
||||
fading_callback = callback;
|
||||
|
||||
if (internal_volume != source_volume)
|
||||
I_SetInternalMusicVolume(source_volume);
|
||||
}
|
||||
}
|
||||
|
||||
return is_fading;
|
||||
}
|
||||
|
||||
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
|
||||
{
|
||||
return I_FadeSongFromVolume(target_volume, internal_volume, ms, callback);
|
||||
}
|
||||
|
||||
boolean I_FadeOutStopSong(UINT32 ms)
|
||||
{
|
||||
return I_FadeSongFromVolume(0, internal_volume, ms, &I_StopSong);
|
||||
}
|
||||
|
||||
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||
{
|
||||
if (I_PlaySong(looping))
|
||||
return I_FadeSongFromVolume(100, 0, ms, NULL);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1375,6 +1375,37 @@ boolean I_SetSongSpeed(float speed)
|
|||
return false;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC SEEKING
|
||||
/// ------------------------
|
||||
|
||||
UINT32 I_GetSongLength(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||
{
|
||||
(void)looppoint;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 I_GetSongLoopPoint(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean I_SetSongPosition(UINT32 position)
|
||||
{
|
||||
(void)position;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 I_GetSongPosition(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC PLAYBACK
|
||||
/// ------------------------
|
||||
|
@ -1443,6 +1474,47 @@ boolean I_SetSongTrack(int track)
|
|||
return false;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// MUSIC FADING
|
||||
/// ------------------------
|
||||
|
||||
void I_SetInternalMusicVolume(UINT8 volume)
|
||||
{
|
||||
(void)volume;
|
||||
}
|
||||
|
||||
void I_StopFadingSong(void)
|
||||
{
|
||||
}
|
||||
|
||||
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void))
|
||||
{
|
||||
(void)target_volume;
|
||||
(void)source_volume;
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
|
||||
{
|
||||
(void)target_volume;
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeOutStopSong(UINT32 ms)
|
||||
{
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||
{
|
||||
(void)ms;
|
||||
(void)looping;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC LOADING AND CLEANUP
|
||||
// \todo Split logic between loading and playing,
|
||||
|
|
|
@ -81,6 +81,7 @@ consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0
|
|||
static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}};
|
||||
// console variables in development
|
||||
consvar_t cv_grmd2 = {"gr_md2", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif
|
||||
|
||||
const UINT8 gammatable[5][256] =
|
||||
|
|
32
src/w_wad.c
32
src/w_wad.c
|
@ -1179,6 +1179,23 @@ void zerr(int ret)
|
|||
}
|
||||
#endif
|
||||
|
||||
#define NO_PNG_LUMPS
|
||||
|
||||
#ifdef NO_PNG_LUMPS
|
||||
static void ErrorIfPNG(UINT8 *d, size_t s, char *f, char *l)
|
||||
{
|
||||
if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/
|
||||
return;
|
||||
// Check for PNG file signature using memcmp
|
||||
// As it may be faster on CPUs with slow unaligned memory access
|
||||
// Ref: http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature
|
||||
if (memcmp(&d[0], "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) == 0)
|
||||
{
|
||||
I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .PNG - please convert to either Doom or Flat (raw) image format.", l, f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Reads bytes from the head of a lump.
|
||||
* Note: If the lump is compressed, the whole thing has to be read anyway.
|
||||
*
|
||||
|
@ -1218,7 +1235,15 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
switch(wadfiles[wad]->lumpinfo[lump].compression)
|
||||
{
|
||||
case CM_NOCOMPRESSION: // If it's uncompressed, we directly write the data into our destination, and return the bytes read.
|
||||
#ifdef NO_PNG_LUMPS
|
||||
{
|
||||
size_t bytesread = fread(dest, 1, size, handle);
|
||||
ErrorIfPNG(dest, bytesread, wadfiles[wad]->filename, l->name2);
|
||||
return bytesread;
|
||||
}
|
||||
#else
|
||||
return fread(dest, 1, size, handle);
|
||||
#endif
|
||||
case CM_LZF: // Is it LZF compressed? Used by ZWADs.
|
||||
{
|
||||
#ifdef ZWAD
|
||||
|
@ -1253,11 +1278,15 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
M_Memcpy(dest, decData + offset, size);
|
||||
Z_Free(rawData);
|
||||
Z_Free(decData);
|
||||
#ifdef NO_PNG_LUMPS
|
||||
ErrorIfPNG(dest, size, wadfiles[wad]->filename, l->name2);
|
||||
#endif
|
||||
return size;
|
||||
#else
|
||||
//I_Error("ZWAD files not supported on this platform.");
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
#ifdef HAVE_ZLIB
|
||||
case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support.
|
||||
|
@ -1311,6 +1340,9 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
Z_Free(rawData);
|
||||
Z_Free(decData);
|
||||
|
||||
#ifdef NO_PNG_LUMPS
|
||||
ErrorIfPNG(dest, size, wadfiles[wad]->filename, l->name2);
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -24,8 +24,10 @@ ifndef NOASM
|
|||
USEASM=1
|
||||
endif
|
||||
|
||||
ifndef NONET
|
||||
ifndef MINGW64 #miniupnc is broken with MINGW64
|
||||
HAVE_MINIUPNPC=1
|
||||
endif
|
||||
endif
|
||||
|
||||
OPTS=-DSTDC_HEADERS
|
||||
|
|
|
@ -815,6 +815,60 @@ void I_SetMusicVolume(UINT8 volume)
|
|||
FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
|
||||
}
|
||||
|
||||
UINT32 I_GetSongLength(void)
|
||||
{
|
||||
UINT32 length;
|
||||
if (I_SongType() == MU_MID)
|
||||
return 0;
|
||||
FMR_MUSIC(FMOD_Sound_GetLength(music_stream, &length, FMOD_TIMEUNIT_MS));
|
||||
return length;
|
||||
}
|
||||
|
||||
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||
{
|
||||
(void)looppoint;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 I_GetSongLoopPoint(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean I_SetSongPosition(UINT32 position)
|
||||
{
|
||||
FMOD_RESULT e;
|
||||
if(I_SongType() == MU_MID)
|
||||
// Dummy out; this works for some MIDI, but not others.
|
||||
// SDL does not support this for any MIDI.
|
||||
return false;
|
||||
e = FMOD_Channel_SetPosition(music_channel, position, FMOD_TIMEUNIT_MS);
|
||||
if (e == FMOD_OK)
|
||||
return true;
|
||||
else if (e == FMOD_ERR_UNSUPPORTED // Only music modules, numbnuts!
|
||||
|| e == FMOD_ERR_INVALID_POSITION) // Out-of-bounds!
|
||||
return false;
|
||||
else // Congrats, you horribly broke it somehow
|
||||
{
|
||||
FMR_MUSIC(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 I_GetSongPosition(void)
|
||||
{
|
||||
FMOD_RESULT e;
|
||||
unsigned int fmposition = 0;
|
||||
if(I_SongType() == MU_MID)
|
||||
// Dummy out because unsupported, even though FMOD does this correctly.
|
||||
return 0;
|
||||
e = FMOD_Channel_GetPosition(music_channel, &fmposition, FMOD_TIMEUNIT_MS);
|
||||
if (e == FMOD_OK)
|
||||
return (UINT32)fmposition;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean I_SetSongTrack(INT32 track)
|
||||
{
|
||||
if (track != current_track) // If the track's already playing, then why bother?
|
||||
|
@ -859,3 +913,46 @@ boolean I_SetSongTrack(INT32 track)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
/// MUSIC FADING
|
||||
/// ------------------------
|
||||
|
||||
void I_SetInternalMusicVolume(UINT8 volume)
|
||||
{
|
||||
(void)volume;
|
||||
}
|
||||
|
||||
void I_StopFadingSong(void)
|
||||
{
|
||||
}
|
||||
|
||||
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void))
|
||||
{
|
||||
(void)target_volume;
|
||||
(void)source_volume;
|
||||
(void)ms;
|
||||
(void)callback;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
|
||||
{
|
||||
(void)target_volume;
|
||||
(void)ms;
|
||||
(void)callback;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeOutStopSong(UINT32 ms)
|
||||
{
|
||||
(void)ms;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||
{
|
||||
(void)ms;
|
||||
(void)looping;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -639,9 +639,6 @@ void I_Error(const char *error, ...)
|
|||
if (!errorcount)
|
||||
{
|
||||
M_SaveConfig(NULL); // save game config, cvars..
|
||||
#ifndef NONET
|
||||
D_SaveBan(); // save the ban list
|
||||
#endif
|
||||
G_SaveGameData();
|
||||
}
|
||||
|
||||
|
|
|
@ -696,7 +696,19 @@ void Y_Ticker(void)
|
|||
boolean anybonuses = false;
|
||||
|
||||
if (!intertic) // first time only
|
||||
S_ChangeMusicInternal("lclear", false); // don't loop it
|
||||
{
|
||||
if (mapheaderinfo[gamemap-1]->musinterfadeout
|
||||
#ifdef _WIN32
|
||||
// can't fade midi due to win32 volume hack
|
||||
&& S_MusicType() != MU_MID
|
||||
#endif
|
||||
)
|
||||
S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musinterfadeout);
|
||||
else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled))
|
||||
S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it
|
||||
else
|
||||
S_ChangeMusicInternal("lclear", false); // don't loop it
|
||||
}
|
||||
|
||||
if (intertic < TICRATE) // one second pause before tally begins
|
||||
return;
|
||||
|
@ -757,7 +769,17 @@ void Y_Ticker(void)
|
|||
|
||||
if (!intertic) // first time only
|
||||
{
|
||||
S_ChangeMusicInternal("lclear", false); // don't loop it
|
||||
if (mapheaderinfo[gamemap-1]->musinterfadeout
|
||||
#ifdef _WIN32
|
||||
// can't fade midi due to win32 volume hack
|
||||
&& S_MusicType() != MU_MID
|
||||
#endif
|
||||
)
|
||||
S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musinterfadeout);
|
||||
else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled))
|
||||
S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it
|
||||
else
|
||||
S_ChangeMusicInternal("lclear", false); // don't loop it
|
||||
tallydonetic = 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue