mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
Merge branch 'musicplus-core' into musicplus-sdlmixerx
This commit is contained in:
commit
f2bfed7892
78 changed files with 3135 additions and 711 deletions
|
@ -13,8 +13,6 @@
|
|||
- libupnp (Linux/OS X only)
|
||||
- libgme (Linux/OS X only)
|
||||
|
||||
Warning: 64-bit builds are not netgame compatible with 32-bit builds. Use at your own risk.
|
||||
|
||||
## Compiling
|
||||
|
||||
See [SRB2 Wiki/Source code compiling](http://wiki.srb2.org/wiki/Source_code_compiling)
|
||||
|
|
21
src/Makefile
21
src/Makefile
|
@ -64,6 +64,7 @@
|
|||
# Compile without 3D sound support, add 'NOHS=1'
|
||||
# Compile with GDBstubs, add 'RDB=1'
|
||||
# Compile without PNG, add 'NOPNG=1'
|
||||
# Compile without zlib, add 'NOZLIB=1'
|
||||
#
|
||||
# Addon for SDL:
|
||||
# To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config'
|
||||
|
@ -109,6 +110,7 @@ include Makefile.cfg
|
|||
|
||||
ifdef DUMMY
|
||||
NOPNG=1
|
||||
NOZLIB=1
|
||||
NONET=1
|
||||
NOHW=1
|
||||
NOHS=1
|
||||
|
@ -271,13 +273,6 @@ LIBS+=$(PNG_LDFLAGS)
|
|||
CFLAGS+=$(PNG_CFLAGS)
|
||||
endif
|
||||
|
||||
ZLIB_PKGCONFIG?=zlib
|
||||
ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags)
|
||||
ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs)
|
||||
|
||||
LIBS+=$(ZLIB_LDFLAGS)
|
||||
CFLAGS+=$(ZLIB_CFLAGS)
|
||||
|
||||
ifdef HAVE_LIBGME
|
||||
OPTS+=-DHAVE_LIBGME
|
||||
|
||||
|
@ -289,6 +284,18 @@ LIBS+=$(LIBGME_LDFLAGS)
|
|||
CFLAGS+=$(LIBGME_CFLAGS)
|
||||
endif
|
||||
|
||||
ifndef NOZLIB
|
||||
OPTS+=-DHAVE_ZLIB
|
||||
ZLIB_PKGCONFIG?=zlib
|
||||
ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags)
|
||||
ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs)
|
||||
|
||||
LIBS+=$(ZLIB_LDFLAGS)
|
||||
CFLAGS+=$(ZLIB_CFLAGS)
|
||||
else
|
||||
NOPNG=1
|
||||
endif
|
||||
|
||||
ifdef STATIC
|
||||
LIBS:=-static $(LIBS)
|
||||
endif
|
||||
|
|
|
@ -21,13 +21,14 @@ void I_ShutdownSound(void){}
|
|||
// SFX I/O
|
||||
//
|
||||
|
||||
INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority)
|
||||
INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority, INT32 channel)
|
||||
{
|
||||
(void)id;
|
||||
(void)vol;
|
||||
(void)sep;
|
||||
(void)pitch;
|
||||
(void)priority;
|
||||
(void)channel;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
#define DEALIGNED
|
||||
#endif
|
||||
|
||||
#ifndef _BIG_ENDIAN
|
||||
#include "endian.h"
|
||||
|
||||
#ifndef SRB2_BIG_ENDIAN
|
||||
//
|
||||
// Little-endian machines
|
||||
//
|
||||
|
@ -75,7 +77,7 @@
|
|||
#define READANGLE(p) *((angle_t *)p)++
|
||||
#endif
|
||||
|
||||
#else //_BIG_ENDIAN
|
||||
#else //SRB2_BIG_ENDIAN
|
||||
//
|
||||
// definitions for big-endian machines with alignment constraints.
|
||||
//
|
||||
|
@ -144,7 +146,7 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
|
|||
#define READCHAR(p) ({ char *p_tmp = ( char *)p; char b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READFIXED(p) ({ fixed_t *p_tmp = (fixed_t *)p; fixed_t b = readlong(p); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = readulong(p); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#endif //_BIG_ENDIAN
|
||||
#endif //SRB2_BIG_ENDIAN
|
||||
|
||||
#undef DEALIGNED
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
|||
CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
||||
|
||||
#define COM_BUF_SIZE 8192 // command buffer size
|
||||
#define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases
|
||||
|
||||
static INT32 com_wait; // one command per frame (for cmd sequences)
|
||||
|
||||
|
@ -485,6 +486,7 @@ static void COM_ExecuteString(char *ptext)
|
|||
{
|
||||
xcommand_t *cmd;
|
||||
cmdalias_t *a;
|
||||
static INT32 recursion = 0; // detects recursion and stops it if it goes too far
|
||||
|
||||
COM_TokenizeString(ptext);
|
||||
|
||||
|
@ -497,6 +499,7 @@ 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;
|
||||
}
|
||||
|
@ -507,11 +510,20 @@ 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;
|
||||
}
|
||||
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)
|
||||
|
|
|
@ -232,18 +232,20 @@ UINT8 *yellowmap, *magentamap, *lgreenmap, *bluemap, *graymap, *redmap, *orangem
|
|||
|
||||
// Console BG color
|
||||
UINT8 *consolebgmap = NULL;
|
||||
UINT8 *promptbgmap = NULL;
|
||||
static UINT8 promptbgcolor = UINT8_MAX;
|
||||
|
||||
void CON_SetupBackColormap(void)
|
||||
void CON_SetupBackColormapEx(INT32 color, boolean prompt)
|
||||
{
|
||||
UINT16 i, palsum;
|
||||
UINT8 j, palindex, shift;
|
||||
UINT8 *pal = W_CacheLumpName(GetPalette(), PU_CACHE);
|
||||
|
||||
if (!consolebgmap)
|
||||
consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL);
|
||||
if (color == INT32_MAX)
|
||||
color = cons_backcolor.value;
|
||||
|
||||
shift = 6; // 12 colors -- shift of 7 means 6 colors
|
||||
switch (cons_backcolor.value)
|
||||
switch (color)
|
||||
{
|
||||
case 0: palindex = 15; break; // White
|
||||
case 1: palindex = 31; break; // Gray
|
||||
|
@ -257,20 +259,42 @@ void CON_SetupBackColormap(void)
|
|||
case 9: palindex = 187; break; // Magenta
|
||||
case 10: palindex = 139; break; // Aqua
|
||||
// Default green
|
||||
default: palindex = 175; break;
|
||||
}
|
||||
default: palindex = 175; color = 11; break;
|
||||
}
|
||||
|
||||
if (prompt)
|
||||
{
|
||||
if (!promptbgmap)
|
||||
promptbgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL);
|
||||
|
||||
if (color == promptbgcolor)
|
||||
return;
|
||||
else
|
||||
promptbgcolor = color;
|
||||
}
|
||||
else if (!consolebgmap)
|
||||
consolebgmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL);
|
||||
|
||||
// setup background colormap
|
||||
for (i = 0, j = 0; i < 768; i += 3, j++)
|
||||
{
|
||||
palsum = (pal[i] + pal[i+1] + pal[i+2]) >> shift;
|
||||
consolebgmap[j] = (UINT8)(palindex - palsum);
|
||||
if (prompt)
|
||||
promptbgmap[j] = (UINT8)(palindex - palsum);
|
||||
else
|
||||
consolebgmap[j] = (UINT8)(palindex - palsum);
|
||||
}
|
||||
}
|
||||
|
||||
void CON_SetupBackColormap(void)
|
||||
{
|
||||
CON_SetupBackColormapEx(cons_backcolor.value, false);
|
||||
CON_SetupBackColormapEx(1, true); // default to gray
|
||||
}
|
||||
|
||||
static void CONS_backcolor_Change(void)
|
||||
{
|
||||
CON_SetupBackColormap();
|
||||
CON_SetupBackColormapEx(cons_backcolor.value, false);
|
||||
}
|
||||
|
||||
static void CON_SetupColormaps(void)
|
||||
|
|
|
@ -38,7 +38,9 @@ extern UINT8 *yellowmap, *magentamap, *lgreenmap, *bluemap, *graymap, *redmap, *
|
|||
|
||||
// Console bg color (auto updated to match)
|
||||
extern UINT8 *consolebgmap;
|
||||
extern UINT8 *promptbgmap;
|
||||
|
||||
void CON_SetupBackColormapEx(INT32 color, boolean prompt);
|
||||
void CON_SetupBackColormap(void);
|
||||
void CON_ClearHUD(void); // clear heads up messages
|
||||
|
||||
|
|
|
@ -2353,7 +2353,7 @@ void CL_ClearPlayer(INT32 playernum)
|
|||
//
|
||||
// Removes a player from the current game
|
||||
//
|
||||
static void CL_RemovePlayer(INT32 playernum)
|
||||
static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||
{
|
||||
// Sanity check: exceptional cases (i.e. c-fails) can cause multiple
|
||||
// kick commands to be issued for the same player.
|
||||
|
@ -2407,6 +2407,10 @@ static void CL_RemovePlayer(INT32 playernum)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
|
||||
#endif
|
||||
|
||||
// Reset player data
|
||||
CL_ClearPlayer(playernum);
|
||||
|
@ -2683,6 +2687,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
INT32 pnum, msg;
|
||||
char buf[3 + MAX_REASONLENGTH];
|
||||
char *reason = buf;
|
||||
kickreason_t kickreason = KR_KICK;
|
||||
|
||||
pnum = READUINT8(*p);
|
||||
msg = READUINT8(*p);
|
||||
|
@ -2765,14 +2770,17 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
{
|
||||
case KICK_MSG_GO_AWAY:
|
||||
CONS_Printf(M_GetText("has been kicked (Go away)\n"));
|
||||
kickreason = KR_KICK;
|
||||
break;
|
||||
#ifdef NEWPING
|
||||
case KICK_MSG_PING_HIGH:
|
||||
CONS_Printf(M_GetText("left the game (Broke ping limit)\n"));
|
||||
kickreason = KR_PINGLIMIT;
|
||||
break;
|
||||
#endif
|
||||
case KICK_MSG_CON_FAIL:
|
||||
CONS_Printf(M_GetText("left the game (Synch failure)\n"));
|
||||
kickreason = KR_SYNCH;
|
||||
|
||||
if (M_CheckParm("-consisdump")) // Helps debugging some problems
|
||||
{
|
||||
|
@ -2809,21 +2817,26 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
break;
|
||||
case KICK_MSG_TIMEOUT:
|
||||
CONS_Printf(M_GetText("left the game (Connection timeout)\n"));
|
||||
kickreason = KR_TIMEOUT;
|
||||
break;
|
||||
case KICK_MSG_PLAYER_QUIT:
|
||||
if (netgame) // not splitscreen/bots
|
||||
CONS_Printf(M_GetText("left the game\n"));
|
||||
kickreason = KR_LEAVE;
|
||||
break;
|
||||
case KICK_MSG_BANNED:
|
||||
CONS_Printf(M_GetText("has been banned (Don't come back)\n"));
|
||||
kickreason = KR_BAN;
|
||||
break;
|
||||
case KICK_MSG_CUSTOM_KICK:
|
||||
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
||||
CONS_Printf(M_GetText("has been kicked (%s)\n"), reason);
|
||||
kickreason = KR_KICK;
|
||||
break;
|
||||
case KICK_MSG_CUSTOM_BAN:
|
||||
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
|
||||
CONS_Printf(M_GetText("has been banned (%s)\n"), reason);
|
||||
kickreason = KR_BAN;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2851,7 +2864,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
}
|
||||
else
|
||||
CL_RemovePlayer(pnum);
|
||||
CL_RemovePlayer(pnum, kickreason);
|
||||
}
|
||||
|
||||
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
|
|
|
@ -454,6 +454,17 @@ extern consvar_t cv_playbackspeed;
|
|||
#define KICK_MSG_CUSTOM_KICK 7
|
||||
#define KICK_MSG_CUSTOM_BAN 8
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KR_KICK = 1, //Kicked by server
|
||||
KR_PINGLIMIT = 2, //Broke Ping Limit
|
||||
KR_SYNCH = 3, //Synch Failure
|
||||
KR_TIMEOUT = 4, //Connection Timeout
|
||||
KR_BAN = 5, //Banned by server
|
||||
KR_LEAVE = 6, //Quit the game
|
||||
|
||||
} kickreason_t;
|
||||
|
||||
extern boolean server;
|
||||
#define client (!server)
|
||||
extern boolean dedicated; // For dedicated server
|
||||
|
|
21
src/d_main.c
21
src/d_main.c
|
@ -71,6 +71,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
|||
#include "fastcmp.h"
|
||||
#include "keys.h"
|
||||
#include "filesrch.h" // refreshdirmenu, mainwadstally
|
||||
#include "g_input.h" // tutorial mode control scheming
|
||||
|
||||
#ifdef CMAKECONFIG
|
||||
#include "config.h"
|
||||
|
@ -151,7 +152,7 @@ void D_PostEvent(const event_t *ev)
|
|||
eventhead = (eventhead+1) & (MAXEVENTS-1);
|
||||
}
|
||||
// just for lock this function
|
||||
#ifndef DOXYGEN
|
||||
#if defined (PC_DOS) && !defined (DOXYGEN)
|
||||
void D_PostEvent_end(void) {};
|
||||
#endif
|
||||
|
||||
|
@ -424,6 +425,7 @@ static void D_Display(void)
|
|||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
ST_Drawer();
|
||||
F_TextPromptDrawer();
|
||||
HU_Drawer();
|
||||
}
|
||||
else
|
||||
|
@ -733,6 +735,19 @@ void D_StartTitle(void)
|
|||
// Reset the palette
|
||||
if (rendermode != render_none)
|
||||
V_SetPaletteLump("PLAYPAL");
|
||||
|
||||
// The title screen is obviously not a tutorial! (Unless I'm mistaken)
|
||||
if (tutorialmode && tutorialgcs)
|
||||
{
|
||||
G_CopyControls(gamecontrol, gamecontroldefault[gcs_custom], gcl_tutorial_full, num_gcl_tutorial_full); // using gcs_custom as temp storage
|
||||
CV_SetValue(&cv_usemouse, tutorialusemouse);
|
||||
CV_SetValue(&cv_alwaysfreelook, tutorialfreelook);
|
||||
CV_SetValue(&cv_mousemove, tutorialmousemove);
|
||||
CV_SetValue(&cv_analog, tutorialanalog);
|
||||
M_StartMessage("Do you want to \x82save the recommended \x82movement controls?\x80\n\nPress 'Y' or 'Enter' to confirm\nPress 'N' or any key to keep \nyour current controls",
|
||||
M_TutorialSaveControlResponse, MM_YESNO);
|
||||
}
|
||||
tutorialmode = false;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -766,10 +781,6 @@ static inline void D_CleanFile(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef _MAX_PATH
|
||||
#define _MAX_PATH MAX_WADPATH
|
||||
#endif
|
||||
|
||||
// ==========================================================================
|
||||
// Identify the SRB2 version, and IWAD file to use.
|
||||
// ==========================================================================
|
||||
|
|
|
@ -40,8 +40,8 @@ void D_SRB2Main(void);
|
|||
|
||||
// Called by IO functions when input is detected.
|
||||
void D_PostEvent(const event_t *ev);
|
||||
#ifndef DOXYGEN
|
||||
FUNCMATH void D_PostEvent_end(void); // delimiter for locking memory
|
||||
#if defined (PC_DOS) && !defined (DOXYGEN)
|
||||
void D_PostEvent_end(void); // delimiter for locking memory
|
||||
#endif
|
||||
|
||||
void D_ProcessEvents(void);
|
||||
|
|
117
src/d_netcmd.c
117
src/d_netcmd.c
|
@ -126,8 +126,6 @@ FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void);
|
|||
static void Command_Playintro_f(void);
|
||||
|
||||
static void Command_Displayplayer_f(void);
|
||||
static void Command_Tunes_f(void);
|
||||
static void Command_RestartAudio_f(void);
|
||||
|
||||
static void Command_ExitLevel_f(void);
|
||||
static void Command_Showmap_f(void);
|
||||
|
@ -315,8 +313,6 @@ consvar_t cv_timetic = {"timerres", "Classic", CV_SAVE, timetic_cons_t, NULL, 0,
|
|||
static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}};
|
||||
consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t,
|
||||
PointLimit_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -685,14 +681,6 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_ghost_guest);
|
||||
|
||||
COM_AddCommand("displayplayer", Command_Displayplayer_f);
|
||||
COM_AddCommand("tunes", Command_Tunes_f);
|
||||
COM_AddCommand("restartaudio", Command_RestartAudio_f);
|
||||
CV_RegisterVar(&cv_resetmusic);
|
||||
#ifdef HAVE_MIXERX
|
||||
CV_RegisterVar(&cv_midiplayer);
|
||||
CV_RegisterVar(&cv_midisoundfontpath);
|
||||
CV_RegisterVar(&cv_miditimiditypath);
|
||||
#endif
|
||||
|
||||
// FIXME: not to be here.. but needs be done for config loading
|
||||
CV_RegisterVar(&cv_globalgamma);
|
||||
|
@ -724,6 +712,7 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_crosshair2);
|
||||
CV_RegisterVar(&cv_alwaysfreelook);
|
||||
CV_RegisterVar(&cv_alwaysfreelook2);
|
||||
CV_RegisterVar(&cv_tutorialprompt);
|
||||
|
||||
// g_input.c
|
||||
CV_RegisterVar(&cv_sideaxis);
|
||||
|
@ -1820,6 +1809,16 @@ static void Command_Map_f(void)
|
|||
else
|
||||
fromlevelselect = ((netgame || multiplayer) && ((gametype == newgametype) && (newgametype == GT_COOP)));
|
||||
|
||||
if (tutorialmode && tutorialgcs)
|
||||
{
|
||||
G_CopyControls(gamecontrol, gamecontroldefault[gcs_custom], gcl_tutorial_full, num_gcl_tutorial_full); // using gcs_custom as temp storage
|
||||
CV_SetValue(&cv_usemouse, tutorialusemouse);
|
||||
CV_SetValue(&cv_alwaysfreelook, tutorialfreelook);
|
||||
CV_SetValue(&cv_mousemove, tutorialmousemove);
|
||||
CV_SetValue(&cv_analog, tutorialanalog);
|
||||
}
|
||||
tutorialmode = false; // warping takes us out of tutorial mode
|
||||
|
||||
D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect);
|
||||
}
|
||||
|
||||
|
@ -3992,100 +3991,6 @@ static void Command_Displayplayer_f(void)
|
|||
CONS_Printf(M_GetText("Displayplayer is %d\n"), displayplayer);
|
||||
}
|
||||
|
||||
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] [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"));
|
||||
CONS_Printf(M_GetText("* With \"-default\", returns to the default music for the map.\n"));
|
||||
CONS_Printf(M_GetText("* With \"-none\", any music playing will be stopped.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
tunearg = COM_Argv(1);
|
||||
tunenum = (UINT16)atoi(tunearg);
|
||||
track = 0;
|
||||
|
||||
if (!strcasecmp(tunearg, "-show"))
|
||||
{
|
||||
CONS_Printf(M_GetText("The current tune is: %s [track %d]\n"),
|
||||
mapmusname, (mapmusflags & MUSIC_TRACKMASK));
|
||||
return;
|
||||
}
|
||||
if (!strcasecmp(tunearg, "-none"))
|
||||
{
|
||||
S_StopMusic();
|
||||
return;
|
||||
}
|
||||
else if (!strcasecmp(tunearg, "-default"))
|
||||
{
|
||||
tunearg = mapheaderinfo[gamemap-1]->musname;
|
||||
track = mapheaderinfo[gamemap-1]->mustrack;
|
||||
}
|
||||
else if (!tunearg[2] && toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z')
|
||||
tunenum = (UINT16)M_MapNumber(tunearg[0], tunearg[1]);
|
||||
|
||||
if (tunenum && tunenum >= 1036)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Valid music slots are 1 to 1035.\n"));
|
||||
return;
|
||||
}
|
||||
if (!tunenum && strlen(tunearg) > 6) // This is automatic -- just show the error just in case
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n"));
|
||||
|
||||
if (argc > 2)
|
||||
track = (UINT16)atoi(COM_Argv(2))-1;
|
||||
|
||||
if (tunenum)
|
||||
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_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||
|
||||
if (argc > 3)
|
||||
{
|
||||
float speed = (float)atof(COM_Argv(3));
|
||||
if (speed > 0.0f)
|
||||
S_SpeedMusic(speed);
|
||||
}
|
||||
}
|
||||
|
||||
static void Command_RestartAudio_f(void)
|
||||
{
|
||||
if (dedicated) // No point in doing anything if game is a dedicated server.
|
||||
return;
|
||||
|
||||
S_StopMusic();
|
||||
S_StopSounds();
|
||||
I_ShutdownMusic();
|
||||
I_ShutdownSound();
|
||||
I_StartupSound();
|
||||
I_InitMusic();
|
||||
|
||||
// These must be called or no sound and music until manually set.
|
||||
|
||||
I_SetSfxVolume(cv_soundvolume.value);
|
||||
S_SetMusicVolume(cv_digmusicvolume.value, cv_midimusicvolume.value);
|
||||
if (Playing()) // Gotta make sure the player is in a level
|
||||
P_RestoreMusic(&players[consoleplayer]);
|
||||
}
|
||||
|
||||
/** Quits a game and returns to the title screen.
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -103,8 +103,6 @@ extern consvar_t cv_startinglives;
|
|||
// for F_finale.c
|
||||
extern consvar_t cv_rollingdemos;
|
||||
|
||||
extern consvar_t cv_resetmusic;
|
||||
|
||||
extern consvar_t cv_ringslinger, cv_soundtest;
|
||||
|
||||
extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes;
|
||||
|
@ -202,6 +200,4 @@ void D_SetPassword(const char *pw);
|
|||
// used for the player setup menu
|
||||
UINT8 CanChangeSkin(INT32 playernum);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
465
src/dehacked.c
465
src/dehacked.c
|
@ -32,6 +32,7 @@
|
|||
#include "fastcmp.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
#include "d_clisrv.h"
|
||||
|
||||
#include "m_cond.h"
|
||||
|
||||
|
@ -165,9 +166,14 @@ static char *myhashfgets(char *buf, size_t bufsize, MYFILE *f)
|
|||
if (c == '\n') // Ensure debug line is right...
|
||||
dbg_line++;
|
||||
if (c == '#')
|
||||
{
|
||||
if (i > 0) // don't let i wrap past 0
|
||||
i--; // don't include hash char in string
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
if (buf[i] != '#') // don't include hash char in string
|
||||
i++;
|
||||
buf[i] = '\0';
|
||||
|
||||
return buf;
|
||||
|
@ -914,7 +920,10 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -1551,6 +1560,365 @@ static void readcutscene(MYFILE *f, INT32 num)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum)
|
||||
{
|
||||
char *s = Z_Calloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
INT32 i;
|
||||
UINT16 usi;
|
||||
UINT8 picid;
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
if (fastcmp(word, "PAGETEXT"))
|
||||
{
|
||||
char *pagetext = NULL;
|
||||
char *buffer;
|
||||
const int bufferlen = 4096;
|
||||
|
||||
for (i = 0; i < MAXLINELEN; i++)
|
||||
{
|
||||
if (s[i] == '=')
|
||||
{
|
||||
pagetext = &s[i+2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pagetext)
|
||||
{
|
||||
Z_Free(textprompts[num]->page[pagenum].text);
|
||||
textprompts[num]->page[pagenum].text = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXLINELEN; i++)
|
||||
{
|
||||
if (s[i] == '\0')
|
||||
{
|
||||
s[i] = '\n';
|
||||
s[i+1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = Z_Malloc(4096, PU_STATIC, NULL);
|
||||
strcpy(buffer, pagetext);
|
||||
|
||||
// \todo trim trailing whitespace before the #
|
||||
// and also support # at the end of a PAGETEXT with no line break
|
||||
|
||||
strcat(buffer,
|
||||
myhashfgets(pagetext, bufferlen
|
||||
- strlen(buffer) - 1, f));
|
||||
|
||||
// A text prompt overwriting another one...
|
||||
Z_Free(textprompts[num]->page[pagenum].text);
|
||||
|
||||
textprompts[num]->page[pagenum].text = Z_StrDup(buffer);
|
||||
|
||||
Z_Free(buffer);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
word2 = strtok(NULL, " = ");
|
||||
if (word2)
|
||||
strupr(word2);
|
||||
else
|
||||
break;
|
||||
|
||||
if (word2[strlen(word2)-1] == '\n')
|
||||
word2[strlen(word2)-1] = '\0';
|
||||
i = atoi(word2);
|
||||
usi = (UINT16)i;
|
||||
|
||||
// copypasta from readcutscenescene
|
||||
if (fastcmp(word, "NUMBEROFPICS"))
|
||||
{
|
||||
textprompts[num]->page[pagenum].numpics = (UINT8)i;
|
||||
}
|
||||
else if (fastcmp(word, "PICMODE"))
|
||||
{
|
||||
UINT8 picmode = 0; // PROMPT_PIC_PERSIST
|
||||
if (usi == 1 || word2[0] == 'L') picmode = PROMPT_PIC_LOOP;
|
||||
else if (usi == 2 || word2[0] == 'D' || word2[0] == 'H') picmode = PROMPT_PIC_DESTROY;
|
||||
textprompts[num]->page[pagenum].picmode = picmode;
|
||||
}
|
||||
else if (fastcmp(word, "PICTOLOOP"))
|
||||
textprompts[num]->page[pagenum].pictoloop = (UINT8)i;
|
||||
else if (fastcmp(word, "PICTOSTART"))
|
||||
textprompts[num]->page[pagenum].pictostart = (UINT8)i;
|
||||
else if (fastcmp(word, "PICSMETAPAGE"))
|
||||
{
|
||||
if (usi && usi <= textprompts[num]->numpages)
|
||||
{
|
||||
UINT8 metapagenum = usi - 1;
|
||||
|
||||
textprompts[num]->page[pagenum].numpics = textprompts[num]->page[metapagenum].numpics;
|
||||
textprompts[num]->page[pagenum].picmode = textprompts[num]->page[metapagenum].picmode;
|
||||
textprompts[num]->page[pagenum].pictoloop = textprompts[num]->page[metapagenum].pictoloop;
|
||||
textprompts[num]->page[pagenum].pictostart = textprompts[num]->page[metapagenum].pictostart;
|
||||
|
||||
for (picid = 0; picid < MAX_PROMPT_PICS; picid++)
|
||||
{
|
||||
strncpy(textprompts[num]->page[pagenum].picname[picid], textprompts[num]->page[metapagenum].picname[picid], 8);
|
||||
textprompts[num]->page[pagenum].pichires[picid] = textprompts[num]->page[metapagenum].pichires[picid];
|
||||
textprompts[num]->page[pagenum].picduration[picid] = textprompts[num]->page[metapagenum].picduration[picid];
|
||||
textprompts[num]->page[pagenum].xcoord[picid] = textprompts[num]->page[metapagenum].xcoord[picid];
|
||||
textprompts[num]->page[pagenum].ycoord[picid] = textprompts[num]->page[metapagenum].ycoord[picid];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fastncmp(word, "PIC", 3))
|
||||
{
|
||||
picid = (UINT8)atoi(word + 3);
|
||||
if (picid > MAX_PROMPT_PICS || picid == 0)
|
||||
{
|
||||
deh_warning("textpromptscene %d: unknown word '%s'", num, word);
|
||||
continue;
|
||||
}
|
||||
--picid;
|
||||
|
||||
if (fastcmp(word+4, "NAME"))
|
||||
{
|
||||
strncpy(textprompts[num]->page[pagenum].picname[picid], word2, 8);
|
||||
}
|
||||
else if (fastcmp(word+4, "HIRES"))
|
||||
{
|
||||
textprompts[num]->page[pagenum].pichires[picid] = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
else if (fastcmp(word+4, "DURATION"))
|
||||
{
|
||||
textprompts[num]->page[pagenum].picduration[picid] = usi;
|
||||
}
|
||||
else if (fastcmp(word+4, "XCOORD"))
|
||||
{
|
||||
textprompts[num]->page[pagenum].xcoord[picid] = usi;
|
||||
}
|
||||
else if (fastcmp(word+4, "YCOORD"))
|
||||
{
|
||||
textprompts[num]->page[pagenum].ycoord[picid] = usi;
|
||||
}
|
||||
else
|
||||
deh_warning("textpromptscene %d: unknown word '%s'", num, word);
|
||||
}
|
||||
else if (fastcmp(word, "MUSIC"))
|
||||
{
|
||||
strncpy(textprompts[num]->page[pagenum].musswitch, word2, 7);
|
||||
textprompts[num]->page[pagenum].musswitch[6] = 0;
|
||||
}
|
||||
#ifdef MUSICSLOT_COMPATIBILITY
|
||||
else if (fastcmp(word, "MUSICSLOT"))
|
||||
{
|
||||
i = get_mus(word2, true);
|
||||
if (i && i <= 1035)
|
||||
snprintf(textprompts[num]->page[pagenum].musswitch, 7, "%sM", G_BuildMapName(i));
|
||||
else if (i && i <= 1050)
|
||||
strncpy(textprompts[num]->page[pagenum].musswitch, compat_special_music_slots[i - 1036], 7);
|
||||
else
|
||||
textprompts[num]->page[pagenum].musswitch[0] = 0; // becomes empty string
|
||||
textprompts[num]->page[pagenum].musswitch[6] = 0;
|
||||
}
|
||||
#endif
|
||||
else if (fastcmp(word, "MUSICTRACK"))
|
||||
{
|
||||
textprompts[num]->page[pagenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK;
|
||||
}
|
||||
else if (fastcmp(word, "MUSICLOOP"))
|
||||
{
|
||||
textprompts[num]->page[pagenum].musicloop = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
}
|
||||
// end copypasta from readcutscenescene
|
||||
else if (fastcmp(word, "NAME"))
|
||||
{
|
||||
INT32 j;
|
||||
|
||||
// HACK: Add yellow control char now
|
||||
// so the drawing function doesn't call it repeatedly
|
||||
char name[34];
|
||||
name[0] = '\x82'; // color yellow
|
||||
name[1] = 0;
|
||||
strncat(name, word2, 33);
|
||||
name[33] = 0;
|
||||
|
||||
// Replace _ with ' '
|
||||
for (j = 0; j < 32 && name[j]; j++)
|
||||
{
|
||||
if (name[j] == '_')
|
||||
name[j] = ' ';
|
||||
}
|
||||
|
||||
strncpy(textprompts[num]->page[pagenum].name, name, 32);
|
||||
}
|
||||
else if (fastcmp(word, "ICON"))
|
||||
strncpy(textprompts[num]->page[pagenum].iconname, word2, 8);
|
||||
else if (fastcmp(word, "ICONALIGN"))
|
||||
textprompts[num]->page[pagenum].rightside = (i || word2[0] == 'R');
|
||||
else if (fastcmp(word, "ICONFLIP"))
|
||||
textprompts[num]->page[pagenum].iconflip = (i || word2[0] == 'T' || word2[0] == 'Y');
|
||||
else if (fastcmp(word, "LINES"))
|
||||
textprompts[num]->page[pagenum].lines = usi;
|
||||
else if (fastcmp(word, "BACKCOLOR"))
|
||||
{
|
||||
INT32 backcolor;
|
||||
if (i == 0 || fastcmp(word2, "WHITE")) backcolor = 0;
|
||||
else if (i == 1 || fastcmp(word2, "GRAY") || fastcmp(word2, "GREY") ||
|
||||
fastcmp(word2, "BLACK")) backcolor = 1;
|
||||
else if (i == 2 || fastcmp(word2, "BROWN")) backcolor = 2;
|
||||
else if (i == 3 || fastcmp(word2, "RED")) backcolor = 3;
|
||||
else if (i == 4 || fastcmp(word2, "ORANGE")) backcolor = 4;
|
||||
else if (i == 5 || fastcmp(word2, "YELLOW")) backcolor = 5;
|
||||
else if (i == 6 || fastcmp(word2, "GREEN")) backcolor = 6;
|
||||
else if (i == 7 || fastcmp(word2, "BLUE")) backcolor = 7;
|
||||
else if (i == 8 || fastcmp(word2, "PURPLE")) backcolor = 8;
|
||||
else if (i == 9 || fastcmp(word2, "MAGENTA")) backcolor = 9;
|
||||
else if (i == 10 || fastcmp(word2, "AQUA")) backcolor = 10;
|
||||
else if (i < 0) backcolor = INT32_MAX; // CONS_BACKCOLOR user-configured
|
||||
else backcolor = 1; // default gray
|
||||
textprompts[num]->page[pagenum].backcolor = backcolor;
|
||||
}
|
||||
else if (fastcmp(word, "ALIGN"))
|
||||
{
|
||||
UINT8 align = 0; // left
|
||||
if (usi == 1 || word2[0] == 'R') align = 1;
|
||||
else if (usi == 2 || word2[0] == 'C' || word2[0] == 'M') align = 2;
|
||||
textprompts[num]->page[pagenum].align = align;
|
||||
}
|
||||
else if (fastcmp(word, "VERTICALALIGN"))
|
||||
{
|
||||
UINT8 align = 0; // top
|
||||
if (usi == 1 || word2[0] == 'B') align = 1;
|
||||
else if (usi == 2 || word2[0] == 'C' || word2[0] == 'M') align = 2;
|
||||
textprompts[num]->page[pagenum].verticalalign = align;
|
||||
}
|
||||
else if (fastcmp(word, "TEXTSPEED"))
|
||||
textprompts[num]->page[pagenum].textspeed = get_number(word2);
|
||||
else if (fastcmp(word, "TEXTSFX"))
|
||||
textprompts[num]->page[pagenum].textsfx = get_number(word2);
|
||||
else if (fastcmp(word, "HIDEHUD"))
|
||||
{
|
||||
UINT8 hidehud = 0;
|
||||
if ((word2[0] == 'F' && (word2[1] == 'A' || !word2[1])) || word2[0] == 'N') hidehud = 0; // false
|
||||
else if (usi == 1 || word2[0] == 'T' || word2[0] == 'Y') hidehud = 1; // true (hide appropriate HUD elements)
|
||||
else if (usi == 2 || word2[0] == 'A' || (word2[0] == 'F' && word2[1] == 'O')) hidehud = 2; // force (hide all HUD elements)
|
||||
textprompts[num]->page[pagenum].hidehud = hidehud;
|
||||
}
|
||||
else if (fastcmp(word, "METAPAGE"))
|
||||
{
|
||||
if (usi && usi <= textprompts[num]->numpages)
|
||||
{
|
||||
UINT8 metapagenum = usi - 1;
|
||||
|
||||
strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[metapagenum].name, 32);
|
||||
strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[metapagenum].iconname, 8);
|
||||
textprompts[num]->page[pagenum].rightside = textprompts[num]->page[metapagenum].rightside;
|
||||
textprompts[num]->page[pagenum].iconflip = textprompts[num]->page[metapagenum].iconflip;
|
||||
textprompts[num]->page[pagenum].lines = textprompts[num]->page[metapagenum].lines;
|
||||
textprompts[num]->page[pagenum].backcolor = textprompts[num]->page[metapagenum].backcolor;
|
||||
textprompts[num]->page[pagenum].align = textprompts[num]->page[metapagenum].align;
|
||||
textprompts[num]->page[pagenum].verticalalign = textprompts[num]->page[metapagenum].verticalalign;
|
||||
textprompts[num]->page[pagenum].textspeed = textprompts[num]->page[metapagenum].textspeed;
|
||||
textprompts[num]->page[pagenum].textsfx = textprompts[num]->page[metapagenum].textsfx;
|
||||
textprompts[num]->page[pagenum].hidehud = textprompts[num]->page[metapagenum].hidehud;
|
||||
|
||||
// music: don't copy, else each page change may reset the music
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "TAG"))
|
||||
strncpy(textprompts[num]->page[pagenum].tag, word2, 33);
|
||||
else if (fastcmp(word, "NEXTPROMPT"))
|
||||
textprompts[num]->page[pagenum].nextprompt = usi;
|
||||
else if (fastcmp(word, "NEXTPAGE"))
|
||||
textprompts[num]->page[pagenum].nextpage = usi;
|
||||
else if (fastcmp(word, "NEXTTAG"))
|
||||
strncpy(textprompts[num]->page[pagenum].nexttag, word2, 33);
|
||||
else if (fastcmp(word, "TIMETONEXT"))
|
||||
textprompts[num]->page[pagenum].timetonext = get_number(word2);
|
||||
else
|
||||
deh_warning("PromptPage %d: unknown word '%s'", num, word);
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readtextprompt(MYFILE *f, INT32 num)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
char *tmp;
|
||||
INT32 value;
|
||||
|
||||
// Allocate memory for this prompt if we don't yet have any
|
||||
if (!textprompts[num])
|
||||
textprompts[num] = Z_Calloc(sizeof (textprompt_t), PU_STATIC, NULL);
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
if (s == tmp)
|
||||
continue; // Skip comment lines, but don't break.
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
word2 = strtok(NULL, " ");
|
||||
if (word2)
|
||||
value = atoi(word2);
|
||||
else
|
||||
{
|
||||
deh_warning("No value for token %s", word);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fastcmp(word, "NUMPAGES"))
|
||||
{
|
||||
textprompts[num]->numpages = min(max(value, 0), MAX_PAGES);
|
||||
}
|
||||
else if (fastcmp(word, "PAGE"))
|
||||
{
|
||||
if (1 <= value && value <= MAX_PAGES)
|
||||
{
|
||||
textprompts[num]->page[value - 1].backcolor = 1; // default to gray
|
||||
textprompts[num]->page[value - 1].hidehud = 1; // hide appropriate HUD elements
|
||||
readtextpromptpage(f, num, value - 1);
|
||||
}
|
||||
else
|
||||
deh_warning("Page number %d out of range (1 - %d)", value, MAX_PAGES);
|
||||
|
||||
}
|
||||
else
|
||||
deh_warning("Prompt %d: unknown word '%s', Page <num> expected.", num, word);
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readhuditem(MYFILE *f, INT32 num)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
|
@ -1579,7 +1947,10 @@ static void readhuditem(MYFILE *f, INT32 num)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -2085,7 +2456,10 @@ static void reademblemdata(MYFILE *f, INT32 num)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -2220,7 +2594,10 @@ static void readextraemblemdata(MYFILE *f, INT32 num)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -2295,7 +2672,10 @@ static void readunlockable(MYFILE *f, INT32 num)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -2582,7 +2962,10 @@ static void readconditionset(MYFILE *f, UINT8 setnum)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -2643,7 +3026,10 @@ static void readmaincfg(MYFILE *f)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -2876,6 +3262,19 @@ static void readmaincfg(MYFILE *f)
|
|||
startchar = (INT16)value;
|
||||
char_on = -1;
|
||||
}
|
||||
else if (fastcmp(word, "TUTORIALMAP"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = M_MapNumber(word2[0], word2[1]);
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
tutorialmap = (INT16)value;
|
||||
}
|
||||
else
|
||||
deh_warning("Maincfg: unknown word '%s'", word);
|
||||
}
|
||||
|
@ -2914,7 +3313,10 @@ static void readwipes(MYFILE *f)
|
|||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
*(tmp-1) = '\0';
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
|
@ -3220,6 +3622,16 @@ static void DEH_LoadDehackedFile(MYFILE *f)
|
|||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "PROMPT"))
|
||||
{
|
||||
if (i > 0 && i < MAX_PROMPTS)
|
||||
readtextprompt(f, i - 1);
|
||||
else
|
||||
{
|
||||
deh_warning("Prompt number %d out of range (1 - %d)", i, MAX_PROMPTS);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
|
@ -6943,6 +7355,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_PULL",
|
||||
"MT_GHOST",
|
||||
"MT_OVERLAY",
|
||||
"MT_ANGLEMAN",
|
||||
"MT_POLYANCHOR",
|
||||
"MT_POLYSPAWN",
|
||||
"MT_POLYSPAWNCRUSH",
|
||||
|
@ -7754,6 +8167,13 @@ struct {
|
|||
// Node flags
|
||||
{"NF_SUBSECTOR",NF_SUBSECTOR}, // Indicate a leaf.
|
||||
#endif
|
||||
#ifdef ESLOPE
|
||||
// Slope flags
|
||||
{"SL_NOPHYSICS",SL_NOPHYSICS}, // Don't do momentum adjustment with this slope
|
||||
{"SL_NODYNAMIC",SL_NODYNAMIC}, // Slope will never need to move during the level, so don't fuss with recalculating it
|
||||
{"SL_ANCHORVERTEX",SL_ANCHORVERTEX},// Slope is using a Slope Vertex Thing to anchor its position
|
||||
{"SL_VERTEXSLOPE",SL_VERTEXSLOPE}, // Slope is built from three Slope Vertex Things
|
||||
#endif
|
||||
|
||||
// Angles
|
||||
{"ANG1",ANG1},
|
||||
|
@ -7886,6 +8306,14 @@ struct {
|
|||
|
||||
{"V_CHARCOLORSHIFT",V_CHARCOLORSHIFT},
|
||||
{"V_ALPHASHIFT",V_ALPHASHIFT},
|
||||
|
||||
//Kick Reasons
|
||||
{"KR_KICK",KR_KICK},
|
||||
{"KR_PINGLIMIT",KR_PINGLIMIT},
|
||||
{"KR_SYNCH",KR_SYNCH},
|
||||
{"KR_TIMEOUT",KR_TIMEOUT},
|
||||
{"KR_BAN",KR_BAN},
|
||||
{"KR_LEAVE",KR_LEAVE},
|
||||
#endif
|
||||
|
||||
{NULL,0}
|
||||
|
@ -8274,7 +8702,7 @@ fixed_t get_number(const char *word)
|
|||
#endif
|
||||
}
|
||||
|
||||
void FUNCMATH DEH_Check(void)
|
||||
void DEH_Check(void)
|
||||
{
|
||||
#if defined(_DEBUG) || defined(PARANOIA)
|
||||
const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*);
|
||||
|
@ -8750,6 +9178,9 @@ static inline int lib_getenum(lua_State *L)
|
|||
} else if (fastcmp(word,"maptol")) {
|
||||
lua_pushinteger(L, maptol);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"ultimatemode")) {
|
||||
lua_pushboolean(L, ultimatemode != 0);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"mariomode")) {
|
||||
lua_pushboolean(L, mariomode != 0);
|
||||
return 1;
|
||||
|
@ -8879,17 +9310,17 @@ static int lib_getActionName(lua_State *L)
|
|||
{
|
||||
lua_settop(L, 1); // set top of stack to 1 (removing any extra args, which there shouldn't be)
|
||||
// get the name for this action, if possible.
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS);
|
||||
lua_pushnil(gL);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS);
|
||||
lua_pushnil(L);
|
||||
// Lua stack at this point:
|
||||
// 1 ... -2 -1
|
||||
// arg ... LREG_ACTIONS nil
|
||||
while (lua_next(gL, -2))
|
||||
while (lua_next(L, -2))
|
||||
{
|
||||
// Lua stack at this point:
|
||||
// 1 ... -3 -2 -1
|
||||
// arg ... LREG_ACTIONS "A_ACTION" function
|
||||
if (lua_rawequal(gL, -1, 1)) // is this the same as the arg?
|
||||
if (lua_rawequal(L, -1, 1)) // is this the same as the arg?
|
||||
{
|
||||
// make sure the key (i.e. "A_ACTION") is a string first
|
||||
// (note: we don't use lua_isstring because it also returns true for numbers)
|
||||
|
@ -8898,12 +9329,12 @@ static int lib_getActionName(lua_State *L)
|
|||
lua_pushvalue(L, -2); // push "A_ACTION" string to top of stack
|
||||
return 1;
|
||||
}
|
||||
lua_pop(gL, 2); // pop the name and function
|
||||
lua_pop(L, 2); // pop the name and function
|
||||
break; // probably should have succeeded but we didn't, so end the loop
|
||||
}
|
||||
lua_pop(gL, 1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(gL, 1); // pop LREG_ACTIONS
|
||||
lua_pop(L, 1); // pop LREG_ACTIONS
|
||||
return 0; // return nothing (don't error)
|
||||
}
|
||||
|
||||
|
|
|
@ -156,9 +156,11 @@ INT32 I_StartSound ( sfxenum_t id,
|
|||
INT32 vol,
|
||||
INT32 sep,
|
||||
INT32 pitch,
|
||||
INT32 priority )
|
||||
INT32 priority,
|
||||
INT32 channel)
|
||||
{
|
||||
int voice;
|
||||
(void)channel;
|
||||
|
||||
if (sound_disabled)
|
||||
return 0;
|
||||
|
@ -548,6 +550,7 @@ void I_ResumeSong (INT32 handle)
|
|||
songpaused = false;
|
||||
}
|
||||
|
||||
|
||||
void I_SetMusicVolume(INT32 volume)
|
||||
{
|
||||
if (midi_disabled)
|
||||
|
@ -563,18 +566,6 @@ boolean I_SetSongTrack(INT32 track)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Is the song playing?
|
||||
#if 0
|
||||
int I_QrySongPlaying(int handle)
|
||||
{
|
||||
if (midi_disabled)
|
||||
return 0;
|
||||
|
||||
//return islooping || musicdies > gametic;
|
||||
return (midi_pos==-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// ------------------------
|
||||
// MUSIC FADING
|
||||
/// ------------------------
|
||||
|
@ -614,4 +605,14 @@ boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
|||
(void)ms;
|
||||
(void)looping;
|
||||
return false;
|
||||
// Is the song playing?
|
||||
#if 0
|
||||
int I_QrySongPlaying(int handle)
|
||||
{
|
||||
if (midi_disabled)
|
||||
return 0;
|
||||
|
||||
//return islooping || musicdies > gametic;
|
||||
return (midi_pos==-1);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -573,4 +573,11 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
/// \note Required for proper collision with moving sloped surfaces that have sector specials on them.
|
||||
#define SECTORSPECIALSAFTERTHINK
|
||||
|
||||
/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up
|
||||
/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down)
|
||||
/// on the bright side it fixes some weird issues with translucent walls
|
||||
/// \note SRB2CB port.
|
||||
/// SRB2CB itself ported this from PrBoom+
|
||||
#define NEWCLIP
|
||||
|
||||
#endif // __DOOMDEF__
|
||||
|
|
|
@ -131,6 +131,14 @@ extern INT16 titlemap;
|
|||
extern boolean hidetitlepics;
|
||||
extern INT16 bootmap; //bootmap for loading a map on startup
|
||||
|
||||
extern INT16 tutorialmap; // map to load for tutorial
|
||||
extern boolean tutorialmode; // are we in a tutorial right now?
|
||||
extern INT32 tutorialgcs; // which control scheme is loaded?
|
||||
extern INT32 tutorialusemouse; // store cv_usemouse user value
|
||||
extern INT32 tutorialfreelook; // store cv_alwaysfreelook user value
|
||||
extern INT32 tutorialmousemove; // store cv_mousemove user value
|
||||
extern INT32 tutorialanalog; // store cv_analog user value
|
||||
|
||||
extern boolean looptitle;
|
||||
|
||||
// CTF colors.
|
||||
|
@ -169,6 +177,60 @@ typedef struct
|
|||
|
||||
extern cutscene_t *cutscenes[128];
|
||||
|
||||
// Reserve prompt space for tutorials
|
||||
#define TUTORIAL_PROMPT 201 // one-based
|
||||
#define TUTORIAL_AREAS 6
|
||||
#define TUTORIAL_AREA_PROMPTS 5
|
||||
#define MAX_PROMPTS (TUTORIAL_PROMPT+TUTORIAL_AREAS*TUTORIAL_AREA_PROMPTS*3) // 3 control modes
|
||||
#define MAX_PAGES 128
|
||||
|
||||
#define PROMPT_PIC_PERSIST 0
|
||||
#define PROMPT_PIC_LOOP 1
|
||||
#define PROMPT_PIC_DESTROY 2
|
||||
#define MAX_PROMPT_PICS 8
|
||||
typedef struct
|
||||
{
|
||||
UINT8 numpics;
|
||||
UINT8 picmode; // sequence mode after displaying last pic, 0 = persist, 1 = loop, 2 = destroy
|
||||
UINT8 pictoloop; // if picmode == loop, which pic to loop to?
|
||||
UINT8 pictostart; // initial pic number to show
|
||||
char picname[MAX_PROMPT_PICS][8];
|
||||
UINT8 pichires[MAX_PROMPT_PICS];
|
||||
UINT16 xcoord[MAX_PROMPT_PICS]; // gfx
|
||||
UINT16 ycoord[MAX_PROMPT_PICS]; // gfx
|
||||
UINT16 picduration[MAX_PROMPT_PICS];
|
||||
|
||||
char musswitch[7];
|
||||
UINT16 musswitchflags;
|
||||
UINT8 musicloop;
|
||||
|
||||
char tag[33]; // page tag
|
||||
char name[34]; // narrator name, extra char for color
|
||||
char iconname[8]; // narrator icon lump
|
||||
boolean rightside; // narrator side, false = left, true = right
|
||||
boolean iconflip; // narrator flip icon horizontally
|
||||
UINT8 hidehud; // hide hud, 0 = show all, 1 = hide depending on prompt position (top/bottom), 2 = hide all
|
||||
UINT8 lines; // # of lines to show. If name is specified, name takes one of the lines. If 0, defaults to 4.
|
||||
INT32 backcolor; // see CON_SetupBackColormap: 0-11, INT32_MAX for user-defined (CONS_BACKCOLOR)
|
||||
UINT8 align; // text alignment, 0 = left, 1 = right, 2 = center
|
||||
UINT8 verticalalign; // vertical text alignment, 0 = top, 1 = bottom, 2 = middle
|
||||
UINT8 textspeed; // text speed, delay in tics between characters.
|
||||
sfxenum_t textsfx; // sfx_ id for printing text
|
||||
UINT8 nextprompt; // next prompt to jump to, one-based. 0 = current prompt
|
||||
UINT8 nextpage; // next page to jump to, one-based. 0 = next page within prompt->numpages
|
||||
char nexttag[33]; // next tag to jump to. If set, this overrides nextprompt and nextpage.
|
||||
INT32 timetonext; // time in tics to jump to next page automatically. 0 = don't jump automatically
|
||||
char *text;
|
||||
} textpage_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
textpage_t page[MAX_PAGES];
|
||||
INT32 numpages; // Number of pages in this prompt
|
||||
} textprompt_t;
|
||||
|
||||
extern textprompt_t *textprompts[MAX_PROMPTS];
|
||||
|
||||
// For the Custom Exit linedef.
|
||||
extern INT16 nextmapoverride;
|
||||
extern boolean skipstats;
|
||||
|
|
196
src/doomtype.h
196
src/doomtype.h
|
@ -40,12 +40,13 @@
|
|||
typedef long ssize_t;
|
||||
|
||||
/* Older Visual C++ headers don't have the Win64-compatible typedefs... */
|
||||
#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR)))
|
||||
#define DWORD_PTR DWORD
|
||||
#endif
|
||||
|
||||
#if ((_MSC_VER <= 1200) && (!defined(PDWORD_PTR)))
|
||||
#define PDWORD_PTR PDWORD
|
||||
#if (_MSC_VER <= 1200)
|
||||
#ifndef DWORD_PTR
|
||||
#define DWORD_PTR DWORD
|
||||
#endif
|
||||
#ifndef PDWORD_PTR
|
||||
#define PDWORD_PTR PDWORD
|
||||
#endif
|
||||
#endif
|
||||
#elif defined (__DJGPP__)
|
||||
#define UINT8 unsigned char
|
||||
|
@ -80,11 +81,13 @@ typedef long ssize_t;
|
|||
#define NOIPX
|
||||
#endif
|
||||
|
||||
/* Strings and some misc platform specific stuff */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Microsoft VisualC++
|
||||
#if (_MSC_VER <= 1800) // MSVC 2013 and back
|
||||
#define snprintf _snprintf
|
||||
#if (_MSC_VER <= 1200) // MSVC 2012 and back
|
||||
#if (_MSC_VER <= 1200) // MSVC 6.0 and back
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#endif
|
||||
|
@ -148,6 +151,8 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
|
|||
// not the number of bytes in the buffer.
|
||||
#define STRBUFCPY(dst,src) strlcpy(dst, src, sizeof dst)
|
||||
|
||||
/* Boolean type definition */
|
||||
|
||||
// \note __BYTEBOOL__ used to be set above if "macintosh" was defined,
|
||||
// if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now?
|
||||
#ifndef __BYTEBOOL__
|
||||
|
@ -155,7 +160,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
|
|||
|
||||
//faB: clean that up !!
|
||||
#if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward
|
||||
#include "stdbool.h"
|
||||
#include "stdbool.h"
|
||||
#elif defined (_WIN32)
|
||||
#define false FALSE // use windows types
|
||||
#define true TRUE
|
||||
|
@ -205,89 +210,65 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
|
|||
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
|
||||
#endif
|
||||
|
||||
union FColorRGBA
|
||||
{
|
||||
UINT32 rgba;
|
||||
struct
|
||||
{
|
||||
UINT8 red;
|
||||
UINT8 green;
|
||||
UINT8 blue;
|
||||
UINT8 alpha;
|
||||
} s;
|
||||
} ATTRPACK;
|
||||
typedef union FColorRGBA RGBA_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
postimg_none,
|
||||
postimg_water,
|
||||
postimg_motion,
|
||||
postimg_flip,
|
||||
postimg_heat
|
||||
} postimg_t;
|
||||
|
||||
typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
|
||||
#define LUMPERROR UINT32_MAX
|
||||
|
||||
typedef UINT32 tic_t;
|
||||
#define INFTICS UINT32_MAX
|
||||
|
||||
#ifdef _BIG_ENDIAN
|
||||
#define UINT2RGBA(a) a
|
||||
#else
|
||||
#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24)
|
||||
#endif
|
||||
/* Compiler-specific attributes and other macros */
|
||||
|
||||
#ifdef __GNUC__ // __attribute__ ((X))
|
||||
#define FUNCNORETURN __attribute__ ((noreturn))
|
||||
#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && defined (__MINGW32__)
|
||||
#include "inttypes.h"
|
||||
#if 0 //defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO > 0
|
||||
#define FUNCPRINTF __attribute__ ((format(gnu_printf, 1, 2)))
|
||||
#define FUNCDEBUG __attribute__ ((format(gnu_printf, 2, 3)))
|
||||
#define FUNCIERROR __attribute__ ((format(gnu_printf, 1, 2),noreturn))
|
||||
#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
|
||||
#define FUNCPRINTF __attribute__ ((format(ms_printf, 1, 2)))
|
||||
#define FUNCDEBUG __attribute__ ((format(ms_printf, 2, 3)))
|
||||
#define FUNCIERROR __attribute__ ((format(ms_printf, 1, 2),noreturn))
|
||||
#else
|
||||
#define FUNCPRINTF __attribute__ ((format(printf, 1, 2)))
|
||||
#define FUNCDEBUG __attribute__ ((format(printf, 2, 3)))
|
||||
#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn))
|
||||
#endif
|
||||
#else
|
||||
#define FUNCPRINTF __attribute__ ((format(printf, 1, 2)))
|
||||
#define FUNCDEBUG __attribute__ ((format(printf, 2, 3)))
|
||||
#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn))
|
||||
#endif
|
||||
#ifndef FUNCIERROR
|
||||
#define FUNCIERROR __attribute__ ((noreturn))
|
||||
#endif
|
||||
#define FUNCMATH __attribute__((const))
|
||||
#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
|
||||
#define FUNCDEAD __attribute__ ((deprecated))
|
||||
#define FUNCINLINE __attribute__((always_inline))
|
||||
#define FUNCNONNULL __attribute__((nonnull))
|
||||
#endif
|
||||
#define FUNCNOINLINE __attribute__((noinline))
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
|
||||
#ifdef __i386__ // i386 only
|
||||
#define FUNCTARGET(X) __attribute__ ((__target__ (X)))
|
||||
#endif
|
||||
#endif
|
||||
#if defined (__MINGW32__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
|
||||
#define ATTRPACK __attribute__((packed, gcc_struct))
|
||||
#else
|
||||
#define ATTRPACK __attribute__((packed))
|
||||
#endif
|
||||
#define ATTRUNUSED __attribute__((unused))
|
||||
#define FUNCNORETURN __attribute__ ((noreturn))
|
||||
|
||||
#if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && defined (__MINGW32__) // MinGW, >= GCC 4.1
|
||||
#include "inttypes.h"
|
||||
#if 0 //defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO > 0
|
||||
#define FUNCPRINTF __attribute__ ((format(gnu_printf, 1, 2)))
|
||||
#define FUNCDEBUG __attribute__ ((format(gnu_printf, 2, 3)))
|
||||
#define FUNCIERROR __attribute__ ((format(gnu_printf, 1, 2),noreturn))
|
||||
#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4
|
||||
#define FUNCPRINTF __attribute__ ((format(ms_printf, 1, 2)))
|
||||
#define FUNCDEBUG __attribute__ ((format(ms_printf, 2, 3)))
|
||||
#define FUNCIERROR __attribute__ ((format(ms_printf, 1, 2),noreturn))
|
||||
#else
|
||||
#define FUNCPRINTF __attribute__ ((format(printf, 1, 2)))
|
||||
#define FUNCDEBUG __attribute__ ((format(printf, 2, 3)))
|
||||
#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn))
|
||||
#endif
|
||||
#else
|
||||
#define FUNCPRINTF __attribute__ ((format(printf, 1, 2)))
|
||||
#define FUNCDEBUG __attribute__ ((format(printf, 2, 3)))
|
||||
#define FUNCIERROR __attribute__ ((format(printf, 1, 2),noreturn))
|
||||
#endif
|
||||
|
||||
#ifndef FUNCIERROR
|
||||
#define FUNCIERROR __attribute__ ((noreturn))
|
||||
#endif
|
||||
|
||||
#define FUNCMATH __attribute__((const))
|
||||
|
||||
#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) // >= GCC 3.1
|
||||
#define FUNCDEAD __attribute__ ((deprecated))
|
||||
#define FUNCINLINE __attribute__((always_inline))
|
||||
#define FUNCNONNULL __attribute__((nonnull))
|
||||
#endif
|
||||
|
||||
#define FUNCNOINLINE __attribute__((noinline))
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) // >= GCC 4.4
|
||||
#ifdef __i386__ // i386 only
|
||||
#define FUNCTARGET(X) __attribute__ ((__target__ (X)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (__MINGW32__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) // MinGW, >= GCC 3.4
|
||||
#define ATTRPACK __attribute__((packed, gcc_struct))
|
||||
#else
|
||||
#define ATTRPACK __attribute__((packed))
|
||||
#endif
|
||||
|
||||
#define ATTRUNUSED __attribute__((unused))
|
||||
#elif defined (_MSC_VER)
|
||||
#define ATTRNORETURN __declspec(noreturn)
|
||||
#define ATTRINLINE __forceinline
|
||||
#if _MSC_VER > 1200
|
||||
#define ATTRNOINLINE __declspec(noinline)
|
||||
#endif
|
||||
#define ATTRNORETURN __declspec(noreturn)
|
||||
#define ATTRINLINE __forceinline
|
||||
#if _MSC_VER > 1200 // >= MSVC 6.0
|
||||
#define ATTRNOINLINE __declspec(noinline)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FUNCPRINTF
|
||||
|
@ -335,4 +316,43 @@ typedef UINT32 tic_t;
|
|||
#ifndef ATTRNOINLINE
|
||||
#define ATTRNOINLINE
|
||||
#endif
|
||||
|
||||
/* Miscellaneous types that don't fit anywhere else (Can this be changed?) */
|
||||
|
||||
union FColorRGBA
|
||||
{
|
||||
UINT32 rgba;
|
||||
struct
|
||||
{
|
||||
UINT8 red;
|
||||
UINT8 green;
|
||||
UINT8 blue;
|
||||
UINT8 alpha;
|
||||
} s;
|
||||
} ATTRPACK;
|
||||
typedef union FColorRGBA RGBA_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
postimg_none,
|
||||
postimg_water,
|
||||
postimg_motion,
|
||||
postimg_flip,
|
||||
postimg_heat
|
||||
} postimg_t;
|
||||
|
||||
typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
|
||||
#define LUMPERROR UINT32_MAX
|
||||
|
||||
typedef UINT32 tic_t;
|
||||
#define INFTICS UINT32_MAX
|
||||
|
||||
#include "endian.h" // This is needed to make sure the below macro acts correctly in big endian builds
|
||||
|
||||
#ifdef SRB2_BIG_ENDIAN
|
||||
#define UINT2RGBA(a) a
|
||||
#else
|
||||
#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24)
|
||||
#endif
|
||||
|
||||
#endif //__DOOMTYPE__
|
||||
|
|
|
@ -23,13 +23,14 @@ void I_UpdateSound(void){};
|
|||
// SFX I/O
|
||||
//
|
||||
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
|
||||
{
|
||||
(void)id;
|
||||
(void)vol;
|
||||
(void)sep;
|
||||
(void)pitch;
|
||||
(void)priority;
|
||||
(void)channel;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -144,13 +145,13 @@ void I_UnloadSong(void)
|
|||
boolean I_PlaySong(boolean looping)
|
||||
{
|
||||
(void)handle;
|
||||
(void)looping;
|
||||
return false;
|
||||
}
|
||||
|
||||
void I_StopSong(void)
|
||||
{
|
||||
(void)handle;
|
||||
(void)looping;
|
||||
return false;
|
||||
}
|
||||
|
||||
void I_PauseSong(void)
|
||||
|
@ -180,7 +181,7 @@ boolean I_SetSongTrack(int track)
|
|||
|
||||
void I_SetInternalMusicVolume(UINT8 volume)
|
||||
{
|
||||
(void)volume;
|
||||
(void)handle;
|
||||
}
|
||||
|
||||
void I_StopFadingSong(void)
|
||||
|
|
632
src/f_finale.c
632
src/f_finale.c
|
@ -33,6 +33,8 @@
|
|||
#include "m_cond.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "st_stuff.h" // hud hiding
|
||||
#include "fastcmp.h"
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
#include "lua_hud.h"
|
||||
|
@ -48,6 +50,7 @@ static INT32 timetonext; // Delay between screen changes
|
|||
static INT32 continuetime; // Short delay when continuing
|
||||
|
||||
static tic_t animtimer; // Used for some animation timings
|
||||
static INT16 skullAnimCounter; // Chevron animation
|
||||
static INT32 roidtics; // Asteroid spinning
|
||||
|
||||
static INT32 deplete;
|
||||
|
@ -78,6 +81,18 @@ static patch_t *ttspop7;
|
|||
|
||||
static void F_SkyScroll(INT32 scrollspeed);
|
||||
|
||||
//
|
||||
// PROMPT STATE
|
||||
//
|
||||
static boolean promptactive = false;
|
||||
static mobj_t *promptmo;
|
||||
static INT16 promptpostexectag;
|
||||
static boolean promptblockcontrols;
|
||||
static char *promptpagetext = NULL;
|
||||
static INT32 callpromptnum = INT32_MAX;
|
||||
static INT32 callpagenum = INT32_MAX;
|
||||
static INT32 callplayer = INT32_MAX;
|
||||
|
||||
//
|
||||
// CUTSCENE TEXT WRITING
|
||||
//
|
||||
|
@ -1414,6 +1429,7 @@ void F_StartGameEnd(void)
|
|||
//
|
||||
void F_GameEndDrawer(void)
|
||||
{
|
||||
// this function does nothing
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1808,7 +1824,7 @@ boolean F_ContinueResponder(event_t *event)
|
|||
// CUSTOM CUTSCENES
|
||||
// ==================
|
||||
static INT32 scenenum, cutnum;
|
||||
static INT32 picxpos, picypos, picnum, pictime;
|
||||
static INT32 picxpos, picypos, picnum, pictime, picmode, numpics, pictoloop;
|
||||
static INT32 textxpos, textypos;
|
||||
static boolean dofadenow = false, cutsceneover = false;
|
||||
static boolean runningprecutscene = false, precutresetplayer = false;
|
||||
|
@ -2017,3 +2033,617 @@ boolean F_CutsceneResponder(event_t *event)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ==================
|
||||
// TEXT PROMPTS
|
||||
// ==================
|
||||
|
||||
static void F_GetPageTextGeometry(UINT8 *pagelines, boolean *rightside, INT32 *boxh, INT32 *texth, INT32 *texty, INT32 *namey, INT32 *chevrony, INT32 *textx, INT32 *textr)
|
||||
{
|
||||
// reuse:
|
||||
// cutnum -> promptnum
|
||||
// scenenum -> pagenum
|
||||
lumpnum_t iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname);
|
||||
|
||||
*pagelines = textprompts[cutnum]->page[scenenum].lines ? textprompts[cutnum]->page[scenenum].lines : 4;
|
||||
*rightside = (iconlump != LUMPERROR && textprompts[cutnum]->page[scenenum].rightside);
|
||||
|
||||
// Vertical calculations
|
||||
*boxh = *pagelines*2;
|
||||
*texth = textprompts[cutnum]->page[scenenum].name[0] ? (*pagelines-1)*2 : *pagelines*2; // name takes up first line if it exists
|
||||
*texty = BASEVIDHEIGHT - ((*texth * 4) + (*texth/2)*4);
|
||||
*namey = BASEVIDHEIGHT - ((*boxh * 4) + (*boxh/2)*4);
|
||||
*chevrony = BASEVIDHEIGHT - (((1*2) * 4) + ((1*2)/2)*4); // force on last line
|
||||
|
||||
// Horizontal calculations
|
||||
// Shift text to the right if we have a character icon on the left side
|
||||
// Add 4 margin against icon
|
||||
*textx = (iconlump != LUMPERROR && !*rightside) ? ((*boxh * 4) + (*boxh/2)*4) + 4 : 4;
|
||||
*textr = *rightside ? BASEVIDWIDTH - (((*boxh * 4) + (*boxh/2)*4) + 4) : BASEVIDWIDTH-4;
|
||||
}
|
||||
|
||||
static fixed_t F_GetPromptHideHudBound(void)
|
||||
{
|
||||
UINT8 pagelines;
|
||||
boolean rightside;
|
||||
INT32 boxh, texth, texty, namey, chevrony;
|
||||
INT32 textx, textr;
|
||||
|
||||
if (cutnum == INT32_MAX || scenenum == INT32_MAX || !textprompts[cutnum] || scenenum >= textprompts[cutnum]->numpages ||
|
||||
!textprompts[cutnum]->page[scenenum].hidehud ||
|
||||
(splitscreen && textprompts[cutnum]->page[scenenum].hidehud != 2)) // don't hide on splitscreen, unless hide all is forced
|
||||
return 0;
|
||||
else if (textprompts[cutnum]->page[scenenum].hidehud == 2) // hide all
|
||||
return BASEVIDHEIGHT;
|
||||
|
||||
F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr);
|
||||
|
||||
// calc boxheight (see V_DrawPromptBack)
|
||||
boxh *= vid.dupy;
|
||||
boxh = (boxh * 4) + (boxh/2)*5; // 4 lines of space plus gaps between and some leeway
|
||||
|
||||
// return a coordinate to check
|
||||
// if negative: don't show hud elements below this coordinate (visually)
|
||||
// if positive: don't show hud elements above this coordinate (visually)
|
||||
return 0 - boxh; // \todo: if prompt at top of screen (someday), make this return positive
|
||||
}
|
||||
|
||||
boolean F_GetPromptHideHudAll(void)
|
||||
{
|
||||
if (cutnum == INT32_MAX || scenenum == INT32_MAX || !textprompts[cutnum] || scenenum >= textprompts[cutnum]->numpages ||
|
||||
!textprompts[cutnum]->page[scenenum].hidehud ||
|
||||
(splitscreen && textprompts[cutnum]->page[scenenum].hidehud != 2)) // don't hide on splitscreen, unless hide all is forced
|
||||
return false;
|
||||
else if (textprompts[cutnum]->page[scenenum].hidehud == 2) // hide all
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean F_GetPromptHideHud(fixed_t y)
|
||||
{
|
||||
INT32 ybound;
|
||||
boolean fromtop;
|
||||
fixed_t ytest;
|
||||
|
||||
if (!promptactive)
|
||||
return false;
|
||||
|
||||
ybound = F_GetPromptHideHudBound();
|
||||
fromtop = (ybound >= 0);
|
||||
ytest = (fromtop ? ybound : BASEVIDHEIGHT + ybound);
|
||||
|
||||
return (fromtop ? y < ytest : y >= ytest); // true means hide
|
||||
}
|
||||
|
||||
static void F_PreparePageText(char *pagetext)
|
||||
{
|
||||
UINT8 pagelines;
|
||||
boolean rightside;
|
||||
INT32 boxh, texth, texty, namey, chevrony;
|
||||
INT32 textx, textr;
|
||||
|
||||
F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr);
|
||||
|
||||
if (promptpagetext)
|
||||
Z_Free(promptpagetext);
|
||||
promptpagetext = (pagetext && pagetext[0]) ? V_WordWrap(textx, textr, 0, pagetext) : Z_StrDup("");
|
||||
|
||||
F_NewCutscene(promptpagetext);
|
||||
cutscene_textspeed = textprompts[cutnum]->page[scenenum].textspeed ? textprompts[cutnum]->page[scenenum].textspeed : TICRATE/5;
|
||||
cutscene_textcount = 0; // no delay in beginning
|
||||
cutscene_boostspeed = 0; // don't print 8 characters to start
|
||||
|
||||
// \todo update control hot strings on re-config
|
||||
// and somehow don't reset cutscene text counters
|
||||
}
|
||||
|
||||
static void F_AdvanceToNextPage(void)
|
||||
{
|
||||
INT32 nextprompt = textprompts[cutnum]->page[scenenum].nextprompt ? textprompts[cutnum]->page[scenenum].nextprompt - 1 : INT32_MAX,
|
||||
nextpage = textprompts[cutnum]->page[scenenum].nextpage ? textprompts[cutnum]->page[scenenum].nextpage - 1 : INT32_MAX,
|
||||
oldcutnum = cutnum;
|
||||
|
||||
if (textprompts[cutnum]->page[scenenum].nexttag[0])
|
||||
F_GetPromptPageByNamedTag(textprompts[cutnum]->page[scenenum].nexttag, &nextprompt, &nextpage);
|
||||
|
||||
// determine next prompt
|
||||
if (nextprompt != INT32_MAX)
|
||||
{
|
||||
if (nextprompt <= MAX_PROMPTS && textprompts[nextprompt])
|
||||
cutnum = nextprompt;
|
||||
else
|
||||
cutnum = INT32_MAX;
|
||||
}
|
||||
|
||||
// determine next page
|
||||
if (nextpage != INT32_MAX)
|
||||
{
|
||||
if (cutnum != INT32_MAX)
|
||||
{
|
||||
scenenum = nextpage;
|
||||
if (scenenum >= MAX_PAGES || scenenum > textprompts[cutnum]->numpages-1)
|
||||
scenenum = INT32_MAX;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cutnum != oldcutnum)
|
||||
scenenum = 0;
|
||||
else if (scenenum + 1 < MAX_PAGES && scenenum < textprompts[cutnum]->numpages-1)
|
||||
scenenum++;
|
||||
else
|
||||
scenenum = INT32_MAX;
|
||||
}
|
||||
|
||||
// close the prompt if either num is invalid
|
||||
if (cutnum == INT32_MAX || scenenum == INT32_MAX)
|
||||
F_EndTextPrompt(false, false);
|
||||
else
|
||||
{
|
||||
// on page mode, number of tics before allowing boost
|
||||
// on timer mode, number of tics until page advances
|
||||
timetonext = textprompts[cutnum]->page[scenenum].timetonext ? textprompts[cutnum]->page[scenenum].timetonext : TICRATE/10;
|
||||
F_PreparePageText(textprompts[cutnum]->page[scenenum].text);
|
||||
|
||||
// gfx
|
||||
picnum = textprompts[cutnum]->page[scenenum].pictostart;
|
||||
numpics = textprompts[cutnum]->page[scenenum].numpics;
|
||||
picmode = textprompts[cutnum]->page[scenenum].picmode;
|
||||
pictoloop = textprompts[cutnum]->page[scenenum].pictoloop > 0 ? textprompts[cutnum]->page[scenenum].pictoloop - 1 : 0;
|
||||
picxpos = textprompts[cutnum]->page[scenenum].xcoord[picnum];
|
||||
picypos = textprompts[cutnum]->page[scenenum].ycoord[picnum];
|
||||
animtimer = pictime = textprompts[cutnum]->page[scenenum].picduration[picnum];
|
||||
|
||||
// music change
|
||||
if (textprompts[cutnum]->page[scenenum].musswitch[0])
|
||||
S_ChangeMusic(textprompts[cutnum]->page[scenenum].musswitch,
|
||||
textprompts[cutnum]->page[scenenum].musswitchflags,
|
||||
textprompts[cutnum]->page[scenenum].musicloop);
|
||||
}
|
||||
}
|
||||
|
||||
void F_EndTextPrompt(boolean forceexec, boolean noexec)
|
||||
{
|
||||
boolean promptwasactive = promptactive;
|
||||
promptactive = false;
|
||||
callpromptnum = callpagenum = callplayer = INT32_MAX;
|
||||
|
||||
if (promptwasactive)
|
||||
{
|
||||
if (promptmo && promptmo->player && promptblockcontrols)
|
||||
promptmo->reactiontime = TICRATE/4; // prevent jumping right away // \todo account freeze realtime for this)
|
||||
// \todo reset frozen realtime?
|
||||
}
|
||||
|
||||
// \todo net safety, maybe loop all player thinkers?
|
||||
if ((promptwasactive || forceexec) && !noexec && promptpostexectag)
|
||||
{
|
||||
if (tmthing) // edge case where starting an invalid prompt immediately on level load will make P_MapStart fail
|
||||
P_LinedefExecute(promptpostexectag, promptmo, NULL);
|
||||
else
|
||||
{
|
||||
P_MapStart();
|
||||
P_LinedefExecute(promptpostexectag, promptmo, NULL);
|
||||
P_MapEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
// if splitscreen and we already have a prompt active, ignore.
|
||||
// \todo Proper per-player splitscreen support (individual prompts)
|
||||
if (promptactive && splitscreen && promptnum == callpromptnum && pagenum == callpagenum)
|
||||
return;
|
||||
|
||||
// \todo proper netgame support
|
||||
if (netgame)
|
||||
{
|
||||
F_EndTextPrompt(true, false); // run the post-effects immediately
|
||||
return;
|
||||
}
|
||||
|
||||
// We share vars, so no starting text prompts over cutscenes or title screens!
|
||||
keypressed = false;
|
||||
finalecount = 0;
|
||||
timetonext = 0;
|
||||
animtimer = 0;
|
||||
stoptimer = 0;
|
||||
skullAnimCounter = 0;
|
||||
|
||||
// Set up state
|
||||
promptmo = mo;
|
||||
promptpostexectag = postexectag;
|
||||
promptblockcontrols = blockcontrols;
|
||||
(void)freezerealtime; // \todo freeze player->realtime, maybe this needs to cycle through player thinkers
|
||||
|
||||
// Initialize current prompt and scene
|
||||
callpromptnum = promptnum;
|
||||
callpagenum = pagenum;
|
||||
cutnum = (promptnum < MAX_PROMPTS && textprompts[promptnum]) ? promptnum : INT32_MAX;
|
||||
scenenum = (cutnum != INT32_MAX && pagenum < MAX_PAGES && pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX;
|
||||
promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX);
|
||||
|
||||
if (promptactive)
|
||||
{
|
||||
// on page mode, number of tics before allowing boost
|
||||
// on timer mode, number of tics until page advances
|
||||
timetonext = textprompts[cutnum]->page[scenenum].timetonext ? textprompts[cutnum]->page[scenenum].timetonext : TICRATE/10;
|
||||
F_PreparePageText(textprompts[cutnum]->page[scenenum].text);
|
||||
|
||||
// gfx
|
||||
picnum = textprompts[cutnum]->page[scenenum].pictostart;
|
||||
numpics = textprompts[cutnum]->page[scenenum].numpics;
|
||||
picmode = textprompts[cutnum]->page[scenenum].picmode;
|
||||
pictoloop = textprompts[cutnum]->page[scenenum].pictoloop > 0 ? textprompts[cutnum]->page[scenenum].pictoloop - 1 : 0;
|
||||
picxpos = textprompts[cutnum]->page[scenenum].xcoord[picnum];
|
||||
picypos = textprompts[cutnum]->page[scenenum].ycoord[picnum];
|
||||
animtimer = pictime = textprompts[cutnum]->page[scenenum].picduration[picnum];
|
||||
|
||||
// music change
|
||||
if (textprompts[cutnum]->page[scenenum].musswitch[0])
|
||||
S_ChangeMusic(textprompts[cutnum]->page[scenenum].musswitch,
|
||||
textprompts[cutnum]->page[scenenum].musswitchflags,
|
||||
textprompts[cutnum]->page[scenenum].musicloop);
|
||||
|
||||
// get the calling player
|
||||
if (promptblockcontrols && mo && mo->player)
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (players[i].mo == mo)
|
||||
{
|
||||
callplayer = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
F_EndTextPrompt(true, false); // run the post-effects immediately
|
||||
}
|
||||
|
||||
static boolean F_GetTextPromptTutorialTag(char *tag, INT32 length)
|
||||
{
|
||||
INT32 gcs = gcs_custom;
|
||||
boolean suffixed = true;
|
||||
|
||||
if (!tag || !tag[0] || !tutorialmode)
|
||||
return false;
|
||||
|
||||
if (!strncmp(tag, "TAM", 3)) // Movement
|
||||
gcs = G_GetControlScheme(gamecontrol, gcl_movement, num_gcl_movement);
|
||||
else if (!strncmp(tag, "TAC", 3)) // Camera
|
||||
{
|
||||
// Check for gcl_movement so we can differentiate between FPS and Platform schemes.
|
||||
gcs = G_GetControlScheme(gamecontrol, gcl_movement, num_gcl_movement);
|
||||
if (gcs == gcs_custom) // try again, maybe we'll get a match
|
||||
gcs = G_GetControlScheme(gamecontrol, gcl_camera, num_gcl_camera);
|
||||
if (gcs == gcs_fps && !cv_usemouse.value)
|
||||
gcs = gcs_platform; // Platform (arrow) scheme is stand-in for no mouse
|
||||
}
|
||||
else if (!strncmp(tag, "TAD", 3)) // Movement and Camera
|
||||
gcs = G_GetControlScheme(gamecontrol, gcl_movement_camera, num_gcl_movement_camera);
|
||||
else if (!strncmp(tag, "TAJ", 3)) // Jump
|
||||
gcs = G_GetControlScheme(gamecontrol, gcl_jump, num_gcl_jump);
|
||||
else if (!strncmp(tag, "TAS", 3)) // Spin
|
||||
gcs = G_GetControlScheme(gamecontrol, gcl_use, num_gcl_use);
|
||||
else if (!strncmp(tag, "TAA", 3)) // Char ability
|
||||
gcs = G_GetControlScheme(gamecontrol, gcl_jump, num_gcl_jump);
|
||||
else if (!strncmp(tag, "TAW", 3)) // Shield ability
|
||||
gcs = G_GetControlScheme(gamecontrol, gcl_jump_use, num_gcl_jump_use);
|
||||
else
|
||||
gcs = G_GetControlScheme(gamecontrol, gcl_tutorial_used, num_gcl_tutorial_used);
|
||||
|
||||
switch (gcs)
|
||||
{
|
||||
case gcs_fps:
|
||||
// strncat(tag, "FPS", length);
|
||||
suffixed = false;
|
||||
break;
|
||||
|
||||
case gcs_platform:
|
||||
strncat(tag, "PLATFORM", length);
|
||||
break;
|
||||
|
||||
default:
|
||||
strncat(tag, "CUSTOM", length);
|
||||
break;
|
||||
}
|
||||
|
||||
return suffixed;
|
||||
}
|
||||
|
||||
void F_GetPromptPageByNamedTag(const char *tag, INT32 *promptnum, INT32 *pagenum)
|
||||
{
|
||||
INT32 nosuffixpromptnum = INT32_MAX, nosuffixpagenum = INT32_MAX;
|
||||
INT32 tutorialpromptnum = (tutorialmode) ? TUTORIAL_PROMPT-1 : 0;
|
||||
boolean suffixed = false, found = false;
|
||||
char suffixedtag[33];
|
||||
|
||||
*promptnum = *pagenum = INT32_MAX;
|
||||
|
||||
if (!tag || !tag[0])
|
||||
return;
|
||||
|
||||
strncpy(suffixedtag, tag, 33);
|
||||
suffixedtag[32] = 0;
|
||||
|
||||
if (tutorialmode)
|
||||
suffixed = F_GetTextPromptTutorialTag(suffixedtag, 33);
|
||||
|
||||
for (*promptnum = 0 + tutorialpromptnum; *promptnum < MAX_PROMPTS; (*promptnum)++)
|
||||
{
|
||||
if (!textprompts[*promptnum])
|
||||
continue;
|
||||
|
||||
for (*pagenum = 0; *pagenum < textprompts[*promptnum]->numpages && *pagenum < MAX_PAGES; (*pagenum)++)
|
||||
{
|
||||
if (suffixed && fastcmp(suffixedtag, textprompts[*promptnum]->page[*pagenum].tag))
|
||||
{
|
||||
// this goes first because fastcmp ends early if first string is shorter
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
else if (nosuffixpromptnum == INT32_MAX && nosuffixpagenum == INT32_MAX && fastcmp(tag, textprompts[*promptnum]->page[*pagenum].tag))
|
||||
{
|
||||
if (suffixed)
|
||||
{
|
||||
nosuffixpromptnum = *promptnum;
|
||||
nosuffixpagenum = *pagenum;
|
||||
// continue searching for the suffixed tag
|
||||
}
|
||||
else
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (suffixed && !found && nosuffixpromptnum != INT32_MAX && nosuffixpagenum != INT32_MAX)
|
||||
{
|
||||
found = true;
|
||||
*promptnum = nosuffixpromptnum;
|
||||
*pagenum = nosuffixpagenum;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
CONS_Debug(DBG_GAMELOGIC, "Text prompt: Can't find a page with named tag %s or suffixed tag %s\n", tag, suffixedtag);
|
||||
}
|
||||
|
||||
void F_TextPromptDrawer(void)
|
||||
{
|
||||
// reuse:
|
||||
// cutnum -> promptnum
|
||||
// scenenum -> pagenum
|
||||
lumpnum_t iconlump;
|
||||
UINT8 pagelines;
|
||||
boolean rightside;
|
||||
INT32 boxh, texth, texty, namey, chevrony;
|
||||
INT32 textx, textr;
|
||||
|
||||
// Data
|
||||
patch_t *patch;
|
||||
|
||||
if (!promptactive)
|
||||
return;
|
||||
|
||||
iconlump = W_CheckNumForName(textprompts[cutnum]->page[scenenum].iconname);
|
||||
F_GetPageTextGeometry(&pagelines, &rightside, &boxh, &texth, &texty, &namey, &chevrony, &textx, &textr);
|
||||
|
||||
// Draw gfx first
|
||||
if (picnum >= 0 && picnum < numpics && textprompts[cutnum]->page[scenenum].picname[picnum][0] != '\0')
|
||||
{
|
||||
if (textprompts[cutnum]->page[scenenum].pichires[picnum])
|
||||
V_DrawSmallScaledPatch(picxpos, picypos, 0,
|
||||
W_CachePatchName(textprompts[cutnum]->page[scenenum].picname[picnum], PU_CACHE));
|
||||
else
|
||||
V_DrawScaledPatch(picxpos,picypos, 0,
|
||||
W_CachePatchName(textprompts[cutnum]->page[scenenum].picname[picnum], PU_CACHE));
|
||||
}
|
||||
|
||||
// Draw background
|
||||
V_DrawPromptBack(boxh, textprompts[cutnum]->page[scenenum].backcolor);
|
||||
|
||||
// Draw narrator icon
|
||||
if (iconlump != LUMPERROR)
|
||||
{
|
||||
INT32 iconx, icony, scale, scaledsize;
|
||||
patch = W_CachePatchName(textprompts[cutnum]->page[scenenum].iconname, PU_CACHE);
|
||||
|
||||
// scale and center
|
||||
if (patch->width > patch->height)
|
||||
{
|
||||
scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->width);
|
||||
scaledsize = FixedMul(patch->height, scale);
|
||||
iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS;
|
||||
icony = ((namey-4) << FRACBITS) + FixedDiv(BASEVIDHEIGHT - namey + 4 - scaledsize, 2); // account for 4 margin
|
||||
}
|
||||
else if (patch->height > patch->width)
|
||||
{
|
||||
scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->height);
|
||||
scaledsize = FixedMul(patch->width, scale);
|
||||
iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS;
|
||||
icony = namey << FRACBITS;
|
||||
iconx += FixedDiv(FixedMul(patch->height, scale) - scaledsize, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = FixedDiv(((boxh * 4) + (boxh/2)*4) - 4, patch->width);
|
||||
iconx = (rightside ? BASEVIDWIDTH - (((boxh * 4) + (boxh/2)*4)) : 4) << FRACBITS;
|
||||
icony = namey << FRACBITS;
|
||||
}
|
||||
|
||||
if (textprompts[cutnum]->page[scenenum].iconflip)
|
||||
iconx += FixedMul(patch->width, scale) << FRACBITS;
|
||||
|
||||
V_DrawFixedPatch(iconx, icony, scale, (V_SNAPTOBOTTOM|(textprompts[cutnum]->page[scenenum].iconflip ? V_FLIP : 0)), patch, NULL);
|
||||
W_UnlockCachedPatch(patch);
|
||||
}
|
||||
|
||||
// Draw text
|
||||
V_DrawString(textx, texty, (V_SNAPTOBOTTOM|V_ALLOWLOWERCASE), cutscene_disptext);
|
||||
|
||||
// Draw name
|
||||
// Don't use V_YELLOWMAP here so that the name color can be changed with control codes
|
||||
if (textprompts[cutnum]->page[scenenum].name[0])
|
||||
V_DrawString(textx, namey, (V_SNAPTOBOTTOM|V_ALLOWLOWERCASE), textprompts[cutnum]->page[scenenum].name);
|
||||
|
||||
// Draw chevron
|
||||
if (promptblockcontrols && !timetonext)
|
||||
V_DrawString(textr-8, chevrony + (skullAnimCounter/5), (V_SNAPTOBOTTOM|V_YELLOWMAP), "\x1B"); // down arrow
|
||||
}
|
||||
|
||||
void F_TextPromptTicker(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
if (!promptactive || paused || P_AutoPause())
|
||||
return;
|
||||
|
||||
// advance animation
|
||||
finalecount++;
|
||||
cutscene_boostspeed = 0;
|
||||
|
||||
// for the chevron
|
||||
if (--skullAnimCounter <= 0)
|
||||
skullAnimCounter = 8;
|
||||
|
||||
// button handling
|
||||
if (textprompts[cutnum]->page[scenenum].timetonext)
|
||||
{
|
||||
if (promptblockcontrols) // same procedure as below, just without the button handling
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (netgame && i != serverplayer && i != adminplayer)
|
||||
continue;
|
||||
else if (splitscreen) {
|
||||
// Both players' controls are locked,
|
||||
// But only consoleplayer can advance the prompt.
|
||||
// \todo Proper per-player splitscreen support (individual prompts)
|
||||
if (i == consoleplayer || i == secondarydisplayplayer)
|
||||
players[i].powers[pw_nocontrol] = 1;
|
||||
}
|
||||
else if (i == consoleplayer)
|
||||
players[i].powers[pw_nocontrol] = 1;
|
||||
|
||||
if (!splitscreen)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (timetonext >= 1)
|
||||
timetonext--;
|
||||
|
||||
if (!timetonext)
|
||||
F_AdvanceToNextPage();
|
||||
|
||||
F_WriteText();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (promptblockcontrols)
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (netgame && i != serverplayer && i != adminplayer)
|
||||
continue;
|
||||
else if (splitscreen) {
|
||||
// Both players' controls are locked,
|
||||
// But only the triggering player can advance the prompt.
|
||||
if (i == consoleplayer || i == secondarydisplayplayer)
|
||||
{
|
||||
players[i].powers[pw_nocontrol] = 1;
|
||||
|
||||
if (callplayer == consoleplayer || callplayer == secondarydisplayplayer)
|
||||
{
|
||||
if (i != callplayer)
|
||||
continue;
|
||||
}
|
||||
else if (i != consoleplayer)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else if (i == consoleplayer)
|
||||
players[i].powers[pw_nocontrol] = 1;
|
||||
else
|
||||
continue;
|
||||
|
||||
if ((players[i].cmd.buttons & BT_USE) || (players[i].cmd.buttons & BT_JUMP))
|
||||
{
|
||||
if (timetonext > 1)
|
||||
timetonext--;
|
||||
else if (cutscene_baseptr) // don't set boost if we just reset the string
|
||||
cutscene_boostspeed = 1; // only after a slight delay
|
||||
|
||||
if (keypressed)
|
||||
{
|
||||
if (!splitscreen)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!timetonext) // is 0 when finished generating text
|
||||
{
|
||||
F_AdvanceToNextPage();
|
||||
if (promptactive)
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
}
|
||||
keypressed = true; // prevent repeat events
|
||||
}
|
||||
else if (!(players[i].cmd.buttons & BT_USE) && !(players[i].cmd.buttons & BT_JUMP))
|
||||
keypressed = false;
|
||||
|
||||
if (!splitscreen)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// generate letter-by-letter text
|
||||
if (scenenum >= MAX_PAGES ||
|
||||
!textprompts[cutnum]->page[scenenum].text ||
|
||||
!textprompts[cutnum]->page[scenenum].text[0] ||
|
||||
!F_WriteText())
|
||||
timetonext = !promptblockcontrols; // never show the chevron if we can't toggle pages
|
||||
}
|
||||
|
||||
// gfx
|
||||
if (picnum >= 0 && picnum < numpics)
|
||||
{
|
||||
if (animtimer <= 0)
|
||||
{
|
||||
boolean persistanimtimer = false;
|
||||
|
||||
if (picnum < numpics-1 && textprompts[cutnum]->page[scenenum].picname[picnum+1][0] != '\0')
|
||||
picnum++;
|
||||
else if (picmode == PROMPT_PIC_LOOP)
|
||||
picnum = pictoloop;
|
||||
else if (picmode == PROMPT_PIC_DESTROY)
|
||||
picnum = -1;
|
||||
else // if (picmode == PROMPT_PIC_PERSIST)
|
||||
persistanimtimer = true;
|
||||
|
||||
if (!persistanimtimer && picnum >= 0)
|
||||
{
|
||||
picxpos = textprompts[cutnum]->page[scenenum].xcoord[picnum];
|
||||
picypos = textprompts[cutnum]->page[scenenum].ycoord[picnum];
|
||||
pictime = textprompts[cutnum]->page[scenenum].picduration[picnum];
|
||||
animtimer = pictime;
|
||||
}
|
||||
}
|
||||
else
|
||||
animtimer--;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "doomtype.h"
|
||||
#include "d_event.h"
|
||||
#include "p_mobj.h"
|
||||
|
||||
//
|
||||
// FINALE
|
||||
|
@ -33,9 +34,10 @@ void F_IntroTicker(void);
|
|||
void F_TitleScreenTicker(boolean run);
|
||||
void F_CutsceneTicker(void);
|
||||
void F_TitleDemoTicker(void);
|
||||
void F_TextPromptTicker(void);
|
||||
|
||||
// Called by main loop.
|
||||
FUNCMATH void F_GameEndDrawer(void);
|
||||
void F_GameEndDrawer(void);
|
||||
void F_IntroDrawer(void);
|
||||
void F_TitleScreenDrawer(void);
|
||||
|
||||
|
@ -50,6 +52,13 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
|||
void F_CutsceneDrawer(void);
|
||||
void F_EndCutScene(void);
|
||||
|
||||
void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postexectag, boolean blockcontrols, boolean freezerealtime);
|
||||
void F_GetPromptPageByNamedTag(const char *tag, INT32 *promptnum, INT32 *pagenum);
|
||||
void F_TextPromptDrawer(void);
|
||||
void F_EndTextPrompt(boolean forceexec, boolean noexec);
|
||||
boolean F_GetPromptHideHudAll(void);
|
||||
boolean F_GetPromptHideHud(fixed_t y);
|
||||
|
||||
void F_StartGameEnd(void);
|
||||
void F_StartIntro(void);
|
||||
void F_StartTitleScreen(void);
|
||||
|
|
10
src/g_game.c
10
src/g_game.c
|
@ -128,6 +128,14 @@ INT16 titlemap = 0;
|
|||
boolean hidetitlepics = false;
|
||||
INT16 bootmap; //bootmap for loading a map on startup
|
||||
|
||||
INT16 tutorialmap = 0; // map to load for tutorial
|
||||
boolean tutorialmode = false; // are we in a tutorial right now?
|
||||
INT32 tutorialgcs = gcs_custom; // which control scheme is loaded?
|
||||
INT32 tutorialusemouse = 0; // store cv_usemouse user value
|
||||
INT32 tutorialfreelook = 0; // store cv_alwaysfreelook user value
|
||||
INT32 tutorialmousemove = 0; // store cv_mousemove user value
|
||||
INT32 tutorialanalog = 0; // store cv_analog user value
|
||||
|
||||
boolean looptitle = false;
|
||||
|
||||
UINT8 skincolor_redteam = SKINCOLOR_RED;
|
||||
|
@ -139,6 +147,7 @@ tic_t countdowntimer = 0;
|
|||
boolean countdowntimeup = false;
|
||||
|
||||
cutscene_t *cutscenes[128];
|
||||
textprompt_t *textprompts[MAX_PROMPTS];
|
||||
|
||||
INT16 nextmapoverride;
|
||||
boolean skipstats;
|
||||
|
@ -1934,6 +1943,7 @@ void G_Ticker(boolean run)
|
|||
F_TitleDemoTicker();
|
||||
P_Ticker(run); // tic the game
|
||||
ST_Ticker();
|
||||
F_TextPromptTicker();
|
||||
AM_Ticker();
|
||||
HU_Ticker();
|
||||
break;
|
||||
|
|
|
@ -55,6 +55,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di
|
|||
extern INT16 rw_maximums[NUM_WEAPONS];
|
||||
|
||||
// used in game menu
|
||||
extern consvar_t cv_tutorialprompt;
|
||||
extern consvar_t cv_crosshair, cv_crosshair2;
|
||||
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove;
|
||||
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2;
|
||||
|
|
187
src/g_input.c
187
src/g_input.c
|
@ -45,6 +45,47 @@ UINT8 gamekeydown[NUMINPUTS];
|
|||
// two key codes (or virtual key) per game control
|
||||
INT32 gamecontrol[num_gamecontrols][2];
|
||||
INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player
|
||||
INT32 gamecontroldefault[num_gamecontrolschemes][num_gamecontrols][2]; // default control storage, use 0 (gcs_custom) for memory retention
|
||||
|
||||
// lists of GC codes for selective operation
|
||||
const INT32 gcl_tutorial_check[num_gcl_tutorial_check] = {
|
||||
gc_forward, gc_backward, gc_strafeleft, gc_straferight,
|
||||
gc_turnleft, gc_turnright
|
||||
};
|
||||
|
||||
const INT32 gcl_tutorial_used[num_gcl_tutorial_used] = {
|
||||
gc_forward, gc_backward, gc_strafeleft, gc_straferight,
|
||||
gc_turnleft, gc_turnright,
|
||||
gc_jump, gc_use
|
||||
};
|
||||
|
||||
const INT32 gcl_tutorial_full[num_gcl_tutorial_full] = {
|
||||
gc_forward, gc_backward, gc_strafeleft, gc_straferight,
|
||||
gc_lookup, gc_lookdown, gc_turnleft, gc_turnright, gc_centerview,
|
||||
gc_jump, gc_use,
|
||||
gc_fire, gc_firenormal
|
||||
};
|
||||
|
||||
const INT32 gcl_movement[num_gcl_movement] = {
|
||||
gc_forward, gc_backward, gc_strafeleft, gc_straferight
|
||||
};
|
||||
|
||||
const INT32 gcl_camera[num_gcl_camera] = {
|
||||
gc_turnleft, gc_turnright
|
||||
};
|
||||
|
||||
const INT32 gcl_movement_camera[num_gcl_movement_camera] = {
|
||||
gc_forward, gc_backward, gc_strafeleft, gc_straferight,
|
||||
gc_turnleft, gc_turnright
|
||||
};
|
||||
|
||||
const INT32 gcl_jump[num_gcl_jump] = { gc_jump };
|
||||
|
||||
const INT32 gcl_use[num_gcl_use] = { gc_use };
|
||||
|
||||
const INT32 gcl_jump_use[num_gcl_jump_use] = {
|
||||
gc_jump, gc_use
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -611,55 +652,117 @@ INT32 G_KeyStringtoNum(const char *keystr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void G_Controldefault(void)
|
||||
void G_DefineDefaultControls(void)
|
||||
{
|
||||
gamecontrol[gc_forward ][0] = 'w';
|
||||
gamecontrol[gc_backward ][0] = 's';
|
||||
gamecontrol[gc_strafeleft ][0] = 'a';
|
||||
gamecontrol[gc_straferight][0] = 'd';
|
||||
gamecontrol[gc_turnleft ][0] = KEY_LEFTARROW;
|
||||
gamecontrol[gc_turnright ][0] = KEY_RIGHTARROW;
|
||||
gamecontrol[gc_weaponnext ][0] = 'e';
|
||||
gamecontrol[gc_weaponprev ][0] = 'q';
|
||||
gamecontrol[gc_wepslot1 ][0] = '1';
|
||||
gamecontrol[gc_wepslot2 ][0] = '2';
|
||||
gamecontrol[gc_wepslot3 ][0] = '3';
|
||||
gamecontrol[gc_wepslot4 ][0] = '4';
|
||||
gamecontrol[gc_wepslot5 ][0] = '5';
|
||||
gamecontrol[gc_wepslot6 ][0] = '6';
|
||||
gamecontrol[gc_wepslot7 ][0] = '7';
|
||||
gamecontrol[gc_wepslot8 ][0] = '8';
|
||||
gamecontrol[gc_wepslot9 ][0] = '9';
|
||||
gamecontrol[gc_wepslot10 ][0] = '0';
|
||||
gamecontrol[gc_fire ][0] = KEY_RCTRL;
|
||||
gamecontrol[gc_fire ][1] = KEY_MOUSE1+0;
|
||||
gamecontrol[gc_firenormal ][0] = 'c';
|
||||
gamecontrol[gc_tossflag ][0] = '\'';
|
||||
gamecontrol[gc_use ][0] = KEY_LSHIFT;
|
||||
gamecontrol[gc_camtoggle ][0] = 'v';
|
||||
gamecontrol[gc_camreset ][0] = 'r';
|
||||
gamecontrol[gc_lookup ][0] = KEY_UPARROW;
|
||||
gamecontrol[gc_lookdown ][0] = KEY_DOWNARROW;
|
||||
gamecontrol[gc_centerview ][0] = KEY_END;
|
||||
gamecontrol[gc_talkkey ][0] = 't';
|
||||
gamecontrol[gc_teamkey ][0] = 'y';
|
||||
gamecontrol[gc_scores ][0] = KEY_TAB;
|
||||
gamecontrol[gc_jump ][0] = KEY_SPACE;
|
||||
gamecontrol[gc_console ][0] = KEY_CONSOLE;
|
||||
gamecontrol[gc_pause ][0] = KEY_PAUSE;
|
||||
INT32 i;
|
||||
|
||||
// FPS game controls (WASD)
|
||||
gamecontroldefault[gcs_fps][gc_forward ][0] = 'w';
|
||||
gamecontroldefault[gcs_fps][gc_backward ][0] = 's';
|
||||
gamecontroldefault[gcs_fps][gc_strafeleft ][0] = 'a';
|
||||
gamecontroldefault[gcs_fps][gc_straferight][0] = 'd';
|
||||
gamecontroldefault[gcs_fps][gc_lookup ][0] = KEY_UPARROW;
|
||||
gamecontroldefault[gcs_fps][gc_lookdown ][0] = KEY_DOWNARROW;
|
||||
gamecontroldefault[gcs_fps][gc_turnleft ][0] = KEY_LEFTARROW;
|
||||
gamecontroldefault[gcs_fps][gc_turnright ][0] = KEY_RIGHTARROW;
|
||||
gamecontroldefault[gcs_fps][gc_centerview ][0] = KEY_END;
|
||||
gamecontroldefault[gcs_fps][gc_jump ][0] = KEY_SPACE;
|
||||
gamecontroldefault[gcs_fps][gc_use ][0] = KEY_LSHIFT;
|
||||
gamecontroldefault[gcs_fps][gc_fire ][0] = KEY_RCTRL;
|
||||
gamecontroldefault[gcs_fps][gc_fire ][1] = KEY_MOUSE1+0;
|
||||
gamecontroldefault[gcs_fps][gc_firenormal ][0] = 'c';
|
||||
|
||||
// Platform game controls (arrow keys)
|
||||
gamecontroldefault[gcs_platform][gc_forward ][0] = KEY_UPARROW;
|
||||
gamecontroldefault[gcs_platform][gc_backward ][0] = KEY_DOWNARROW;
|
||||
gamecontroldefault[gcs_platform][gc_strafeleft ][0] = 'a';
|
||||
gamecontroldefault[gcs_platform][gc_straferight][0] = 'd';
|
||||
gamecontroldefault[gcs_platform][gc_lookup ][0] = KEY_PGUP;
|
||||
gamecontroldefault[gcs_platform][gc_lookdown ][0] = KEY_PGDN;
|
||||
gamecontroldefault[gcs_platform][gc_turnleft ][0] = KEY_LEFTARROW;
|
||||
gamecontroldefault[gcs_platform][gc_turnright ][0] = KEY_RIGHTARROW;
|
||||
gamecontroldefault[gcs_platform][gc_centerview ][0] = KEY_END;
|
||||
gamecontroldefault[gcs_platform][gc_jump ][0] = KEY_SPACE;
|
||||
gamecontroldefault[gcs_platform][gc_use ][0] = KEY_LSHIFT;
|
||||
gamecontroldefault[gcs_platform][gc_fire ][0] = 's';
|
||||
gamecontroldefault[gcs_platform][gc_fire ][1] = KEY_MOUSE1+0;
|
||||
gamecontroldefault[gcs_platform][gc_firenormal ][0] = 'w';
|
||||
|
||||
for (i = 1; i < num_gamecontrolschemes; i++) // skip gcs_custom (0)
|
||||
{
|
||||
gamecontroldefault[i][gc_weaponnext ][0] = 'e';
|
||||
gamecontroldefault[i][gc_weaponprev ][0] = 'q';
|
||||
gamecontroldefault[i][gc_wepslot1 ][0] = '1';
|
||||
gamecontroldefault[i][gc_wepslot2 ][0] = '2';
|
||||
gamecontroldefault[i][gc_wepslot3 ][0] = '3';
|
||||
gamecontroldefault[i][gc_wepslot4 ][0] = '4';
|
||||
gamecontroldefault[i][gc_wepslot5 ][0] = '5';
|
||||
gamecontroldefault[i][gc_wepslot6 ][0] = '6';
|
||||
gamecontroldefault[i][gc_wepslot7 ][0] = '7';
|
||||
gamecontroldefault[i][gc_wepslot8 ][0] = '8';
|
||||
gamecontroldefault[i][gc_wepslot9 ][0] = '9';
|
||||
gamecontroldefault[i][gc_wepslot10 ][0] = '0';
|
||||
gamecontroldefault[i][gc_tossflag ][0] = '\'';
|
||||
gamecontroldefault[i][gc_camtoggle ][0] = 'v';
|
||||
gamecontroldefault[i][gc_camreset ][0] = 'r';
|
||||
gamecontroldefault[i][gc_talkkey ][0] = 't';
|
||||
gamecontroldefault[i][gc_teamkey ][0] = 'y';
|
||||
gamecontroldefault[i][gc_scores ][0] = KEY_TAB;
|
||||
gamecontroldefault[i][gc_console ][0] = KEY_CONSOLE;
|
||||
gamecontroldefault[i][gc_pause ][0] = KEY_PAUSE;
|
||||
}
|
||||
}
|
||||
|
||||
void G_SaveKeySetting(FILE *f)
|
||||
INT32 G_GetControlScheme(INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen)
|
||||
{
|
||||
INT32 i, j, gc;
|
||||
boolean skipscheme;
|
||||
|
||||
for (i = 1; i < num_gamecontrolschemes; i++) // skip gcs_custom (0)
|
||||
{
|
||||
skipscheme = false;
|
||||
for (j = 0; j < (gclist && gclen ? gclen : num_gamecontrols); j++)
|
||||
{
|
||||
gc = (gclist && gclen) ? gclist[j] : j;
|
||||
if (((fromcontrols[gc][0] && gamecontroldefault[i][gc][0]) ? fromcontrols[gc][0] != gamecontroldefault[i][gc][0] : true) &&
|
||||
((fromcontrols[gc][0] && gamecontroldefault[i][gc][1]) ? fromcontrols[gc][0] != gamecontroldefault[i][gc][1] : true) &&
|
||||
((fromcontrols[gc][1] && gamecontroldefault[i][gc][0]) ? fromcontrols[gc][1] != gamecontroldefault[i][gc][0] : true) &&
|
||||
((fromcontrols[gc][1] && gamecontroldefault[i][gc][1]) ? fromcontrols[gc][1] != gamecontroldefault[i][gc][1] : true))
|
||||
{
|
||||
skipscheme = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!skipscheme)
|
||||
return i;
|
||||
}
|
||||
|
||||
return gcs_custom;
|
||||
}
|
||||
|
||||
void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen)
|
||||
{
|
||||
INT32 i, gc;
|
||||
|
||||
for (i = 0; i < (gclist && gclen ? gclen : num_gamecontrols); i++)
|
||||
{
|
||||
gc = (gclist && gclen) ? gclist[i] : i;
|
||||
setupcontrols[gc][0] = fromcontrols[gc][0];
|
||||
setupcontrols[gc][1] = fromcontrols[gc][1];
|
||||
}
|
||||
}
|
||||
|
||||
void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis)[2])
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 1; i < num_gamecontrols; i++)
|
||||
{
|
||||
fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i],
|
||||
G_KeynumToString(gamecontrol[i][0]));
|
||||
G_KeynumToString(fromcontrols[i][0]));
|
||||
|
||||
if (gamecontrol[i][1])
|
||||
fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrol[i][1]));
|
||||
if (fromcontrols[i][1])
|
||||
fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrols[i][1]));
|
||||
else
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
@ -667,10 +770,10 @@ void G_SaveKeySetting(FILE *f)
|
|||
for (i = 1; i < num_gamecontrols; i++)
|
||||
{
|
||||
fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i],
|
||||
G_KeynumToString(gamecontrolbis[i][0]));
|
||||
G_KeynumToString(fromcontrolsbis[i][0]));
|
||||
|
||||
if (gamecontrolbis[i][1])
|
||||
fprintf(f, " \"%s\"\n", G_KeynumToString(gamecontrolbis[i][1]));
|
||||
if (fromcontrolsbis[i][1])
|
||||
fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrolsbis[i][1]));
|
||||
else
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
|
|
@ -99,6 +99,14 @@ typedef enum
|
|||
num_gamecontrols
|
||||
} gamecontrols_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
gcs_custom,
|
||||
gcs_fps,
|
||||
gcs_platform,
|
||||
num_gamecontrolschemes
|
||||
} gamecontrolschemes_e;
|
||||
|
||||
// mouse values are used once
|
||||
extern consvar_t cv_mousesens, cv_mouseysens;
|
||||
extern consvar_t cv_mousesens2, cv_mouseysens2;
|
||||
|
@ -116,9 +124,30 @@ extern UINT8 gamekeydown[NUMINPUTS];
|
|||
// two key codes (or virtual key) per game control
|
||||
extern INT32 gamecontrol[num_gamecontrols][2];
|
||||
extern INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player
|
||||
extern INT32 gamecontroldefault[num_gamecontrolschemes][num_gamecontrols][2]; // default control storage, use 0 (gcs_custom) for memory retention
|
||||
#define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]])
|
||||
#define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]])
|
||||
|
||||
#define num_gcl_tutorial_check 6
|
||||
#define num_gcl_tutorial_used 8
|
||||
#define num_gcl_tutorial_full 13
|
||||
#define num_gcl_movement 4
|
||||
#define num_gcl_camera 2
|
||||
#define num_gcl_movement_camera 6
|
||||
#define num_gcl_jump 1
|
||||
#define num_gcl_use 1
|
||||
#define num_gcl_jump_use 2
|
||||
|
||||
extern const INT32 gcl_tutorial_check[num_gcl_tutorial_check];
|
||||
extern const INT32 gcl_tutorial_used[num_gcl_tutorial_used];
|
||||
extern const INT32 gcl_tutorial_full[num_gcl_tutorial_full];
|
||||
extern const INT32 gcl_movement[num_gcl_movement];
|
||||
extern const INT32 gcl_camera[num_gcl_camera];
|
||||
extern const INT32 gcl_movement_camera[num_gcl_movement_camera];
|
||||
extern const INT32 gcl_jump[num_gcl_jump];
|
||||
extern const INT32 gcl_use[num_gcl_use];
|
||||
extern const INT32 gcl_jump_use[num_gcl_jump_use];
|
||||
|
||||
// peace to my little coder fingers!
|
||||
// check a gamecontrol being active or not
|
||||
|
||||
|
@ -133,8 +162,10 @@ INT32 G_KeyStringtoNum(const char *keystr);
|
|||
void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control);
|
||||
void Command_Setcontrol_f(void);
|
||||
void Command_Setcontrol2_f(void);
|
||||
void G_Controldefault(void);
|
||||
void G_SaveKeySetting(FILE *f);
|
||||
void G_DefineDefaultControls(void);
|
||||
INT32 G_GetControlScheme(INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen);
|
||||
void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen);
|
||||
void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis)[2]);
|
||||
void G_CheckDoubleUsage(INT32 keynum);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -338,7 +338,7 @@ angle_t gld_FrustumAngle(void)
|
|||
}
|
||||
|
||||
// If the pitch is larger than this you can look all around at a FOV of 90
|
||||
if (aimingangle > (ANGLE_45+ANG1) && (ANGLE_315-ANG1) > aimingangle)
|
||||
if (abs((signed)aimingangle) > 46 * ANG1)
|
||||
return 0xffffffff;
|
||||
|
||||
// ok, this is a gross hack that barely works...
|
||||
|
|
|
@ -26,10 +26,6 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined (VID_X11) && !defined (HAVE_SDL)
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
|
||||
#include "../doomdef.h"
|
||||
//THIS MUST DISAPPEAR!!!
|
||||
#include "hw_glide.h"
|
||||
|
|
|
@ -114,10 +114,10 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option)
|
|||
if (option & V_NOSCALESTART)
|
||||
sdupx = sdupy = 2.0f;
|
||||
|
||||
v[0].x = v[3].x = (x*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1;
|
||||
v[2].x = v[1].x = (x*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1;
|
||||
v[0].y = v[1].y = 1-(y*sdupy-gpatch->topoffset*pdupy)/vid.height;
|
||||
v[2].y = v[3].y = 1-(y*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height;
|
||||
v[0].x = v[3].x = (x*sdupx-SHORT(gpatch->leftoffset)*pdupx)/vid.width - 1;
|
||||
v[2].x = v[1].x = (x*sdupx+(SHORT(gpatch->width)-SHORT(gpatch->leftoffset))*pdupx)/vid.width - 1;
|
||||
v[0].y = v[1].y = 1-(y*sdupy-SHORT(gpatch->topoffset)*pdupy)/vid.height;
|
||||
v[2].y = v[3].y = 1-(y*sdupy+(SHORT(gpatch->height)-SHORT(gpatch->topoffset))*pdupy)/vid.height;
|
||||
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
||||
|
||||
|
@ -183,18 +183,29 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
dupx = dupy = (dupx < dupy ? dupx : dupy);
|
||||
fscalew = fscaleh = FIXED_TO_FLOAT(pscale);
|
||||
|
||||
if (option & V_OFFSET)
|
||||
// See my comments in v_video.c's V_DrawFixedPatch
|
||||
// -- Monster Iestyn 29/10/18
|
||||
{
|
||||
cx -= (float)gpatch->leftoffset * dupx * fscalew;
|
||||
cy -= (float)gpatch->topoffset * dupy * fscaleh;
|
||||
}
|
||||
else
|
||||
{
|
||||
cy -= (float)gpatch->topoffset * fscaleh;
|
||||
float offsetx = 0.0f, offsety = 0.0f;
|
||||
|
||||
// left offset
|
||||
if (option & V_FLIP)
|
||||
cx -= ((float)gpatch->width - (float)gpatch->leftoffset) * fscalew;
|
||||
offsetx = (float)(SHORT(gpatch->width) - SHORT(gpatch->leftoffset)) * fscalew;
|
||||
else
|
||||
cx -= (float)gpatch->leftoffset * fscalew;
|
||||
offsetx = (float)SHORT(gpatch->leftoffset) * fscalew;
|
||||
|
||||
// top offset
|
||||
// TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!?
|
||||
offsety = (float)SHORT(gpatch->topoffset) * fscaleh;
|
||||
|
||||
if ((option & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs
|
||||
{
|
||||
offsetx *= dupx;
|
||||
offsety *= dupy;
|
||||
}
|
||||
|
||||
cx -= offsetx;
|
||||
cy -= offsety;
|
||||
}
|
||||
|
||||
if (splitscreen && (option & V_PERPLAYER))
|
||||
|
@ -312,13 +323,13 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
|
||||
if (pscale != FRACUNIT || (splitscreen && option & V_PERPLAYER))
|
||||
{
|
||||
fwidth = (float)gpatch->width * fscalew * dupx;
|
||||
fheight = (float)gpatch->height * fscaleh * dupy;
|
||||
fwidth = (float)SHORT(gpatch->width) * fscalew * dupx;
|
||||
fheight = (float)SHORT(gpatch->height) * fscaleh * dupy;
|
||||
}
|
||||
else
|
||||
{
|
||||
fwidth = (float)gpatch->width * dupx;
|
||||
fheight = (float)gpatch->height * dupy;
|
||||
fwidth = (float)SHORT(gpatch->width) * dupx;
|
||||
fheight = (float)SHORT(gpatch->height) * dupy;
|
||||
}
|
||||
|
||||
// positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1
|
||||
|
@ -418,8 +429,8 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
|
|||
|
||||
// fuck it, no GL support for croppedpatch v_perplayer right now. it's not like it's accessible to Lua or anything, and we only use it for menus...
|
||||
|
||||
cy -= (float)gpatch->topoffset * fscale;
|
||||
cx -= (float)gpatch->leftoffset * fscale;
|
||||
cy -= (float)SHORT(gpatch->topoffset) * fscale;
|
||||
cx -= (float)SHORT(gpatch->leftoffset) * fscale;
|
||||
|
||||
if (!(option & V_NOSCALESTART))
|
||||
{
|
||||
|
@ -461,11 +472,11 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
|
|||
fwidth = w;
|
||||
fheight = h;
|
||||
|
||||
if (fwidth > gpatch->width)
|
||||
fwidth = gpatch->width;
|
||||
if (fwidth > SHORT(gpatch->width))
|
||||
fwidth = SHORT(gpatch->width);
|
||||
|
||||
if (fheight > gpatch->height)
|
||||
fheight = gpatch->height;
|
||||
if (fheight > SHORT(gpatch->height))
|
||||
fheight = SHORT(gpatch->height);
|
||||
|
||||
if (pscale != FRACUNIT)
|
||||
{
|
||||
|
@ -495,17 +506,17 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
|
|||
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
||||
|
||||
v[0].sow = v[3].sow = ((sx )/(float)gpatch->width )*gpatch->max_s;
|
||||
if (sx + w > gpatch->width)
|
||||
v[0].sow = v[3].sow = ((sx )/(float)SHORT(gpatch->width) )*gpatch->max_s;
|
||||
if (sx + w > SHORT(gpatch->width))
|
||||
v[2].sow = v[1].sow = gpatch->max_s;
|
||||
else
|
||||
v[2].sow = v[1].sow = ((sx+w)/(float)gpatch->width )*gpatch->max_s;
|
||||
v[2].sow = v[1].sow = ((sx+w)/(float)SHORT(gpatch->width) )*gpatch->max_s;
|
||||
|
||||
v[0].tow = v[1].tow = ((sy )/(float)gpatch->height)*gpatch->max_t;
|
||||
if (sy + h > gpatch->height)
|
||||
v[0].tow = v[1].tow = ((sy )/(float)SHORT(gpatch->height))*gpatch->max_t;
|
||||
if (sy + h > SHORT(gpatch->height))
|
||||
v[2].tow = v[3].tow = gpatch->max_t;
|
||||
else
|
||||
v[2].tow = v[3].tow = ((sy+h)/(float)gpatch->height)*gpatch->max_t;
|
||||
v[2].tow = v[3].tow = ((sy+h)/(float)SHORT(gpatch->height))*gpatch->max_t;
|
||||
|
||||
flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest;
|
||||
|
||||
|
@ -705,6 +716,32 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height)
|
|||
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
||||
}
|
||||
|
||||
// Very similar to HWR_DrawConsoleBack, except we draw from the middle(-ish) of the screen to the bottom.
|
||||
void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight)
|
||||
{
|
||||
FOutVector v[4];
|
||||
FSurfaceInfo Surf;
|
||||
INT32 height = (boxheight * 4) + (boxheight/2)*5; // 4 lines of space plus gaps between and some leeway
|
||||
|
||||
// setup some neat-o translucency effect
|
||||
|
||||
v[0].x = v[3].x = -1.0f;
|
||||
v[2].x = v[1].x = 1.0f;
|
||||
v[0].y = v[1].y = -1.0f;
|
||||
v[2].y = v[3].y = -1.0f+((height<<1)/(float)vid.height);
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
||||
|
||||
v[0].sow = v[3].sow = 0.0f;
|
||||
v[2].sow = v[1].sow = 1.0f;
|
||||
v[0].tow = v[1].tow = 1.0f;
|
||||
v[2].tow = v[3].tow = 0.0f;
|
||||
|
||||
Surf.FlatColor.rgba = UINT2RGBA(color);
|
||||
Surf.FlatColor.s.alpha = (color == 0 ? 0xC0 : 0x80); // make black darker, like software
|
||||
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
|
||||
}
|
||||
|
||||
|
||||
// ==========================================================================
|
||||
// R_DRAW.C STUFF
|
||||
|
|
|
@ -32,10 +32,6 @@
|
|||
// STANDARD DLL EXPORTS
|
||||
// ==========================================================================
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
#undef VID_X11
|
||||
#endif
|
||||
|
||||
EXPORT boolean HWRAPI(Init) (I_Error_t ErrorFunction);
|
||||
#ifndef HAVE_SDL
|
||||
EXPORT void HWRAPI(Shutdown) (void);
|
||||
|
@ -43,9 +39,6 @@ EXPORT void HWRAPI(Shutdown) (void);
|
|||
#ifdef _WINDOWS
|
||||
EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes);
|
||||
#endif
|
||||
#ifdef VID_X11
|
||||
EXPORT Window HWRAPI(HookXwin) (Display *, INT32, INT32, boolean);
|
||||
#endif
|
||||
#if defined (PURESDL) || defined (macintosh)
|
||||
EXPORT void HWRAPI(SetPalette) (INT32 *, RGBA_t *gamma);
|
||||
#else
|
||||
|
@ -71,10 +64,6 @@ EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
|
|||
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
||||
EXPORT INT32 HWRAPI(GetRenderVersion) (void);
|
||||
|
||||
#ifdef VID_X11 // ifdef to be removed as soon as windoze supports that as well
|
||||
// metzgermeister: added for Voodoo detection
|
||||
EXPORT char *HWRAPI(GetRenderer) (void);
|
||||
#endif
|
||||
#ifdef SHUFFLE
|
||||
#define SCREENVERTS 10
|
||||
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
|
||||
|
@ -115,10 +104,6 @@ struct hwdriver_s
|
|||
#ifdef _WINDOWS
|
||||
GetModeList pfnGetModeList;
|
||||
#endif
|
||||
#ifdef VID_X11
|
||||
HookXwin pfnHookXwin;
|
||||
GetRenderer pfnGetRenderer;
|
||||
#endif
|
||||
#ifndef HAVE_SDL
|
||||
Shutdown pfnShutdown;
|
||||
#endif
|
||||
|
|
|
@ -2116,6 +2116,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
else
|
||||
{
|
||||
fixed_t texturevpeg;
|
||||
boolean attachtobottom = false;
|
||||
#ifdef ESLOPE
|
||||
boolean slopeskew = false; // skew FOF walls with slopes?
|
||||
#endif
|
||||
|
||||
// Wow, how was this missing from OpenGL for so long?
|
||||
// ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software
|
||||
|
@ -2123,24 +2127,50 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
if (newline)
|
||||
{
|
||||
texturevpeg = sides[newline->sidenum[0]].rowoffset;
|
||||
if (newline->flags & ML_DONTPEGBOTTOM)
|
||||
texturevpeg -= *rover->topheight - *rover->bottomheight;
|
||||
attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM);
|
||||
#ifdef ESLOPE
|
||||
slopeskew = !!(newline->flags & ML_DONTPEGTOP);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
texturevpeg = sides[rover->master->sidenum[0]].rowoffset;
|
||||
if (gr_linedef->flags & ML_DONTPEGBOTTOM)
|
||||
texturevpeg -= *rover->topheight - *rover->bottomheight;
|
||||
attachtobottom = !!(gr_linedef->flags & ML_DONTPEGBOTTOM);
|
||||
#ifdef ESLOPE
|
||||
slopeskew = !!(rover->master->flags & ML_DONTPEGTOP);
|
||||
#endif
|
||||
}
|
||||
|
||||
grTex = HWR_GetTexture(texnum);
|
||||
|
||||
#ifdef ESLOPE
|
||||
wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY;
|
||||
if (!slopeskew) // no skewing
|
||||
{
|
||||
if (attachtobottom)
|
||||
texturevpeg -= *rover->topheight - *rover->bottomheight;
|
||||
wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!attachtobottom) // skew by top
|
||||
{
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[1].t = (hS - lS + texturevpeg) * grTex->scaleY;
|
||||
}
|
||||
else // skew by bottom
|
||||
{
|
||||
wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[3].t = wallVerts[0].t - (h - l) * grTex->scaleY;
|
||||
wallVerts[2].t = wallVerts[1].t - (hS - lS) * grTex->scaleY;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (attachtobottom)
|
||||
texturevpeg -= *rover->topheight - *rover->bottomheight;
|
||||
wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY;
|
||||
#endif
|
||||
|
@ -5270,8 +5300,10 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
||||
if (approx_dist <= limit_dist)
|
||||
HWR_ProjectSprite(thing);
|
||||
if (approx_dist > limit_dist)
|
||||
continue;
|
||||
|
||||
HWR_ProjectSprite(thing);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5293,8 +5325,10 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
|
||||
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
||||
|
||||
if (approx_dist <= limit_dist)
|
||||
HWR_ProjectPrecipitationSprite(precipthing);
|
||||
if (approx_dist > limit_dist)
|
||||
continue;
|
||||
|
||||
HWR_ProjectPrecipitationSprite(precipthing);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5624,6 +5658,16 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
x1 = tr_x + x1 * rightcos;
|
||||
x2 = tr_x - x2 * rightcos;
|
||||
|
||||
// okay, we can't return now... this is a hack, but weather isn't networked, so it should be ok
|
||||
if (!(thing->precipflags & PCF_THUNK))
|
||||
{
|
||||
if (thing->precipflags & PCF_RAIN)
|
||||
P_RainThinker(thing);
|
||||
else
|
||||
P_SnowThinker(thing);
|
||||
thing->precipflags |= PCF_THUNK;
|
||||
}
|
||||
|
||||
//
|
||||
// store information in a vissprite
|
||||
//
|
||||
|
|
|
@ -35,6 +35,7 @@ void HWR_clearAutomap(void);
|
|||
void HWR_drawAMline(const fline_t *fl, INT32 color);
|
||||
void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength);
|
||||
void HWR_DrawConsoleBack(UINT32 color, INT32 height);
|
||||
void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight);
|
||||
void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player);
|
||||
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player);
|
||||
void HWR_DrawViewBorder(INT32 clearlines);
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
// model version
|
||||
#define MD2_VERSION 8
|
||||
|
||||
// magic number "IDP2" or 844121161
|
||||
#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')
|
||||
// model version
|
||||
#define MD2_VERSION 8
|
||||
|
||||
#define MD2_MAX_TRIANGLES 8192
|
||||
#define MD2_MAX_VERTICES 4096
|
||||
#define MD2_MAX_TEXCOORDS 4096
|
||||
|
|
|
@ -86,7 +86,7 @@ void HU_Init(void);
|
|||
void HU_LoadGraphics(void);
|
||||
|
||||
// reset heads up when consoleplayer respawns.
|
||||
FUNCMATH void HU_Start(void);
|
||||
void HU_Start(void);
|
||||
|
||||
boolean HU_Responder(event_t *ev);
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ void I_ShutdownSound(void);
|
|||
|
||||
\return sfx handle
|
||||
*/
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority);
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel);
|
||||
|
||||
/** \brief Stops a sound channel.
|
||||
|
||||
|
@ -289,4 +289,4 @@ void I_PlayCD(UINT8 track, UINT8 looping);
|
|||
*/
|
||||
boolean I_SetVolumeCD(INT32 volume);
|
||||
|
||||
#endif
|
||||
#endif
|
37
src/i_tcp.c
37
src/i_tcp.c
|
@ -225,6 +225,33 @@ static void wattcp_outch(char s)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
// stupid microsoft makes things complicated
|
||||
static char *get_WSAErrorStr(int e)
|
||||
{
|
||||
static char buf[256]; // allow up to 255 bytes
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
FormatMessageA(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
(DWORD)e,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)buf,
|
||||
sizeof (buf),
|
||||
NULL);
|
||||
|
||||
if (!buf[0]) // provide a fallback error message if no message is available for some reason
|
||||
sprintf(buf, "Unknown error");
|
||||
|
||||
return buf;
|
||||
}
|
||||
#undef strerror
|
||||
#define strerror get_WSAErrorStr
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINSOCK2
|
||||
#define inet_ntop inet_ntopA
|
||||
#define HAVE_NTOP
|
||||
|
@ -703,9 +730,13 @@ static void SOCK_Send(void)
|
|||
c = SOCK_SendToAddr(nodesocket[doomcom->remotenode], &clientaddress[doomcom->remotenode]);
|
||||
}
|
||||
|
||||
if (c == ERRSOCKET && errno != ECONNREFUSED && errno != EWOULDBLOCK)
|
||||
I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode,
|
||||
SOCK_GetNodeAddress(doomcom->remotenode), errno, strerror(errno));
|
||||
if (c == ERRSOCKET)
|
||||
{
|
||||
int e = errno; // save error code so it can't be modified later
|
||||
if (e != ECONNREFUSED && e != EWOULDBLOCK)
|
||||
I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode,
|
||||
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
31
src/info.c
31
src/info.c
|
@ -3458,8 +3458,8 @@ state_t states[NUMSTATES] =
|
|||
|
||||
{SPR_FMCE, 0, 20, {NULL}, 0, 0, S_SMASHSPIKE_EASE1}, // S_SMASHSPIKE_FLOAT
|
||||
{SPR_FMCE, 0, 4, {A_ZThrust}, 4, (1<<16)|1, S_SMASHSPIKE_EASE2}, // S_SMASHSPIKE_EASE1
|
||||
{SPR_FMCE, 0, 4, {A_ZThrust}, 0, (1<<16)|1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_EASE1
|
||||
{SPR_FMCE, 0, 2, {A_ZThrust}, -6, (1<<16)|1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_FALL
|
||||
{SPR_FMCE, 0, 4, {A_ZThrust}, 0, (1<<16)|1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_EASE2
|
||||
{SPR_FMCE, 0, 2, {A_ZThrust}, -6, 1, S_SMASHSPIKE_FALL}, // S_SMASHSPIKE_FALL
|
||||
{SPR_FMCE, 1, 2, {A_MultiShotDist}, (MT_DUST<<16)|10, -48, S_SMASHSPIKE_STOMP2}, // S_SMASHSPIKE_STOMP1
|
||||
{SPR_FMCE, 2, 14, {NULL}, 0, 0, S_SMASHSPIKE_RISE1}, // S_SMASHSPIKE_STOMP2
|
||||
{SPR_FMCE, 1, 2, {NULL}, 0, 0, S_SMASHSPIKE_RISE2}, // S_SMASHSPIKE_RISE1
|
||||
|
@ -17814,6 +17814,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_ANGLEMAN
|
||||
758, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
1000, // spawnhealth
|
||||
S_NULL, // seestate
|
||||
sfx_None, // seesound
|
||||
8, // reactiontime
|
||||
sfx_None, // attacksound
|
||||
S_NULL, // painstate
|
||||
0, // painchance
|
||||
sfx_None, // painsound
|
||||
S_NULL, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
0, // speed
|
||||
8, // radius
|
||||
8, // height
|
||||
0, // display offset
|
||||
10, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
{ // MT_POLYANCHOR
|
||||
760, // doomednum
|
||||
S_INVISIBLE, // spawnstate
|
||||
|
|
|
@ -4305,6 +4305,7 @@ typedef enum mobj_type
|
|||
MT_PULL,
|
||||
MT_GHOST,
|
||||
MT_OVERLAY,
|
||||
MT_ANGLEMAN,
|
||||
MT_POLYANCHOR,
|
||||
MT_POLYSPAWN,
|
||||
MT_POLYSPAWNCRUSH,
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#ifdef HAVE_BLUA
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h" // So we can have P_SetupLevelSky
|
||||
#ifdef ESLOPE
|
||||
#include "p_slopes.h" // P_GetZAt
|
||||
#endif
|
||||
#include "z_zone.h"
|
||||
#include "r_main.h"
|
||||
#include "r_things.h"
|
||||
|
@ -2009,6 +2012,24 @@ static int lib_evStartCrumble(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
// P_SLOPES
|
||||
////////////
|
||||
|
||||
static int lib_pGetZAt(lua_State *L)
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
|
||||
fixed_t x = luaL_checkfixed(L, 2);
|
||||
fixed_t y = luaL_checkfixed(L, 3);
|
||||
//HUDSAFE
|
||||
if (!slope)
|
||||
return LUA_ErrInvalid(L, "pslope_t");
|
||||
|
||||
lua_pushfixed(L, P_GetZAt(slope, x, y));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// R_DEFS
|
||||
////////////
|
||||
|
||||
|
@ -2633,6 +2654,11 @@ static luaL_Reg lib[] = {
|
|||
{"EV_CrumbleChain",lib_evCrumbleChain},
|
||||
{"EV_StartCrumble",lib_evStartCrumble},
|
||||
|
||||
#ifdef ESLOPE
|
||||
// p_slopes
|
||||
{"P_GetZAt",lib_pGetZAt},
|
||||
#endif
|
||||
|
||||
// r_defs
|
||||
{"R_PointToAngle",lib_rPointToAngle},
|
||||
{"R_PointToAngle2",lib_rPointToAngle2},
|
||||
|
|
|
@ -48,6 +48,7 @@ enum hook {
|
|||
hook_MobjMoveBlocked,
|
||||
hook_MapThingSpawn,
|
||||
hook_FollowMobj,
|
||||
hook_PlayerQuit,
|
||||
|
||||
hook_MAX // last hook
|
||||
};
|
||||
|
@ -87,5 +88,6 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8
|
|||
#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked)
|
||||
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type
|
||||
boolean LUAh_FollowMobj(player_t *player, mobj_t *mo); // Hook for P_PlayerAfterThink Smiles mobj-following
|
||||
void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting
|
||||
|
||||
#endif
|
||||
|
|
|
@ -59,6 +59,7 @@ const char *const hookNames[hook_MAX+1] = {
|
|||
"MobjMoveBlocked",
|
||||
"MapThingSpawn",
|
||||
"FollowMobj",
|
||||
"PlayerQuit",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1192,4 +1193,30 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj)
|
|||
return hooked;
|
||||
}
|
||||
|
||||
void LUAh_PlayerQuit(player_t *plr, int reason)
|
||||
{
|
||||
hook_p hookp;
|
||||
if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8))))
|
||||
return;
|
||||
|
||||
lua_settop(gL, 0);
|
||||
|
||||
for (hookp = roothook; hookp; hookp = hookp->next)
|
||||
if (hookp->type == hook_PlayerQuit)
|
||||
{
|
||||
if (lua_gettop(gL) == 0)
|
||||
{
|
||||
LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit
|
||||
lua_pushinteger(gL, reason); // Reason for quitting
|
||||
}
|
||||
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(gL, -3);
|
||||
lua_pushvalue(gL, -3);
|
||||
LUA_Call(gL, 2);
|
||||
}
|
||||
|
||||
lua_settop(gL, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -814,6 +814,15 @@ static int libd_RandomChance(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// 30/10/18 Lat': Get cv_translucenthud's value for HUD rendering as a normal V_xxTRANS int
|
||||
// Could as well be thrown in global vars for ease of access but I guess it makes sense for it to be a HUD fn
|
||||
static int libd_getlocaltransflag(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
lua_pushinteger(L, (10-cv_translucenthud.value)*V_10TRANS); // A bit weird that it's called "translucenthud" yet 10 is fully opaque :V
|
||||
return 1;
|
||||
}
|
||||
|
||||
static luaL_Reg lib_draw[] = {
|
||||
// cache
|
||||
{"patchExists", libd_patchExists},
|
||||
|
@ -844,6 +853,7 @@ static luaL_Reg lib_draw[] = {
|
|||
{"dupx", libd_dupx},
|
||||
{"dupy", libd_dupy},
|
||||
{"renderer", libd_renderer},
|
||||
{"localTransFlag", libd_getlocaltransflag},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -867,6 +877,19 @@ static int lib_huddisable(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// 30/10/18: Lat': How come this wasn't here before?
|
||||
static int lib_hudenabled(lua_State *L)
|
||||
{
|
||||
enum hud option = luaL_checkoption(L, 1, NULL, hud_disable_options);
|
||||
if (hud_enabled[option/8] & (1<<(option%8)))
|
||||
lua_pushboolean(L, true);
|
||||
else
|
||||
lua_pushboolean(L, false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// add a HUD element for rendering
|
||||
static int lib_hudadd(lua_State *L)
|
||||
{
|
||||
|
@ -894,6 +917,7 @@ static int lib_hudadd(lua_State *L)
|
|||
static luaL_Reg lib_hud[] = {
|
||||
{"enable", lib_hudenable},
|
||||
{"disable", lib_huddisable},
|
||||
{"enabled", lib_hudenabled},
|
||||
{"add", lib_hudadd},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
|
|
@ -42,6 +42,11 @@ extern lua_State *gL;
|
|||
#define META_SEG "SEG_T*"
|
||||
#define META_NODE "NODE_T*"
|
||||
#endif
|
||||
#ifdef ESLOPE
|
||||
#define META_SLOPE "PSLOPE_T*"
|
||||
#define META_VECTOR2 "VECTOR2_T"
|
||||
#define META_VECTOR3 "VECTOR3_T"
|
||||
#endif
|
||||
#define META_MAPHEADER "MAPHEADER_T*"
|
||||
|
||||
#define META_CVAR "CONSVAR_T*"
|
||||
|
|
290
src/lua_maplib.c
290
src/lua_maplib.c
|
@ -16,6 +16,10 @@
|
|||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "z_zone.h"
|
||||
#ifdef ESLOPE
|
||||
#include "p_slopes.h"
|
||||
#endif
|
||||
#include "r_main.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
@ -38,7 +42,13 @@ enum sector_e {
|
|||
sector_heightsec,
|
||||
sector_camsec,
|
||||
sector_lines,
|
||||
#ifdef ESLOPE
|
||||
sector_ffloors,
|
||||
sector_fslope,
|
||||
sector_cslope
|
||||
#else
|
||||
sector_ffloors
|
||||
#endif
|
||||
};
|
||||
|
||||
static const char *const sector_opt[] = {
|
||||
|
@ -55,6 +65,10 @@ static const char *const sector_opt[] = {
|
|||
"camsec",
|
||||
"lines",
|
||||
"ffloors",
|
||||
#ifdef ESLOPE
|
||||
"f_slope",
|
||||
"c_slope",
|
||||
#endif
|
||||
NULL};
|
||||
|
||||
enum subsector_e {
|
||||
|
@ -160,6 +174,10 @@ enum ffloor_e {
|
|||
ffloor_toplightlevel,
|
||||
ffloor_bottomheight,
|
||||
ffloor_bottompic,
|
||||
#ifdef ESLOPE
|
||||
ffloor_tslope,
|
||||
ffloor_bslope,
|
||||
#endif
|
||||
ffloor_sector,
|
||||
ffloor_flags,
|
||||
ffloor_master,
|
||||
|
@ -176,6 +194,10 @@ static const char *const ffloor_opt[] = {
|
|||
"toplightlevel",
|
||||
"bottomheight",
|
||||
"bottompic",
|
||||
#ifdef ESLOPE
|
||||
"t_slope",
|
||||
"b_slope",
|
||||
#endif
|
||||
"sector", // secnum pushed as control sector userdata
|
||||
"flags",
|
||||
"master", // control linedef
|
||||
|
@ -261,6 +283,47 @@ static const char *const bbox_opt[] = {
|
|||
"right",
|
||||
NULL};
|
||||
|
||||
#ifdef ESLOPE
|
||||
enum slope_e {
|
||||
slope_valid = 0,
|
||||
slope_o,
|
||||
slope_d,
|
||||
slope_zdelta,
|
||||
slope_normal,
|
||||
slope_zangle,
|
||||
slope_xydirection,
|
||||
slope_sourceline,
|
||||
slope_refpos,
|
||||
slope_flags
|
||||
};
|
||||
|
||||
static const char *const slope_opt[] = {
|
||||
"valid",
|
||||
"o",
|
||||
"d",
|
||||
"zdelta",
|
||||
"normal",
|
||||
"zangle",
|
||||
"xydirection",
|
||||
"sourceline",
|
||||
"refpos",
|
||||
"flags",
|
||||
NULL};
|
||||
|
||||
// shared by both vector2_t and vector3_t
|
||||
enum vector_e {
|
||||
vector_x = 0,
|
||||
vector_y,
|
||||
vector_z
|
||||
};
|
||||
|
||||
static const char *const vector_opt[] = {
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
NULL};
|
||||
#endif
|
||||
|
||||
static const char *const array_opt[] ={"iterate",NULL};
|
||||
static const char *const valid_opt[] ={"valid",NULL};
|
||||
|
||||
|
@ -493,6 +556,14 @@ static int sector_get(lua_State *L)
|
|||
LUA_PushUserdata(L, sector->ffloors, META_FFLOOR);
|
||||
lua_pushcclosure(L, sector_iterate, 2); // push lib_iterateFFloors and sector->ffloors as upvalues for the function
|
||||
return 1;
|
||||
#ifdef ESLOPE
|
||||
case sector_fslope: // f_slope
|
||||
LUA_PushUserdata(L, sector->f_slope, META_SLOPE);
|
||||
return 1;
|
||||
case sector_cslope: // c_slope
|
||||
LUA_PushUserdata(L, sector->c_slope, META_SLOPE);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -515,6 +586,10 @@ static int sector_set(lua_State *L)
|
|||
case sector_heightsec: // heightsec
|
||||
case sector_camsec: // camsec
|
||||
case sector_ffloors: // ffloors
|
||||
#ifdef ESLOPE
|
||||
case sector_fslope: // f_slope
|
||||
case sector_cslope: // c_slope
|
||||
#endif
|
||||
default:
|
||||
return luaL_error(L, "sector_t field " LUA_QS " cannot be set.", sector_opt[field]);
|
||||
case sector_floorheight: { // floorheight
|
||||
|
@ -1602,6 +1677,14 @@ static int ffloor_get(lua_State *L)
|
|||
lua_pushlstring(L, levelflat->name, 8);
|
||||
return 1;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
case ffloor_tslope:
|
||||
LUA_PushUserdata(L, *ffloor->t_slope, META_SLOPE);
|
||||
return 1;
|
||||
case ffloor_bslope:
|
||||
LUA_PushUserdata(L, *ffloor->b_slope, META_SLOPE);
|
||||
return 1;
|
||||
#endif
|
||||
case ffloor_sector:
|
||||
LUA_PushUserdata(L, §ors[ffloor->secnum], META_SECTOR);
|
||||
return 1;
|
||||
|
@ -1641,6 +1724,10 @@ static int ffloor_set(lua_State *L)
|
|||
switch(field)
|
||||
{
|
||||
case ffloor_valid: // valid
|
||||
#ifdef ESLOPE
|
||||
case ffloor_tslope: // t_slope
|
||||
case ffloor_bslope: // b_slope
|
||||
#endif
|
||||
case ffloor_sector: // sector
|
||||
case ffloor_master: // master
|
||||
case ffloor_target: // target
|
||||
|
@ -1701,6 +1788,189 @@ static int ffloor_set(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
//////////////
|
||||
// pslope_t //
|
||||
//////////////
|
||||
|
||||
static int slope_get(lua_State *L)
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
|
||||
enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt);
|
||||
|
||||
if (!slope)
|
||||
{
|
||||
if (field == slope_valid) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed pslope_t doesn't exist anymore.");
|
||||
}
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case slope_valid: // valid
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
case slope_o: // o
|
||||
LUA_PushUserdata(L, &slope->o, META_VECTOR3);
|
||||
return 1;
|
||||
case slope_d: // d
|
||||
LUA_PushUserdata(L, &slope->d, META_VECTOR2);
|
||||
return 1;
|
||||
case slope_zdelta: // zdelta
|
||||
lua_pushfixed(L, slope->zdelta);
|
||||
return 1;
|
||||
case slope_normal: // normal
|
||||
LUA_PushUserdata(L, &slope->normal, META_VECTOR3);
|
||||
return 1;
|
||||
case slope_zangle: // zangle
|
||||
lua_pushangle(L, slope->zangle);
|
||||
return 1;
|
||||
case slope_xydirection: // xydirection
|
||||
lua_pushangle(L, slope->xydirection);
|
||||
return 1;
|
||||
case slope_sourceline: // source linedef
|
||||
LUA_PushUserdata(L, slope->sourceline, META_LINE);
|
||||
return 1;
|
||||
case slope_refpos: // refpos
|
||||
lua_pushinteger(L, slope->refpos);
|
||||
return 1;
|
||||
case slope_flags: // flags
|
||||
lua_pushinteger(L, slope->flags);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int slope_set(lua_State *L)
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE));
|
||||
enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt);
|
||||
|
||||
if (!slope)
|
||||
return luaL_error(L, "accessed pslope_t doesn't exist anymore.");
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter pslope_t in HUD rendering code!");
|
||||
|
||||
switch(field) // todo: reorganize this shit
|
||||
{
|
||||
case slope_valid: // valid
|
||||
case slope_sourceline: // sourceline
|
||||
case slope_d: // d
|
||||
case slope_flags: // flags
|
||||
case slope_normal: // normal
|
||||
case slope_refpos: // refpos
|
||||
default:
|
||||
return luaL_error(L, "pslope_t field " LUA_QS " cannot be set.", slope_opt[field]);
|
||||
case slope_o: { // o
|
||||
luaL_checktype(L, 3, LUA_TTABLE);
|
||||
|
||||
lua_getfield(L, 3, "x");
|
||||
if (lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, 3, 1);
|
||||
}
|
||||
if (!lua_isnil(L, -1))
|
||||
slope->o.x = luaL_checkfixed(L, -1);
|
||||
else
|
||||
slope->o.x = 0;
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 3, "y");
|
||||
if (lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, 3, 2);
|
||||
}
|
||||
if (!lua_isnil(L, -1))
|
||||
slope->o.y = luaL_checkfixed(L, -1);
|
||||
else
|
||||
slope->o.y = 0;
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 3, "z");
|
||||
if (lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, 3, 3);
|
||||
}
|
||||
if (!lua_isnil(L, -1))
|
||||
slope->o.z = luaL_checkfixed(L, -1);
|
||||
else
|
||||
slope->o.z = 0;
|
||||
lua_pop(L, 1);
|
||||
break;
|
||||
}
|
||||
case slope_zdelta: { // zdelta, this is temp until i figure out wtf to do
|
||||
slope->zdelta = luaL_checkfixed(L, 3);
|
||||
slope->zangle = R_PointToAngle2(0, 0, FRACUNIT, -slope->zdelta);
|
||||
P_CalculateSlopeNormal(slope);
|
||||
break;
|
||||
}
|
||||
case slope_zangle: { // zangle
|
||||
angle_t zangle = luaL_checkangle(L, 3);
|
||||
if (zangle == ANGLE_90 || zangle == ANGLE_270)
|
||||
return luaL_error(L, "invalid zangle for slope!");
|
||||
slope->zangle = zangle;
|
||||
slope->zdelta = -FINETANGENT(((slope->zangle+ANGLE_90)>>ANGLETOFINESHIFT) & 4095);
|
||||
P_CalculateSlopeNormal(slope);
|
||||
break;
|
||||
}
|
||||
case slope_xydirection: // xydirection
|
||||
slope->xydirection = luaL_checkangle(L, 3);
|
||||
slope->d.x = -FINECOSINE((slope->xydirection>>ANGLETOFINESHIFT) & FINEMASK);
|
||||
slope->d.y = -FINESINE((slope->xydirection>>ANGLETOFINESHIFT) & FINEMASK);
|
||||
P_CalculateSlopeNormal(slope);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////
|
||||
// vector*_t //
|
||||
///////////////
|
||||
|
||||
static int vector2_get(lua_State *L)
|
||||
{
|
||||
vector2_t *vec = *((vector2_t **)luaL_checkudata(L, 1, META_VECTOR2));
|
||||
enum vector_e field = luaL_checkoption(L, 2, vector_opt[0], vector_opt);
|
||||
|
||||
if (!vec)
|
||||
return luaL_error(L, "accessed vector2_t doesn't exist anymore.");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case vector_x: lua_pushfixed(L, vec->x); return 1;
|
||||
case vector_y: lua_pushfixed(L, vec->y); return 1;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vector3_get(lua_State *L)
|
||||
{
|
||||
vector3_t *vec = *((vector3_t **)luaL_checkudata(L, 1, META_VECTOR3));
|
||||
enum vector_e field = luaL_checkoption(L, 2, vector_opt[0], vector_opt);
|
||||
|
||||
if (!vec)
|
||||
return luaL_error(L, "accessed vector3_t doesn't exist anymore.");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case vector_x: lua_pushfixed(L, vec->x); return 1;
|
||||
case vector_y: lua_pushfixed(L, vec->y); return 1;
|
||||
case vector_z: lua_pushfixed(L, vec->z); return 1;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////
|
||||
// mapheaderinfo[] //
|
||||
/////////////////////
|
||||
|
@ -1924,6 +2194,26 @@ int LUA_MapLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
#ifdef ESLOPE
|
||||
luaL_newmetatable(L, META_SLOPE);
|
||||
lua_pushcfunction(L, slope_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, slope_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_VECTOR2);
|
||||
lua_pushcfunction(L, vector2_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_VECTOR3);
|
||||
lua_pushcfunction(L, vector3_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
#endif
|
||||
|
||||
luaL_newmetatable(L, META_MAPHEADER);
|
||||
lua_pushcfunction(L, mapheaderinfo_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
|
|
@ -83,7 +83,12 @@ enum mobj_e {
|
|||
mobj_extravalue1,
|
||||
mobj_extravalue2,
|
||||
mobj_cusval,
|
||||
#ifdef ESLOPE
|
||||
mobj_cvmem,
|
||||
mobj_standingslope
|
||||
#else
|
||||
mobj_cvmem
|
||||
#endif
|
||||
};
|
||||
|
||||
static const char *const mobj_opt[] = {
|
||||
|
@ -146,6 +151,9 @@ static const char *const mobj_opt[] = {
|
|||
"extravalue2",
|
||||
"cusval",
|
||||
"cvmem",
|
||||
#ifdef ESLOPE
|
||||
"standingslope",
|
||||
#endif
|
||||
NULL};
|
||||
|
||||
#define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field])
|
||||
|
@ -358,6 +366,11 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_cvmem:
|
||||
lua_pushinteger(L, mo->cvmem);
|
||||
break;
|
||||
#ifdef ESLOPE
|
||||
case mobj_standingslope:
|
||||
LUA_PushUserdata(L, mo->standingslope, META_SLOPE);
|
||||
break;
|
||||
#endif
|
||||
default: // extra custom variables in Lua memory
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
|
@ -675,6 +688,10 @@ static int mobj_set(lua_State *L)
|
|||
case mobj_cvmem:
|
||||
mo->cvmem = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
#ifdef ESLOPE
|
||||
case mobj_standingslope:
|
||||
return NOSET;
|
||||
#endif
|
||||
default:
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include "byteptr.h"
|
||||
#include "p_saveg.h"
|
||||
#include "p_local.h"
|
||||
#ifdef ESLOPE
|
||||
#include "p_slopes.h" // for P_SlopeById
|
||||
#endif
|
||||
#ifdef LUA_ALLOW_BYTECODE
|
||||
#include "d_netfil.h" // for LUA_DumpFile
|
||||
#endif
|
||||
|
@ -193,25 +196,27 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
|
|||
{
|
||||
MYFILE f;
|
||||
char *name;
|
||||
|
||||
size_t len;
|
||||
f.wad = wad;
|
||||
f.size = W_LumpLengthPwad(wad, lump);
|
||||
f.data = Z_Malloc(f.size, PU_LUA, NULL);
|
||||
W_ReadLumpPwad(wad, lump, f.data);
|
||||
f.curpos = f.data;
|
||||
|
||||
len = strlen(wadfiles[wad]->filename); // length of file name
|
||||
|
||||
if (wadfiles[wad]->type == RET_LUA)
|
||||
{
|
||||
name = malloc(strlen(wadfiles[wad]->filename)+1);
|
||||
name = malloc(len+1);
|
||||
strcpy(name, wadfiles[wad]->filename);
|
||||
}
|
||||
else // If it's not a .lua file, copy the lump name in too.
|
||||
{
|
||||
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
|
||||
size_t length = strlen(wadfiles[wad]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
||||
name = malloc(length + 1);
|
||||
len += 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
||||
name = malloc(len+1);
|
||||
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->name2);
|
||||
name[length] = '\0';
|
||||
name[len] = '\0';
|
||||
}
|
||||
|
||||
LUA_LoadFile(&f, name); // actually load file!
|
||||
|
@ -496,6 +501,9 @@ enum
|
|||
ARCH_NODE,
|
||||
#endif
|
||||
ARCH_FFLOOR,
|
||||
#ifdef ESLOPE
|
||||
ARCH_SLOPE,
|
||||
#endif
|
||||
ARCH_MAPHEADER,
|
||||
|
||||
ARCH_TEND=0xFF,
|
||||
|
@ -520,6 +528,9 @@ static const struct {
|
|||
{META_NODE, ARCH_NODE},
|
||||
#endif
|
||||
{META_FFLOOR, ARCH_FFLOOR},
|
||||
#ifdef ESLOPE
|
||||
{META_SLOPE, ARCH_SLOPE},
|
||||
#endif
|
||||
{META_MAPHEADER, ARCH_MAPHEADER},
|
||||
{NULL, ARCH_NULL}
|
||||
};
|
||||
|
@ -774,6 +785,19 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
}
|
||||
break;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
case ARCH_SLOPE:
|
||||
{
|
||||
pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex));
|
||||
if (!slope)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_SLOPE);
|
||||
WRITEUINT16(save_p, slope->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case ARCH_MAPHEADER:
|
||||
{
|
||||
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
|
||||
|
@ -995,8 +1019,13 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
LUA_PushUserdata(gL, rover, META_FFLOOR);
|
||||
break;
|
||||
}
|
||||
#ifdef ESLOPE
|
||||
case ARCH_SLOPE:
|
||||
LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE);
|
||||
break;
|
||||
#endif
|
||||
case ARCH_MAPHEADER:
|
||||
LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_MAPHEADER);
|
||||
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
|
||||
break;
|
||||
case ARCH_TEND:
|
||||
return 1;
|
||||
|
|
|
@ -497,7 +497,9 @@ static void GIF_framewrite(void)
|
|||
|
||||
// screen regions are handled in GIF_lzw
|
||||
{
|
||||
UINT16 delay = 3; // todo
|
||||
int d1 = (int)((100.0/NEWTICRATE)*(gif_frames+1));
|
||||
int d2 = (int)((100.0/NEWTICRATE)*(gif_frames));
|
||||
UINT16 delay = d1-d2;
|
||||
INT32 startline;
|
||||
|
||||
WRITEMEM(p, gifframe_gchead, 4);
|
||||
|
|
140
src/m_menu.c
140
src/m_menu.c
|
@ -273,6 +273,7 @@ menu_t SP_MainDef, OP_MainDef;
|
|||
menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef;
|
||||
|
||||
// Single Player
|
||||
static void M_StartTutorial(INT32 choice);
|
||||
static void M_LoadGame(INT32 choice);
|
||||
static void M_TimeAttackLevelSelect(INT32 choice);
|
||||
static void M_TimeAttack(INT32 choice);
|
||||
|
@ -443,6 +444,9 @@ static CV_PossibleValue_t serversort_cons_t[] = {
|
|||
};
|
||||
consvar_t cv_serversort = {"serversort", "Ping", CV_HIDEN | CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// first time memory
|
||||
consvar_t cv_tutorialprompt = {"tutorialprompt", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// autorecord demos for time attack
|
||||
static consvar_t cv_autorecord = {"autorecord", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
@ -734,6 +738,7 @@ static menuitem_t SR_EmblemHintMenu[] =
|
|||
// Single Player Main
|
||||
static menuitem_t SP_MainMenu[] =
|
||||
{
|
||||
{IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 84},
|
||||
{IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92},
|
||||
{IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100},
|
||||
{IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108},
|
||||
|
@ -742,6 +747,7 @@ static menuitem_t SP_MainMenu[] =
|
|||
|
||||
enum
|
||||
{
|
||||
sptutorial,
|
||||
sploadgame,
|
||||
sprecordattack,
|
||||
spnightsmode,
|
||||
|
@ -1572,7 +1578,18 @@ menu_t SR_EmblemHintDef =
|
|||
};
|
||||
|
||||
// Single Player
|
||||
menu_t SP_MainDef = CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72);
|
||||
menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72);
|
||||
{
|
||||
NULL,
|
||||
sizeof(SP_MainMenu)/sizeof(menuitem_t),
|
||||
&MainDef,
|
||||
SP_MainMenu,
|
||||
M_DrawCenteredMenu,
|
||||
BASEVIDWIDTH/2, 72,
|
||||
1, // start at "Start Game" on first entry
|
||||
NULL
|
||||
};
|
||||
|
||||
menu_t SP_LoadDef =
|
||||
{
|
||||
"M_PICKG",
|
||||
|
@ -6114,6 +6131,8 @@ static void M_CustomLevelSelect(INT32 choice)
|
|||
static void M_SinglePlayerMenu(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
SP_MainMenu[sptutorial].status =
|
||||
tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED;
|
||||
SP_MainMenu[sprecordattack].status =
|
||||
(M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
|
||||
SP_MainMenu[spnightsmode].status =
|
||||
|
@ -6139,6 +6158,80 @@ static void M_LoadGameLevelSelect(INT32 choice)
|
|||
M_SetupNextMenu(&SP_LevelSelectDef);
|
||||
}
|
||||
|
||||
void M_TutorialSaveControlResponse(INT32 ch)
|
||||
{
|
||||
if (ch == 'y' || ch == KEY_ENTER)
|
||||
{
|
||||
G_CopyControls(gamecontrol, gamecontroldefault[tutorialgcs], gcl_tutorial_full, num_gcl_tutorial_full);
|
||||
CV_Set(&cv_usemouse, cv_usemouse.defaultvalue);
|
||||
CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue);
|
||||
CV_Set(&cv_mousemove, cv_mousemove.defaultvalue);
|
||||
CV_Set(&cv_analog, cv_analog.defaultvalue);
|
||||
S_StartSound(NULL, sfx_itemup);
|
||||
}
|
||||
else
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
}
|
||||
|
||||
static void M_TutorialControlResponse(INT32 ch)
|
||||
{
|
||||
if (ch != KEY_ESCAPE)
|
||||
{
|
||||
G_CopyControls(gamecontroldefault[gcs_custom], gamecontrol, NULL, 0); // using gcs_custom as temp storage for old controls
|
||||
if (ch == 'y' || ch == KEY_ENTER)
|
||||
{
|
||||
tutorialgcs = gcs_fps;
|
||||
tutorialusemouse = cv_usemouse.value;
|
||||
tutorialfreelook = cv_alwaysfreelook.value;
|
||||
tutorialmousemove = cv_mousemove.value;
|
||||
tutorialanalog = cv_analog.value;
|
||||
|
||||
G_CopyControls(gamecontrol, gamecontroldefault[tutorialgcs], gcl_tutorial_full, num_gcl_tutorial_full);
|
||||
CV_Set(&cv_usemouse, cv_usemouse.defaultvalue);
|
||||
CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue);
|
||||
CV_Set(&cv_mousemove, cv_mousemove.defaultvalue);
|
||||
CV_Set(&cv_analog, cv_analog.defaultvalue);
|
||||
|
||||
//S_StartSound(NULL, sfx_itemup);
|
||||
}
|
||||
else
|
||||
{
|
||||
tutorialgcs = gcs_custom;
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
}
|
||||
M_StartTutorial(INT32_MAX);
|
||||
}
|
||||
else
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
|
||||
MessageDef.prevMenu = &SP_MainDef; // if FirstPrompt -> ControlsPrompt -> ESC, we would go to the main menu unless we force this
|
||||
}
|
||||
|
||||
// Starts up the tutorial immediately (tbh I wasn't sure where else to put this)
|
||||
static void M_StartTutorial(INT32 choice)
|
||||
{
|
||||
if (!tutorialmap)
|
||||
return; // no map to go to, don't bother
|
||||
|
||||
if (choice != INT32_MAX && G_GetControlScheme(gamecontrol, gcl_tutorial_check, num_gcl_tutorial_check) != gcs_fps)
|
||||
{
|
||||
M_StartMessage("Do you want to try the \202recommended \202movement controls\x80?\n\nWe will set them just for this tutorial.\n\nPress 'Y' or 'Enter' to confirm\nPress 'N' or any key to keep \nyour current controls.\n",M_TutorialControlResponse,MM_YESNO);
|
||||
return;
|
||||
}
|
||||
else if (choice != INT32_MAX)
|
||||
tutorialgcs = gcs_custom;
|
||||
|
||||
CV_SetValue(&cv_tutorialprompt, 0); // first-time prompt
|
||||
|
||||
tutorialmode = true; // turn on tutorial mode
|
||||
|
||||
emeralds = 0;
|
||||
M_ClearMenus(true);
|
||||
gamecomplete = false;
|
||||
cursaveslot = 0;
|
||||
G_DeferedInitNew(false, G_BuildMapName(tutorialmap), 0, false, false);
|
||||
}
|
||||
|
||||
// ==============
|
||||
// LOAD GAME MENU
|
||||
// ==============
|
||||
|
@ -6746,6 +6839,26 @@ static void M_HandleLoadSave(INT32 choice)
|
|||
}
|
||||
}
|
||||
|
||||
static void M_FirstTimeResponse(INT32 ch)
|
||||
{
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
|
||||
if (ch == KEY_ESCAPE)
|
||||
return;
|
||||
|
||||
if (ch != 'y' && ch != KEY_ENTER)
|
||||
{
|
||||
CV_SetValue(&cv_tutorialprompt, 0);
|
||||
M_ReadSaveStrings();
|
||||
MessageDef.prevMenu = &SP_LoadDef; // calls M_SetupNextMenu
|
||||
}
|
||||
else
|
||||
{
|
||||
M_StartTutorial(0);
|
||||
MessageDef.prevMenu = &MessageDef; // otherwise, the controls prompt won't fire
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Selected from SRB2 menu
|
||||
//
|
||||
|
@ -6753,6 +6866,13 @@ static void M_LoadGame(INT32 choice)
|
|||
{
|
||||
(void)choice;
|
||||
|
||||
if (tutorialmap && cv_tutorialprompt.value)
|
||||
{
|
||||
M_StartMessage("Do you want to \x82play a brief Tutorial\x80?\n\nWe highly recommend this because \nthe controls are slightly different \nfrom other games.\n\nPress 'Y' or 'Enter' to go\nPress 'N' or any key to skip\n",
|
||||
M_FirstTimeResponse, MM_YESNO);
|
||||
return;
|
||||
}
|
||||
|
||||
M_ReadSaveStrings();
|
||||
M_SetupNextMenu(&SP_LoadDef);
|
||||
}
|
||||
|
@ -9219,9 +9339,17 @@ static void M_DrawControl(void)
|
|||
// draw title (or big pic)
|
||||
M_DrawMenuTitle();
|
||||
|
||||
M_CentreText(30,
|
||||
(setupcontrols_secondaryplayer ? "SET CONTROLS FOR SECONDARY PLAYER" :
|
||||
"PRESS ENTER TO CHANGE, BACKSPACE TO CLEAR"));
|
||||
if (tutorialmode && tutorialgcs)
|
||||
{
|
||||
if ((gametic / TICRATE) % 2)
|
||||
M_CentreText(30, "\202EXIT THE TUTORIAL TO CHANGE THE CONTROLS");
|
||||
else
|
||||
M_CentreText(30, "EXIT THE TUTORIAL TO CHANGE THE CONTROLS");
|
||||
}
|
||||
else
|
||||
M_CentreText(30,
|
||||
(setupcontrols_secondaryplayer ? "SET CONTROLS FOR SECONDARY PLAYER" :
|
||||
"PRESS ENTER TO CHANGE, BACKSPACE TO CLEAR"));
|
||||
|
||||
if (i)
|
||||
V_DrawString(currentMenu->x - 16, y-(skullAnimCounter/5), V_YELLOWMAP, "\x1A"); // up arrow
|
||||
|
@ -9356,6 +9484,9 @@ static void M_ChangeControl(INT32 choice)
|
|||
{
|
||||
static char tmp[55];
|
||||
|
||||
if (tutorialmode && tutorialgcs) // don't allow control changes if temp control override is active
|
||||
return;
|
||||
|
||||
controltochange = currentMenu->menuitems[choice].alphaKey;
|
||||
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
|
||||
currentMenu->menuitems[choice].text);
|
||||
|
@ -9544,7 +9675,6 @@ static void M_ToggleMIDI(INT32 choice)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (midi_disabled)
|
||||
{
|
||||
midi_disabled = false;
|
||||
|
|
|
@ -240,6 +240,8 @@ extern INT16 char_on, startchar;
|
|||
|
||||
#define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he
|
||||
|
||||
void M_TutorialSaveControlResponse(INT32 ch);
|
||||
|
||||
void M_ForceSaveSlotSelected(INT32 sslot);
|
||||
|
||||
void M_CheatActivationResponder(INT32 ch);
|
||||
|
|
29
src/m_misc.c
29
src/m_misc.c
|
@ -58,7 +58,7 @@ typedef off_t off64_t;
|
|||
|
||||
#if defined(__MINGW32__) && ((__GNUC__ > 7) || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3))
|
||||
#define PRIdS "u"
|
||||
#elif defined (_WIN32)
|
||||
#elif defined (_WIN32)
|
||||
#define PRIdS "Iu"
|
||||
#elif defined (DJGPP)
|
||||
#define PRIdS "u"
|
||||
|
@ -475,7 +475,8 @@ void M_FirstLoadConfig(void)
|
|||
}
|
||||
|
||||
// load default control
|
||||
G_Controldefault();
|
||||
G_DefineDefaultControls();
|
||||
G_CopyControls(gamecontrol, gamecontroldefault[gcs_fps], NULL, 0);
|
||||
|
||||
// load config, make sure those commands doesnt require the screen...
|
||||
COM_BufInsertText(va("exec \"%s\"\n", configfile));
|
||||
|
@ -538,8 +539,28 @@ void M_SaveConfig(const char *filename)
|
|||
|
||||
// FIXME: save key aliases if ever implemented..
|
||||
|
||||
CV_SaveVariables(f);
|
||||
if (!dedicated) G_SaveKeySetting(f);
|
||||
if (tutorialmode && tutorialgcs)
|
||||
{
|
||||
CV_SetValue(&cv_usemouse, tutorialusemouse);
|
||||
CV_SetValue(&cv_alwaysfreelook, tutorialfreelook);
|
||||
CV_SetValue(&cv_mousemove, tutorialmousemove);
|
||||
CV_SetValue(&cv_analog, tutorialanalog);
|
||||
CV_SaveVariables(f);
|
||||
CV_Set(&cv_usemouse, cv_usemouse.defaultvalue);
|
||||
CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue);
|
||||
CV_Set(&cv_mousemove, cv_mousemove.defaultvalue);
|
||||
CV_Set(&cv_analog, cv_analog.defaultvalue);
|
||||
}
|
||||
else
|
||||
CV_SaveVariables(f);
|
||||
|
||||
if (!dedicated)
|
||||
{
|
||||
if (tutorialmode && tutorialgcs)
|
||||
G_SaveKeySetting(f, gamecontroldefault[gcs_custom], gamecontrolbis); // using gcs_custom as temp storage
|
||||
else
|
||||
G_SaveKeySetting(f, gamecontrol, gamecontrolbis);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
|
|
@ -3324,6 +3324,11 @@ void A_MonitorPop(mobj_t *actor)
|
|||
newmobj->sprite = SPR_TV1P;
|
||||
}
|
||||
}
|
||||
|
||||
// Run a linedef executor immediately upon popping
|
||||
// You may want to delay your effects by 18 tics to sync with the reward giving
|
||||
if (actor->spawnpoint && actor->lastlook)
|
||||
P_LinedefExecute(actor->lastlook, actor->target, NULL);
|
||||
}
|
||||
|
||||
// Function: A_GoldMonitorPop
|
||||
|
@ -3407,6 +3412,11 @@ void A_GoldMonitorPop(mobj_t *actor)
|
|||
newmobj->sprite = SPR_TV1P;
|
||||
}
|
||||
}
|
||||
|
||||
// Run a linedef executor immediately upon popping
|
||||
// You may want to delay your effects by 18 tics to sync with the reward giving
|
||||
if (actor->spawnpoint && actor->lastlook)
|
||||
P_LinedefExecute(actor->lastlook, actor->target, NULL);
|
||||
}
|
||||
|
||||
// Function: A_GoldMonitorRestore
|
||||
|
|
94
src/p_mobj.c
94
src/p_mobj.c
|
@ -3729,14 +3729,15 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|
|||
|
||||
if (player->pflags & PF_FLIPCAM && !(player->powers[pw_carry] == CR_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP)
|
||||
postimg = postimg_flip;
|
||||
else if (player->awayviewtics)
|
||||
else if (player->awayviewtics && player->awayviewmobj != NULL) // Camera must obviously exist
|
||||
{
|
||||
camera_t dummycam;
|
||||
dummycam.subsector = player->awayviewmobj->subsector;
|
||||
dummycam.x = player->awayviewmobj->x;
|
||||
dummycam.y = player->awayviewmobj->y;
|
||||
dummycam.z = player->awayviewmobj->z;
|
||||
dummycam.height = 40*FRACUNIT; // alt view height is 20*FRACUNIT
|
||||
//dummycam.height = 40*FRACUNIT; // alt view height is 20*FRACUNIT
|
||||
dummycam.height = 0; // Why? Remote viewpoint cameras have no height.
|
||||
// Are we in water?
|
||||
if (P_CameraCheckWater(&dummycam))
|
||||
postimg = postimg_water;
|
||||
|
@ -4059,7 +4060,8 @@ void P_RecalcPrecipInSector(sector_t *sector)
|
|||
//
|
||||
void P_NullPrecipThinker(precipmobj_t *mobj)
|
||||
{
|
||||
(void)mobj;
|
||||
//(void)mobj;
|
||||
mobj->precipflags &= ~PCF_THUNK;
|
||||
}
|
||||
|
||||
void P_SnowThinker(precipmobj_t *mobj)
|
||||
|
@ -4079,25 +4081,26 @@ void P_RainThinker(precipmobj_t *mobj)
|
|||
{
|
||||
// cycle through states,
|
||||
// calling action functions at transitions
|
||||
if (mobj->tics > 0 && --mobj->tics == 0)
|
||||
{
|
||||
// you can cycle through multiple states in a tic
|
||||
if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate))
|
||||
return; // freed itself
|
||||
}
|
||||
if (mobj->tics <= 0)
|
||||
return;
|
||||
|
||||
if (--mobj->tics)
|
||||
return;
|
||||
|
||||
if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate))
|
||||
return;
|
||||
|
||||
if (mobj->state != &states[S_RAINRETURN])
|
||||
return;
|
||||
|
||||
mobj->z = mobj->ceilingz;
|
||||
P_SetPrecipMobjState(mobj, S_RAIN1);
|
||||
|
||||
if (mobj->state == &states[S_RAINRETURN])
|
||||
{
|
||||
mobj->z = mobj->ceilingz;
|
||||
P_SetPrecipMobjState(mobj, S_RAIN1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// adjust height
|
||||
mobj->z += mobj->momz;
|
||||
|
||||
if (mobj->z <= mobj->floorz)
|
||||
if ((mobj->z += mobj->momz) <= mobj->floorz)
|
||||
{
|
||||
// no splashes on sky or bottomless pits
|
||||
if (mobj->precipflags & PCF_PIT)
|
||||
|
@ -7433,6 +7436,48 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if ((mobj->flags & MF_ENEMY) && (mobj->state->nextstate == mobj->info->spawnstate && mobj->tics == 1))
|
||||
mobj->flags2 &= ~MF2_FRET;
|
||||
|
||||
// Angle-to-tracer to trigger a linedef exec
|
||||
// See Linedef Exec 457 (Track mobj angle to point)
|
||||
if ((mobj->eflags & MFE_TRACERANGLE) && mobj->tracer && mobj->extravalue2)
|
||||
{
|
||||
// mobj->lastlook - Don't disable behavior after first failure
|
||||
// mobj->extravalue1 - Angle tolerance
|
||||
// mobj->extravalue2 - Exec tag upon failure
|
||||
// mobj->cvval - Allowable failure delay
|
||||
// mobj->cvmem - Failure timer
|
||||
|
||||
angle_t ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y);
|
||||
|
||||
// \todo account for distance between mobj and tracer
|
||||
// Because closer mobjs can be facing beyond the angle tolerance
|
||||
// yet tracer is still in the camera view
|
||||
|
||||
// failure state: mobj is not facing tracer
|
||||
// Reasaonable defaults: ANGLE_67h, ANGLE_292h
|
||||
if (ang >= (UINT32)mobj->extravalue1 && ang <= ANGLE_MAX - (UINT32)mobj->extravalue1)
|
||||
{
|
||||
if (mobj->cvmem)
|
||||
mobj->cvmem--;
|
||||
else
|
||||
{
|
||||
INT32 exectag = mobj->extravalue2; // remember this before we erase the values
|
||||
|
||||
if (mobj->lastlook)
|
||||
mobj->cvmem = mobj->cusval; // reset timer for next failure
|
||||
else
|
||||
{
|
||||
// disable after first failure
|
||||
mobj->eflags &= ~MFE_TRACERANGLE;
|
||||
mobj->lastlook = mobj->extravalue1 = mobj->extravalue2 = mobj->cvmem = mobj->cusval = 0;
|
||||
}
|
||||
|
||||
P_LinedefExecute(exectag, mobj, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
mobj->cvmem = mobj->cusval; // reset failure timer
|
||||
}
|
||||
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_WALLSPIKEBASE:
|
||||
|
@ -8921,14 +8966,15 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
|||
static inline precipmobj_t *P_SpawnRainMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||
{
|
||||
precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type);
|
||||
mo->thinker.function.acp1 = (actionf_p1)P_RainThinker;
|
||||
mo->precipflags |= PCF_RAIN;
|
||||
//mo->thinker.function.acp1 = (actionf_p1)P_RainThinker;
|
||||
return mo;
|
||||
}
|
||||
|
||||
static inline precipmobj_t *P_SpawnSnowMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||
{
|
||||
precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type);
|
||||
mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker;
|
||||
//mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker;
|
||||
return mo;
|
||||
}
|
||||
|
||||
|
@ -10891,6 +10937,16 @@ ML_EFFECT4 : Don't clip inside the ground
|
|||
mobj->flags2 |= MF2_OBJECTFLIP;
|
||||
}
|
||||
|
||||
// Extra functionality
|
||||
if (mthing->options & MTF_EXTRA)
|
||||
{
|
||||
if (mobj->flags & MF_MONITOR && (mthing->angle & 16384))
|
||||
{
|
||||
// Store line exec tag to run upon popping
|
||||
mobj->lastlook = (mthing->angle & 16383);
|
||||
}
|
||||
}
|
||||
|
||||
// Final set of not being able to draw nightsitems.
|
||||
if (mobj->flags & MF_NIGHTSITEM)
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
|
|
|
@ -239,6 +239,9 @@ typedef enum
|
|||
MFE_SPRUNG = 1<<8,
|
||||
// Platform movement
|
||||
MFE_APPLYPMOMZ = 1<<9,
|
||||
// Compute and trigger on mobj angle relative to tracer
|
||||
// See Linedef Exec 457 (Track mobj angle to point)
|
||||
MFE_TRACERANGLE = 1<<10,
|
||||
// free: to and including 1<<15
|
||||
} mobjeflag_t;
|
||||
|
||||
|
@ -254,6 +257,10 @@ typedef enum {
|
|||
PCF_FOF = 4,
|
||||
// Above MOVING FOF (this means we need to keep floorz up to date...)
|
||||
PCF_MOVINGFOF = 8,
|
||||
// Is rain.
|
||||
PCF_RAIN = 16,
|
||||
// Ran the thinker this tic.
|
||||
PCF_THUNK = 32,
|
||||
} precipflag_t;
|
||||
// Map Object definition.
|
||||
typedef struct mobj_s
|
||||
|
@ -449,7 +456,7 @@ boolean P_SupermanLook4Players(mobj_t *actor);
|
|||
void P_DestroyRobots(void);
|
||||
void P_SnowThinker(precipmobj_t *mobj);
|
||||
void P_RainThinker(precipmobj_t *mobj);
|
||||
FUNCMATH void P_NullPrecipThinker(precipmobj_t *mobj);
|
||||
void P_NullPrecipThinker(precipmobj_t *mobj);
|
||||
void P_RemovePrecipMobj(precipmobj_t *mobj);
|
||||
void P_SetScale(mobj_t *mobj, fixed_t newscale);
|
||||
void P_XYMovement(mobj_t *mo);
|
||||
|
|
|
@ -2121,8 +2121,7 @@ static void P_NetArchiveThinkers(void)
|
|||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed
|
||||
|| th->function.acp1 == (actionf_p1)P_RainThinker
|
||||
|| th->function.acp1 == (actionf_p1)P_SnowThinker))
|
||||
|| th->function.acp1 == (actionf_p1)P_NullPrecipThinker))
|
||||
numsaved++;
|
||||
|
||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
||||
|
@ -2131,8 +2130,7 @@ static void P_NetArchiveThinkers(void)
|
|||
continue;
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
else if (th->function.acp1 == (actionf_p1)P_RainThinker
|
||||
|| th->function.acp1 == (actionf_p1)P_SnowThinker);
|
||||
else if (th->function.acp1 == (actionf_p1)P_NullPrecipThinker);
|
||||
#endif
|
||||
else if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
|
||||
{
|
||||
|
|
|
@ -1542,6 +1542,7 @@ static void P_LoadRawSideDefs2(void *data)
|
|||
}
|
||||
|
||||
case 443: // Calls a named Lua function
|
||||
case 459: // Control text prompt (named tag)
|
||||
{
|
||||
char process[8*3+1];
|
||||
memset(process,0,8*3+1);
|
||||
|
@ -2754,6 +2755,9 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
I_UpdateNoVsync();
|
||||
}
|
||||
|
||||
// Close text prompt before freeing the old level
|
||||
F_EndTextPrompt(false, true);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUA_InvalidateLevel();
|
||||
#endif
|
||||
|
|
|
@ -29,7 +29,7 @@ static pslope_t *slopelist = NULL;
|
|||
static UINT16 slopecount = 0;
|
||||
|
||||
// Calculate line normal
|
||||
static void P_CalculateSlopeNormal(pslope_t *slope) {
|
||||
void P_CalculateSlopeNormal(pslope_t *slope) {
|
||||
slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT);
|
||||
slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x);
|
||||
slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define P_SLOPES_H__
|
||||
|
||||
#ifdef ESLOPE
|
||||
void P_CalculateSlopeNormal(pslope_t *slope);
|
||||
void P_ResetDynamicSlopes(void);
|
||||
void P_RunDynamicSlopes(void);
|
||||
// P_SpawnSlope_Line
|
||||
|
|
329
src/p_spec.c
329
src/p_spec.c
|
@ -35,6 +35,7 @@
|
|||
#include "m_misc.h"
|
||||
#include "m_cond.h" //unlock triggers
|
||||
#include "lua_hook.h" // LUAh_LinedefExecute
|
||||
#include "f_finale.h" // control text prompt
|
||||
|
||||
#ifdef HW3SOUND
|
||||
#include "hardware/hw3sound.h"
|
||||
|
@ -2226,8 +2227,7 @@ void P_SwitchWeather(INT32 weathernum)
|
|||
|
||||
for (think = thinkercap.next; think != &thinkercap; think = think->next)
|
||||
{
|
||||
if ((think->function.acp1 != (actionf_p1)P_SnowThinker)
|
||||
&& (think->function.acp1 != (actionf_p1)P_RainThinker))
|
||||
if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
|
||||
continue; // not a precipmobj thinker
|
||||
|
||||
precipmobj = (precipmobj_t *)think;
|
||||
|
@ -2243,14 +2243,12 @@ void P_SwitchWeather(INT32 weathernum)
|
|||
|
||||
for (think = thinkercap.next; think != &thinkercap; think = think->next)
|
||||
{
|
||||
if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
|
||||
continue; // not a precipmobj thinker
|
||||
precipmobj = (precipmobj_t *)think;
|
||||
|
||||
if (swap == PRECIP_RAIN) // Snow To Rain
|
||||
{
|
||||
if (!(think->function.acp1 == (actionf_p1)P_SnowThinker
|
||||
|| think->function.acp1 == (actionf_p1)P_NullPrecipThinker))
|
||||
continue; // not a precipmobj thinker
|
||||
|
||||
precipmobj = (precipmobj_t *)think;
|
||||
|
||||
precipmobj->flags = mobjinfo[MT_RAIN].flags;
|
||||
st = &states[mobjinfo[MT_RAIN].spawnstate];
|
||||
precipmobj->state = st;
|
||||
|
@ -2261,18 +2259,13 @@ void P_SwitchWeather(INT32 weathernum)
|
|||
|
||||
precipmobj->precipflags &= ~PCF_INVISIBLE;
|
||||
|
||||
think->function.acp1 = (actionf_p1)P_RainThinker;
|
||||
precipmobj->precipflags |= PCF_RAIN;
|
||||
//think->function.acp1 = (actionf_p1)P_RainThinker;
|
||||
}
|
||||
else if (swap == PRECIP_SNOW) // Rain To Snow
|
||||
{
|
||||
INT32 z;
|
||||
|
||||
if (!(think->function.acp1 == (actionf_p1)P_RainThinker
|
||||
|| think->function.acp1 == (actionf_p1)P_NullPrecipThinker))
|
||||
continue; // not a precipmobj thinker
|
||||
|
||||
precipmobj = (precipmobj_t *)think;
|
||||
|
||||
precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags;
|
||||
z = M_RandomByte();
|
||||
|
||||
|
@ -2290,19 +2283,13 @@ void P_SwitchWeather(INT32 weathernum)
|
|||
precipmobj->frame = st->frame;
|
||||
precipmobj->momz = mobjinfo[MT_SNOWFLAKE].speed;
|
||||
|
||||
precipmobj->precipflags &= ~PCF_INVISIBLE;
|
||||
precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_RAIN);
|
||||
|
||||
think->function.acp1 = (actionf_p1)P_SnowThinker;
|
||||
//think->function.acp1 = (actionf_p1)P_SnowThinker;
|
||||
}
|
||||
else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse.
|
||||
{
|
||||
if (!(think->function.acp1 == (actionf_p1)P_RainThinker
|
||||
|| think->function.acp1 == (actionf_p1)P_SnowThinker))
|
||||
continue;
|
||||
|
||||
precipmobj = (precipmobj_t *)think;
|
||||
|
||||
think->function.acp1 = (actionf_p1)P_NullPrecipThinker;
|
||||
//think->function.acp1 = (actionf_p1)P_NullPrecipThinker;
|
||||
|
||||
precipmobj->precipflags |= PCF_INVISIBLE;
|
||||
}
|
||||
|
@ -3093,6 +3080,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
|
||||
sector_t *sec; // Sector that the FOF is visible in
|
||||
ffloor_t *rover; // FOF that we are going to crumble
|
||||
boolean foundrover = false; // for debug, "Can't find a FOF" message
|
||||
|
||||
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
|
||||
{
|
||||
|
@ -3107,16 +3095,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag == foftag)
|
||||
break;
|
||||
{
|
||||
foundrover = true;
|
||||
|
||||
EV_CrumbleChain(sec, rover);
|
||||
}
|
||||
}
|
||||
|
||||
if (!rover)
|
||||
if (!foundrover)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 436 Executor: Can't find a FOF control sector with tag %d\n", foftag);
|
||||
return;
|
||||
}
|
||||
|
||||
EV_CrumbleChain(sec, rover);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -3277,6 +3267,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
|
||||
sector_t *sec; // Sector that the FOF is visible (or not visible) in
|
||||
ffloor_t *rover; // FOF to vanish/un-vanish
|
||||
boolean foundrover = false; // for debug, "Can't find a FOF" message
|
||||
ffloortype_e oldflags; // store FOF's old flags
|
||||
|
||||
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
|
||||
|
@ -3292,26 +3283,28 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag == foftag)
|
||||
break;
|
||||
{
|
||||
foundrover = true;
|
||||
|
||||
oldflags = rover->flags;
|
||||
|
||||
// Abracadabra!
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
rover->flags |= FF_EXISTS;
|
||||
else
|
||||
rover->flags &= ~FF_EXISTS;
|
||||
|
||||
// if flags changed, reset sector's light list
|
||||
if (rover->flags != oldflags)
|
||||
sec->moved = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rover)
|
||||
if (!foundrover)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 445 Executor: Can't find a FOF control sector with tag %d\n", foftag);
|
||||
return;
|
||||
}
|
||||
|
||||
oldflags = rover->flags;
|
||||
|
||||
// Abracadabra!
|
||||
if (line->flags & ML_NOCLIMB)
|
||||
rover->flags |= FF_EXISTS;
|
||||
else
|
||||
rover->flags &= ~FF_EXISTS;
|
||||
|
||||
// if flags changed, reset sector's light list
|
||||
if (rover->flags != oldflags)
|
||||
sec->moved = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -3322,6 +3315,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
|
||||
sector_t *sec; // Sector that the FOF is visible in
|
||||
ffloor_t *rover; // FOF that we are going to make fall down
|
||||
boolean foundrover = false; // for debug, "Can't find a FOF" message
|
||||
player_t *player = NULL; // player that caused FOF to fall
|
||||
boolean respawn = true; // should the fallen FOF respawn?
|
||||
|
||||
|
@ -3344,19 +3338,21 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag == foftag)
|
||||
break;
|
||||
{
|
||||
foundrover = true;
|
||||
|
||||
if (line->flags & ML_BLOCKMONSTERS) // FOF flags determine respawn ability instead?
|
||||
respawn = !(rover->flags & FF_NORETURN) ^ !!(line->flags & ML_NOCLIMB); // no climb inverts
|
||||
|
||||
EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, respawn);
|
||||
}
|
||||
}
|
||||
|
||||
if (!rover)
|
||||
if (!foundrover)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 446 Executor: Can't find a FOF control sector with tag %d\n", foftag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (line->flags & ML_BLOCKMONSTERS) // FOF flags determine respawn ability instead?
|
||||
respawn = !(rover->flags & FF_NORETURN) ^ !!(line->flags & ML_NOCLIMB); // no climb inverts
|
||||
|
||||
EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, respawn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -3489,6 +3485,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
|
||||
sector_t *sec; // Sector that the FOF is visible in
|
||||
ffloor_t *rover; // FOF that we are going to operate
|
||||
boolean foundrover = false; // for debug, "Can't find a FOF" message
|
||||
|
||||
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
|
||||
{
|
||||
|
@ -3503,38 +3500,40 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag == foftag)
|
||||
break;
|
||||
{
|
||||
foundrover = true;
|
||||
|
||||
// If fading an invisible FOF whose render flags we did not yet set,
|
||||
// initialize its alpha to 1
|
||||
// for relative alpha calc
|
||||
if (!(line->flags & ML_NOCLIMB) && // do translucent
|
||||
(rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE
|
||||
!(rover->spawnflags & FF_RENDERSIDES) &&
|
||||
!(rover->spawnflags & FF_RENDERPLANES) &&
|
||||
!(rover->flags & FF_RENDERALL))
|
||||
rover->alpha = 1;
|
||||
|
||||
P_RemoveFakeFloorFader(rover);
|
||||
P_FadeFakeFloor(rover,
|
||||
rover->alpha,
|
||||
max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)),
|
||||
0, // set alpha immediately
|
||||
false, NULL, // tic-based logic
|
||||
false, // do not handle FF_EXISTS
|
||||
!(line->flags & ML_NOCLIMB), // handle FF_TRANSLUCENT
|
||||
false, // do not handle lighting
|
||||
false, // do not handle colormap
|
||||
false, // do not handle collision
|
||||
false, // do not do ghost fade (no collision during fade)
|
||||
true); // use exact alpha values (for opengl)
|
||||
}
|
||||
}
|
||||
|
||||
if (!rover)
|
||||
if (!foundrover)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 452 Executor: Can't find a FOF control sector with tag %d\n", foftag);
|
||||
return;
|
||||
}
|
||||
|
||||
// If fading an invisible FOF whose render flags we did not yet set,
|
||||
// initialize its alpha to 1
|
||||
// for relative alpha calc
|
||||
if (!(line->flags & ML_NOCLIMB) && // do translucent
|
||||
(rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE
|
||||
!(rover->spawnflags & FF_RENDERSIDES) &&
|
||||
!(rover->spawnflags & FF_RENDERPLANES) &&
|
||||
!(rover->flags & FF_RENDERALL))
|
||||
rover->alpha = 1;
|
||||
|
||||
P_RemoveFakeFloorFader(rover);
|
||||
P_FadeFakeFloor(rover,
|
||||
rover->alpha,
|
||||
max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)),
|
||||
0, // set alpha immediately
|
||||
false, NULL, // tic-based logic
|
||||
false, // do not handle FF_EXISTS
|
||||
!(line->flags & ML_NOCLIMB), // handle FF_TRANSLUCENT
|
||||
false, // do not handle lighting
|
||||
false, // do not handle colormap
|
||||
false, // do not handle collision
|
||||
false, // do not do ghost fade (no collision during fade)
|
||||
true); // use exact alpha values (for opengl)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3549,6 +3548,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
|
||||
sector_t *sec; // Sector that the FOF is visible in
|
||||
ffloor_t *rover; // FOF that we are going to operate
|
||||
boolean foundrover = false; // for debug, "Can't find a FOF" message
|
||||
size_t j = 0; // sec->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc
|
||||
|
||||
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
|
||||
|
@ -3564,64 +3564,66 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag == foftag)
|
||||
break;
|
||||
{
|
||||
foundrover = true;
|
||||
|
||||
// Prevent continuous execs from interfering on an existing fade
|
||||
if (!(line->flags & ML_EFFECT5)
|
||||
&& rover->fadingdata)
|
||||
//&& ((fade_t*)rover->fadingdata)->timer > (ticbased ? 2 : speed*2))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Fade FOF thinker already exists, timer: %d\n", ((fade_t*)rover->fadingdata)->timer);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (speed > 0)
|
||||
P_AddFakeFloorFader(rover, secnum, j,
|
||||
destvalue,
|
||||
speed,
|
||||
(line->flags & ML_EFFECT4), // tic-based logic
|
||||
(line->flags & ML_EFFECT3), // Relative destvalue
|
||||
!(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS
|
||||
!(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT
|
||||
!(line->flags & ML_EFFECT2), // do not handle lighting
|
||||
!(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags)
|
||||
!(line->flags & ML_BOUNCY), // do not handle collision
|
||||
(line->flags & ML_EFFECT1), // do ghost fade (no collision during fade)
|
||||
(line->flags & ML_TFERLINE)); // use exact alpha values (for opengl)
|
||||
else
|
||||
{
|
||||
// If fading an invisible FOF whose render flags we did not yet set,
|
||||
// initialize its alpha to 1
|
||||
// for relative alpha calc
|
||||
if (!(line->flags & ML_NOCLIMB) && // do translucent
|
||||
(rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE
|
||||
!(rover->spawnflags & FF_RENDERSIDES) &&
|
||||
!(rover->spawnflags & FF_RENDERPLANES) &&
|
||||
!(rover->flags & FF_RENDERALL))
|
||||
rover->alpha = 1;
|
||||
|
||||
P_RemoveFakeFloorFader(rover);
|
||||
P_FadeFakeFloor(rover,
|
||||
rover->alpha,
|
||||
max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)),
|
||||
0, // set alpha immediately
|
||||
false, NULL, // tic-based logic
|
||||
!(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS
|
||||
!(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT
|
||||
!(line->flags & ML_EFFECT2), // do not handle lighting
|
||||
!(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags)
|
||||
!(line->flags & ML_BOUNCY), // do not handle collision
|
||||
(line->flags & ML_EFFECT1), // do ghost fade (no collision during fade)
|
||||
(line->flags & ML_TFERLINE)); // use exact alpha values (for opengl)
|
||||
}
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
if (!rover)
|
||||
if (!foundrover)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Can't find a FOF control sector with tag %d\n", foftag);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent continuous execs from interfering on an existing fade
|
||||
if (!(line->flags & ML_EFFECT5)
|
||||
&& rover->fadingdata)
|
||||
//&& ((fade_t*)rover->fadingdata)->timer > (ticbased ? 2 : speed*2))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 453 Executor: Fade FOF thinker already exists, timer: %d\n", ((fade_t*)rover->fadingdata)->timer);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (speed > 0)
|
||||
P_AddFakeFloorFader(rover, secnum, j,
|
||||
destvalue,
|
||||
speed,
|
||||
(line->flags & ML_EFFECT4), // tic-based logic
|
||||
(line->flags & ML_EFFECT3), // Relative destvalue
|
||||
!(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS
|
||||
!(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT
|
||||
!(line->flags & ML_EFFECT2), // do not handle lighting
|
||||
!(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags)
|
||||
!(line->flags & ML_BOUNCY), // do not handle collision
|
||||
(line->flags & ML_EFFECT1), // do ghost fade (no collision during fade)
|
||||
(line->flags & ML_TFERLINE)); // use exact alpha values (for opengl)
|
||||
else
|
||||
{
|
||||
// If fading an invisible FOF whose render flags we did not yet set,
|
||||
// initialize its alpha to 1
|
||||
// for relative alpha calc
|
||||
if (!(line->flags & ML_NOCLIMB) && // do translucent
|
||||
(rover->spawnflags & FF_NOSHADE) && // do not include light blocks, which don't set FF_NOSHADE
|
||||
!(rover->spawnflags & FF_RENDERSIDES) &&
|
||||
!(rover->spawnflags & FF_RENDERPLANES) &&
|
||||
!(rover->flags & FF_RENDERALL))
|
||||
rover->alpha = 1;
|
||||
|
||||
P_RemoveFakeFloorFader(rover);
|
||||
P_FadeFakeFloor(rover,
|
||||
rover->alpha,
|
||||
max(1, min(256, (line->flags & ML_EFFECT3) ? rover->alpha + destvalue : destvalue)),
|
||||
0, // set alpha immediately
|
||||
false, NULL, // tic-based logic
|
||||
!(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS
|
||||
!(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT
|
||||
!(line->flags & ML_EFFECT2), // do not handle lighting
|
||||
!(line->flags & ML_EFFECT2), // do not handle colormap (ran out of flags)
|
||||
!(line->flags & ML_BOUNCY), // do not handle collision
|
||||
(line->flags & ML_EFFECT1), // do ghost fade (no collision during fade)
|
||||
(line->flags & ML_TFERLINE)); // use exact alpha values (for opengl)
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3632,6 +3634,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
|
||||
sector_t *sec; // Sector that the FOF is visible in
|
||||
ffloor_t *rover; // FOF that we are going to operate
|
||||
boolean foundrover = false; // for debug, "Can't find a FOF" message
|
||||
|
||||
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
|
||||
{
|
||||
|
@ -3646,17 +3649,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master->frontsector->tag == foftag)
|
||||
break;
|
||||
{
|
||||
foundrover = true;
|
||||
|
||||
P_ResetFakeFloorFader(rover, NULL,
|
||||
!(line->flags & ML_BLOCKMONSTERS)); // do not finalize collision flags
|
||||
}
|
||||
}
|
||||
|
||||
if (!rover)
|
||||
if (!foundrover)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 454 Executor: Can't find a FOF control sector with tag %d\n", foftag);
|
||||
return;
|
||||
}
|
||||
|
||||
P_ResetFakeFloorFader(rover, NULL,
|
||||
!(line->flags & ML_BLOCKMONSTERS)); // do not finalize collision flags
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3755,6 +3760,68 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
P_ResetColormapFader(§ors[secnum]);
|
||||
break;
|
||||
|
||||
case 457: // Track mobj angle to point
|
||||
if (mo)
|
||||
{
|
||||
INT32 failureangle = min(max(abs(sides[line->sidenum[0]].textureoffset>>FRACBITS), 0), 360) * ANG1;
|
||||
INT32 failuredelay = abs(sides[line->sidenum[0]].rowoffset>>FRACBITS);
|
||||
INT32 failureexectag = line->sidenum[1] != 0xffff ?
|
||||
(INT32)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : 0;
|
||||
boolean persist = (line->flags & ML_EFFECT2);
|
||||
mobj_t *anchormo;
|
||||
|
||||
if ((secnum = P_FindSectorFromLineTag(line, -1)) < 0)
|
||||
return;
|
||||
|
||||
anchormo = P_GetObjectTypeInSectorNum(MT_ANGLEMAN, secnum);
|
||||
if (!anchormo)
|
||||
return;
|
||||
|
||||
mo->eflags |= MFE_TRACERANGLE;
|
||||
P_SetTarget(&mo->tracer, anchormo);
|
||||
mo->lastlook = persist; // don't disable behavior after first failure
|
||||
mo->extravalue1 = failureangle; // angle to exceed for failure state
|
||||
mo->extravalue2 = failureexectag; // exec tag for failure state (angle is not within range)
|
||||
mo->cusval = mo->cvmem = failuredelay; // cusval = tics to allow failure before line trigger; cvmem = decrement timer
|
||||
}
|
||||
break;
|
||||
|
||||
case 458: // Stop tracking mobj angle to point
|
||||
if (mo && (mo->eflags & MFE_TRACERANGLE))
|
||||
{
|
||||
mo->eflags &= ~MFE_TRACERANGLE;
|
||||
P_SetTarget(&mo->tracer, NULL);
|
||||
mo->lastlook = mo->cvmem = mo->cusval = mo->extravalue1 = mo->extravalue2 = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 459: // Control Text Prompt
|
||||
// console player only unless NOCLIMB is set
|
||||
if (mo && mo->player && P_IsLocalPlayer(mo->player) && (!bot || bot != mo))
|
||||
{
|
||||
INT32 promptnum = max(0, (sides[line->sidenum[0]].textureoffset>>FRACBITS)-1);
|
||||
INT32 pagenum = max(0, (sides[line->sidenum[0]].rowoffset>>FRACBITS)-1);
|
||||
INT32 postexectag = abs((line->sidenum[1] != 0xFFFF) ? sides[line->sidenum[1]].textureoffset>>FRACBITS : line->tag);
|
||||
|
||||
boolean closetextprompt = (line->flags & ML_BLOCKMONSTERS);
|
||||
//boolean allplayers = (line->flags & ML_NOCLIMB);
|
||||
boolean runpostexec = (line->flags & ML_EFFECT1);
|
||||
boolean blockcontrols = !(line->flags & ML_EFFECT2);
|
||||
boolean freezerealtime = !(line->flags & ML_EFFECT3);
|
||||
//boolean freezethinkers = (line->flags & ML_EFFECT4);
|
||||
boolean callbynamedtag = (line->flags & ML_TFERLINE);
|
||||
|
||||
if (closetextprompt)
|
||||
F_EndTextPrompt(false, false);
|
||||
else
|
||||
{
|
||||
if (callbynamedtag && sides[line->sidenum[0]].text && sides[line->sidenum[0]].text[0])
|
||||
F_GetPromptPageByNamedTag(sides[line->sidenum[0]].text, &promptnum, &pagenum);
|
||||
F_StartTextPrompt(promptnum, pagenum, mo, runpostexec ? postexectag : 0, blockcontrols, freezerealtime);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef POLYOBJECTS
|
||||
case 480: // Polyobj_DoorSlide
|
||||
case 481: // Polyobj_DoorSwing
|
||||
|
|
24
src/p_tick.c
24
src/p_tick.c
|
@ -56,12 +56,12 @@ void Command_Numthinkers_f(void)
|
|||
CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n"));
|
||||
CONS_Printf(
|
||||
"\t1: P_MobjThinker\n"
|
||||
"\t2: P_RainThinker\n"
|
||||
"\t3: P_SnowThinker\n"
|
||||
"\t4: P_NullPrecipThinker\n"
|
||||
"\t5: T_Friction\n"
|
||||
"\t6: T_Pusher\n"
|
||||
"\t7: P_RemoveThinkerDelayed\n");
|
||||
/*"\t2: P_RainThinker\n"
|
||||
"\t3: P_SnowThinker\n"*/
|
||||
"\t2: P_NullPrecipThinker\n"
|
||||
"\t3: T_Friction\n"
|
||||
"\t4: T_Pusher\n"
|
||||
"\t5: P_RemoveThinkerDelayed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -73,27 +73,27 @@ void Command_Numthinkers_f(void)
|
|||
action = (actionf_p1)P_MobjThinker;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker");
|
||||
break;
|
||||
case 2:
|
||||
/*case 2:
|
||||
action = (actionf_p1)P_RainThinker;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker");
|
||||
break;
|
||||
case 3:
|
||||
action = (actionf_p1)P_SnowThinker;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker");
|
||||
break;
|
||||
case 4:
|
||||
break;*/
|
||||
case 2:
|
||||
action = (actionf_p1)P_NullPrecipThinker;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker");
|
||||
break;
|
||||
case 5:
|
||||
case 3:
|
||||
action = (actionf_p1)T_Friction;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "T_Friction");
|
||||
break;
|
||||
case 6:
|
||||
case 4:
|
||||
action = (actionf_p1)T_Pusher;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "T_Pusher");
|
||||
break;
|
||||
case 7:
|
||||
case 5:
|
||||
action = (actionf_p1)P_RemoveThinkerDelayed;
|
||||
CONS_Printf(M_GetText("Number of %s: "), "P_RemoveThinkerDelayed");
|
||||
break;
|
||||
|
|
71
src/p_user.c
71
src/p_user.c
|
@ -8777,9 +8777,15 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
subsector_t *newsubsec;
|
||||
fixed_t f1, f2;
|
||||
|
||||
cameranoclip = (player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (player->mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
|
||||
// We probably shouldn't move the camera if there is no player or player mobj somehow
|
||||
if (!player || !player->mo)
|
||||
return true;
|
||||
|
||||
if (!(player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD))
|
||||
mo = player->mo;
|
||||
|
||||
cameranoclip = (player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
|
||||
|
||||
if (!(player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || tutorialmode))
|
||||
{
|
||||
if (player->spectator) // force cam off for spectators
|
||||
return true;
|
||||
|
@ -8798,7 +8804,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
else if (player == &players[secondarydisplayplayer])
|
||||
focusangle = localangle2;
|
||||
else
|
||||
focusangle = player->mo->angle;
|
||||
focusangle = mo->angle;
|
||||
if (thiscam == &camera)
|
||||
camrotate = cv_cam_rotate.value;
|
||||
else if (thiscam == &camera2)
|
||||
|
@ -8810,17 +8816,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!player || !player->mo)
|
||||
return true;
|
||||
|
||||
mo = player->mo;
|
||||
|
||||
thiscam->radius = FixedMul(20*FRACUNIT, mo->scale);
|
||||
thiscam->height = FixedMul(16*FRACUNIT, mo->scale);
|
||||
|
||||
if (!mo)
|
||||
return true;
|
||||
|
||||
// Don't run while respawning from a starpost
|
||||
// Inu 4/8/13 Why not?!
|
||||
// if (leveltime > 0 && timeinmap <= 0)
|
||||
|
@ -8828,7 +8826,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
|
||||
if (player->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
{
|
||||
focusangle = player->mo->angle;
|
||||
focusangle = mo->angle;
|
||||
focusaiming = 0;
|
||||
}
|
||||
else if (player == &players[consoleplayer])
|
||||
|
@ -8843,14 +8841,23 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
}
|
||||
else
|
||||
{
|
||||
focusangle = player->mo->angle;
|
||||
focusangle = mo->angle;
|
||||
focusaiming = player->aiming;
|
||||
}
|
||||
|
||||
if (P_CameraThinker(player, thiscam, resetcalled))
|
||||
return true;
|
||||
|
||||
if (thiscam == &camera)
|
||||
if (tutorialmode)
|
||||
{
|
||||
// force defaults because we have a camera look section
|
||||
camspeed = (INT32)(atof(cv_cam_speed.defaultvalue) * FRACUNIT);
|
||||
camstill = (!stricmp(cv_cam_still.defaultvalue, "off")) ? false : true;
|
||||
camrotate = atoi(cv_cam_rotate.defaultvalue);
|
||||
camdist = FixedMul((INT32)(atof(cv_cam_dist.defaultvalue) * FRACUNIT), mo->scale);
|
||||
camheight = FixedMul((INT32)(atof(cv_cam_height.defaultvalue) * FRACUNIT), FixedMul(player->camerascale, mo->scale));
|
||||
}
|
||||
else if (thiscam == &camera)
|
||||
{
|
||||
camspeed = cv_cam_speed.value;
|
||||
camstill = cv_cam_still.value;
|
||||
|
@ -8890,12 +8897,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
angle = R_PointToAngle2(player->axis1->x, player->axis1->y, player->axis2->x, player->axis2->y);
|
||||
angle += ANGLE_90;
|
||||
}
|
||||
else if (player->mo->target)
|
||||
else if (mo->target)
|
||||
{
|
||||
if (player->mo->target->flags2 & MF2_AMBUSH)
|
||||
angle = R_PointToAngle2(player->mo->target->x, player->mo->target->y, player->mo->x, player->mo->y);
|
||||
if (mo->target->flags2 & MF2_AMBUSH)
|
||||
angle = R_PointToAngle2(mo->target->x, mo->target->y, mo->x, mo->y);
|
||||
else
|
||||
angle = R_PointToAngle2(player->mo->x, player->mo->y, player->mo->target->x, player->mo->target->y);
|
||||
angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y);
|
||||
}
|
||||
}
|
||||
else if (P_AnalogMove(player)) // Analog
|
||||
|
@ -8984,7 +8991,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
if (twodlevel || (mo->flags2 & MF2_TWOD))
|
||||
{
|
||||
// Camera doesn't ALWAYS need to move, only when running...
|
||||
if (abs(player->mo->momx) > 10)
|
||||
if (abs(mo->momx) > 10)
|
||||
{
|
||||
// Move the camera all smooth-like, not jerk it around...
|
||||
if (mo->momx > 0)
|
||||
|
@ -9291,24 +9298,20 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
// Make player translucent if camera is too close (only in single player).
|
||||
if (!(multiplayer || netgame) && !splitscreen)
|
||||
{
|
||||
fixed_t vx = 0, vy = 0;
|
||||
if (player->awayviewtics) {
|
||||
fixed_t vx = thiscam->x, vy = thiscam->y;
|
||||
if (player->awayviewtics && player->awayviewmobj != NULL) // Camera must obviously exist
|
||||
{
|
||||
vx = player->awayviewmobj->x;
|
||||
vy = player->awayviewmobj->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
vx = thiscam->x;
|
||||
vy = thiscam->y;
|
||||
}
|
||||
|
||||
if (P_AproxDistance(vx - player->mo->x, vy - player->mo->y) < FixedMul(48*FRACUNIT, mo->scale))
|
||||
player->mo->flags2 |= MF2_SHADOW;
|
||||
if (P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale))
|
||||
mo->flags2 |= MF2_SHADOW;
|
||||
else
|
||||
player->mo->flags2 &= ~MF2_SHADOW;
|
||||
mo->flags2 &= ~MF2_SHADOW;
|
||||
}
|
||||
else
|
||||
player->mo->flags2 &= ~MF2_SHADOW;
|
||||
mo->flags2 &= ~MF2_SHADOW;
|
||||
|
||||
/* if (!resetcalled && (player->powers[pw_carry] == CR_NIGHTSMODE && player->exiting))
|
||||
{
|
||||
|
@ -9623,8 +9626,9 @@ void P_PlayerThink(player_t *player)
|
|||
if (player->flashcount)
|
||||
player->flashcount--;
|
||||
|
||||
if (player->awayviewtics)
|
||||
player->awayviewtics--;
|
||||
// By the time P_MoveChaseCamera is called, this might be zero. Do not do it here.
|
||||
//if (player->awayviewtics)
|
||||
// player->awayviewtics--;
|
||||
|
||||
/// \note do this in the cheat code
|
||||
if (player->pflags & PF_NOCLIP)
|
||||
|
@ -10597,6 +10601,9 @@ void P_PlayerAfterThink(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
if (player->awayviewtics)
|
||||
player->awayviewtics--;
|
||||
|
||||
// spectator invisibility and nogravity.
|
||||
if ((netgame || multiplayer) && player->spectator)
|
||||
{
|
||||
|
|
|
@ -261,7 +261,7 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
|||
val = source[frac>>FRACBITS];
|
||||
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[*(transmap + (val<<8) + (*dest))];
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
|
||||
dest += vid.width;
|
||||
|
||||
|
@ -281,12 +281,12 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
|||
{
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[*(transmap + (val<<8) + (*dest))];
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
dest += vid.width;
|
||||
frac += fracstep;
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[*(transmap + (val<<8) + (*dest))];
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
dest += vid.width;
|
||||
frac += fracstep;
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
|||
{
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[*(transmap + (val<<8) + (*dest))];
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -913,7 +913,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
|
|||
chasecam = (cv_chasecam.value != 0);
|
||||
}
|
||||
|
||||
if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN)
|
||||
if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode)
|
||||
chasecam = true; // force chasecam on
|
||||
else if (player->spectator) // no spectator chasecam
|
||||
chasecam = false; // force chasecam off
|
||||
|
|
|
@ -87,7 +87,7 @@ extern lighttable_t **planezlight;
|
|||
extern fixed_t *yslope;
|
||||
extern fixed_t distscale[MAXVIDWIDTH];
|
||||
|
||||
FUNCMATH void R_InitPlanes(void);
|
||||
void R_InitPlanes(void);
|
||||
void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
|
||||
void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
|
||||
void R_ClearPlanes(void);
|
||||
|
|
|
@ -63,11 +63,7 @@ typedef struct floorsplat_s
|
|||
fixed_t P_SegLength(seg_t *seg);
|
||||
|
||||
// call at P_SetupLevel()
|
||||
#if !(defined (WALLSPLATS) || defined (FLOORSPLATS))
|
||||
FUNCMATH void R_ClearLevelSplats(void);
|
||||
#else
|
||||
void R_ClearLevelSplats(void);
|
||||
#endif
|
||||
|
||||
#ifdef WALLSPLATS
|
||||
void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, fixed_t top,
|
||||
|
|
|
@ -1525,6 +1525,17 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
return;
|
||||
}
|
||||
|
||||
// okay, we can't return now except for vertical clipping... this is a hack, but weather isn't networked, so it should be ok
|
||||
if (!(thing->precipflags & PCF_THUNK))
|
||||
{
|
||||
if (thing->precipflags & PCF_RAIN)
|
||||
P_RainThinker(thing);
|
||||
else
|
||||
P_SnowThinker(thing);
|
||||
thing->precipflags |= PCF_THUNK;
|
||||
}
|
||||
|
||||
|
||||
//SoM: 3/17/2000: Disregard sprites that are out of view..
|
||||
gzt = thing->z + spritecachedinfo[lump].topoffset;
|
||||
gz = gzt - spritecachedinfo[lump].height;
|
||||
|
@ -1642,8 +1653,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
||||
if (approx_dist <= limit_dist)
|
||||
R_ProjectSprite(thing);
|
||||
if (approx_dist > limit_dist)
|
||||
continue;
|
||||
|
||||
R_ProjectSprite(thing);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1664,8 +1677,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
|
||||
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
||||
|
||||
if (approx_dist <= limit_dist)
|
||||
R_ProjectPrecipitationSprite(precipthing);
|
||||
if (approx_dist > limit_dist)
|
||||
continue;
|
||||
|
||||
R_ProjectPrecipitationSprite(precipthing);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
104
src/s_sound.c
104
src/s_sound.c
|
@ -37,6 +37,7 @@ extern INT32 msg_id;
|
|||
#include "r_sky.h" // skyflatnum
|
||||
#include "p_local.h" // camera info
|
||||
#include "fastcmp.h"
|
||||
#include "m_misc.h" // for tunes command
|
||||
|
||||
#if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS)
|
||||
#include "lua_hook.h" // MusicChange hook
|
||||
|
@ -51,6 +52,8 @@ static INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, I
|
|||
|
||||
CV_PossibleValue_t soundvolume_cons_t[] = {{0, "MIN"}, {31, "MAX"}, {0, NULL}};
|
||||
static void SetChannelsNum(void);
|
||||
static void Command_Tunes_f(void);
|
||||
static void Command_RestartAudio_f(void);
|
||||
|
||||
// commands for music and sound servers
|
||||
#ifdef MUSSERV
|
||||
|
@ -96,6 +99,7 @@ consvar_t cv_closedcaptioning = {"closedcaptioning", "Off", CV_SAVE|CV_CALL, CV_
|
|||
consvar_t cv_numChannels = {"snd_channels", "32", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#if defined(HAVE_MIXERX) && !defined(HAVE_MIXER) // mixer_sound.c defines these with static handler methods
|
||||
static CV_PossibleValue_t midiplayer_cons_t[] = {{MIDI_OPNMIDI, "OPNMIDI"}, {MIDI_Fluidsynth, "Fluidsynth"}, {MIDI_Timidity, "Timidity"}, {MIDI_Native, "Native"}, {0, NULL}};
|
||||
|
@ -258,6 +262,17 @@ void S_RegisterSoundStuff(void)
|
|||
#endif
|
||||
CV_RegisterVar(&surround);
|
||||
CV_RegisterVar(&cv_samplerate);
|
||||
CV_RegisterVar(&cv_resetmusic);
|
||||
|
||||
COM_AddCommand("tunes", Command_Tunes_f);
|
||||
COM_AddCommand("restartaudio", Command_RestartAudio_f);
|
||||
|
||||
#ifdef HAVE_MIXERX
|
||||
CV_RegisterVar(&cv_midiplayer);
|
||||
CV_RegisterVar(&cv_midisoundfontpath);
|
||||
CV_RegisterVar(&cv_miditimiditypath);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (macintosh) && !defined (HAVE_SDL) // mp3 playlist stuff
|
||||
{
|
||||
|
@ -637,7 +652,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
|||
|
||||
// Assigns the handle to one of the channels in the
|
||||
// mix/output buffer.
|
||||
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
|
||||
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
|
||||
}
|
||||
|
||||
dontplay:
|
||||
|
@ -690,7 +705,7 @@ dontplay:
|
|||
|
||||
// Assigns the handle to one of the channels in the
|
||||
// mix/output buffer.
|
||||
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
|
||||
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
|
||||
}
|
||||
|
||||
void S_StartSound(const void *origin, sfxenum_t sfx_id)
|
||||
|
@ -1755,3 +1770,88 @@ void S_StartEx(boolean reset)
|
|||
S_StopMusic();
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||
}
|
||||
|
||||
static void Command_Tunes_f(void)
|
||||
{
|
||||
const char *tunearg;
|
||||
UINT16 tunenum, track = 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(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"));
|
||||
CONS_Printf(M_GetText("* With \"-default\", returns to the default music for the map.\n"));
|
||||
CONS_Printf(M_GetText("* With \"-none\", any music playing will be stopped.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
tunearg = COM_Argv(1);
|
||||
tunenum = (UINT16)atoi(tunearg);
|
||||
track = 0;
|
||||
|
||||
if (!strcasecmp(tunearg, "-show"))
|
||||
{
|
||||
CONS_Printf(M_GetText("The current tune is: %s [track %d]\n"),
|
||||
mapmusname, (mapmusflags & MUSIC_TRACKMASK));
|
||||
return;
|
||||
}
|
||||
if (!strcasecmp(tunearg, "-none"))
|
||||
{
|
||||
S_StopMusic();
|
||||
return;
|
||||
}
|
||||
else if (!strcasecmp(tunearg, "-default"))
|
||||
{
|
||||
tunearg = mapheaderinfo[gamemap-1]->musname;
|
||||
track = mapheaderinfo[gamemap-1]->mustrack;
|
||||
}
|
||||
else if (!tunearg[2] && toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z')
|
||||
tunenum = (UINT16)M_MapNumber(tunearg[0], tunearg[1]);
|
||||
|
||||
if (tunenum && tunenum >= 1036)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Valid music slots are 1 to 1035.\n"));
|
||||
return;
|
||||
}
|
||||
if (!tunenum && strlen(tunearg) > 6) // This is automatic -- just show the error just in case
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n"));
|
||||
|
||||
if (argc > 2)
|
||||
track = (UINT16)atoi(COM_Argv(2))-1;
|
||||
|
||||
if (tunenum)
|
||||
snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum));
|
||||
else
|
||||
strncpy(mapmusname, tunearg, 7);
|
||||
mapmusname[6] = 0;
|
||||
mapmusflags = (track & MUSIC_TRACKMASK);
|
||||
|
||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
||||
|
||||
if (argc > 3)
|
||||
{
|
||||
float speed = (float)atof(COM_Argv(3));
|
||||
if (speed > 0.0f)
|
||||
S_SpeedMusic(speed);
|
||||
}
|
||||
}
|
||||
|
||||
static void Command_RestartAudio_f(void)
|
||||
{
|
||||
S_StopMusic();
|
||||
S_StopSounds();
|
||||
I_ShutdownMusic();
|
||||
I_ShutdownSound();
|
||||
I_StartupSound();
|
||||
I_InitMusic();
|
||||
|
||||
// These must be called or no sound and music until manually set.
|
||||
|
||||
I_SetSfxVolume(cv_soundvolume.value);
|
||||
S_SetMusicVolume(cv_digmusicvolume.value, cv_midimusicvolume.value);
|
||||
if (Playing()) // Gotta make sure the player is in a level
|
||||
P_RestoreMusic(&players[consoleplayer]);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
extern consvar_t stereoreverse;
|
||||
extern consvar_t cv_soundvolume, cv_closedcaptioning, cv_digmusicvolume, cv_midimusicvolume;
|
||||
extern consvar_t cv_numChannels;
|
||||
extern consvar_t cv_resetmusic;
|
||||
|
||||
#ifdef HAVE_MIXERX
|
||||
extern consvar_t cv_midiplayer;
|
||||
|
|
|
@ -69,11 +69,7 @@ consvar_t cv_scr_height = {"scr_height", "800", CV_SAVE, CV_Unsigned, NULL, 0, N
|
|||
consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#ifdef DIRECTFULLSCREEN
|
||||
static FUNCMATH void SCR_ChangeFullscreen (void);
|
||||
#else
|
||||
static void SCR_ChangeFullscreen (void);
|
||||
#endif
|
||||
|
||||
consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
|
|
@ -12,19 +12,19 @@ consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NUL
|
|||
consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
||||
FUNCMATH void I_InitCD(void){}
|
||||
void I_InitCD(void){}
|
||||
|
||||
FUNCMATH void I_StopCD(void){}
|
||||
void I_StopCD(void){}
|
||||
|
||||
FUNCMATH void I_PauseCD(void){}
|
||||
void I_PauseCD(void){}
|
||||
|
||||
FUNCMATH void I_ResumeCD(void){}
|
||||
void I_ResumeCD(void){}
|
||||
|
||||
FUNCMATH void I_ShutdownCD(void){}
|
||||
void I_ShutdownCD(void){}
|
||||
|
||||
FUNCMATH void I_UpdateCD(void){}
|
||||
void I_UpdateCD(void){}
|
||||
|
||||
FUNCMATH void I_PlayCD(UINT8 track, UINT8 looping)
|
||||
void I_PlayCD(UINT8 track, UINT8 looping)
|
||||
{
|
||||
(void)track;
|
||||
(void)looping;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Portions Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 2014-2018 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -124,6 +127,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
|||
#include "macosx/mac_resources.h"
|
||||
#endif
|
||||
|
||||
#ifndef errno
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
// Locations for searching the srb2.pk3
|
||||
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
|
||||
#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2"
|
||||
|
@ -1149,6 +1156,7 @@ static void I_ShutdownJoystick2(void)
|
|||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
joystick2_started = 0;
|
||||
JoyReset(&JoyInfo2);
|
||||
if (!joystick_started && !joystick2_started && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||
{
|
||||
|
@ -1678,7 +1686,7 @@ static void I_ShutdownMouse2(void)
|
|||
EscapeCommFunction(mouse2filehandle, CLRRTS);
|
||||
|
||||
PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT |
|
||||
PURGE_TXCLEAR | PURGE_RXCLEAR);
|
||||
PURGE_TXCLEAR | PURGE_RXCLEAR);
|
||||
|
||||
CloseHandle(mouse2filehandle);
|
||||
|
||||
|
@ -1871,11 +1879,11 @@ void I_StartupMouse2(void)
|
|||
{
|
||||
// COM file handle
|
||||
mouse2filehandle = CreateFileA(cv_mouse2port.string, GENERIC_READ | GENERIC_WRITE,
|
||||
0, // exclusive access
|
||||
NULL, // no security attrs
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
0, // exclusive access
|
||||
NULL, // no security attrs
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if (mouse2filehandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
INT32 e = GetLastError();
|
||||
|
@ -1895,7 +1903,7 @@ void I_StartupMouse2(void)
|
|||
|
||||
// purge buffers
|
||||
PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT
|
||||
| PURGE_TXCLEAR | PURGE_RXCLEAR);
|
||||
| PURGE_TXCLEAR | PURGE_RXCLEAR);
|
||||
|
||||
// setup port to 1200 7N1
|
||||
dcb.DCBlength = sizeof (DCB);
|
||||
|
@ -1921,14 +1929,14 @@ void I_StartupMouse2(void)
|
|||
//
|
||||
// I_Tactile
|
||||
//
|
||||
FUNCMATH void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect)
|
||||
void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect)
|
||||
{
|
||||
// UNUSED.
|
||||
(void)pFFType;
|
||||
(void)FFEffect;
|
||||
}
|
||||
|
||||
FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
|
||||
void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
|
||||
{
|
||||
// UNUSED.
|
||||
(void)pFFType;
|
||||
|
@ -1939,7 +1947,7 @@ FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
|
|||
*/
|
||||
static ticcmd_t emptycmd;
|
||||
|
||||
FUNCMATH ticcmd_t *I_BaseTiccmd(void)
|
||||
ticcmd_t *I_BaseTiccmd(void)
|
||||
{
|
||||
return &emptycmd;
|
||||
}
|
||||
|
@ -1948,7 +1956,7 @@ FUNCMATH ticcmd_t *I_BaseTiccmd(void)
|
|||
*/
|
||||
static ticcmd_t emptycmd2;
|
||||
|
||||
FUNCMATH ticcmd_t *I_BaseTiccmd2(void)
|
||||
ticcmd_t *I_BaseTiccmd2(void)
|
||||
{
|
||||
return &emptycmd2;
|
||||
}
|
||||
|
@ -2024,7 +2032,7 @@ static void I_ShutdownTimer(void)
|
|||
tic_t I_GetTime (void)
|
||||
{
|
||||
static Uint32 basetime = 0;
|
||||
Uint32 ticks = SDL_GetTicks();
|
||||
Uint32 ticks = SDL_GetTicks();
|
||||
|
||||
if (!basetime)
|
||||
basetime = ticks;
|
||||
|
@ -2042,7 +2050,7 @@ tic_t I_GetTime (void)
|
|||
//
|
||||
//I_StartupTimer
|
||||
//
|
||||
FUNCMATH void I_StartupTimer(void)
|
||||
void I_StartupTimer(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// for win2k time bug
|
||||
|
@ -2090,7 +2098,6 @@ INT32 I_StartupSystem(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// I_Quit
|
||||
//
|
||||
|
@ -2142,11 +2149,11 @@ void I_WaitVBL(INT32 count)
|
|||
SDL_Delay(count);
|
||||
}
|
||||
|
||||
FUNCMATH void I_BeginRead(void)
|
||||
void I_BeginRead(void)
|
||||
{
|
||||
}
|
||||
|
||||
FUNCMATH void I_EndRead(void)
|
||||
void I_EndRead(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2369,7 +2376,7 @@ void I_GetDiskFreeSpace(INT64 *freespace)
|
|||
{
|
||||
DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
|
||||
GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
|
||||
&NumberOfFreeClusters, &TotalNumberOfClusters);
|
||||
&NumberOfFreeClusters, &TotalNumberOfClusters);
|
||||
*freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters;
|
||||
}
|
||||
#else // Dummy for platform independent; 1GB should be enough
|
||||
|
@ -2576,22 +2583,22 @@ static const char *locateWad(void)
|
|||
|
||||
#ifdef CMAKECONFIG
|
||||
#ifndef NDEBUG
|
||||
I_OutputMsg(","CMAKE_ASSETS_DIR);
|
||||
strcpy(returnWadPath, CMAKE_ASSETS_DIR);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
{
|
||||
return returnWadPath;
|
||||
}
|
||||
I_OutputMsg(","CMAKE_ASSETS_DIR);
|
||||
strcpy(returnWadPath, CMAKE_ASSETS_DIR);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
{
|
||||
return returnWadPath;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
OSX_GetResourcesPath(returnWadPath);
|
||||
I_OutputMsg(",%s", returnWadPath);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
{
|
||||
return returnWadPath;
|
||||
}
|
||||
OSX_GetResourcesPath(returnWadPath);
|
||||
I_OutputMsg(",%s", returnWadPath);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
{
|
||||
return returnWadPath;
|
||||
}
|
||||
#endif
|
||||
|
||||
// examine default dirs
|
||||
|
@ -2696,7 +2703,30 @@ const char *I_LocateWad(void)
|
|||
#ifdef __linux__
|
||||
#define MEMINFO_FILE "/proc/meminfo"
|
||||
#define MEMTOTAL "MemTotal:"
|
||||
#define MEMAVAILABLE "MemAvailable:"
|
||||
#define MEMFREE "MemFree:"
|
||||
#define CACHED "Cached:"
|
||||
#define BUFFERS "Buffers:"
|
||||
#define SHMEM "Shmem:"
|
||||
|
||||
/* Parse the contents of /proc/meminfo (in buf), return value of "name"
|
||||
* (example: MemTotal) */
|
||||
static long get_entry(const char* name, const char* buf)
|
||||
{
|
||||
long val;
|
||||
char* hit = strstr(buf, name);
|
||||
if (hit == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
val = strtol(hit + strlen(name), NULL, 10);
|
||||
if (errno != 0) {
|
||||
CONS_Alert(CONS_ERROR, M_GetText("get_entry: strtol() failed: %s\n"), strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
// quick fix for compil
|
||||
|
@ -2758,6 +2788,11 @@ UINT32 I_GetFreeMem(UINT32 *total)
|
|||
UINT32 totalKBytes;
|
||||
INT32 n;
|
||||
INT32 meminfo_fd = -1;
|
||||
long Cached;
|
||||
long MemFree;
|
||||
long Buffers;
|
||||
long Shmem;
|
||||
long MemAvailable = -1;
|
||||
|
||||
meminfo_fd = open(MEMINFO_FILE, O_RDONLY);
|
||||
n = read(meminfo_fd, buf, 1023);
|
||||
|
@ -2783,16 +2818,28 @@ UINT32 I_GetFreeMem(UINT32 *total)
|
|||
memTag += sizeof (MEMTOTAL);
|
||||
totalKBytes = atoi(memTag);
|
||||
|
||||
if ((memTag = strstr(buf, MEMFREE)) == NULL)
|
||||
if ((memTag = strstr(buf, MEMAVAILABLE)) == NULL)
|
||||
{
|
||||
// Error
|
||||
if (total)
|
||||
*total = 0L;
|
||||
return 0;
|
||||
}
|
||||
Cached = get_entry(CACHED, buf);
|
||||
MemFree = get_entry(MEMFREE, buf);
|
||||
Buffers = get_entry(BUFFERS, buf);
|
||||
Shmem = get_entry(SHMEM, buf);
|
||||
MemAvailable = Cached + MemFree + Buffers - Shmem;
|
||||
|
||||
memTag += sizeof (MEMFREE);
|
||||
freeKBytes = atoi(memTag);
|
||||
if (MemAvailable == -1)
|
||||
{
|
||||
// Error
|
||||
if (total)
|
||||
*total = 0L;
|
||||
return 0;
|
||||
}
|
||||
freeKBytes = MemAvailable;
|
||||
}
|
||||
else
|
||||
{
|
||||
memTag += sizeof (MEMAVAILABLE);
|
||||
freeKBytes = atoi(memTag);
|
||||
}
|
||||
|
||||
if (total)
|
||||
*total = totalKBytes << 10;
|
||||
|
@ -2869,5 +2916,5 @@ const CPUInfoFlags *I_CPUInfo(void)
|
|||
}
|
||||
|
||||
// note CPUAFFINITY code used to reside here
|
||||
FUNCMATH void I_RegisterSysCommands(void) {}
|
||||
void I_RegisterSysCommands(void) {}
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Portions Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 2014-2018 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
|
@ -1057,7 +1059,7 @@ void I_SetPalette(RGBA_t *palette)
|
|||
}
|
||||
|
||||
// return number of fullscreen + X11 modes
|
||||
FUNCMATH INT32 VID_NumModes(void)
|
||||
INT32 VID_NumModes(void)
|
||||
{
|
||||
if (USE_FULLSCREEN && numVidModes != -1)
|
||||
return numVidModes - firstEntry;
|
||||
|
@ -1065,7 +1067,7 @@ FUNCMATH INT32 VID_NumModes(void)
|
|||
return MAXWINMODES;
|
||||
}
|
||||
|
||||
FUNCMATH const char *VID_GetModeName(INT32 modeNum)
|
||||
const char *VID_GetModeName(INT32 modeNum)
|
||||
{
|
||||
#if 0
|
||||
if (USE_FULLSCREEN && numVidModes != -1) // fullscreen modes
|
||||
|
@ -1095,7 +1097,7 @@ FUNCMATH const char *VID_GetModeName(INT32 modeNum)
|
|||
return &vidModeName[modeNum][0];
|
||||
}
|
||||
|
||||
FUNCMATH INT32 VID_GetModeForSize(INT32 w, INT32 h)
|
||||
INT32 VID_GetModeForSize(INT32 w, INT32 h)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAXWINMODES; i++)
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2014-2018 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief SDL Mixer interface for sound
|
||||
|
||||
|
@ -49,10 +57,8 @@
|
|||
#include "gme/gme.h"
|
||||
#define GME_TREBLE 5.0
|
||||
#define GME_BASS 1.0
|
||||
#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng
|
||||
|
||||
#define HAVE_ZLIB
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#ifndef _MSC_VER
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
|
@ -68,8 +74,8 @@
|
|||
#endif
|
||||
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif // HAVE_ZLIB
|
||||
#endif // HAVE_LIBGME
|
||||
|
||||
UINT8 sound_started = false;
|
||||
|
||||
|
@ -250,7 +256,7 @@ void I_ShutdownSound(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
FUNCMATH void I_UpdateSound(void)
|
||||
void I_UpdateSound(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -306,7 +312,7 @@ static Mix_Chunk *ds2chunk(void *stream)
|
|||
return NULL; // would and/or did wrap, can't store.
|
||||
break;
|
||||
}
|
||||
sound = malloc(newsamples<<2); // samples * frequency shift * bytes per sample * channels
|
||||
sound = Z_Malloc(newsamples<<2, PU_SOUND, NULL); // samples * frequency shift * bytes per sample * channels
|
||||
|
||||
s = (SINT8 *)stream;
|
||||
d = (INT16 *)sound;
|
||||
|
@ -374,6 +380,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
|
|||
{
|
||||
void *lump;
|
||||
Mix_Chunk *chunk;
|
||||
SDL_RWops *rw;
|
||||
#ifdef HAVE_LIBGME
|
||||
Music_Emu *emu;
|
||||
gme_info_t *info;
|
||||
|
@ -490,7 +497,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
|
|||
}
|
||||
Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
|
||||
#else
|
||||
//CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
|
||||
return NULL; // No zlib support
|
||||
#endif
|
||||
}
|
||||
// Try to read it as a GME sound
|
||||
|
@ -517,21 +524,43 @@ void *I_GetSfx(sfxinfo_t *sfx)
|
|||
#endif
|
||||
|
||||
// Try to load it as a WAVE or OGG using Mixer.
|
||||
return Mix_LoadWAV_RW(SDL_RWFromMem(lump, sfx->length), 1);
|
||||
rw = SDL_RWFromMem(lump, sfx->length);
|
||||
if (rw != NULL)
|
||||
{
|
||||
chunk = Mix_LoadWAV_RW(rw, 1);
|
||||
return chunk;
|
||||
}
|
||||
|
||||
return NULL; // haven't been able to get anything
|
||||
}
|
||||
|
||||
void I_FreeSfx(sfxinfo_t *sfx)
|
||||
{
|
||||
if (sfx->data)
|
||||
{
|
||||
Mix_Chunk *chunk = (Mix_Chunk*)sfx->data;
|
||||
UINT8 *abufdata = NULL;
|
||||
if (chunk->allocated == 0)
|
||||
{
|
||||
// We allocated the data in this chunk, so get the abuf from mixer, then let it free the chunk, THEN we free the data
|
||||
// I believe this should ensure the sound is not playing when we free it
|
||||
abufdata = chunk->abuf;
|
||||
}
|
||||
Mix_FreeChunk(sfx->data);
|
||||
if (abufdata)
|
||||
{
|
||||
// I'm going to assume we used Z_Malloc to allocate this data.
|
||||
Z_Free(abufdata);
|
||||
}
|
||||
}
|
||||
sfx->data = NULL;
|
||||
sfx->lumpnum = LUMPERROR;
|
||||
}
|
||||
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
|
||||
{
|
||||
UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
|
||||
INT32 handle = Mix_PlayChannel(-1, S_sfx[id].data, 0);
|
||||
INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0);
|
||||
Mix_Volume(handle, volume);
|
||||
Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
|
||||
(void)pitch; // Mixer can't handle pitch
|
||||
|
@ -686,7 +715,7 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
|
|||
/// Music System
|
||||
/// ------------------------
|
||||
|
||||
FUNCMATH void I_InitMusic(void)
|
||||
void I_InitMusic(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -987,6 +1016,7 @@ boolean I_LoadSong(char *data, size_t len)
|
|||
|
||||
size_t wstart, wp;
|
||||
char *p = data;
|
||||
SDL_RWops *rw;
|
||||
|
||||
if (music
|
||||
#ifdef HAVE_LIBGME
|
||||
|
@ -1082,7 +1112,8 @@ boolean I_LoadSong(char *data, size_t len)
|
|||
}
|
||||
Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
|
||||
#else
|
||||
//CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
|
||||
CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
else if (!gme_open_data(data, len, &gme, 44100))
|
||||
|
@ -1101,7 +1132,10 @@ boolean I_LoadSong(char *data, size_t len)
|
|||
Mix_Timidity_addToPathList(cv_miditimiditypath.string); // this overwrites previous custom path
|
||||
#endif
|
||||
|
||||
music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE);
|
||||
rw = SDL_RWFromMem(data, len);
|
||||
{
|
||||
music = Mix_LoadMUS_RW(rw, 1);
|
||||
}
|
||||
if (!music)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
|
||||
|
@ -1149,6 +1183,7 @@ boolean I_LoadSong(char *data, size_t len)
|
|||
song_length = (float)(atoi(p) / 1000.0L);
|
||||
}
|
||||
// below: search MP3 or other tags that use wide char encoding
|
||||
// \todo this isn't actually how MP3 stores its tags. We're just using endian markers as context clues.
|
||||
else if (!loop_point && !memcmp(p, key1w, key1len*2)) // LOOP wide char
|
||||
{
|
||||
p += key1len*2;
|
||||
|
|
|
@ -219,7 +219,7 @@ static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio
|
|||
#endif
|
||||
}
|
||||
|
||||
FUNCMATH static inline Uint16 Snd_LowerRate(Uint16 sr)
|
||||
static inline Uint16 Snd_LowerRate(Uint16 sr)
|
||||
{
|
||||
if (sr <= audio.freq) // already lowered rate?
|
||||
return sr; // good then
|
||||
|
@ -604,10 +604,11 @@ void I_FreeSfx(sfxinfo_t * sfx)
|
|||
// Pitching (that is, increased speed of playback)
|
||||
// is set, but currently not used by mixing.
|
||||
//
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
|
||||
{
|
||||
(void)priority;
|
||||
(void)pitch;
|
||||
(void)channel;
|
||||
|
||||
if (sound_disabled)
|
||||
return 0;
|
||||
|
@ -1350,12 +1351,12 @@ musictype_t I_SongType(void)
|
|||
|
||||
boolean I_SongPlaying(void)
|
||||
{
|
||||
return musicStarted;
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean I_SongPaused(void)
|
||||
{
|
||||
return Mix_PausedMusic();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ------------------------
|
||||
|
@ -1379,8 +1380,8 @@ UINT32 I_GetSongLength(void)
|
|||
|
||||
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||
{
|
||||
(void)looppoint;
|
||||
return false;
|
||||
(void)looppoint;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 I_GetSongLoopPoint(void)
|
||||
|
|
|
@ -603,6 +603,9 @@ static void ST_drawDebugInfo(void)
|
|||
|
||||
static void ST_drawScore(void)
|
||||
{
|
||||
if (F_GetPromptHideHud(hudinfo[HUD_SCORE].y))
|
||||
return;
|
||||
|
||||
// SCORE:
|
||||
ST_DrawPatchFromHud(HUD_SCORE, sboscore, V_HUDTRANS);
|
||||
if (objectplacing)
|
||||
|
@ -712,6 +715,9 @@ static void ST_drawTime(void)
|
|||
tictrn = G_TicsToCentiseconds(tics);
|
||||
}
|
||||
|
||||
if (F_GetPromptHideHud(hudinfo[HUD_TIME].y))
|
||||
return;
|
||||
|
||||
// TIME:
|
||||
ST_DrawPatchFromHud(HUD_TIME, ((downwards && (tics < 30*TICRATE) && (leveltime/5 & 1)) ? sboredtime : sbotime), V_HUDTRANS);
|
||||
|
||||
|
@ -738,6 +744,9 @@ static inline void ST_drawRings(void)
|
|||
{
|
||||
INT32 ringnum;
|
||||
|
||||
if (F_GetPromptHideHud(hudinfo[HUD_RINGS].y))
|
||||
return;
|
||||
|
||||
ST_DrawPatchFromHud(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS));
|
||||
|
||||
ringnum = ((objectplacing) ? op_currentdoomednum : max(stplyr->rings, 0));
|
||||
|
@ -756,6 +765,9 @@ static void ST_drawLivesArea(void)
|
|||
if (!stplyr->skincolor)
|
||||
return; // Just joined a server, skin isn't loaded yet!
|
||||
|
||||
if (F_GetPromptHideHud(hudinfo[HUD_LIVES].y))
|
||||
return;
|
||||
|
||||
// face background
|
||||
V_DrawSmallScaledPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y,
|
||||
hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, livesback);
|
||||
|
@ -927,6 +939,9 @@ static void ST_drawInput(void)
|
|||
if (stplyr->powers[pw_carry] == CR_NIGHTSMODE)
|
||||
y -= 16;
|
||||
|
||||
if (F_GetPromptHideHud(y))
|
||||
return;
|
||||
|
||||
// O backing
|
||||
V_DrawFill(x, y-1, 16, 16, hudinfo[HUD_LIVES].f|20);
|
||||
V_DrawFill(x, y+15, 16, 1, hudinfo[HUD_LIVES].f|29);
|
||||
|
@ -1202,6 +1217,9 @@ static void ST_drawPowerupHUD(void)
|
|||
static INT32 flagoffs[2] = {0, 0}, shieldoffs[2] = {0, 0};
|
||||
#define ICONSEP (16+4) // matches weapon rings HUD
|
||||
|
||||
if (F_GetPromptHideHud(hudinfo[HUD_POWERUPS].y))
|
||||
return;
|
||||
|
||||
if (stplyr->spectator || stplyr->playerstate != PST_LIVE)
|
||||
return;
|
||||
|
||||
|
@ -1364,7 +1382,7 @@ static void ST_drawFirstPersonHUD(void)
|
|||
p = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
||||
|
||||
// Display the countdown drown numbers!
|
||||
if (p)
|
||||
if (p && !F_GetPromptHideHud(60 - SHORT(p->topoffset)))
|
||||
V_DrawScaledPatch((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset), 60 - SHORT(p->topoffset),
|
||||
V_PERPLAYER|V_PERPLAYER|V_TRANSLUCENT, p);
|
||||
}
|
||||
|
@ -1908,6 +1926,9 @@ static void ST_drawMatchHUD(void)
|
|||
const INT32 y = 176; // HUD_LIVES
|
||||
INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10) - 6;
|
||||
|
||||
if (F_GetPromptHideHud(y))
|
||||
return;
|
||||
|
||||
if (!G_RingSlingerGametype())
|
||||
return;
|
||||
|
||||
|
@ -1954,6 +1975,9 @@ static void ST_drawTextHUD(void)
|
|||
y -= 8;\
|
||||
}
|
||||
|
||||
if (F_GetPromptHideHud(y))
|
||||
return;
|
||||
|
||||
if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator))
|
||||
{
|
||||
if (leveltime < hidetime * TICRATE)
|
||||
|
@ -2087,6 +2111,9 @@ static void ST_drawTeamHUD(void)
|
|||
patch_t *p;
|
||||
#define SEP 20
|
||||
|
||||
if (F_GetPromptHideHud(0)) // y base is 0
|
||||
return;
|
||||
|
||||
if (gametype == GT_CTF)
|
||||
p = bflagico;
|
||||
else
|
||||
|
@ -2200,7 +2227,8 @@ static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offse
|
|||
interval = 0;
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, hudinfo[HUD_HUNTPICS].f|V_PERPLAYER|V_HUDTRANS, patches[i]);
|
||||
if (!F_GetPromptHideHud(hudinfo[HUD_HUNTPICS].y))
|
||||
V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, hudinfo[HUD_HUNTPICS].f|V_PERPLAYER|V_HUDTRANS, patches[i]);
|
||||
return interval;
|
||||
}
|
||||
|
||||
|
@ -2298,7 +2326,8 @@ static void ST_overlayDrawer(void)
|
|||
//hu_showscores = auto hide score/time/rings when tab rankings are shown
|
||||
if (!(hu_showscores && (netgame || multiplayer)))
|
||||
{
|
||||
if (maptol & TOL_NIGHTS || G_IsSpecialStage(gamemap))
|
||||
if ((maptol & TOL_NIGHTS || G_IsSpecialStage(gamemap)) &&
|
||||
!F_GetPromptHideHudAll())
|
||||
ST_drawNiGHTSHUD();
|
||||
else
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
//
|
||||
|
||||
// Called by main loop.
|
||||
FUNCMATH void ST_Ticker(void);
|
||||
void ST_Ticker(void);
|
||||
|
||||
// Called by main loop.
|
||||
void ST_Drawer(void);
|
||||
|
|
|
@ -532,7 +532,6 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
|
|||
{
|
||||
UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t);
|
||||
UINT32 alphalevel = 0;
|
||||
boolean flip = false;
|
||||
|
||||
fixed_t col, ofs, colfrac, rowfrac, fdup;
|
||||
INT32 dupx, dupy;
|
||||
|
@ -610,22 +609,32 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
|
|||
colfrac = FixedDiv(FRACUNIT, fdup);
|
||||
rowfrac = FixedDiv(FRACUNIT, fdup);
|
||||
|
||||
if (scrn & V_OFFSET) // Crosshair shit
|
||||
// So it turns out offsets aren't scaled in V_NOSCALESTART unless V_OFFSET is applied ...poo, that's terrible
|
||||
// For now let's just at least give V_OFFSET the ability to support V_FLIP
|
||||
// I'll probably make a better fix for 2.2 where I don't have to worry about breaking existing support for stuff
|
||||
// -- Monster Iestyn 29/10/18
|
||||
{
|
||||
y -= FixedMul((SHORT(patch->topoffset)*dupy)<<FRACBITS, pscale);
|
||||
x -= FixedMul((SHORT(patch->leftoffset)*dupx)<<FRACBITS, pscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
y -= FixedMul(SHORT(patch->topoffset)<<FRACBITS, pscale);
|
||||
fixed_t offsetx = 0, offsety = 0;
|
||||
|
||||
// left offset
|
||||
if (scrn & V_FLIP)
|
||||
{
|
||||
flip = true;
|
||||
x -= FixedMul((SHORT(patch->width) - SHORT(patch->leftoffset))<<FRACBITS, pscale) + 1;
|
||||
}
|
||||
offsetx = FixedMul((SHORT(patch->width) - SHORT(patch->leftoffset))<<FRACBITS, pscale) + 1;
|
||||
else
|
||||
x -= FixedMul(SHORT(patch->leftoffset)<<FRACBITS, pscale);
|
||||
offsetx = FixedMul(SHORT(patch->leftoffset)<<FRACBITS, pscale);
|
||||
|
||||
// top offset
|
||||
// TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!?
|
||||
offsety = FixedMul(SHORT(patch->topoffset)<<FRACBITS, pscale);
|
||||
|
||||
if ((scrn & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs
|
||||
{
|
||||
offsetx = FixedMul(offsetx, dupx<<FRACBITS);
|
||||
offsety = FixedMul(offsety, dupy<<FRACBITS);
|
||||
}
|
||||
|
||||
// Subtract the offsets from x/y positions
|
||||
x -= offsetx;
|
||||
y -= offsety;
|
||||
}
|
||||
|
||||
if (splitscreen && (scrn & V_PERPLAYER))
|
||||
|
@ -774,7 +783,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
|
|||
for (col = 0; (col>>FRACBITS) < SHORT(patch->width); col += colfrac, ++offx, desttop++)
|
||||
{
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
if (flip) // offx is measured from right edge instead of left
|
||||
if (scrn & V_FLIP) // offx is measured from right edge instead of left
|
||||
{
|
||||
if (x+pwidth-offx < 0) // don't draw off the left of the screen (WRAP PREVENTION)
|
||||
break;
|
||||
|
@ -798,7 +807,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
|
|||
prevdelta = topdelta;
|
||||
source = (const UINT8 *)(column) + 3;
|
||||
dest = desttop;
|
||||
if (flip)
|
||||
if (scrn & V_FLIP)
|
||||
dest = deststart + (destend - desttop);
|
||||
dest += FixedInt(FixedMul(topdelta<<FRACBITS,fdup))*vid.width;
|
||||
|
||||
|
@ -1045,7 +1054,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
|
|||
//
|
||||
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
|
||||
{
|
||||
if (skins[skinnum].flags & SF_HIRES)
|
||||
if (skinnum < 0 || skinnum >= numskins || (skins[skinnum].flags & SF_HIRES))
|
||||
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
|
||||
else
|
||||
{
|
||||
|
@ -1480,6 +1489,49 @@ void V_DrawFadeConsBack(INT32 plines)
|
|||
*buf = consolebgmap[*buf];
|
||||
}
|
||||
|
||||
// Very similar to F_DrawFadeConsBack, except we draw from the middle(-ish) of the screen to the bottom.
|
||||
void V_DrawPromptBack(INT32 boxheight, INT32 color)
|
||||
{
|
||||
UINT8 *deststop, *buf;
|
||||
|
||||
boxheight *= vid.dupy;
|
||||
|
||||
if (color == INT32_MAX)
|
||||
color = cons_backcolor.value;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft && rendermode != render_none)
|
||||
{
|
||||
UINT32 hwcolor;
|
||||
switch (color)
|
||||
{
|
||||
case 0: hwcolor = 0xffffff00; break; // White
|
||||
case 1: hwcolor = 0x00000000; break; // Gray // Note this is different from V_DrawFadeConsBack
|
||||
case 2: hwcolor = 0x40201000; break; // Brown
|
||||
case 3: hwcolor = 0xff000000; break; // Red
|
||||
case 4: hwcolor = 0xff800000; break; // Orange
|
||||
case 5: hwcolor = 0x80800000; break; // Yellow
|
||||
case 6: hwcolor = 0x00800000; break; // Green
|
||||
case 7: hwcolor = 0x0000ff00; break; // Blue
|
||||
case 8: hwcolor = 0x4080ff00; break; // Cyan
|
||||
// Default green
|
||||
default: hwcolor = 0x00800000; break;
|
||||
}
|
||||
HWR_DrawTutorialBack(hwcolor, boxheight);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CON_SetupBackColormapEx(color, true);
|
||||
|
||||
// heavily simplified -- we don't need to know x or y position,
|
||||
// just the start and stop positions
|
||||
deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
buf = deststop - vid.rowbytes * ((boxheight * 4) + (boxheight/2)*5); // 4 lines of space plus gaps between and some leeway
|
||||
for (; buf < deststop; ++buf)
|
||||
*buf = promptbgmap[*buf];
|
||||
}
|
||||
|
||||
// Gets string colormap, used for 0x80 color codes
|
||||
//
|
||||
static const UINT8 *V_GetStringColormap(INT32 colorflags)
|
||||
|
|
|
@ -158,6 +158,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum);
|
|||
void V_DrawFadeScreen(UINT16 color, UINT8 strength);
|
||||
|
||||
void V_DrawFadeConsBack(INT32 plines);
|
||||
void V_DrawPromptBack(INT32 boxheight, INT32 color);
|
||||
|
||||
// draw a single character
|
||||
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed);
|
||||
|
|
14
src/w_wad.c
14
src/w_wad.c
|
@ -234,10 +234,10 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum)
|
|||
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
|
||||
if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
|
||||
{ // shameless copy+paste of code from LUA_LoadLump
|
||||
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
||||
char *name = malloc(length + 1);
|
||||
size_t len = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
|
||||
char *name = malloc(len+1);
|
||||
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
|
||||
name[length] = '\0';
|
||||
name[len] = '\0';
|
||||
|
||||
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
|
||||
DEH_LoadDehackedLumpPwad(wadnum, lump);
|
||||
|
@ -389,6 +389,8 @@ UINT16 W_InitFile(const char *filename)
|
|||
if (!memcmp(wadfiles[i]->md5sum, md5sum, 16))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename);
|
||||
if (handle)
|
||||
fclose(handle);
|
||||
return INT16_MAX;
|
||||
}
|
||||
}
|
||||
|
@ -634,6 +636,8 @@ UINT16 W_InitFile(const char *filename)
|
|||
if (fread(&header, 1, sizeof header, handle) < sizeof header)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't read wad header from %s because %s\n"), filename, strerror(ferror(handle)));
|
||||
if (handle)
|
||||
fclose(handle);
|
||||
return INT16_MAX;
|
||||
}
|
||||
|
||||
|
@ -644,6 +648,8 @@ UINT16 W_InitFile(const char *filename)
|
|||
&& memcmp(header.identification, "SDLL", 4) != 0)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s does not have a valid WAD header\n"), filename);
|
||||
if (handle)
|
||||
fclose(handle);
|
||||
return INT16_MAX;
|
||||
}
|
||||
|
||||
|
@ -658,6 +664,8 @@ UINT16 W_InitFile(const char *filename)
|
|||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Wadfile directory in %s is corrupted (%s)\n"), filename, strerror(ferror(handle)));
|
||||
free(fileinfov);
|
||||
if (handle)
|
||||
fclose(handle);
|
||||
return INT16_MAX;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,8 @@
|
|||
#include "gme/gme.h"
|
||||
#define GME_TREBLE 5.0
|
||||
#define GME_BASS 1.0
|
||||
#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng
|
||||
|
||||
#define HAVE_ZLIB
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#ifndef _MSC_VER
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
|
@ -36,8 +34,8 @@
|
|||
#endif
|
||||
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif // HAVE_ZLIB
|
||||
#endif // HAVE_LIBGME
|
||||
|
||||
static FMOD_SYSTEM *fsys;
|
||||
static FMOD_SOUND *music_stream;
|
||||
|
@ -354,12 +352,13 @@ void I_FreeSfx(sfxinfo_t *sfx)
|
|||
sfx->data = NULL;
|
||||
}
|
||||
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
|
||||
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
|
||||
{
|
||||
FMOD_SOUND *sound;
|
||||
FMOD_CHANNEL *chan;
|
||||
INT32 i;
|
||||
float frequency;
|
||||
(void)channel;
|
||||
|
||||
sound = (FMOD_SOUND *)S_sfx[id].data;
|
||||
I_Assert(sound != NULL);
|
||||
|
@ -927,6 +926,7 @@ boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms
|
|||
(void)target_volume;
|
||||
(void)source_volume;
|
||||
(void)ms;
|
||||
(void)callback;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -934,6 +934,7 @@ boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
|
|||
{
|
||||
(void)target_volume;
|
||||
(void)ms;
|
||||
(void)callback;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue