Merge branch 'master' of github.com:chocolate-doom/chocolate-doom

This commit is contained in:
Fabian Greffrath 2024-02-26 22:09:23 +01:00
commit 580096dd8c
34 changed files with 482 additions and 92 deletions

View file

@ -19,9 +19,9 @@ jobs:
compiler: [clang]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install libfluidsynth-dev libpng-dev libsamplerate0-dev libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-net-dev ninja-build
run: sudo apt-get update && sudo apt-get install libfluidsynth-dev libpng-dev libsamplerate0-dev libsdl2-dev libsdl2-mixer-dev libsdl2-net-dev ninja-build
- name: Run cmake to generate compilation database
run: cmake -S . -B . -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=1
- uses: cpp-linter/cpp-linter-action@v2

View file

@ -9,13 +9,13 @@ on:
jobs:
cppcheck:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install cppcheck
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Run cppcheck
env:

View file

@ -4,6 +4,8 @@ on:
push:
branches:
- "master"
tags:
- "*"
paths-ignore:
- "**.md"
pull_request:
@ -33,6 +35,9 @@ jobs:
os: macos-latest
compiler: clang
shell: bash
artifacts: true
pkg-path: pkg/osx/*.dmg
pkg-dir: pkg/osx
- name: MSYS2 UCRT64
os: windows-latest
@ -40,6 +45,9 @@ jobs:
shell: 'msys2 {0}'
msystem: ucrt64
msys-env: mingw-w64-ucrt-x86_64
artifacts: true
pkg-path: pkg/win32/*.zip
pkg-dir: pkg/win32
- name: MSYS2 MINGW32
os: windows-latest
@ -47,6 +55,9 @@ jobs:
shell: 'msys2 {0}'
msystem: mingw32
msys-env: mingw-w64-i686
artifacts: true
pkg-path: pkg/win32/*.zip
pkg-dir: pkg/win32
steps:
- name: Install pandoc
@ -84,7 +95,7 @@ jobs:
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.config.msystem }}
update: false
update: true
path-type: inherit
install: >-
autotools
@ -115,28 +126,30 @@ jobs:
PREFIX=`sed -n '/PROGRAM_PREFIX/p' ${PWD}/config.h | cut -d '"' -f 2`
make -j4 -C quickcheck check SOURCE_PORT=$PWD/src/${PREFIX}doom
- name: Package (macOS)
if: runner.os == 'macOS'
- name: Package
if: ${{ matrix.config.artifacts }}
run: |
cd pkg/osx
cd ${{ matrix.config.pkg-dir }}
make
- name: Package (MSYS2)
if: runner.os == 'Windows'
- name: Upload artifacts
if: ${{ matrix.config.artifacts }}
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.config.name }}
path: ${{ matrix.config.pkg-path }}
- name: Extract Package String
if: ${{ contains(github.ref, 'tags') }}
run: |
cd pkg/win32
make
PACKAGE_STRING=`sed -n '/PACKAGE_STRING/p' ${PWD}/config.h | cut -d '"' -f 2`
echo "PACKAGE_STRING=${PACKAGE_STRING}" >> $GITHUB_ENV
- name: Upload artifacts (macOS)
if: runner.os == 'macOS'
uses: actions/upload-artifact@v3
- name: Release
if: ${{ contains(github.ref, 'tags') && matrix.config.artifacts }}
uses: ncipollo/release-action@v1
with:
name: macOS
path: pkg/osx/*.dmg
- name: Upload artifacts (MSYS2)
if: runner.os == 'Windows'
uses: actions/upload-artifact@v3
with:
name: Win-${{ matrix.config.msystem }}
path: pkg/win32/*.zip
name: ${{ env.PACKAGE_STRING }}
bodyFile: RELEASE_NOTES.md
allowUpdates: true
artifacts: ${{ matrix.config.pkg-path }}

View file

@ -15,7 +15,7 @@ set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/fabiangreffrath/crispy-doom/issues")
string(REGEX REPLACE " Doom$" "" PACKAGE_SHORTNAME "${PACKAGE_NAME}")
set(PACKAGE_COPYRIGHT "Copyright (C) 1993-2023")
set(PACKAGE_COPYRIGHT "Copyright (C) 1993-2024")
set(PACKAGE_LICENSE "GNU General Public License, version 2")
# Any settings that should apply to all targets in this directory and all

View file

@ -26,7 +26,7 @@ of compatibility:
* DOS Doom 1.9 (although there are actually multiple “1.9”s).
* DOS Heretic 1.3.
* DOS Hexen 1.1.
* DOS Hexen 1.1 (although there are actually two known “1.1”s).
* DOS Strife 1.31.
* DOS Chex Quest.

1
RELEASE_NOTES.md Normal file
View file

@ -0,0 +1 @@
Test

View file

@ -3,7 +3,7 @@ AC_INIT(Crispy Doom, 6.0.0,
PACKAGE_SHORTNAME=${PACKAGE_NAME% Doom}
PACKAGE_SHORTDESC="Limit-removing enhanced-resolution Doom source port"
PACKAGE_COPYRIGHT="Copyright (C) 1993-2023"
PACKAGE_COPYRIGHT="Copyright (C) 1993-2024"
PACKAGE_LICENSE="GNU General Public License, version 2"
PACKAGE_MAINTAINER="Fabian Greffrath"
PACKAGE_URL="http://fabiangreffrath.github.io/crispy-doom"
@ -31,6 +31,19 @@ then
CFLAGS="-O$OPT_LEVEL -g $WARNINGS $orig_CFLAGS"
fi
AC_CANONICAL_TARGET
TARGET_OS=""
AS_CASE([$target_cpu],
[x86_64|aarch64*],
[
TARGET_OS="64"
],
[i?86|arm*],
[
TARGET_OS="32"
])
AC_SUBST([TARGET_OS])
PKG_CHECK_MODULES(SDL, [sdl2 >= 2.0.14])
# Check for SDL2_mixer
AC_ARG_ENABLE([sdl2mixer],

View file

@ -27,6 +27,9 @@ _@PROGRAM_SPREFIX@_hexen()
esac
case $prev in
-gameversion)
COMPREPLY=(1.1 1.1r2)
;;
-setmem)
COMPREPLY=(dos622 dos71 dosbox)
;;

View file

@ -1,32 +1,32 @@
.TH @PROGRAM_SPREFIX@\-doom.cfg 5
.TH @PROGRAM_SPREFIX@\-@GAME@.cfg 5
.SH NAME
@PROGRAM_SPREFIX@\-doom.cfg \- @PACKAGE_NAME@ configuration file
@PROGRAM_SPREFIX@\-@GAME@.cfg \- @PACKAGE_SHORTNAME@ @GAME_UPPER@ configuration file
.SH DESCRIPTION
.PP
\fI@PROGRAM_SPREFIX@\-doom.cfg\fR
is a configuration file for \fB@PROGRAM_SPREFIX@\-doom\fR(6). This file acts
\fI@PROGRAM_SPREFIX@\-@GAME@.cfg\fR
is a configuration file for \fB@PROGRAM_SPREFIX@\-@GAME@\fR(6). This file acts
as an auxiliary configuration file; the main configuration options
are stored in \fBdefault.cfg\fR, which contains the same configuration
options as Vanilla Doom (for compatibility). \fI@PROGRAM_SPREFIX@\-doom.cfg\fR
contains configuration options that are specific to @PACKAGE_NAME@
are stored in \fB@CFGFILE@\fR, which contains the same configuration
options as Vanilla @GAME_UPPER@ (for compatibility). \fI@PROGRAM_SPREFIX@\-@GAME@.cfg\fR
contains configuration options that are specific to @PACKAGE_SHORTNAME@\-@GAME_UPPER@
only.
.PP
\fI@PROGRAM_SPREFIX@\-doom.cfg\fR is normally stored in the user's home directory,
as \fI~/.local/share/@PROGRAM_SPREFIX@\-doom/@PROGRAM_SPREFIX@\-doom.cfg\fR. The path can be
\fI@PROGRAM_SPREFIX@\-@GAME@.cfg\fR is normally stored in the user's home directory,
as \fI~/.local/share/@PROGRAM_SPREFIX@\-@GAME@/@PROGRAM_SPREFIX@\-@GAME@.cfg\fR. The path can be
overridden using the \fBXDG_DATA_HOME\fR environment variable (see the XDG
Base Directory Specification).
.PP
The \fB@PROGRAM_SPREFIX@\-setup\fR(6) tool provides a simple to use front-end
for editing \fI@PROGRAM_SPREFIX@\-doom.cfg\fR.
The \fB@PROGRAM_SPREFIX@\-@GAME@\-setup\fR(6) tool provides a simple to use front-end
for editing \fI@PROGRAM_SPREFIX@\-@GAME@.cfg\fR.
.SH FILE FORMAT
.PP
The file format is the same as that used for \fBdefault.cfg\fR(5).
The file format is the same as that used for \fB@CFGFILE@\fR(5).
.br
@content
.SH SEE ALSO
\fB@PROGRAM_SPREFIX@\-doom\fR(6),
\fBdefault.cfg\fR(5),
\fB@PROGRAM_SPREFIX@\-setup\fR(6)
\fB@PROGRAM_SPREFIX@\-@GAME@\fR(6),
\fB@CFGFILE@\fR(5),
\fB@PROGRAM_SPREFIX@\-@GAME@\-setup\fR(6)

View file

@ -19,6 +19,8 @@ PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
TARGET_OS = @TARGET_OS@
# Documentation files to distribute with packages.
DOC_FILES = README.md \

View file

@ -3,11 +3,10 @@ include ../config.make
TOPLEVEL=../..
SYS:=$(shell uname)
ifneq (, $(findstring MINGW64, $(SYS)))
POSTFIX=win64
ifeq ($(TARGET_OS),64)
POSTFIX=win64
else
POSTFIX=win32
POSTFIX=win32
endif
DOOM_ZIP=$(PROGRAM_PREFIX)doom-$(PACKAGE_VERSION)-$(POSTFIX).zip

View file

@ -134,6 +134,7 @@ static struct {
{ doom, exe_chex },
{ heretic, exe_heretic_1_3 },
{ hexen, exe_hexen_1_1 },
{ hexen, exe_hexen_1_1r2 },
{ strife, exe_strife_1_2 },
{ strife, exe_strife_1_31 },
};

View file

@ -73,6 +73,7 @@ typedef enum
exe_heretic_1_3, // Heretic 1.3
exe_hexen_1_1, // Hexen 1.1
exe_hexen_1_1r2, // Hexen 1.1 (alternate exe)
exe_strife_1_2, // Strife v1.2
exe_strife_1_31 // Strife v1.31
} GameVersion_t;

View file

@ -1110,7 +1110,7 @@ void PrintDehackedBanners(void)
}
}
static struct
static const struct
{
const char *description;
const char *cmdline;
@ -1140,11 +1140,11 @@ static void InitGameVersion(void)
int i;
boolean status;
//!
//!
// @arg <version>
// @category compat
//
// Emulate a specific version of Doom. Valid values are "1.2",
// Emulate a specific version of Doom. Valid values are "1.2",
// "1.666", "1.7", "1.8", "1.9", "ultimate", "final", "final2",
// "hacx" and "chex".
//
@ -1161,8 +1161,8 @@ static void InitGameVersion(void)
break;
}
}
if (gameversions[i].description == NULL)
if (gameversions[i].description == NULL)
{
printf("Supported game versions:\n");
@ -1171,7 +1171,7 @@ static void InitGameVersion(void)
printf("\t%s (%s)\n", gameversions[i].cmdline,
gameversions[i].description);
}
I_Error("Unknown game version '%s'", myargv[p+1]);
}
}
@ -1260,7 +1260,7 @@ static void InitGameVersion(void)
{
deathmatch = 1;
}
// The original exe does not support retail - 4th episode not supported
if (gameversion < exe_ultimate && gamemode == retail)

View file

@ -320,6 +320,12 @@ static int G_NextWeapon(int direction)
}
}
// The current weapon must be present in weapon_order_table
// otherwise something has gone terribly wrong
if (i >= arrlen(weapon_order_table)) {
I_Error("Internal error: weapon %d not present in weapon_order_table", weapon);
}
// Switch weapon. Don't loop forever.
start_i = i;
do

View file

@ -64,6 +64,9 @@ void G_DoSaveGame(void);
void D_PageTicker(void);
void D_AdvanceDemo(void);
static boolean InventoryMoveLeft();
static boolean InventoryMoveRight();
struct
{
int type; // mobjtype_t
@ -272,6 +275,12 @@ static int G_NextWeapon(int direction)
}
}
// The current weapon must be present in weapon_order_table
// otherwise something has gone terribly wrong
if (i >= arrlen(weapon_order_table)) {
I_Error("Internal error: weapon %d not present in weapon_order_table", weapon);
}
// Switch weapon. Don't loop forever.
start_i = i;
do
@ -574,15 +583,15 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
// haleyjd: removed externdriver crap
// Fly up/down/drop keys
if (gamekeydown[key_flyup])
if (gamekeydown[key_flyup] || joybuttons[joybflyup])
{
flyheight = 5; // note that the actual flyheight will be twice this
}
if (gamekeydown[key_flydown])
if (gamekeydown[key_flydown] || joybuttons[joybflydown])
{
flyheight = -5;
}
if (gamekeydown[key_flycenter])
if (gamekeydown[key_flycenter] || joybuttons[joybflycenter])
{
flyheight = TOCENTER;
// haleyjd: removed externdriver crap
@ -590,7 +599,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
}
// Use artifact key
if (gamekeydown[key_useartifact] || mousebuttons[mousebuseartifact])
if (gamekeydown[key_useartifact] || mousebuttons[mousebuseartifact]
|| joybuttons[joybuseartifact])
{
if (gamekeydown[key_speed] && !noartiskip)
{
@ -990,6 +1000,9 @@ void G_DoLoadLevel(void)
static void SetJoyButtons(unsigned int buttons_mask)
{
int i;
player_t* plr;
plr = &players[consoleplayer];
for (i=0; i<MAX_JOY_BUTTONS; ++i)
{
@ -1009,6 +1022,22 @@ static void SetJoyButtons(unsigned int buttons_mask)
{
next_weapon = 1;
}
else if (i == joybinvleft)
{
InventoryMoveLeft();
}
else if (i == joybinvright)
{
InventoryMoveRight();
}
else if (i == joybuseartifact)
{
if (!inventory)
{
plr->readyArtifact = plr->inventory[inv_ptr].type;
}
usearti = true;
}
}
joybuttons[i] = button_on;

View file

@ -1222,14 +1222,21 @@ boolean PTR_AimTraverse(intercept_t * in)
dist = FixedMul(attackrange, in->frac);
if (li->frontsector->floorheight != li->backsector->floorheight)
// Added checks if there is no backsector to prevent crashing.
// Crashes didn't happen in the DOS version of Heretic
// because reading NULL pointer produces unpredictable but
// deterministic values instead of crashing.
// See https://github.com/chocolate-doom/chocolate-doom/issues/1665
if (li->backsector == NULL
|| li->frontsector->floorheight != li->backsector->floorheight)
{
slope = FixedDiv(openbottom - shootz, dist);
if (slope > bottomslope)
bottomslope = slope;
}
if (li->frontsector->ceilingheight != li->backsector->ceilingheight)
if (li->backsector == NULL
|| li->frontsector->ceilingheight != li->backsector->ceilingheight)
{
slope = FixedDiv(opentop - shootz, dist);
if (slope < topslope)

View file

@ -1821,7 +1821,7 @@ void A_GauntletAttack(mobj_t *actor, player_t *player, pspdef_t *psp)
linetarget->x, linetarget->y);
if (angle - player->mo->angle > ANG180)
{
if (angle - player->mo->angle < -ANG90 / 20)
if ((signed int) (angle - player->mo->angle) < -ANG90 / 20)
player->mo->angle = angle + ANG90 / 21;
else
player->mo->angle -= ANG90 / 20;

View file

@ -1174,11 +1174,9 @@ void A_SoAExplode(mobj_t *actor, player_t *player, pspdef_t *psp)
}
if (actor->args[0])
{ // Spawn an item
#if 0 // Checks are not present in version 1.1
if (!nomonsters
if ((gameversion != exe_hexen_1_1r2) || !nomonsters
|| !(mobjinfo[TranslateThingType[actor->args[0]]].
flags & MF_COUNTKILL))
#endif
{ // Only spawn monsters if not -nomonsters
P_SpawnMobj(actor->x, actor->y, actor->z,
TranslateThingType[actor->args[0]]);

View file

@ -60,6 +60,9 @@ void G_DoSingleReborn(void);
void H2_PageTicker(void);
void H2_AdvanceDemo(void);
static boolean InventoryMoveLeft();
static boolean InventoryMoveRight();
gameaction_t gameaction;
gamestate_t gamestate;
@ -499,22 +502,23 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
// haleyjd: removed externdriver crap
// Fly up/down/drop keys
if (gamekeydown[key_flyup])
if (gamekeydown[key_flyup] || joybuttons[joybflyup])
{
flyheight = 5; // note that the actual flyheight will be twice this
}
if (gamekeydown[key_flydown])
if (gamekeydown[key_flydown] || joybuttons[joybflydown])
{
flyheight = -5;
}
if (gamekeydown[key_flycenter])
if (gamekeydown[key_flycenter] || joybuttons[joybflycenter])
{
flyheight = TOCENTER;
// haleyjd: removed externdriver crap
look = TOCENTER;
}
// Use artifact key
if (gamekeydown[key_useartifact] || mousebuttons[mousebuseartifact])
if (gamekeydown[key_useartifact] || mousebuttons[mousebuseartifact]
|| joybuttons[joybuseartifact])
{
if (gamekeydown[key_speed] && artiskip)
{
@ -522,6 +526,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, int maketic)
{ // Skip an artifact
gamekeydown[key_useartifact] = false;
mousebuttons[mousebuseartifact] = false;
joybuttons[joybuseartifact] = false;
P_PlayerNextArtifact(&players[consoleplayer]);
}
}
@ -920,6 +925,9 @@ void G_DoLoadLevel(void)
static void SetJoyButtons(unsigned int buttons_mask)
{
int i;
player_t *plr;
plr = &players[consoleplayer];
for (i=0; i<MAX_JOY_BUTTONS; ++i)
{
@ -939,6 +947,22 @@ static void SetJoyButtons(unsigned int buttons_mask)
{
next_weapon = 1;
}
else if (i == joybinvleft)
{
InventoryMoveLeft();
}
else if (i == joybinvright)
{
InventoryMoveRight();
}
else if (i == joybuseartifact)
{
if (!inventory)
{
plr->readyArtifact = plr->inventory[inv_ptr].type;
}
usearti = true;
}
}
joybuttons[i] = button_on;

View file

@ -93,6 +93,7 @@ static void CrispyDrawStats(void); // [crispy]
// PUBLIC DATA DEFINITIONS -------------------------------------------------
GameMode_t gamemode;
GameVersion_t gameversion = exe_hexen_1_1;
static const char *gamedescription;
char *iwadfile;
static char demolumpname[9]; // Demo lump to start playing.
@ -379,6 +380,81 @@ void D_SetGameDescription(void)
}
}
static const struct
{
const char *description;
const char *cmdline;
GameVersion_t version;
} gameversions[] = {
{"Hexen 1.1", "1.1", exe_hexen_1_1},
{"Hexen 1.1 (alt)", "1.1r2", exe_hexen_1_1r2},
{ NULL, NULL, 0},
};
// Initialize the game version
static void InitGameVersion(void)
{
int p;
//!
// @arg <version>
// @category compat
//
// Emulate a specific version of Hexen.
// Valid values are "1.1" and "1.1r2".
//
p = M_CheckParmWithArgs("-gameversion", 1);
if (p)
{
int i;
for (i=0; gameversions[i].description != NULL; ++i)
{
if (!strcmp(myargv[p+1], gameversions[i].cmdline))
{
gameversion = gameversions[i].version;
break;
}
}
if (gameversions[i].description == NULL)
{
printf("Supported game versions:\n");
for (i=0; gameversions[i].description != NULL; ++i)
{
printf("\t%s (%s)\n", gameversions[i].cmdline,
gameversions[i].description);
}
I_Error("Unknown game version '%s'", myargv[p+1]);
}
}
else
{
// Determine automatically
gameversion = exe_hexen_1_1;
}
}
void PrintGameVersion(void)
{
int i;
for (i=0; gameversions[i].description != NULL; ++i)
{
if (gameversions[i].version == gameversion)
{
printf("Emulating the behavior of the "
"'%s' executable.\n", gameversions[i].description);
break;
}
}
}
static const char *const loadparms[] = {"-file", "-merge", NULL}; // [crispy]
//==========================================================================
@ -464,6 +540,7 @@ void D_DoomMain(void)
D_AddFile(iwadfile);
W_CheckCorrectIWAD(hexen);
D_IdentifyVersion();
InitGameVersion();
D_SetGameDescription();
AdjustForMacIWAD();
@ -565,6 +642,8 @@ void D_DoomMain(void)
ST_Message("D_CheckNetGame: Checking network game status.\n");
D_CheckNetGame();
PrintGameVersion();
ST_Message("SB_Init: Loading patches.\n");
SB_Init();

View file

@ -73,6 +73,8 @@
//#endif
#define HEXEN_VERSIONTEXT ((gamemode == shareware) ? \
"DEMO 10 16 95" : \
(gameversion != exe_hexen_1_1r2) ? \
"VERSION 1.1 MAR 12 1996 (CBI)" : \
"VERSION 1.1 MAR 22 1996 (BCP)")
// all exterior data is defined here
@ -611,7 +613,8 @@ void NET_SendFrags(player_t * player);
#define TELEFOGHEIGHT (32*FRACUNIT)
extern GameMode_t gamemode; // Always commercial
extern GameMode_t gamemode;
extern GameVersion_t gameversion;
extern gameaction_t gameaction;

View file

@ -528,6 +528,7 @@ boolean P_LookForPlayers(mobj_t * actor, boolean allaround)
player_t *player;
angle_t an;
fixed_t dist;
int consecutive_missing = 0; // for breaking infinite loop
if (!netgame && players[0].health <= 0)
{ // Single player game and player is dead, look for monsters
@ -535,18 +536,38 @@ boolean P_LookForPlayers(mobj_t * actor, boolean allaround)
}
c = 0;
// NOTE: This behavior has been changed from the Vanilla behavior, where
// an infinite loop can occur if players 0-3 all quit the game. Although
// technically this is not what Vanilla does, fixing this is highly
// desirable, and having the game simply lock up is not acceptable.
// stop = (actor->lastlook - 1) & 3;
// for (;; actor->lastlook = (actor->lastlook + 1) & 3)
// The 3 below is probably a mistake (it should be MAXPLAYERS - 1, or 7)
// and in vanilla this can potentially cause an infinite loop in
// multiplayer. Unfortunately we can't correct the mistake - doing so will
// cause desyncs. Upon spawning, each enemy's lastlook is initialized to a
// random value between 0 and 7 (i.e MAXPLAYERS - 1). There's a chance
// that the first call of this function for that enemy will return early
// courtesy of the actor->lastlook == stop condition. In a single-player
// game this occurs when (actor->lastlook - 1) & 3 equals 0, or when
// lastlook equals 1 or 5.
stop = (actor->lastlook + maxplayers - 1) % maxplayers;
for (;; actor->lastlook = (actor->lastlook + 1) % maxplayers)
// If you use MAXPLAYERS - 1, it has the side effect of altering which
// enemies are affected by an early actor->lastlook == stop return. Now it
// happens when (actor->lastlook - 1) & 7 equals 0, or when lastlook equals
// 1, *not* 1 and 5 as above.
stop = (actor->lastlook - 1) & 3;
for (;; actor->lastlook = (actor->lastlook + 1) & 3)
{
if (!playeringame[actor->lastlook])
{
// Break the vanilla infinite loop here. It can occur if there are
// > 4 players and players 0 - 3 all quit the game. Error out
// instead.
if (consecutive_missing == 4)
{
I_Error("P_LookForPlayers: No player 1 - 4.\n");
}
consecutive_missing++;
continue;
}
consecutive_missing = 0;
if (c++ == 2 || actor->lastlook == stop)
return false; // done looking

View file

@ -90,7 +90,7 @@ int joystick_look_sensitivity = 10;
// Virtual to physical button joystick button mapping. By default this
// is a straight mapping.
static int joystick_physical_buttons[NUM_VIRTUAL_BUTTONS] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
};
void I_ShutdownGamepad(void)

View file

@ -24,7 +24,7 @@
// Number of "virtual" joystick buttons defined in configuration files.
// This needs to be at least as large as the number of different key
// bindings supported by the higher-level game code (joyb* variables).
#define NUM_VIRTUAL_BUTTONS 11
#define NUM_VIRTUAL_BUTTONS 17
// Max allowed number of virtual mappings. Chosen to be less than joybspeed
// autorun value.

View file

@ -1529,6 +1529,48 @@ static default_t extra_defaults_list[] =
CONFIG_VARIABLE_INT(joystick_physical_button10),
//!
// The physical joystick button that corresponds to joystick
// virtual button #11.
//
CONFIG_VARIABLE_INT(joystick_physical_button11),
//!
// The physical joystick button that corresponds to joystick
// virtual button #12.
//
CONFIG_VARIABLE_INT(joystick_physical_button12),
//!
// The physical joystick button that corresponds to joystick
// virtual button #13.
//
CONFIG_VARIABLE_INT(joystick_physical_button13),
//!
// The physical joystick button that corresponds to joystick
// virtual button #14.
//
CONFIG_VARIABLE_INT(joystick_physical_button14),
//!
// The physical joystick button that corresponds to joystick
// virtual button #15.
//
CONFIG_VARIABLE_INT(joystick_physical_button15),
//!
// The physical joystick button that corresponds to joystick
// virtual button #16.
//
CONFIG_VARIABLE_INT(joystick_physical_button16),
//!
// If non-zero, use the SDL_GameController interface instead of the
// SDL_Joystick interface.
@ -1606,6 +1648,48 @@ static default_t extra_defaults_list[] =
CONFIG_VARIABLE_INT(joyb_nextweapon),
//!
// @game heretic hexen
// Joystick virtual button to activate artifact.
//
CONFIG_VARIABLE_INT(joyb_useartifact),
//!
// @game heretic hexen
// Joystick virtual button to move left in the inventory.
//
CONFIG_VARIABLE_INT(joyb_invleft),
//!
// @game heretic hexen
// Joystick virtual button to move right in the inventory.
//
CONFIG_VARIABLE_INT(joyb_invright),
//!
// @game heretic hexen
// Joystick virtual button to fly up.
//
CONFIG_VARIABLE_INT(joyb_flyup),
//!
// @game heretic hexen
// Joystick virtual button to fly down.
//
CONFIG_VARIABLE_INT(joyb_flydown),
//!
// @game heretic hexen
// Joystick virtual button to center flying.
//
CONFIG_VARIABLE_INT(joyb_flycenter),
//!
// Key to pause or unpause the game.
//

View file

@ -232,6 +232,14 @@ int joybnextweapon = -1;
int joybmenu = -1;
int joybautomap = -1;
int joybuseartifact = -1;
int joybinvleft = -1;
int joybinvright = -1;
int joybflyup = -1;
int joybflydown = -1;
int joybflycenter = -1;
// Control whether if a mouse button is double clicked, it acts like
// "use" has been pressed
@ -317,6 +325,14 @@ void M_BindHereticControls(void)
M_BindIntVariable("mouseb_invright", &mousebinvright);
M_BindIntVariable("mouseb_useartifact", &mousebuseartifact);
M_BindIntVariable("joyb_invleft", &joybinvleft);
M_BindIntVariable("joyb_invright", &joybinvright);
M_BindIntVariable("joyb_useartifact", &joybuseartifact);
M_BindIntVariable("joyb_flyup", &joybflyup);
M_BindIntVariable("joyb_flydown", &joybflydown);
M_BindIntVariable("joyb_flycenter", &joybflycenter);
M_BindIntVariable("key_arti_quartz", &key_arti_quartz);
M_BindIntVariable("key_arti_urn", &key_arti_urn);
M_BindIntVariable("key_arti_bomb", &key_arti_bomb);

View file

@ -191,6 +191,14 @@ extern int joybnextweapon;
extern int joybmenu;
extern int joybautomap;
extern int joybuseartifact;
extern int joybinvleft;
extern int joybinvright;
extern int joybflyup;
extern int joybflydown;
extern int joybflycenter;
extern int dclick_use;
void M_BindBaseControls(void);

View file

@ -323,6 +323,7 @@ static void NET_Query_ParseResponse(net_addr_t *addr, net_packet_t *packet,
// Create new target.
target = GetTargetForAddr(addr, true);
broadcast_target = GetTargetForAddr(NULL, false);
target->state = QUERY_TARGET_QUERIED;
target->query_time = broadcast_target->query_time;
}

View file

@ -100,7 +100,7 @@ int joystick_look_sensitivity = 10;
// Virtual to physical mapping.
int joystick_physical_buttons[NUM_VIRTUAL_BUTTONS] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
};
static txt_button_t *joystick_button;
@ -164,6 +164,12 @@ static const joystick_config_t empty_defaults[] =
{"joyb_jump", -1},
{"joyb_menu_activate", -1},
{"joyb_toggle_automap", -1},
{"joyb_useartifact", -1},
{"joyb_invleft", -1},
{"joyb_invright", -1},
{"joyb_flyup", -1},
{"joyb_flydown", -1},
{"joyb_flycenter", -1},
{"joystick_physical_button0", 0},
{"joystick_physical_button1", 1},
{"joystick_physical_button2", 2},
@ -174,6 +180,13 @@ static const joystick_config_t empty_defaults[] =
{"joystick_physical_button7", 7},
{"joystick_physical_button8", 8},
{"joystick_physical_button9", 9},
{"joystick_physical_button10", 10},
{"joystick_physical_button11", 11},
{"joystick_physical_button12", 12},
{"joystick_physical_button13", 13},
{"joystick_physical_button14", 14},
{"joystick_physical_button15", 15},
{"joystick_physical_button16", 16},
{NULL, 0},
};
@ -630,6 +643,12 @@ static const joystick_config_t modern_gamepad[] =
{"joyb_nextweapon", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER},
{"joyb_menu_activate", SDL_CONTROLLER_BUTTON_START},
{"joyb_toggle_automap", SDL_CONTROLLER_BUTTON_Y},
{"joyb_useartifact", SDL_CONTROLLER_BUTTON_X},
{"joyb_invleft", SDL_CONTROLLER_BUTTON_DPAD_LEFT},
{"joyb_invright", SDL_CONTROLLER_BUTTON_DPAD_RIGHT},
{"joyb_flyup", SDL_CONTROLLER_BUTTON_DPAD_UP},
{"joyb_flydown", SDL_CONTROLLER_BUTTON_DPAD_DOWN},
{"joyb_flycenter", SDL_CONTROLLER_BUTTON_LEFTSTICK},
{NULL, 0},
};
@ -1167,13 +1186,35 @@ static void AdjustAnalog(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
TXT_SetWidgetAlign(window, TXT_HORIZ_CENTER);
}
static void MoreControls(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
{
txt_window_t *window;
window = TXT_NewWindow("Additional Gamepad/Joystick buttons");
TXT_SetTableColumns(window, 6);
TXT_SetColumnWidths(window, 18, 10, 1, 18, 10, 0);
AddJoystickControl(window, "Use artifact", &joybuseartifact);
AddJoystickControl(window, "Inventory left", &joybinvleft);
AddJoystickControl(window, "Inventory right", &joybinvright);
AddJoystickControl(window, "Fly up", &joybflyup);
AddJoystickControl(window, "Fly down", &joybflydown);
AddJoystickControl(window, "Fly center", &joybflycenter);
TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL);
TXT_SetWindowAction(window, TXT_HORIZ_CENTER,
TXT_NewWindowEscapeAction(window));
TXT_SetWindowAction(window, TXT_HORIZ_RIGHT, NULL);
TXT_SetWidgetAlign(window, TXT_HORIZ_CENTER);
}
void ConfigJoystick(TXT_UNCAST_ARG(widget), void *user_data)
{
txt_window_t *window;
window = TXT_NewWindow("Gamepad/Joystick configuration");
TXT_SetTableColumns(window, 6);
TXT_SetColumnWidths(window, 18, 10, 1, 15, 10, 0);
TXT_SetColumnWidths(window, 18, 10, 1, 18, 10, 0);
TXT_SetWindowHelpURL(window, WINDOW_HELP_URL);
TXT_AddWidgets(window,
@ -1269,6 +1310,13 @@ void ConfigJoystick(TXT_UNCAST_ARG(widget), void *user_data)
AddJoystickControl(window, "Toggle Automap", &joybautomap);
if (gamemission == heretic || gamemission == hexen)
{
TXT_AddWidget(window,
TXT_NewButton2("More controls...", MoreControls, NULL));
TXT_AddWidget(window, TXT_TABLE_EOL);
}
TXT_SignalConnect(joystick_button, "pressed", CalibrateJoystick, window);
TXT_SetWindowAction(window, TXT_HORIZ_CENTER, TestConfigAction());

View file

@ -58,6 +58,12 @@ static int *all_joystick_buttons[NUM_VIRTUAL_BUTTONS] =
&joybjump,
&joybmenu,
&joybautomap,
&joybuseartifact,
&joybinvleft,
&joybinvright,
&joybflyup,
&joybflydown,
&joybflycenter,
};
// For indirection so that we're not dependent on item ordering in the

View file

@ -1095,7 +1095,7 @@ void PrintDehackedBanners(void)
}
}
static struct
static const struct
{
const char *description;
const char *cmdline;
@ -1111,9 +1111,8 @@ static struct
static void InitGameVersion(void)
{
int p;
int i;
// haleyjd: we support emulating either the 1.2 or the 1.31 versions of
// haleyjd: we support emulating either the 1.2 or the 1.31 versions of
// Strife, which are the most significant. 1.2 is the most mature version
// that still has the single saveslot restriction, whereas 1.31 is the
// final revision. The differences between the two are barely worth
@ -1130,6 +1129,7 @@ static void InitGameVersion(void)
if (p)
{
int i;
for (i=0; gameversions[i].description != NULL; ++i)
{
if (!strcmp(myargv[p+1], gameversions[i].cmdline))
@ -1139,7 +1139,7 @@ static void InitGameVersion(void)
}
}
if (gameversions[i].description == NULL)
if (gameversions[i].description == NULL)
{
printf("Supported game versions:\n");

View file

@ -313,6 +313,12 @@ static int G_NextWeapon(int direction)
}
}
// The current weapon must be present in weapon_order_table
// otherwise something has gone terribly wrong
if (i >= arrlen(weapon_order_table)) {
I_Error("Internal error: weapon %d not present in weapon_order_table", weapon);
}
// Switch weapon.
start_i = i;
do

View file

@ -737,6 +737,7 @@ P_LookForPlayers
angle_t an;
fixed_t dist;
mobj_t * master = players[actor->miscdata].mo;
int consecutive_missing = 0; // for breaking infinite loop
// haleyjd 09/05/10: handle Allies
if(actor->flags & MF_ALLY)
@ -794,19 +795,39 @@ P_LookForPlayers
c = 0;
// NOTE: This behavior has been changed from the Vanilla behavior, where
// an infinite loop can occur if players 0-3 all quit the game. Although
// technically this is not what Vanilla does, fixing this is highly
// desirable, and having the game simply lock up is not acceptable.
// stop = (actor->lastlook - 1) & 3;
// for (;; actor->lastlook = (actor->lastlook + 1) & 3)
// The 3 below is probably a mistake (it should be MAXPLAYERS - 1, or 7)
// and in vanilla this can potentially cause an infinite loop in
// multiplayer. Unfortunately we can't correct the mistake - doing so will
// cause desyncs. Upon spawning, each enemy's lastlook is initialized to a
// random value between 0 and 7 (i.e MAXPLAYERS - 1). There's a chance
// that the first call of this function for that enemy will return early
// courtesy of the actor->lastlook == stop condition. In a single-player
// game this occurs when (actor->lastlook - 1) & 3 equals 0, or when
// lastlook equals 1 or 5.
stop = (actor->lastlook + MAXPLAYERS - 1) % MAXPLAYERS;
// If you use MAXPLAYERS - 1, it has the side effect of altering which
// enemies are affected by an early actor->lastlook == stop return. Now it
// happens when (actor->lastlook - 1) & 7 equals 0, or when lastlook equals
// 1, *not* 1 and 5 as above.
for ( ; ; actor->lastlook = (actor->lastlook + 1) % MAXPLAYERS)
stop = (actor->lastlook-1)&3;
for ( ; ; actor->lastlook = (actor->lastlook+1)&3 )
{
if (!playeringame[actor->lastlook])
{
// Break the vanilla infinite loop here. It can occur if there are
// > 4 players and players 0 - 3 all quit the game. Error out
// instead.
if (consecutive_missing == 4)
{
I_Error("P_LookForPlayers: No player 1 - 4.\n");
}
consecutive_missing++;
continue;
}
consecutive_missing = 0;
if (c++ == 2
|| actor->lastlook == stop)