mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-04-19 16:51:53 +00:00
Merge commit '8e66ed73ab2371e89a548344e4ad26139e7d5db2' (internal branch 2214)~1 into add-noipv4-flag
This commit is contained in:
commit
f8d0833eab
168 changed files with 4708 additions and 3467 deletions
|
@ -39,7 +39,7 @@ https://facebook.com/SonicRoboBlast2
|
|||
|
||||
COPYRIGHT AND DISCLAIMER
|
||||
|
||||
Design and content in Sonic Robo Blast 2 is copyright 1998-2023 by Sonic Team Jr.
|
||||
Design and content in Sonic Robo Blast 2 is copyright 1998-2024 by Sonic Team Jr.
|
||||
|
||||
All original material in this game is copyrighted by their respective owners, and no copyright infringement is intended. Sonic Team Jr. is in no way affiliated with SEGA or Sonic Team, and we do not claim ownership of any of SEGA's intellectual property used in SRB2.
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ Upstream Author(s):
|
|||
|
||||
Copyright:
|
||||
|
||||
Copyright (C) 1998-2018 by Sonic Team Junior
|
||||
Copyright (C) 1998-2024 by Sonic Team Junior
|
||||
|
||||
License:
|
||||
|
||||
|
@ -21,7 +21,7 @@ License:
|
|||
The Debian packaging is:
|
||||
|
||||
Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com>
|
||||
Copyright (C) 2010-2018 by Sonic Team Junior <stjr@srb2.org>
|
||||
Copyright (C) 2010-2024 by Sonic Team Junior <stjr@srb2.org>
|
||||
|
||||
and is licensed under the GPL version 2,
|
||||
see "/usr/share/common-licenses/GPL-2".
|
||||
|
|
|
@ -12,7 +12,7 @@ Upstream Author(s):
|
|||
|
||||
Copyright:
|
||||
|
||||
Copyright (C) 1998-2018 by Sonic Team Junior
|
||||
Copyright (C) 1998-2024 by Sonic Team Junior
|
||||
|
||||
License:
|
||||
|
||||
|
@ -21,7 +21,7 @@ License:
|
|||
The Debian packaging is:
|
||||
|
||||
Copyright (C) 2010 Callum Dickinson <gcfreak_ag20@hotmail.com>
|
||||
Copyright (C) 2010-2018 by Sonic Team Junior <stjr@srb2.org>
|
||||
Copyright (C) 2010-2024 by Sonic Team Junior <stjr@srb2.org>
|
||||
|
||||
and is licensed under the GPL version 2,
|
||||
see "/usr/share/common-licenses/GPL-2".
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
===============================================================================
|
||||
Universal Doom Map Format Sonic Robo Blast 2 extensions v1.0 19.02.2024
|
||||
Universal Doom Map Format Sonic Robo Blast 2 extensions v1.0 19.06.2024
|
||||
|
||||
Copyright (c) 2024 Sonic Team Junior
|
||||
uses Universal Doom Map Format Specification v1.1 as a template,
|
||||
|
@ -143,6 +143,9 @@ Sonic Robo Blast 2 defines the following standardized fields:
|
|||
offsetx_bottom = <float>; // X offset for lower texture. Default = 0.0.
|
||||
offsety_bottom = <float>; // Y offset for lower texture. Default = 0.0.
|
||||
|
||||
light = <integer>; // Light level, relative to 'sector' light level. Default = 0.
|
||||
lightabsolute = <bool>; // true = 'light' is an absolute value, ignoring 'sector' light level.
|
||||
|
||||
comment = <string>; // A comment. Implementors should attach no special
|
||||
// semantic meaning to this field.
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ mapformat_udmf
|
|||
|
||||
// Enables setting distinct brightness for floor, ceiling, and walls
|
||||
distinctfloorandceilingbrightness = true;
|
||||
distinctwallbrightness = false;
|
||||
distinctwallbrightness = true;
|
||||
|
||||
// Enables setting distinct brightness for upper, middle, and lower sidedef parts
|
||||
distinctsidedefpartbrightness = false;
|
||||
|
|
|
@ -280,18 +280,18 @@ universalfields
|
|||
default = "";
|
||||
}
|
||||
|
||||
//light
|
||||
//{
|
||||
// type = 0;
|
||||
// default = 0;
|
||||
//}
|
||||
//
|
||||
//lightabsolute
|
||||
//{
|
||||
// type = 3;
|
||||
// default = false;
|
||||
//}
|
||||
//
|
||||
light
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
|
||||
lightabsolute
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
}
|
||||
|
||||
//light_top
|
||||
//{
|
||||
// type = 0;
|
||||
|
|
7
scripts/arm64-osx-1015.cmake
Normal file
7
scripts/arm64-osx-1015.cmake
Normal file
|
@ -0,0 +1,7 @@
|
|||
set(VCPKG_TARGET_ARCHITECTURE arm64)
|
||||
set(VCPKG_OSX_DEPLOYMENT_TARGET 10.15)
|
||||
set(VCPKG_CRT_LINKAGE dynamic)
|
||||
set(VCPKG_LIBRARY_LINKAGE static)
|
||||
|
||||
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
|
||||
set(VCPKG_OSX_ARCHITECTURES arm64)
|
25
scripts/make-macos-universal.sh
Executable file
25
scripts/make-macos-universal.sh
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Makes a fused macOS Universal app bundle in the arm64 release preset dir
|
||||
# Only works if in master branch or in source tarball
|
||||
|
||||
set -e
|
||||
|
||||
rm -rf "build/ninja-x64_osx_vcpkg-release"
|
||||
rm -rf "build/ninja-arm64_osx_vcpkg-release"
|
||||
cmake --preset ninja-x64_osx_vcpkg-release -DVCPKG_OVERLAY_TRIPLETS=scripts/ -DVCPKG_TARGET_TRIPLET=x64-osx-1015 -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 "-DSRB2_SDL2_EXE_NAME=srb2"
|
||||
cmake --build --preset ninja-x64_osx_vcpkg-release
|
||||
cmake --preset ninja-arm64_osx_vcpkg-release -DVCPKG_OVERLAY_TRIPLETS=scripts/ -DVCPKG_TARGET_TRIPLET=arm64-osx-1015 -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 "-DSRB2_SDL2_EXE_NAME=srb2"
|
||||
cmake --build --preset ninja-arm64_osx_vcpkg-release
|
||||
|
||||
mkdir -p build/dist
|
||||
rm -rf "build/dist/Sonic Robo Blast 2.app" "build/dist/srb2.app"
|
||||
|
||||
cp -r build/ninja-arm64_osx_vcpkg-release/bin/srb2.app build/dist/
|
||||
|
||||
lipo -create \
|
||||
-output "build/dist/srb2.app/Contents/MacOS/srb2" \
|
||||
build/ninja-x64_osx_vcpkg-release/bin/srb2.app/Contents/MacOS/srb2 \
|
||||
build/ninja-arm64_osx_vcpkg-release/bin/srb2.app/Contents/MacOS/srb2
|
||||
|
||||
mv build/dist/srb2.app "build/dist/Sonic Robo Blast 2.app"
|
7
scripts/x64-osx-1015.cmake
Normal file
7
scripts/x64-osx-1015.cmake
Normal file
|
@ -0,0 +1,7 @@
|
|||
set(VCPKG_TARGET_ARCHITECTURE x64)
|
||||
set(VCPKG_OSX_DEPLOYMENT_TARGET 10.15)
|
||||
set(VCPKG_CRT_LINKAGE dynamic)
|
||||
set(VCPKG_LIBRARY_LINKAGE static)
|
||||
|
||||
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
|
||||
set(VCPKG_OSX_ARCHITECTURES x86_64)
|
|
@ -71,7 +71,7 @@ apng_create_info_struct (png_structp pngp)
|
|||
{
|
||||
apng_infop ainfop;
|
||||
(void)pngp;
|
||||
if (( ainfop = calloc(sizeof (apng_info),1) ))
|
||||
if (( ainfop = calloc(1,sizeof (apng_info)) ))
|
||||
{
|
||||
apng_set_write_fn(pngp, ainfop, 0, 0, 0, 0, 0);
|
||||
apng_set_set_acTL_fn(pngp, ainfop, 0);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2007-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2011-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2011-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -11,9 +11,6 @@
|
|||
/// \brief Macros to read/write from/to a UINT8 *,
|
||||
/// used for packet creation and such
|
||||
|
||||
#if defined (__alpha__) || defined (__arm__) || defined (__mips__) || defined (__ia64__) || defined (__clang__)
|
||||
#define DEALIGNED
|
||||
#endif
|
||||
|
||||
#include "endian.h"
|
||||
|
||||
|
@ -21,7 +18,6 @@
|
|||
//
|
||||
// Little-endian machines
|
||||
//
|
||||
#ifdef DEALIGNED
|
||||
#define WRITEUINT8(p,b) do { UINT8 *p_tmp = (void *)p; const UINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITESINT8(p,b) do { SINT8 *p_tmp = (void *)p; const SINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEINT16(p,b) do { INT16 *p_tmp = (void *)p; const INT16 tv = ( INT16)(b); memcpy(p, &tv, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
|
@ -31,20 +27,8 @@
|
|||
#define WRITECHAR(p,b) do { char *p_tmp = (void *)p; const char tv = ( char)(b); memcpy(p, &tv, sizeof( char)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEFIXED(p,b) do { fixed_t *p_tmp = (void *)p; const fixed_t tv = (fixed_t)(b); memcpy(p, &tv, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEANGLE(p,b) do { angle_t *p_tmp = (void *)p; const angle_t tv = (angle_t)(b); memcpy(p, &tv, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#else
|
||||
#define WRITEUINT8(p,b) do { UINT8 *p_tmp = ( UINT8 *)p; *p_tmp = ( UINT8)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITESINT8(p,b) do { SINT8 *p_tmp = ( SINT8 *)p; *p_tmp = ( SINT8)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEINT16(p,b) do { INT16 *p_tmp = ( INT16 *)p; *p_tmp = ( INT16)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEUINT16(p,b) do { UINT16 *p_tmp = ( UINT16 *)p; *p_tmp = ( UINT16)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEINT32(p,b) do { INT32 *p_tmp = ( INT32 *)p; *p_tmp = ( INT32)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEUINT32(p,b) do { UINT32 *p_tmp = ( UINT32 *)p; *p_tmp = ( UINT32)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITECHAR(p,b) do { char *p_tmp = ( char *)p; *p_tmp = ( char)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEFIXED(p,b) do { fixed_t *p_tmp = (fixed_t *)p; *p_tmp = (fixed_t)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEANGLE(p,b) do { angle_t *p_tmp = (angle_t *)p; *p_tmp = (angle_t)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef DEALIGNED
|
||||
#define READUINT8(p) ({ UINT8 *p_tmp = (void *)p; UINT8 b; memcpy(&b, p, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READSINT8(p) ({ SINT8 *p_tmp = (void *)p; SINT8 b; memcpy(&b, p, sizeof( SINT8)); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READINT16(p) ({ INT16 *p_tmp = (void *)p; INT16 b; memcpy(&b, p, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; b; })
|
||||
|
@ -55,17 +39,6 @@
|
|||
#define READFIXED(p) ({ fixed_t *p_tmp = (void *)p; fixed_t b; memcpy(&b, p, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READANGLE(p) ({ angle_t *p_tmp = (void *)p; angle_t b; memcpy(&b, p, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#else
|
||||
#define READUINT8(p) ({ UINT8 *p_tmp = ( UINT8 *)p; UINT8 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READSINT8(p) ({ SINT8 *p_tmp = ( SINT8 *)p; SINT8 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READINT16(p) ({ INT16 *p_tmp = ( INT16 *)p; INT16 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READUINT16(p) ({ UINT16 *p_tmp = ( UINT16 *)p; UINT16 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READINT32(p) ({ INT32 *p_tmp = ( INT32 *)p; INT32 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READUINT32(p) ({ UINT32 *p_tmp = ( UINT32 *)p; UINT32 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#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 = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#endif
|
||||
#else
|
||||
#define READUINT8(p) *(( UINT8 *)p)++
|
||||
#define READSINT8(p) *(( SINT8 *)p)++
|
||||
#define READINT16(p) *(( INT16 *)p)++
|
||||
|
@ -148,8 +121,6 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
|
|||
#define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = readulong(p); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#endif //SRB2_BIG_ENDIAN
|
||||
|
||||
#undef DEALIGNED
|
||||
|
||||
#define WRITESTRINGN(p, s, n) { \
|
||||
size_t tmp_i; \
|
||||
\
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -1722,8 +1722,7 @@ badinput:
|
|||
|
||||
static boolean serverloading = false;
|
||||
|
||||
static consvar_t *
|
||||
ReadNetVar (UINT8 **p, char **return_value, boolean *return_stealth)
|
||||
static consvar_t *ReadNetVar(save_t *p, char **return_value, boolean *return_stealth)
|
||||
{
|
||||
UINT16 netid;
|
||||
char *val;
|
||||
|
@ -1731,10 +1730,10 @@ ReadNetVar (UINT8 **p, char **return_value, boolean *return_stealth)
|
|||
|
||||
consvar_t *cvar;
|
||||
|
||||
netid = READUINT16 (*p);
|
||||
val = (char *)*p;
|
||||
SKIPSTRING (*p);
|
||||
stealth = READUINT8 (*p);
|
||||
netid = P_ReadUINT16(p);
|
||||
val = (char *)&p->buf[p->pos];
|
||||
P_SkipString(p);
|
||||
stealth = P_ReadUINT8(p);
|
||||
|
||||
cvar = CV_FindNetVar(netid);
|
||||
|
||||
|
@ -1752,8 +1751,7 @@ ReadNetVar (UINT8 **p, char **return_value, boolean *return_stealth)
|
|||
}
|
||||
|
||||
#ifdef OLD22DEMOCOMPAT
|
||||
static consvar_t *
|
||||
ReadOldDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
|
||||
static consvar_t *ReadOldDemoVar(save_t *p, char **return_value, boolean *return_stealth)
|
||||
{
|
||||
UINT16 id;
|
||||
char *val;
|
||||
|
@ -1761,10 +1759,10 @@ ReadOldDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
|
|||
|
||||
old_demo_var_t *demovar;
|
||||
|
||||
id = READUINT16 (*p);
|
||||
val = (char *)*p;
|
||||
SKIPSTRING (*p);
|
||||
stealth = READUINT8 (*p);
|
||||
id = P_ReadUINT16(p);
|
||||
val = (char *)&p->buf[p->pos];
|
||||
P_SkipString(p);
|
||||
stealth = P_ReadUINT8(p);
|
||||
|
||||
demovar = CV_FindOldDemoVar(id);
|
||||
|
||||
|
@ -1783,8 +1781,7 @@ ReadOldDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
|
|||
}
|
||||
#endif/*OLD22DEMOCOMPAT*/
|
||||
|
||||
static consvar_t *
|
||||
ReadDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
|
||||
static consvar_t *ReadDemoVar(save_t *p, char **return_value, boolean *return_stealth)
|
||||
{
|
||||
char *name;
|
||||
char *val;
|
||||
|
@ -1792,11 +1789,11 @@ ReadDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
|
|||
|
||||
consvar_t *cvar;
|
||||
|
||||
name = (char *)*p;
|
||||
SKIPSTRING (*p);
|
||||
val = (char *)*p;
|
||||
SKIPSTRING (*p);
|
||||
stealth = READUINT8 (*p);
|
||||
name = (char *)&p->buf[p->pos];
|
||||
P_SkipString(p);
|
||||
val = (char *)&p->buf[p->pos];
|
||||
P_SkipString(p);
|
||||
stealth = P_ReadUINT8(p);
|
||||
|
||||
cvar = CV_FindVar(name);
|
||||
|
||||
|
@ -1826,41 +1823,46 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
cvar = ReadNetVar(p, &svalue, &stealth);
|
||||
save_t save_p;
|
||||
save_p.buf = *p;
|
||||
save_p.size = MAXTEXTCMD;
|
||||
save_p.pos = 0;
|
||||
cvar = ReadNetVar(&save_p, &svalue, &stealth);
|
||||
*p = &save_p.buf[save_p.pos];
|
||||
|
||||
if (cvar)
|
||||
Setvalue(cvar, svalue, stealth);
|
||||
}
|
||||
|
||||
void CV_SaveVars(UINT8 **p, boolean in_demo)
|
||||
void CV_SaveVars(save_t *p, boolean in_demo)
|
||||
{
|
||||
consvar_t *cvar;
|
||||
UINT8 *count_p = *p;
|
||||
UINT8 *count_p = &p->buf[p->pos];
|
||||
UINT16 count = 0;
|
||||
|
||||
// send only changed cvars ...
|
||||
// the client will reset all netvars to default before loading
|
||||
WRITEUINT16(*p, 0x0000);
|
||||
P_WriteUINT16(p, 0x0000);
|
||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||
if ((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar))
|
||||
{
|
||||
if (in_demo)
|
||||
{
|
||||
WRITESTRING(*p, cvar->name);
|
||||
P_WriteString(p, cvar->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT16(*p, cvar->netid);
|
||||
P_WriteUINT16(p, cvar->netid);
|
||||
}
|
||||
WRITESTRING(*p, cvar->string);
|
||||
WRITEUINT8(*p, false);
|
||||
P_WriteString(p, cvar->string);
|
||||
P_WriteUINT8(p, false);
|
||||
++count;
|
||||
}
|
||||
WRITEUINT16(count_p, count);
|
||||
}
|
||||
|
||||
static void CV_LoadVars(UINT8 **p,
|
||||
consvar_t *(*got)(UINT8 **p, char **ret_value, boolean *ret_stealth))
|
||||
static void CV_LoadVars(save_t *p,
|
||||
consvar_t *(*got)(save_t *p, char **ret_value, boolean *ret_stealth))
|
||||
{
|
||||
const boolean store = (client || demoplayback);
|
||||
|
||||
|
@ -1888,7 +1890,7 @@ static void CV_LoadVars(UINT8 **p,
|
|||
}
|
||||
}
|
||||
|
||||
count = READUINT16(*p);
|
||||
count = P_ReadUINT16(p);
|
||||
while (count--)
|
||||
{
|
||||
cvar = (*got)(p, &val, &stealth);
|
||||
|
@ -1921,19 +1923,19 @@ void CV_RevertNetVars(void)
|
|||
}
|
||||
}
|
||||
|
||||
void CV_LoadNetVars(UINT8 **p)
|
||||
void CV_LoadNetVars(save_t *p)
|
||||
{
|
||||
CV_LoadVars(p, ReadNetVar);
|
||||
}
|
||||
|
||||
#ifdef OLD22DEMOCOMPAT
|
||||
void CV_LoadOldDemoVars(UINT8 **p)
|
||||
void CV_LoadOldDemoVars(save_t *p)
|
||||
{
|
||||
CV_LoadVars(p, ReadOldDemoVar);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CV_LoadDemoVars(UINT8 **p)
|
||||
void CV_LoadDemoVars(save_t *p)
|
||||
{
|
||||
CV_LoadVars(p, ReadDemoVar);
|
||||
}
|
||||
|
@ -1992,7 +1994,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
|
|||
if (var->flags & CV_NETVAR)
|
||||
{
|
||||
// send the value of the variable
|
||||
UINT8 buf[128];
|
||||
UINT8 buf[512];
|
||||
UINT8 *p = buf;
|
||||
|
||||
// Loading from a config in a netgame? Set revert value.
|
||||
|
@ -2065,11 +2067,10 @@ static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth
|
|||
if (var == &cv_forceskin) // Special handling.
|
||||
{
|
||||
const char *tmpskin = NULL;
|
||||
if ((value < 0) || (value >= numskins))
|
||||
;
|
||||
else
|
||||
if (value >= 0 && value < numskins)
|
||||
tmpskin = skins[value]->name;
|
||||
memcpy(val, tmpskin, SKINNAMESIZE);
|
||||
if (tmpskin)
|
||||
memcpy(val, tmpskin, SKINNAMESIZE);
|
||||
}
|
||||
else
|
||||
sprintf(val, "%d", value);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include "doomdef.h"
|
||||
#include "p_saveg.h"
|
||||
|
||||
//===================================
|
||||
// Command buffer & command execution
|
||||
|
@ -218,19 +219,19 @@ void CV_AddValue(consvar_t *var, INT32 increment);
|
|||
void CV_SaveVariables(FILE *f);
|
||||
|
||||
// load/save gamesate (load and save option and for network join in game)
|
||||
void CV_SaveVars(UINT8 **p, boolean in_demo);
|
||||
void CV_SaveVars(save_t *p, boolean in_demo);
|
||||
|
||||
#define CV_SaveNetVars(p) CV_SaveVars(p, false)
|
||||
void CV_LoadNetVars(UINT8 **p);
|
||||
void CV_LoadNetVars(save_t *p);
|
||||
|
||||
// then revert after leaving a netgame
|
||||
void CV_RevertNetVars(void);
|
||||
|
||||
#define CV_SaveDemoVars(p) CV_SaveVars(p, true)
|
||||
void CV_LoadDemoVars(UINT8 **p);
|
||||
void CV_LoadDemoVars(save_t *p);
|
||||
|
||||
#ifdef OLD22DEMOCOMPAT
|
||||
void CV_LoadOldDemoVars(UINT8 **p);
|
||||
void CV_LoadOldDemoVars(save_t *p);
|
||||
#endif
|
||||
|
||||
// reset cheat netvars after cheats is deactivated
|
||||
|
|
|
@ -40,9 +40,10 @@
|
|||
* Last updated 2023 / 05 / 02 - v2.2.11 - patch.pk3 & zones.pk3
|
||||
* Last updated 2023 / 09 / 06 - v2.2.12 - patch.pk3
|
||||
* Last updated 2023 / 09 / 09 - v2.2.13 - none
|
||||
* Last updated 2024 / 07 / 04 - v2.2.14 - main assets
|
||||
*/
|
||||
#define ASSET_HASH_SRB2_PK3 "ad911f29a28a18968ee5b2d11c2acb39"
|
||||
#define ASSET_HASH_ZONES_PK3 "1c8adf8d079ecb87d00081f158acf3c7"
|
||||
#define ASSET_HASH_SRB2_PK3 "4ef6f57eefdf263288cae12084791cd2"
|
||||
#define ASSET_HASH_ZONES_PK3 "b7db0245434ca3ad61935ee36403e966"
|
||||
#define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c"
|
||||
#ifdef USE_PATCH_DTA
|
||||
#define ASSET_HASH_PATCH_PK3 "3c7b73f34af7e9a7bceb2d5260f76172"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
16
src/d_main.c
16
src/d_main.c
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -679,13 +679,13 @@ static void D_Display(void)
|
|||
s[sizeof s - 1] = '\0';
|
||||
|
||||
snprintf(s, sizeof s - 1, "get %d b/s", getbps);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-40, V_YELLOWMAP, s);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-40, V_YELLOWMAP, s);
|
||||
snprintf(s, sizeof s - 1, "send %d b/s", sendbps);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-30, V_YELLOWMAP, s);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-30, V_YELLOWMAP, s);
|
||||
snprintf(s, sizeof s - 1, "GameMiss %.2f%%", gamelostpercent);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-20, V_YELLOWMAP, s);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-20, V_YELLOWMAP, s);
|
||||
snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-10, V_YELLOWMAP, s);
|
||||
}
|
||||
|
||||
if (cv_perfstats.value)
|
||||
|
@ -1024,7 +1024,7 @@ void D_StartTitle(void)
|
|||
#define REALLOC_FILE_LIST \
|
||||
if (list->files == NULL) \
|
||||
{ \
|
||||
list->files = calloc(sizeof(list->files), 2); \
|
||||
list->files = calloc(2, sizeof(list->files)); \
|
||||
list->numfiles = 1; \
|
||||
} \
|
||||
else \
|
||||
|
@ -1250,7 +1250,7 @@ void D_SRB2Main(void)
|
|||
// Print GPL notice for our console users (Linux)
|
||||
CONS_Printf(
|
||||
"\n\nSonic Robo Blast 2\n"
|
||||
"Copyright (C) 1998-2023 by Sonic Team Junior\n\n"
|
||||
"Copyright (C) 1998-2024 by Sonic Team Junior\n\n"
|
||||
"This program comes with ABSOLUTELY NO WARRANTY.\n\n"
|
||||
"This is free software, and you are welcome to redistribute it\n"
|
||||
"and/or modify it under the terms of the GNU General Public License\n"
|
||||
|
@ -1535,7 +1535,7 @@ void D_SRB2Main(void)
|
|||
I_Error("Cannot find a map remotely named '%s'\n", word);
|
||||
else
|
||||
{
|
||||
if (!M_CheckParm("-server"))
|
||||
if (!(M_CheckParm("-server") || dedicated))
|
||||
G_SetUsedCheats(true);
|
||||
autostart = true;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Portions Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 2014-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2014-2024 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
|
||||
|
@ -999,20 +999,8 @@ static void I_GetConsoleEvents(void)
|
|||
static void I_StartupConsole(void)
|
||||
{
|
||||
HANDLE ci, co;
|
||||
const INT32 ded = M_CheckParm("-dedicated");
|
||||
BOOL gotConsole = FALSE;
|
||||
if (M_CheckParm("-console") || ded)
|
||||
gotConsole = AllocConsole();
|
||||
#ifdef _DEBUG
|
||||
else if (M_CheckParm("-noconsole") && !ded)
|
||||
#else
|
||||
else if (!M_CheckParm("-console") && !ded)
|
||||
#endif
|
||||
{
|
||||
FreeConsole();
|
||||
gotConsole = FALSE;
|
||||
}
|
||||
|
||||
BOOL gotConsole = AllocConsole();
|
||||
consolevent = !M_CheckParm("-noconsole");
|
||||
if (gotConsole)
|
||||
{
|
||||
SetConsoleTitleA("SRB2 Console");
|
||||
|
@ -1040,12 +1028,7 @@ static inline void I_ShutdownConsole(void){}
|
|||
static void I_GetConsoleEvents(void){}
|
||||
static inline void I_StartupConsole(void)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
consolevent = !M_CheckParm("-noconsole");
|
||||
#else
|
||||
consolevent = M_CheckParm("-console");
|
||||
#endif
|
||||
|
||||
framebuffer = M_CheckParm("-framebuffer");
|
||||
|
||||
if (framebuffer)
|
||||
|
@ -1390,8 +1373,8 @@ static const char *searchWad(const char *searchDir)
|
|||
|
||||
#define CHECKWADPATH(ret) \
|
||||
do { \
|
||||
I_OutputMsg(",%s", returnWadPath); \
|
||||
if (isWadPathOk(returnWadPath)) \
|
||||
I_OutputMsg(",%s", ret); \
|
||||
if (isWadPathOk(ret)) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
|
@ -1416,7 +1399,9 @@ static const char *locateWad(void)
|
|||
#ifndef NOCWD
|
||||
// examine current dir
|
||||
strcpy(returnWadPath, ".");
|
||||
CHECKWADPATH(NULL);
|
||||
I_OutputMsg(",%s", returnWadPath);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -1433,9 +1418,15 @@ static const char *locateWad(void)
|
|||
|
||||
#ifndef NOHOME
|
||||
// find in $HOME
|
||||
I_OutputMsg(",HOME");
|
||||
if ((envstr = I_GetEnv("HOME")) != NULL)
|
||||
SEARCHWAD(envstr);
|
||||
{
|
||||
char *tmp = malloc(strlen(envstr) + 1 + sizeof(DEFAULTDIR));
|
||||
strcpy(tmp, envstr);
|
||||
strcat(tmp, "/");
|
||||
strcat(tmp, DEFAULTDIR);
|
||||
CHECKWADPATH(tmp);
|
||||
free(tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
// search paths
|
||||
|
|
|
@ -157,7 +157,7 @@ void I_wake_all_cond(I_cond *anchor)
|
|||
pthread_mutex_lock(&thread_lock);
|
||||
if (*anchor == NULL)
|
||||
{
|
||||
*anchor = malloc(sizeof(pthread_t));
|
||||
*anchor = malloc(sizeof(pthread_cond_t));
|
||||
pthread_cond_init(*anchor, NULL);
|
||||
}
|
||||
pthread_mutex_unlock(&thread_lock);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -2791,7 +2791,7 @@ void readframe(MYFILE *f, INT32 num)
|
|||
size_t z;
|
||||
boolean found = false;
|
||||
size_t actionlen = strlen(word2) + 1;
|
||||
char *actiontocompare = calloc(actionlen, 1);
|
||||
char *actiontocompare = calloc(1, actionlen);
|
||||
|
||||
strcpy(actiontocompare, word2);
|
||||
strupr(actiontocompare);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -4483,6 +4483,8 @@ const char *const PLAYERFLAG_LIST[] = {
|
|||
"CANCARRY", // Can carry?
|
||||
"FINISHED",
|
||||
|
||||
"SHIELDDOWN", // Shield has been pressed.
|
||||
|
||||
NULL // stop loop here.
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -168,7 +168,7 @@ extern char logfilename[1024];
|
|||
|
||||
// Does this version require an added patch file?
|
||||
// Comment or uncomment this as necessary.
|
||||
#define USE_PATCH_DTA
|
||||
//#define USE_PATCH_DTA
|
||||
|
||||
// Enforce a limit of loaded WAD files.
|
||||
//#define ENFORCE_WAD_LIMIT
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -1065,12 +1065,12 @@ static const char *credits[] = {
|
|||
"Julio \"Chaos Zero 64\" Guir",
|
||||
"\"Hanicef\"",
|
||||
"\"Hannu_Hanhi\"", // For many OpenGL performance improvements!
|
||||
"\"hazepastel\"",
|
||||
"Kepa \"Nev3r\" Iceta",
|
||||
"Thomas \"Shadow Hog\" Igoe",
|
||||
"Iestyn \"Monster Iestyn\" Jealous",
|
||||
"\"Kaito Sinclaire\"",
|
||||
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
|
||||
"\"katsy\"",
|
||||
"Ronald \"Furyhunter\" Kinard", // The SDL2 port
|
||||
"\"Lat'\"", // SRB2-CHAT, the chat window from Kart
|
||||
"\"LZA\"",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -444,12 +444,11 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
|||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
if (dent->d_type == DT_UNKNOWN)
|
||||
if (lstat(searchpath,&fsstat) == 0 && S_ISDIR(fsstat.st_mode))
|
||||
if (dent->d_type == DT_UNKNOWN || dent->d_type == DT_LNK)
|
||||
if (stat(searchpath,&fsstat) == 0 && S_ISDIR(fsstat.st_mode))
|
||||
dent->d_type = DT_DIR;
|
||||
|
||||
// Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups.
|
||||
// FIXME: should we also follow symlinks?
|
||||
if (dent->d_type == DT_DIR && depthleft)
|
||||
#else
|
||||
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||
|
@ -1191,7 +1190,7 @@ boolean preparefilemenu(boolean samedepth)
|
|||
size_t i;
|
||||
|
||||
if (filenamebuf == NULL)
|
||||
filenamebuf = calloc(sizeof(char) * MAX_WADPATH, numwadfiles);
|
||||
filenamebuf = calloc(numwadfiles, sizeof(char) * MAX_WADPATH);
|
||||
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
{
|
||||
|
|
27
src/g_demo.c
27
src/g_demo.c
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -1454,6 +1454,7 @@ void G_BeginRecording(void)
|
|||
char *filename;
|
||||
UINT16 totalfiles;
|
||||
UINT8 *m;
|
||||
save_t savebuffer;
|
||||
|
||||
if (demo_p)
|
||||
return;
|
||||
|
@ -1603,7 +1604,11 @@ void G_BeginRecording(void)
|
|||
}
|
||||
|
||||
// Save netvar data
|
||||
CV_SaveDemoVars(&demo_p);
|
||||
savebuffer.buf = demo_p;
|
||||
savebuffer.size = demoend - demo_p;
|
||||
savebuffer.pos = 0;
|
||||
CV_SaveDemoVars(&savebuffer);
|
||||
demo_p = &savebuffer.buf[savebuffer.pos];
|
||||
|
||||
memset(&oldcmd,0,sizeof(oldcmd));
|
||||
memset(&oldghost,0,sizeof(oldghost));
|
||||
|
@ -2236,10 +2241,24 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
// net var data
|
||||
#ifdef OLD22DEMOCOMPAT
|
||||
if (demoversion < 0x000d)
|
||||
CV_LoadOldDemoVars(&demo_p);
|
||||
{
|
||||
save_t savebuffer;
|
||||
savebuffer.buf = demo_p;
|
||||
savebuffer.size = demoend - demo_p;
|
||||
savebuffer.pos = 0;
|
||||
CV_LoadOldDemoVars(&savebuffer);
|
||||
demo_p = &savebuffer.buf[savebuffer.pos];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
CV_LoadDemoVars(&demo_p);
|
||||
{
|
||||
save_t savebuffer;
|
||||
savebuffer.buf = demo_p;
|
||||
savebuffer.size = demoend - demo_p;
|
||||
savebuffer.pos = 0;
|
||||
CV_LoadDemoVars(&savebuffer);
|
||||
demo_p = &savebuffer.buf[savebuffer.pos];
|
||||
}
|
||||
|
||||
// Sigh ... it's an empty demo.
|
||||
if (*demo_p == DEMOMARKER)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
251
src/g_game.c
251
src/g_game.c
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -256,8 +256,6 @@ boolean precache = true; // if true, load all graphics at start
|
|||
|
||||
INT16 prevmap, nextmap;
|
||||
|
||||
static UINT8 *savebuffer;
|
||||
|
||||
// Analog Control
|
||||
static void UserAnalog_OnChange(void);
|
||||
static void UserAnalog2_OnChange(void);
|
||||
|
@ -1936,6 +1934,8 @@ void G_DoLoadLevel(boolean resetplayer)
|
|||
//
|
||||
void G_StartTitleCard(void)
|
||||
{
|
||||
ST_stopTitleCard();
|
||||
|
||||
// The title card has been disabled for this map.
|
||||
// Oh well.
|
||||
if (!G_IsTitleCardAvailable())
|
||||
|
@ -2624,6 +2624,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
boolean spectator;
|
||||
boolean outofcoop;
|
||||
boolean removing;
|
||||
boolean muted;
|
||||
INT16 bot;
|
||||
SINT8 pity;
|
||||
INT16 rings;
|
||||
|
@ -2641,6 +2642,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
spectator = players[player].spectator;
|
||||
outofcoop = players[player].outofcoop;
|
||||
removing = players[player].removing;
|
||||
muted = players[player].muted;
|
||||
pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER));
|
||||
playerangleturn = players[player].angleturn;
|
||||
oldrelangleturn = players[player].oldrelangleturn;
|
||||
|
@ -2718,6 +2720,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->spectator = spectator;
|
||||
p->outofcoop = outofcoop;
|
||||
p->removing = removing;
|
||||
p->muted = muted;
|
||||
p->angleturn = playerangleturn;
|
||||
p->oldrelangleturn = oldrelangleturn;
|
||||
|
||||
|
@ -3352,7 +3355,7 @@ void G_AddPlayer(INT32 playernum)
|
|||
|
||||
p->playerstate = PST_REBORN;
|
||||
|
||||
p->height = mobjinfo[MT_PLAYER].height;
|
||||
p->height = skins[p->skin]->height;
|
||||
|
||||
if (G_GametypeUsesLives() || ((netgame || multiplayer) && (gametyperules & GTR_FRIENDLY)))
|
||||
p->lives = cv_startinglives.value;
|
||||
|
@ -4396,7 +4399,7 @@ void G_LoadGameSettings(void)
|
|||
// Loads the main data file, which stores information such as emblems found, etc.
|
||||
void G_LoadGameData(gamedata_t *data)
|
||||
{
|
||||
size_t length;
|
||||
save_t savebuffer;
|
||||
INT32 i, j;
|
||||
|
||||
UINT32 versionID;
|
||||
|
@ -4438,18 +4441,18 @@ void G_LoadGameData(gamedata_t *data)
|
|||
return;
|
||||
}
|
||||
|
||||
length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer);
|
||||
if (!length)
|
||||
savebuffer.size = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer.buf);
|
||||
if (!savebuffer.size)
|
||||
{
|
||||
// No gamedata. We can save a new one.
|
||||
data->loaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
save_p = savebuffer;
|
||||
savebuffer.pos = 0;
|
||||
|
||||
// Version check
|
||||
versionID = READUINT32(save_p);
|
||||
versionID = P_ReadUINT32(&savebuffer);
|
||||
if (versionID != GAMEDATA_ID
|
||||
#ifdef COMPAT_GAMEDATA_ID // backwards compat behavior
|
||||
&& versionID != COMPAT_GAMEDATA_ID
|
||||
|
@ -4460,8 +4463,7 @@ void G_LoadGameData(gamedata_t *data)
|
|||
if (strcmp(srb2home,"."))
|
||||
gdfolder = srb2home;
|
||||
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
Z_Free(savebuffer.buf);
|
||||
I_Error("Game data is from another version of SRB2.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
|
||||
}
|
||||
|
||||
|
@ -4473,14 +4475,14 @@ void G_LoadGameData(gamedata_t *data)
|
|||
}
|
||||
#endif
|
||||
|
||||
data->totalplaytime = READUINT32(save_p);
|
||||
data->totalplaytime = P_ReadUINT32(&savebuffer);
|
||||
|
||||
#ifdef COMPAT_GAMEDATA_ID
|
||||
if (versionID == COMPAT_GAMEDATA_ID)
|
||||
{
|
||||
// We'll temporarily use the old condition when loading an older file.
|
||||
// The proper mod-specific hash will get saved in afterwards.
|
||||
boolean modded = READUINT8(save_p);
|
||||
boolean modded = P_ReadUINT8(&savebuffer);
|
||||
|
||||
if (modded && !savemoddata)
|
||||
{
|
||||
|
@ -4500,13 +4502,13 @@ void G_LoadGameData(gamedata_t *data)
|
|||
strcpy(currentfilename, gamedatafilename);
|
||||
STRBUFCPY(backupfilename, strcat(currentfilename, bak));
|
||||
|
||||
FIL_WriteFile(va(pandf, srb2home, backupfilename), savebuffer, length);
|
||||
FIL_WriteFile(va(pandf, srb2home, backupfilename), &savebuffer.buf, savebuffer.size);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Quick & dirty hash for what mod this save file is for.
|
||||
UINT32 modID = READUINT32(save_p);
|
||||
UINT32 modID = P_ReadUINT32(&savebuffer);
|
||||
UINT32 expectedID = quickncasehash(timeattackfolder, sizeof timeattackfolder);
|
||||
|
||||
if (modID != expectedID)
|
||||
|
@ -4518,50 +4520,50 @@ void G_LoadGameData(gamedata_t *data)
|
|||
|
||||
// TODO put another cipher on these things? meh, I don't care...
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
if ((data->mapvisited[i] = READUINT8(save_p)) > MV_MAX)
|
||||
if ((data->mapvisited[i] = P_ReadUINT8(&savebuffer)) > MV_MAX)
|
||||
goto datacorrupt;
|
||||
|
||||
// To save space, use one bit per collected/achieved/unlocked flag
|
||||
for (i = 0; i < max_emblems;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
rtemp = P_ReadUINT8(&savebuffer);
|
||||
for (j = 0; j < 8 && j+i < max_emblems; ++j)
|
||||
data->collected[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < max_extraemblems;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
rtemp = P_ReadUINT8(&savebuffer);
|
||||
for (j = 0; j < 8 && j+i < max_extraemblems; ++j)
|
||||
data->extraCollected[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < max_unlockables;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
rtemp = P_ReadUINT8(&savebuffer);
|
||||
for (j = 0; j < 8 && j+i < max_unlockables; ++j)
|
||||
data->unlocked[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < max_conditionsets;)
|
||||
{
|
||||
rtemp = READUINT8(save_p);
|
||||
rtemp = P_ReadUINT8(&savebuffer);
|
||||
for (j = 0; j < 8 && j+i < max_conditionsets; ++j)
|
||||
data->achieved[j+i] = ((rtemp >> j) & 1);
|
||||
i += j;
|
||||
}
|
||||
|
||||
data->timesBeaten = READUINT32(save_p);
|
||||
data->timesBeatenWithEmeralds = READUINT32(save_p);
|
||||
data->timesBeatenUltimate = READUINT32(save_p);
|
||||
data->timesBeaten = P_ReadUINT32(&savebuffer);
|
||||
data->timesBeatenWithEmeralds = P_ReadUINT32(&savebuffer);
|
||||
data->timesBeatenUltimate = P_ReadUINT32(&savebuffer);
|
||||
|
||||
// Main records
|
||||
for (i = 0; i < NUMMAPS; ++i)
|
||||
{
|
||||
recscore = READUINT32(save_p);
|
||||
rectime = (tic_t)READUINT32(save_p);
|
||||
recrings = READUINT16(save_p);
|
||||
save_p++; // compat
|
||||
recscore = P_ReadUINT32(&savebuffer);
|
||||
rectime = (tic_t)P_ReadUINT32(&savebuffer);
|
||||
recrings = P_ReadUINT16(&savebuffer);
|
||||
P_ReadUINT8(&savebuffer); // compat
|
||||
|
||||
if (recrings > 10000 || recscore > MAXSCORE)
|
||||
goto datacorrupt;
|
||||
|
@ -4578,16 +4580,16 @@ void G_LoadGameData(gamedata_t *data)
|
|||
// Nights records
|
||||
for (i = 0; i < NUMMAPS; ++i)
|
||||
{
|
||||
if ((recmares = READUINT8(save_p)) == 0)
|
||||
if ((recmares = P_ReadUINT8(&savebuffer)) == 0)
|
||||
continue;
|
||||
|
||||
G_AllocNightsRecordData((INT16)i, data);
|
||||
|
||||
for (curmare = 0; curmare < (recmares+1); ++curmare)
|
||||
{
|
||||
data->nightsrecords[i]->score[curmare] = READUINT32(save_p);
|
||||
data->nightsrecords[i]->grade[curmare] = READUINT8(save_p);
|
||||
data->nightsrecords[i]->time[curmare] = (tic_t)READUINT32(save_p);
|
||||
data->nightsrecords[i]->score[curmare] = P_ReadUINT32(&savebuffer);
|
||||
data->nightsrecords[i]->grade[curmare] = P_ReadUINT8(&savebuffer);
|
||||
data->nightsrecords[i]->time[curmare] = (tic_t)P_ReadUINT32(&savebuffer);
|
||||
|
||||
if (data->nightsrecords[i]->grade[curmare] > GRADE_S)
|
||||
{
|
||||
|
@ -4599,8 +4601,7 @@ void G_LoadGameData(gamedata_t *data)
|
|||
}
|
||||
|
||||
// done
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
Z_Free(savebuffer.buf);
|
||||
|
||||
// Don't consider loaded until it's a success!
|
||||
// It used to do this much earlier, but this would cause the gamedata to
|
||||
|
@ -4621,8 +4622,7 @@ void G_LoadGameData(gamedata_t *data)
|
|||
if (strcmp(srb2home,"."))
|
||||
gdfolder = srb2home;
|
||||
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
Z_Free(savebuffer.buf);
|
||||
|
||||
I_Error("Corrupt game data file.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder);
|
||||
}
|
||||
|
@ -4632,9 +4632,8 @@ void G_LoadGameData(gamedata_t *data)
|
|||
// Saves the main data file, which stores information such as emblems found, etc.
|
||||
void G_SaveGameData(gamedata_t *data)
|
||||
{
|
||||
UINT8 *data_p;
|
||||
save_t savebuffer;
|
||||
|
||||
size_t length;
|
||||
INT32 i, j;
|
||||
UINT8 btemp;
|
||||
|
||||
|
@ -4646,30 +4645,31 @@ void G_SaveGameData(gamedata_t *data)
|
|||
if (!data->loaded)
|
||||
return; // If never loaded (-nodata), don't save
|
||||
|
||||
data_p = savebuffer = (UINT8 *)malloc(GAMEDATASIZE);
|
||||
if (!data_p)
|
||||
savebuffer.size = GAMEDATASIZE;
|
||||
savebuffer.buf = (UINT8 *)malloc(savebuffer.size);
|
||||
if (!savebuffer.buf)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n"));
|
||||
return;
|
||||
}
|
||||
savebuffer.pos = 0;
|
||||
|
||||
if (usedCheats)
|
||||
{
|
||||
free(savebuffer);
|
||||
savebuffer = NULL;
|
||||
free(savebuffer.buf);
|
||||
return;
|
||||
}
|
||||
|
||||
// Version test
|
||||
WRITEUINT32(data_p, GAMEDATA_ID);
|
||||
P_WriteUINT32(&savebuffer, GAMEDATA_ID);
|
||||
|
||||
WRITEUINT32(data_p, data->totalplaytime);
|
||||
P_WriteUINT32(&savebuffer, data->totalplaytime);
|
||||
|
||||
WRITEUINT32(data_p, quickncasehash(timeattackfolder, sizeof timeattackfolder));
|
||||
P_WriteUINT32(&savebuffer, quickncasehash(timeattackfolder, sizeof timeattackfolder));
|
||||
|
||||
// TODO put another cipher on these things? meh, I don't care...
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
WRITEUINT8(data_p, (data->mapvisited[i] & MV_MAX));
|
||||
P_WriteUINT8(&savebuffer, (data->mapvisited[i] & MV_MAX));
|
||||
|
||||
// To save space, use one bit per collected/achieved/unlocked flag
|
||||
for (i = 0; i < MAXEMBLEMS;)
|
||||
|
@ -4677,7 +4677,7 @@ void G_SaveGameData(gamedata_t *data)
|
|||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
|
||||
btemp |= (data->collected[j+i] << j);
|
||||
WRITEUINT8(data_p, btemp);
|
||||
P_WriteUINT8(&savebuffer, btemp);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXEXTRAEMBLEMS;)
|
||||
|
@ -4685,7 +4685,7 @@ void G_SaveGameData(gamedata_t *data)
|
|||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j)
|
||||
btemp |= (data->extraCollected[j+i] << j);
|
||||
WRITEUINT8(data_p, btemp);
|
||||
P_WriteUINT8(&savebuffer, btemp);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXUNLOCKABLES;)
|
||||
|
@ -4693,7 +4693,7 @@ void G_SaveGameData(gamedata_t *data)
|
|||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
|
||||
btemp |= (data->unlocked[j+i] << j);
|
||||
WRITEUINT8(data_p, btemp);
|
||||
P_WriteUINT8(&savebuffer, btemp);
|
||||
i += j;
|
||||
}
|
||||
for (i = 0; i < MAXCONDITIONSETS;)
|
||||
|
@ -4701,30 +4701,30 @@ void G_SaveGameData(gamedata_t *data)
|
|||
btemp = 0;
|
||||
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
|
||||
btemp |= (data->achieved[j+i] << j);
|
||||
WRITEUINT8(data_p, btemp);
|
||||
P_WriteUINT8(&savebuffer, btemp);
|
||||
i += j;
|
||||
}
|
||||
|
||||
WRITEUINT32(data_p, data->timesBeaten);
|
||||
WRITEUINT32(data_p, data->timesBeatenWithEmeralds);
|
||||
WRITEUINT32(data_p, data->timesBeatenUltimate);
|
||||
P_WriteUINT32(&savebuffer, data->timesBeaten);
|
||||
P_WriteUINT32(&savebuffer, data->timesBeatenWithEmeralds);
|
||||
P_WriteUINT32(&savebuffer, data->timesBeatenUltimate);
|
||||
|
||||
// Main records
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
{
|
||||
if (data->mainrecords[i])
|
||||
{
|
||||
WRITEUINT32(data_p, data->mainrecords[i]->score);
|
||||
WRITEUINT32(data_p, data->mainrecords[i]->time);
|
||||
WRITEUINT16(data_p, data->mainrecords[i]->rings);
|
||||
P_WriteUINT32(&savebuffer, data->mainrecords[i]->score);
|
||||
P_WriteUINT32(&savebuffer, data->mainrecords[i]->time);
|
||||
P_WriteUINT16(&savebuffer, data->mainrecords[i]->rings);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT32(data_p, 0);
|
||||
WRITEUINT32(data_p, 0);
|
||||
WRITEUINT16(data_p, 0);
|
||||
P_WriteUINT32(&savebuffer, 0);
|
||||
P_WriteUINT32(&savebuffer, 0);
|
||||
P_WriteUINT16(&savebuffer, 0);
|
||||
}
|
||||
WRITEUINT8(data_p, 0); // compat
|
||||
P_WriteUINT8(&savebuffer, 0); // compat
|
||||
}
|
||||
|
||||
// NiGHTS records
|
||||
|
@ -4732,25 +4732,22 @@ void G_SaveGameData(gamedata_t *data)
|
|||
{
|
||||
if (!data->nightsrecords[i] || !data->nightsrecords[i]->nummares)
|
||||
{
|
||||
WRITEUINT8(data_p, 0);
|
||||
P_WriteUINT8(&savebuffer, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
WRITEUINT8(data_p, data->nightsrecords[i]->nummares);
|
||||
P_WriteUINT8(&savebuffer, data->nightsrecords[i]->nummares);
|
||||
|
||||
for (curmare = 0; curmare < (data->nightsrecords[i]->nummares + 1); ++curmare)
|
||||
{
|
||||
WRITEUINT32(data_p, data->nightsrecords[i]->score[curmare]);
|
||||
WRITEUINT8(data_p, data->nightsrecords[i]->grade[curmare]);
|
||||
WRITEUINT32(data_p, data->nightsrecords[i]->time[curmare]);
|
||||
P_WriteUINT32(&savebuffer, data->nightsrecords[i]->score[curmare]);
|
||||
P_WriteUINT8(&savebuffer, data->nightsrecords[i]->grade[curmare]);
|
||||
P_WriteUINT32(&savebuffer, data->nightsrecords[i]->time[curmare]);
|
||||
}
|
||||
}
|
||||
|
||||
length = data_p - savebuffer;
|
||||
|
||||
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer, length);
|
||||
free(savebuffer);
|
||||
savebuffer = NULL;
|
||||
FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer.buf, savebuffer.pos);
|
||||
free(savebuffer.buf);
|
||||
}
|
||||
|
||||
#define VERSIONSIZE 16
|
||||
|
@ -4761,7 +4758,7 @@ void G_SaveGameData(gamedata_t *data)
|
|||
//
|
||||
void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
||||
{
|
||||
size_t length;
|
||||
save_t savebuffer;
|
||||
char vcheck[VERSIONSIZE];
|
||||
char savename[255];
|
||||
|
||||
|
@ -4778,18 +4775,18 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
|||
else
|
||||
sprintf(savename, savegamename, slot);
|
||||
|
||||
length = FIL_ReadFile(savename, &savebuffer);
|
||||
if (!length)
|
||||
savebuffer.size = FIL_ReadFile(savename, &savebuffer.buf);
|
||||
if (!savebuffer.size)
|
||||
{
|
||||
CONS_Printf(M_GetText("Couldn't read file %s\n"), savename);
|
||||
return;
|
||||
}
|
||||
|
||||
save_p = savebuffer;
|
||||
savebuffer.pos = 0;
|
||||
|
||||
memset(vcheck, 0, sizeof (vcheck));
|
||||
sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION);
|
||||
if (strcmp((const char *)save_p, (const char *)vcheck))
|
||||
if (strcmp((const char *)&savebuffer.buf[savebuffer.pos], (const char *)vcheck))
|
||||
{
|
||||
#ifdef SAVEGAME_OTHERVERSIONS
|
||||
M_StartMessage(M_GetText("Save game from different version.\nYou can load this savegame, but\nsaving afterwards will be disabled.\n\nDo you want to continue anyway?\n\n(Press 'Y' to confirm)\n"),
|
||||
|
@ -4799,15 +4796,14 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
|||
M_ClearMenus(true); // so ESC backs out to title
|
||||
M_StartMessage(M_GetText("Save game from different version\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
Command_ExitGame_f();
|
||||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
Z_Free(savebuffer.buf);
|
||||
|
||||
// no cheating!
|
||||
memset(&savedata, 0, sizeof(savedata));
|
||||
#endif
|
||||
return; // bad version
|
||||
}
|
||||
save_p += VERSIONSIZE;
|
||||
savebuffer.pos += VERSIONSIZE;
|
||||
|
||||
// if (demoplayback) // reset game engine
|
||||
// G_StopDemo();
|
||||
|
@ -4816,13 +4812,12 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
|||
// automapactive = false;
|
||||
|
||||
// dearchive all the modifications
|
||||
if (!P_LoadGame(mapoverride))
|
||||
if (!P_LoadGame(&savebuffer, mapoverride))
|
||||
{
|
||||
M_ClearMenus(true); // so ESC backs out to title
|
||||
M_StartMessage(M_GetText("Savegame file corrupted\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
Command_ExitGame_f();
|
||||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
Z_Free(savebuffer.buf);
|
||||
|
||||
// no cheating!
|
||||
memset(&savedata, 0, sizeof(savedata));
|
||||
|
@ -4830,13 +4825,12 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
|||
}
|
||||
if (marathonmode)
|
||||
{
|
||||
marathontime = READUINT32(save_p);
|
||||
marathonmode |= READUINT8(save_p);
|
||||
marathontime = P_ReadUINT32(&savebuffer);
|
||||
marathonmode |= P_ReadUINT8(&savebuffer);
|
||||
}
|
||||
|
||||
// done
|
||||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
Z_Free(savebuffer.buf);
|
||||
|
||||
displayplayer = consoleplayer;
|
||||
multiplayer = splitscreen = false;
|
||||
|
@ -4854,6 +4848,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
|
|||
//
|
||||
void G_SaveGame(UINT32 slot, INT16 mapnum)
|
||||
{
|
||||
save_t savebuffer;
|
||||
boolean saved;
|
||||
char savename[256] = "";
|
||||
const char *backup;
|
||||
|
@ -4867,33 +4862,32 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
|
|||
gameaction = ga_nothing;
|
||||
{
|
||||
char name[VERSIONSIZE];
|
||||
size_t length;
|
||||
|
||||
save_p = savebuffer = (UINT8 *)malloc(SAVEGAMESIZE);
|
||||
if (!save_p)
|
||||
savebuffer.size = SAVEGAMESIZE;
|
||||
savebuffer.buf = (UINT8 *)malloc(savebuffer.size);
|
||||
if (!savebuffer.buf)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for saving game data\n"));
|
||||
return;
|
||||
}
|
||||
savebuffer.pos = 0;
|
||||
|
||||
memset(name, 0, sizeof (name));
|
||||
sprintf(name, (marathonmode ? "back-up %d" : "version %d"), VERSION);
|
||||
WRITEMEM(save_p, name, VERSIONSIZE);
|
||||
P_WriteMem(&savebuffer, name, VERSIONSIZE);
|
||||
|
||||
P_SaveGame(mapnum);
|
||||
P_SaveGame(&savebuffer, mapnum);
|
||||
if (marathonmode)
|
||||
{
|
||||
UINT32 writetime = marathontime;
|
||||
if (!(marathonmode & MA_INGAME))
|
||||
writetime += TICRATE*5; // live event backup penalty because we don't know how long it takes to get to the next map
|
||||
WRITEUINT32(save_p, writetime);
|
||||
WRITEUINT8(save_p, (marathonmode & ~MA_INIT));
|
||||
P_WriteUINT32(&savebuffer, writetime);
|
||||
P_WriteUINT8(&savebuffer, (marathonmode & ~MA_INIT));
|
||||
}
|
||||
|
||||
length = save_p - savebuffer;
|
||||
saved = FIL_WriteFile(backup, savebuffer, length);
|
||||
free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
saved = FIL_WriteFile(backup, savebuffer.buf, savebuffer.pos);
|
||||
free(savebuffer.buf);
|
||||
}
|
||||
|
||||
gameaction = ga_nothing;
|
||||
|
@ -4905,11 +4899,10 @@ void G_SaveGame(UINT32 slot, INT16 mapnum)
|
|||
}
|
||||
|
||||
#define BADSAVE goto cleanup;
|
||||
#define CHECKPOS if (save_p >= end_p) BADSAVE
|
||||
void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
||||
{
|
||||
save_t savebuffer;
|
||||
boolean saved = false;
|
||||
size_t length;
|
||||
char vcheck[VERSIONSIZE];
|
||||
char savename[255];
|
||||
const char *backup;
|
||||
|
@ -4920,42 +4913,38 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
|||
sprintf(savename, savegamename, slot);
|
||||
backup = va("%s",savename);
|
||||
|
||||
length = FIL_ReadFile(savename, &savebuffer);
|
||||
if (!length)
|
||||
savebuffer.size = FIL_ReadFile(savename, &savebuffer.buf);
|
||||
if (!savebuffer.size)
|
||||
{
|
||||
CONS_Printf(M_GetText("Couldn't read file %s\n"), savename);
|
||||
return;
|
||||
}
|
||||
|
||||
savebuffer.pos = 0;
|
||||
|
||||
{
|
||||
char temp[sizeof(timeattackfolder)];
|
||||
UINT8 *end_p = savebuffer + length;
|
||||
UINT8 *lives_p;
|
||||
SINT8 pllives;
|
||||
#ifdef NEWSKINSAVES
|
||||
INT16 backwardsCompat = 0;
|
||||
#endif
|
||||
|
||||
save_p = savebuffer;
|
||||
// Version check
|
||||
memset(vcheck, 0, sizeof (vcheck));
|
||||
sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION);
|
||||
if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE
|
||||
save_p += VERSIONSIZE;
|
||||
if (strcmp((const char *)&savebuffer.buf[savebuffer.pos], (const char *)vcheck)) BADSAVE
|
||||
savebuffer.pos += VERSIONSIZE;
|
||||
|
||||
// P_UnArchiveMisc()
|
||||
(void)READINT16(save_p);
|
||||
CHECKPOS
|
||||
(void)READUINT16(save_p); // emeralds
|
||||
CHECKPOS
|
||||
READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to
|
||||
(void)P_ReadINT16(&savebuffer);
|
||||
(void)P_ReadUINT16(&savebuffer); // emeralds
|
||||
P_ReadStringN(&savebuffer, temp, sizeof(temp)); // mod it belongs to
|
||||
if (strcmp(temp, timeattackfolder)) BADSAVE
|
||||
|
||||
// P_UnArchivePlayer()
|
||||
CHECKPOS
|
||||
#ifdef NEWSKINSAVES
|
||||
backwardsCompat = READUINT16(save_p);
|
||||
CHECKPOS
|
||||
backwardsCompat = P_ReadUINT16(&savebuffer);
|
||||
|
||||
if (backwardsCompat == NEWSKINSAVES) // New save, read skin names
|
||||
#endif
|
||||
|
@ -4963,47 +4952,37 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
|||
char ourSkinName[SKINNAMESIZE+1];
|
||||
char botSkinName[SKINNAMESIZE+1];
|
||||
|
||||
READSTRINGN(save_p, ourSkinName, SKINNAMESIZE);
|
||||
CHECKPOS
|
||||
P_ReadStringN(&savebuffer, ourSkinName, SKINNAMESIZE);
|
||||
|
||||
READSTRINGN(save_p, botSkinName, SKINNAMESIZE);
|
||||
CHECKPOS
|
||||
P_ReadStringN(&savebuffer, botSkinName, SKINNAMESIZE);
|
||||
}
|
||||
|
||||
WRITEUINT8(save_p, numgameovers);
|
||||
CHECKPOS
|
||||
P_WriteUINT8(&savebuffer, numgameovers);
|
||||
|
||||
lives_p = save_p;
|
||||
pllives = READSINT8(save_p); // lives
|
||||
CHECKPOS
|
||||
lives_p = &savebuffer.buf[savebuffer.pos];
|
||||
pllives = P_ReadSINT8(&savebuffer); // lives
|
||||
if (modifylives && pllives < startinglivesbalance[numgameovers])
|
||||
{
|
||||
pllives = startinglivesbalance[numgameovers];
|
||||
WRITESINT8(lives_p, pllives);
|
||||
*lives_p = startinglivesbalance[numgameovers];
|
||||
}
|
||||
|
||||
(void)READINT32(save_p); // Score
|
||||
CHECKPOS
|
||||
(void)READINT32(save_p); // continues
|
||||
(void)P_ReadINT32(&savebuffer); // Score
|
||||
(void)P_ReadINT32(&savebuffer); // continues
|
||||
|
||||
// File end marker check
|
||||
CHECKPOS
|
||||
switch (READUINT8(save_p))
|
||||
switch (P_ReadUINT8(&savebuffer))
|
||||
{
|
||||
case 0xb7:
|
||||
{
|
||||
UINT8 i, banksinuse;
|
||||
CHECKPOS
|
||||
banksinuse = READUINT8(save_p);
|
||||
CHECKPOS
|
||||
banksinuse = P_ReadUINT8(&savebuffer);
|
||||
if (banksinuse > NUM_LUABANKS)
|
||||
BADSAVE
|
||||
for (i = 0; i < banksinuse; i++)
|
||||
{
|
||||
(void)READINT32(save_p);
|
||||
CHECKPOS
|
||||
(void)P_ReadINT32(&savebuffer);
|
||||
}
|
||||
if (READUINT8(save_p) != 0x1d)
|
||||
if (P_ReadUINT8(&savebuffer) != 0x1d)
|
||||
BADSAVE
|
||||
}
|
||||
case 0x1d:
|
||||
|
@ -5013,7 +4992,7 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
|
|||
}
|
||||
|
||||
// done
|
||||
saved = FIL_WriteFile(backup, savebuffer, length);
|
||||
saved = FIL_WriteFile(backup, savebuffer.buf, savebuffer.size);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
@ -5021,11 +5000,9 @@ cleanup:
|
|||
CONS_Printf(M_GetText("Game saved.\n"));
|
||||
else if (!saved)
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename));
|
||||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
Z_Free(savebuffer.buf);
|
||||
|
||||
}
|
||||
#undef CHECKPOS
|
||||
#undef BADSAVE
|
||||
|
||||
//
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2020-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2020-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2020-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2020-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -450,15 +450,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t
|
|||
|
||||
texture = textures[texnum];
|
||||
|
||||
mipmap->flags = TF_WRAPXY;
|
||||
mipmap->width = (UINT16)texture->width;
|
||||
mipmap->height = (UINT16)texture->height;
|
||||
mipmap->format = textureformat;
|
||||
|
||||
blockwidth = texture->width;
|
||||
blockheight = texture->height;
|
||||
blocksize = (blockwidth * blockheight);
|
||||
block = MakeBlock(&grtex->mipmap);
|
||||
blocksize = blockwidth * blockheight;
|
||||
block = MakeBlock(mipmap);
|
||||
|
||||
// Composite the columns together.
|
||||
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
|
||||
|
@ -488,7 +483,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t
|
|||
realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH);
|
||||
}
|
||||
|
||||
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
|
||||
HWR_DrawTexturePatchInCache(mipmap, blockwidth, blockheight, texture, patch, realpatch);
|
||||
|
||||
if (free_patch)
|
||||
Patch_Free(realpatch);
|
||||
|
@ -680,25 +675,24 @@ void HWR_InitMapTextures(void)
|
|||
gl_maptexturesloaded = false;
|
||||
}
|
||||
|
||||
static void DeleteTextureMipmap(GLMipmap_t *grMipmap)
|
||||
static void DeleteTextureMipmap(GLMipmap_t *grMipmap, boolean delete_mipmap)
|
||||
{
|
||||
HWD.pfnDeleteTexture(grMipmap);
|
||||
|
||||
// Chroma-keyed textures do not own their texture data, so do not free it
|
||||
if (!(grMipmap->flags & TF_CHROMAKEYED))
|
||||
if (delete_mipmap)
|
||||
Z_Free(grMipmap->data);
|
||||
}
|
||||
|
||||
static void FreeMapTexture(GLMapTexture_t *tex)
|
||||
static void FreeMapTexture(GLMapTexture_t *tex, boolean delete_chromakeys)
|
||||
{
|
||||
if (tex->mipmap.nextcolormap)
|
||||
{
|
||||
DeleteTextureMipmap(tex->mipmap.nextcolormap);
|
||||
DeleteTextureMipmap(tex->mipmap.nextcolormap, delete_chromakeys);
|
||||
free(tex->mipmap.nextcolormap);
|
||||
tex->mipmap.nextcolormap = NULL;
|
||||
}
|
||||
|
||||
DeleteTextureMipmap(&tex->mipmap);
|
||||
DeleteTextureMipmap(&tex->mipmap, true);
|
||||
}
|
||||
|
||||
void HWR_FreeMapTextures(void)
|
||||
|
@ -707,8 +701,8 @@ void HWR_FreeMapTextures(void)
|
|||
|
||||
for (i = 0; i < gl_numtextures; i++)
|
||||
{
|
||||
FreeMapTexture(&gl_textures[i]);
|
||||
FreeMapTexture(&gl_flats[i]);
|
||||
FreeMapTexture(&gl_textures[i], true);
|
||||
FreeMapTexture(&gl_flats[i], false);
|
||||
}
|
||||
|
||||
// now the heap don't have any 'user' pointing to our
|
||||
|
@ -741,22 +735,7 @@ void HWR_LoadMapTextures(size_t pnumtextures)
|
|||
// --------------------------------------------------------------------------
|
||||
// Make sure texture is downloaded and set it as the source
|
||||
// --------------------------------------------------------------------------
|
||||
static void GetMapTexture(INT32 tex, GLMapTexture_t *grtex, GLMipmap_t *mipmap)
|
||||
{
|
||||
// Generate texture if missing from the cache
|
||||
if (!mipmap->data && !mipmap->downloaded)
|
||||
HWR_GenerateTexture(tex, grtex, mipmap);
|
||||
|
||||
// If hardware does not have the texture, then call pfnSetTexture to upload it
|
||||
if (!mipmap->downloaded)
|
||||
HWD.pfnSetTexture(mipmap);
|
||||
HWR_SetCurrentTexture(mipmap);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(mipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
GLMapTexture_t *HWR_GetTexture(INT32 tex)
|
||||
GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed)
|
||||
{
|
||||
if (tex < 0 || tex >= (signed)gl_numtextures)
|
||||
{
|
||||
|
@ -769,7 +748,46 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex)
|
|||
|
||||
GLMapTexture_t *grtex = &gl_textures[tex];
|
||||
|
||||
GetMapTexture(tex, grtex, &grtex->mipmap);
|
||||
GLMipmap_t *grMipmap = &grtex->mipmap;
|
||||
GLMipmap_t *originalMipmap = grMipmap;
|
||||
|
||||
if (!originalMipmap->downloaded)
|
||||
{
|
||||
originalMipmap->flags = TF_WRAPXY;
|
||||
originalMipmap->width = (UINT16)textures[tex]->width;
|
||||
originalMipmap->height = (UINT16)textures[tex]->height;
|
||||
originalMipmap->format = textureformat;
|
||||
}
|
||||
|
||||
// If chroma-keyed, create or use a different mipmap for the variant
|
||||
if (chromakeyed && !textures[tex]->transparency)
|
||||
{
|
||||
// Allocate it if it wasn't already
|
||||
if (!originalMipmap->nextcolormap)
|
||||
{
|
||||
GLMipmap_t *newMipmap = calloc(1, sizeof (*grMipmap));
|
||||
if (newMipmap == NULL)
|
||||
I_Error("%s: Out of memory", "HWR_GetTexture");
|
||||
|
||||
newMipmap->flags = originalMipmap->flags | TF_CHROMAKEYED;
|
||||
newMipmap->width = originalMipmap->width;
|
||||
newMipmap->height = originalMipmap->height;
|
||||
newMipmap->format = originalMipmap->format;
|
||||
originalMipmap->nextcolormap = newMipmap;
|
||||
}
|
||||
|
||||
// Generate, upload and bind the variant texture instead of the original one
|
||||
grMipmap = originalMipmap->nextcolormap;
|
||||
}
|
||||
|
||||
if (!grMipmap->data)
|
||||
HWR_GenerateTexture(tex, grtex, grMipmap);
|
||||
|
||||
if (!grMipmap->downloaded)
|
||||
HWD.pfnSetTexture(grMipmap);
|
||||
HWR_SetCurrentTexture(grMipmap);
|
||||
|
||||
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||
|
||||
return grtex;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -120,7 +120,7 @@ void HWR_GetPatch(patch_t *patch);
|
|||
void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap);
|
||||
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
|
||||
|
||||
GLMapTexture_t *HWR_GetTexture(INT32 tex);
|
||||
GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed);
|
||||
void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed);
|
||||
void HWR_GetRawFlat(lumpnum_t flatlumpnum);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -226,89 +226,56 @@ UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if
|
|||
return surfcolor.s.alpha;
|
||||
}
|
||||
|
||||
static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y)
|
||||
static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y) // TODO: improve "fake contrast" system
|
||||
{
|
||||
INT16 finallight = lightnum;
|
||||
const UINT8 contrast = 8;
|
||||
|
||||
if (cv_glfakecontrast.value != 0)
|
||||
{
|
||||
const UINT8 contrast = 8;
|
||||
fixed_t extralight = 0;
|
||||
if (v1y == v2y)
|
||||
finallight -= contrast;
|
||||
else if (v1x == v2x)
|
||||
finallight += contrast;
|
||||
|
||||
if (cv_glfakecontrast.value == 2) // Smooth setting
|
||||
{
|
||||
extralight = (-(contrast<<FRACBITS) +
|
||||
FixedDiv(AngleFixed(R_PointToAngle2(0, 0,
|
||||
abs(v1x - v2x),
|
||||
abs(v1y - v2y))), 90<<FRACBITS)
|
||||
* (contrast * 2)) >> FRACBITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v1y == v2y)
|
||||
extralight = -contrast;
|
||||
else if (v1x == v2x)
|
||||
extralight = contrast;
|
||||
}
|
||||
|
||||
if (extralight != 0)
|
||||
{
|
||||
finallight += extralight;
|
||||
|
||||
if (finallight < 0)
|
||||
finallight = 0;
|
||||
if (finallight > 255)
|
||||
finallight = 255;
|
||||
}
|
||||
}
|
||||
|
||||
return (FUINT)finallight;
|
||||
return (FUINT)max(0, min(255, finallight));
|
||||
}
|
||||
|
||||
static FUINT HWR_CalcSlopeLight(FUINT lightnum, angle_t dir, fixed_t delta)
|
||||
static UINT8 HWR_SideLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
INT16 finallight = lightnum;
|
||||
|
||||
if (cv_glfakecontrast.value != 0 && cv_glslopecontrast.value != 0)
|
||||
{
|
||||
const UINT8 contrast = 8;
|
||||
fixed_t extralight = 0;
|
||||
|
||||
if (cv_glfakecontrast.value == 2) // Smooth setting
|
||||
{
|
||||
fixed_t dirmul = abs(FixedDiv(AngleFixed(dir) - (180<<FRACBITS), 180<<FRACBITS));
|
||||
|
||||
extralight = -(contrast<<FRACBITS) + (dirmul * (contrast * 2));
|
||||
|
||||
extralight = FixedMul(extralight, delta*4) >> FRACBITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
dir = ((dir + ANGLE_45) / ANGLE_90) * ANGLE_90;
|
||||
|
||||
if (dir == ANGLE_180)
|
||||
extralight = -contrast;
|
||||
else if (dir == 0)
|
||||
extralight = contrast;
|
||||
|
||||
if (delta >= FRACUNIT/2)
|
||||
extralight *= 2;
|
||||
}
|
||||
|
||||
if (extralight != 0)
|
||||
{
|
||||
finallight += extralight;
|
||||
|
||||
if (finallight < 0)
|
||||
finallight = 0;
|
||||
if (finallight > 255)
|
||||
finallight = 255;
|
||||
}
|
||||
}
|
||||
|
||||
return (FUINT)finallight;
|
||||
return max(0, min(255, side->light +
|
||||
((side->lightabsolute) ? 0 : base_lightlevel)));
|
||||
}
|
||||
|
||||
/* TODO: implement per-texture lighting
|
||||
static UINT8 HWR_TopLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light_top +
|
||||
((side->lightabsolute_top) ? 0 : HWR_SideLightLevel(side, base_lightlevel))));
|
||||
}
|
||||
|
||||
static UINT8 HWR_MidLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light_mid +
|
||||
((side->lightabsolute_mid) ? 0 : HWR_SideLightLevel(side, base_lightlevel))));
|
||||
}
|
||||
|
||||
static UINT8 HWR_BottomLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light_bottom +
|
||||
((side->lightabsolute_bottom) ? 0 : HWR_SideLightLevel(side, base_lightlevel))));
|
||||
}
|
||||
*/
|
||||
|
||||
static UINT8 HWR_FloorLightLevel(sector_t *sector, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, sector->floorlightlevel +
|
||||
((sector->floorlightabsolute) ? 0 : base_lightlevel)));
|
||||
}
|
||||
|
||||
static UINT8 HWR_CeilingLightLevel(sector_t *sector, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, sector->ceilinglightlevel +
|
||||
((sector->ceilinglightabsolute) ? 0 : base_lightlevel)));
|
||||
}
|
||||
// ==========================================================================
|
||||
// FLOOR/CEILING GENERATION FROM SUBSECTORS
|
||||
// ==========================================================================
|
||||
|
@ -461,9 +428,6 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
|||
for (i = 0, v3d = planeVerts; i < (INT32)nrPlaneVerts; i++,v3d++,pv++)
|
||||
SETUP3DVERT(v3d, pv->x, pv->y);
|
||||
|
||||
if (slope)
|
||||
lightlevel = HWR_CalcSlopeLight(lightlevel, R_PointToAngle2(0, 0, slope->normal.x, slope->normal.y), abs(slope->zdelta));
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, planecolormap);
|
||||
|
||||
if (PolyFlags & (PF_Translucent|PF_Fog|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
|
||||
|
@ -705,8 +669,9 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
fixed_t v2x = FloatToFixed(wallVerts[1].x);
|
||||
fixed_t v2y = FloatToFixed(wallVerts[1].z);
|
||||
|
||||
FUINT lightnum = HWR_SideLightLevel(gl_sidedef, sector->lightlevel);
|
||||
const UINT8 alpha = Surf->PolyColor.s.alpha;
|
||||
FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y);
|
||||
lightnum = HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
|
||||
extracolormap_t *colormap = NULL;
|
||||
|
||||
if (!r_renderwalls)
|
||||
|
@ -750,13 +715,13 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
{
|
||||
if (pfloor && (pfloor->fofflags & FOF_FOG))
|
||||
{
|
||||
lightnum = pfloor->master->frontsector->lightlevel;
|
||||
lightnum = HWR_SideLightLevel(gl_sidedef, pfloor->master->frontsector->lightlevel);
|
||||
colormap = pfloor->master->frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightnum = *list[i].lightlevel;
|
||||
lightnum = HWR_SideLightLevel(gl_sidedef, *list[i].lightlevel);
|
||||
colormap = *list[i].extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
|
||||
}
|
||||
|
@ -951,7 +916,7 @@ static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliph
|
|||
else
|
||||
repeats = 1;
|
||||
|
||||
GLMapTexture_t *grTex = HWR_GetTexture(gl_midtexture);
|
||||
GLMapTexture_t *grTex = HWR_GetTexture(gl_midtexture, true);
|
||||
float xscale = FixedToFloat(gl_sidedef->scalex_mid);
|
||||
float yscale = FixedToFloat(gl_sidedef->scaley_mid);
|
||||
|
||||
|
@ -1167,7 +1132,7 @@ static void HWR_ProcessSeg(void)
|
|||
float cliplow = (float)gl_curline->offset;
|
||||
float cliphigh = cliplow + (gl_curline->flength * FRACUNIT);
|
||||
|
||||
FUINT lightnum = gl_frontsector->lightlevel;
|
||||
FUINT lightnum = HWR_SideLightLevel(gl_sidedef, gl_frontsector->lightlevel);
|
||||
extracolormap_t *colormap = gl_frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||
|
||||
|
@ -1210,7 +1175,7 @@ static void HWR_ProcessSeg(void)
|
|||
// check TOP TEXTURE
|
||||
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture)
|
||||
{
|
||||
grTex = HWR_GetTexture(gl_toptexture);
|
||||
grTex = HWR_GetTexture(gl_toptexture, false);
|
||||
xscale = FixedToFloat(abs(gl_sidedef->scalex_top));
|
||||
yscale = FixedToFloat(abs(gl_sidedef->scaley_top));
|
||||
|
||||
|
@ -1300,7 +1265,7 @@ static void HWR_ProcessSeg(void)
|
|||
// check BOTTOM TEXTURE
|
||||
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture)
|
||||
{
|
||||
grTex = HWR_GetTexture(gl_bottomtexture);
|
||||
grTex = HWR_GetTexture(gl_bottomtexture, false);
|
||||
xscale = FixedToFloat(abs(gl_sidedef->scalex_bottom));
|
||||
yscale = FixedToFloat(abs(gl_sidedef->scaley_bottom));
|
||||
|
||||
|
@ -1414,7 +1379,7 @@ static void HWR_ProcessSeg(void)
|
|||
// Single sided line... Deal only with the middletexture (if one exists)
|
||||
if (gl_midtexture && gl_linedef->special != SPECIAL_HORIZON_LINE) // (Ignore horizon line for OGL)
|
||||
{
|
||||
grTex = HWR_GetTexture(gl_midtexture);
|
||||
grTex = HWR_GetTexture(gl_midtexture, false);
|
||||
xscale = FixedToFloat(gl_sidedef->scalex_mid);
|
||||
yscale = FixedToFloat(gl_sidedef->scaley_mid);
|
||||
|
||||
|
@ -1588,7 +1553,7 @@ static void HWR_ProcessSeg(void)
|
|||
// -- Monster Iestyn 26/06/18
|
||||
fixed_t texturevpeg = side->rowoffset + side->offsety_mid;
|
||||
|
||||
grTex = HWR_GetTexture(texnum);
|
||||
grTex = HWR_GetTexture(texnum, true);
|
||||
xscale = FixedToFloat(side->scalex_mid);
|
||||
yscale = FixedToFloat(side->scaley_mid);
|
||||
|
||||
|
@ -1628,11 +1593,11 @@ static void HWR_ProcessSeg(void)
|
|||
{
|
||||
blendmode = PF_Fog|PF_NoTexture;
|
||||
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
lightnum = HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel);
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel), rover->master->frontsector->extra_colormap);
|
||||
|
||||
if (gl_frontsector->numlights)
|
||||
HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->fofflags, rover, blendmode);
|
||||
|
@ -1745,7 +1710,7 @@ static void HWR_ProcessSeg(void)
|
|||
// -- Monster Iestyn 26/06/18
|
||||
fixed_t texturevpeg = side->rowoffset + side->offsety_mid;
|
||||
|
||||
grTex = HWR_GetTexture(texnum);
|
||||
grTex = HWR_GetTexture(texnum, true);
|
||||
xscale = FixedToFloat(side->scalex_mid);
|
||||
yscale = FixedToFloat(side->scaley_mid);
|
||||
|
||||
|
@ -1785,7 +1750,7 @@ static void HWR_ProcessSeg(void)
|
|||
{
|
||||
blendmode = PF_Fog|PF_NoTexture;
|
||||
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
lightnum = HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel);
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||
|
||||
|
@ -2442,7 +2407,7 @@ static void HWR_Subsector(size_t num)
|
|||
rover; rover = rover->next)
|
||||
{
|
||||
fixed_t bottomCullHeight, topCullHeight, centerHeight;
|
||||
|
||||
|
||||
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES))
|
||||
continue;
|
||||
if (sub->validcount == validcount)
|
||||
|
@ -2471,13 +2436,13 @@ static void HWR_Subsector(size_t num)
|
|||
UINT8 alpha;
|
||||
|
||||
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false);
|
||||
alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap);
|
||||
alpha = HWR_FogBlockAlpha(HWR_FloorLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel), rover->master->frontsector->extra_colormap);
|
||||
|
||||
HWR_AddTransparentFloor(0,
|
||||
&extrasubsectors[num],
|
||||
false,
|
||||
*rover->bottomheight,
|
||||
*gl_frontsector->lightlist[light].lightlevel,
|
||||
HWR_FloorLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
|
||||
true, false, rover->master->frontsector->extra_colormap);
|
||||
}
|
||||
|
@ -2489,7 +2454,7 @@ static void HWR_Subsector(size_t num)
|
|||
&extrasubsectors[num],
|
||||
false,
|
||||
*rover->bottomheight,
|
||||
*gl_frontsector->lightlist[light].lightlevel,
|
||||
HWR_FloorLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
max(0, min(rover->alpha, 255)), rover->master->frontsector,
|
||||
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
|
||||
false, rover->fofflags & FOF_SPLAT, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
|
@ -2498,8 +2463,9 @@ static void HWR_Subsector(size_t num)
|
|||
{
|
||||
HWR_GetLevelFlat(&levelflats[*rover->bottompic], rover->fofflags & FOF_SPLAT);
|
||||
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false);
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
|
||||
rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude,
|
||||
HWR_FloorLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
&levelflats[*rover->bottompic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2516,13 +2482,13 @@ static void HWR_Subsector(size_t num)
|
|||
UINT8 alpha;
|
||||
|
||||
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false);
|
||||
alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap);
|
||||
alpha = HWR_FogBlockAlpha(HWR_CeilingLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel), rover->master->frontsector->extra_colormap);
|
||||
|
||||
HWR_AddTransparentFloor(0,
|
||||
&extrasubsectors[num],
|
||||
true,
|
||||
*rover->topheight,
|
||||
*gl_frontsector->lightlist[light].lightlevel,
|
||||
HWR_CeilingLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
|
||||
true, false, rover->master->frontsector->extra_colormap);
|
||||
}
|
||||
|
@ -2534,7 +2500,7 @@ static void HWR_Subsector(size_t num)
|
|||
&extrasubsectors[num],
|
||||
true,
|
||||
*rover->topheight,
|
||||
*gl_frontsector->lightlist[light].lightlevel,
|
||||
HWR_CeilingLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
max(0, min(rover->alpha, 255)), rover->master->frontsector,
|
||||
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
|
||||
false, rover->fofflags & FOF_SPLAT, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
|
@ -2543,8 +2509,9 @@ static void HWR_Subsector(size_t num)
|
|||
{
|
||||
HWR_GetLevelFlat(&levelflats[*rover->toppic], rover->fofflags & FOF_SPLAT);
|
||||
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false);
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
|
||||
rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude,
|
||||
HWR_CeilingLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
&levelflats[*rover->toppic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2880,7 +2847,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
}
|
||||
|
||||
HWR_Lighting(&sSurf, 0, colormap);
|
||||
sSurf.PolyColor.s.alpha = alpha;
|
||||
sSurf.PolyColor.s.alpha = FixedMul(thing->alpha, alpha);
|
||||
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
|
@ -3054,11 +3021,16 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
// baseWallVerts is used to know the final shape to easily get the vertex
|
||||
// co-ordinates
|
||||
memcpy(wallVerts, baseWallVerts, sizeof(baseWallVerts));
|
||||
|
||||
fixed_t newalpha = spr->mobj->alpha;
|
||||
|
||||
// if sprite has linkdraw, then dont write to z-buffer (by not using PF_Occlude)
|
||||
// this will result in sprites drawn afterwards to be drawn on top like intended when using linkdraw.
|
||||
if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer)
|
||||
{
|
||||
newalpha = spr->mobj->tracer->alpha;
|
||||
occlusion = 0;
|
||||
}
|
||||
else
|
||||
occlusion = PF_Occlude;
|
||||
|
||||
|
@ -3094,6 +3066,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
blend = HWR_GetBlendModeFlag(blendmode)|occlusion;
|
||||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
|
||||
Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha);
|
||||
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
|
@ -3543,11 +3517,15 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
FBITFIELD blend = 0;
|
||||
FBITFIELD occlusion;
|
||||
boolean use_linkdraw_hack = false;
|
||||
fixed_t newalpha = spr->mobj->alpha;
|
||||
|
||||
// if sprite has linkdraw, then dont write to z-buffer (by not using PF_Occlude)
|
||||
// this will result in sprites drawn afterwards to be drawn on top like intended when using linkdraw.
|
||||
if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer)
|
||||
{
|
||||
occlusion = 0;
|
||||
newalpha = spr->mobj->tracer->alpha;
|
||||
}
|
||||
else
|
||||
occlusion = PF_Occlude;
|
||||
|
||||
|
@ -3583,6 +3561,8 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
blend = HWR_GetBlendModeFlag(blendmode)|occlusion;
|
||||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
|
||||
Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha);
|
||||
|
||||
if (spr->renderflags & RF_SHADOWEFFECTS)
|
||||
{
|
||||
|
@ -3893,7 +3873,7 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo
|
|||
|
||||
planeinfo[numplanes].isceiling = isceiling;
|
||||
planeinfo[numplanes].fixedheight = fixedheight;
|
||||
planeinfo[numplanes].lightlevel = (planecolormap && (planecolormap->flags & CMF_FOG)) ? 255 : lightlevel;
|
||||
planeinfo[numplanes].lightlevel = (planecolormap && (planecolormap->flags & CMF_FOG)) ? lightlevel : 255; // TODO: 2.3: Make transparent FOF planes always use light level
|
||||
planeinfo[numplanes].levelflat = levelflat;
|
||||
planeinfo[numplanes].xsub = xsub;
|
||||
planeinfo[numplanes].alpha = alpha;
|
||||
|
@ -3925,7 +3905,7 @@ void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polyse
|
|||
|
||||
polyplaneinfo[numpolyplanes].isceiling = isceiling;
|
||||
polyplaneinfo[numpolyplanes].fixedheight = fixedheight;
|
||||
polyplaneinfo[numpolyplanes].lightlevel = (planecolormap && (planecolormap->flags & CMF_FOG)) ? 255 : lightlevel;
|
||||
polyplaneinfo[numpolyplanes].lightlevel = (planecolormap && (planecolormap->flags & CMF_FOG)) ? lightlevel : 255; // TODO: 2.3: Make transparent polyobject planes always use light level
|
||||
polyplaneinfo[numpolyplanes].levelflat = levelflat;
|
||||
polyplaneinfo[numpolyplanes].polysector = polysector;
|
||||
polyplaneinfo[numpolyplanes].alpha = alpha;
|
||||
|
@ -4086,7 +4066,7 @@ static void HWR_CreateDrawNodes(void)
|
|||
else if (sortnode[sortindex[i]].wall)
|
||||
{
|
||||
if (!(sortnode[sortindex[i]].wall->blend & PF_NoTexture))
|
||||
HWR_GetTexture(sortnode[sortindex[i]].wall->texnum);
|
||||
HWR_GetTexture(sortnode[sortindex[i]].wall->texnum, true);
|
||||
HWR_RenderWall(sortnode[sortindex[i]].wall->wallVerts, &sortnode[sortindex[i]].wall->Surf, sortnode[sortindex[i]].wall->blend, sortnode[sortindex[i]].wall->fogwall,
|
||||
sortnode[sortindex[i]].wall->lightlevel, sortnode[sortindex[i]].wall->wallcolormap);
|
||||
}
|
||||
|
@ -5066,6 +5046,8 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
|
||||
HWD.pfnSetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture], false);
|
||||
|
||||
if (cv_glskydome.value)
|
||||
{
|
||||
FTransform dometransform;
|
||||
|
@ -5081,8 +5063,6 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
HWR_SetTransformAiming(&dometransform, player, false);
|
||||
dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture]);
|
||||
|
||||
if (gl_sky.texture != texturetranslation[skytexture])
|
||||
{
|
||||
HWR_ClearSkyDome();
|
||||
|
@ -5102,7 +5082,6 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
float aspectratio;
|
||||
float angleturn;
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture]);
|
||||
aspectratio = (float)vid.width/(float)vid.height;
|
||||
|
||||
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
|
||||
|
@ -5542,7 +5521,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
|||
// Can't have palette rendering if shaders are disabled.
|
||||
boolean HWR_ShouldUsePaletteRendering(void)
|
||||
{
|
||||
return (cv_glpaletterendering.value && HWR_UseShader());
|
||||
return (pMasterPalette != NULL && cv_glpaletterendering.value && HWR_UseShader());
|
||||
}
|
||||
|
||||
// enable or disable palette rendering state depending on settings and availability
|
||||
|
@ -5613,7 +5592,6 @@ void HWR_LoadLevel(void)
|
|||
|
||||
static CV_PossibleValue_t glshaders_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Ignore custom shaders"}, {0, NULL}};
|
||||
static CV_PossibleValue_t glmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}};
|
||||
static CV_PossibleValue_t glfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}};
|
||||
static CV_PossibleValue_t glshearing_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Third-person"}, {0, NULL}};
|
||||
|
||||
static void CV_glfiltermode_OnChange(void);
|
||||
|
@ -5647,8 +5625,6 @@ consvar_t cv_glmodellighting = CVAR_INIT ("gr_modellighting", "Off", CV_SAVE|CV_
|
|||
consvar_t cv_glshearing = CVAR_INIT ("gr_shearing", "Off", CV_SAVE, glshearing_cons_t, NULL);
|
||||
consvar_t cv_glspritebillboarding = CVAR_INIT ("gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
consvar_t cv_glskydome = CVAR_INIT ("gr_skydome", "On", CV_SAVE, CV_OnOff, NULL);
|
||||
consvar_t cv_glfakecontrast = CVAR_INIT ("gr_fakecontrast", "Smooth", CV_SAVE, glfakecontrast_cons_t, NULL);
|
||||
consvar_t cv_glslopecontrast = CVAR_INIT ("gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_glfiltermode = CVAR_INIT ("gr_filtermode", "Nearest", CV_SAVE|CV_CALL, glfiltermode_cons_t, CV_glfiltermode_OnChange);
|
||||
consvar_t cv_glanisotropicmode = CVAR_INIT ("gr_anisotropicmode", "1", CV_SAVE|CV_CALL, glanisotropicmode_cons_t, CV_glanisotropic_OnChange);
|
||||
|
@ -5659,7 +5635,7 @@ consvar_t cv_glbatching = CVAR_INIT ("gr_batching", "On", 0, CV_OnOff, NULL);
|
|||
|
||||
static CV_PossibleValue_t glpalettedepth_cons_t[] = {{16, "16 bits"}, {24, "24 bits"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_glpaletterendering = CVAR_INIT ("gr_paletterendering", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_glpaletterendering_OnChange);
|
||||
consvar_t cv_glpaletterendering = CVAR_INIT ("gr_paletterendering", "On", CV_SAVE|CV_CALL, CV_OnOff, CV_glpaletterendering_OnChange);
|
||||
consvar_t cv_glpalettedepth = CVAR_INIT ("gr_palettedepth", "16 bits", CV_SAVE|CV_CALL, glpalettedepth_cons_t, CV_glpalettedepth_OnChange);
|
||||
|
||||
#define ONLY_IF_GL_LOADED if (vid.glstate != VID_GL_LIBRARY_LOADED) return;
|
||||
|
@ -5730,7 +5706,6 @@ void HWR_AddCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_glskydome);
|
||||
CV_RegisterVar(&cv_glspritebillboarding);
|
||||
CV_RegisterVar(&cv_glfakecontrast);
|
||||
CV_RegisterVar(&cv_glshearing);
|
||||
CV_RegisterVar(&cv_glshaders);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -91,8 +91,6 @@ extern consvar_t cv_glsolvetjoin;
|
|||
extern consvar_t cv_glshearing;
|
||||
extern consvar_t cv_glspritebillboarding;
|
||||
extern consvar_t cv_glskydome;
|
||||
extern consvar_t cv_glfakecontrast;
|
||||
extern consvar_t cv_glslopecontrast;
|
||||
extern consvar_t cv_glbatching;
|
||||
extern consvar_t cv_glpaletterendering;
|
||||
extern consvar_t cv_glpalettedepth;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -1154,6 +1154,9 @@ static void adjustTextureCoords(model_t *model, patch_t *patch)
|
|||
int i;
|
||||
GLPatch_t *gpatch = ((GLPatch_t *)patch->hardware);
|
||||
|
||||
if (!gpatch)
|
||||
return;
|
||||
|
||||
for (i = 0; i < model->numMeshes; i++)
|
||||
{
|
||||
int j;
|
||||
|
@ -1286,6 +1289,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
// Apparently people don't like jump frames like that, so back it goes
|
||||
//if (tics > durs)
|
||||
//durs = tics;
|
||||
|
||||
// Make linkdraw objects use their tracer's alpha value
|
||||
fixed_t newalpha = spr->mobj->alpha;
|
||||
if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer)
|
||||
newalpha = spr->mobj->tracer->alpha;
|
||||
|
||||
INT32 blendmode;
|
||||
if (spr->mobj->frame & FF_BLENDMASK)
|
||||
|
@ -1300,6 +1308,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
Surf.PolyColor.s.alpha = (spr->mobj->flags2 & MF2_SHADOW) ? 0x40 : 0xff;
|
||||
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
|
||||
}
|
||||
|
||||
Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha);
|
||||
|
||||
// don't forget to enable the depth test because we can't do this
|
||||
// like before: model polygons are not sorted
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2021 by Sonic Team Junior.
|
||||
// Copyright (C) 2021-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -448,6 +448,101 @@ void HWR_LoadAllCustomShaders(void)
|
|||
HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i]));
|
||||
}
|
||||
|
||||
static const char version_directives[][14] = {
|
||||
"#version 330\n",
|
||||
"#version 150\n",
|
||||
"#version 140\n",
|
||||
"#version 130\n",
|
||||
"#version 120\n",
|
||||
"#version 110\n",
|
||||
};
|
||||
|
||||
static boolean HWR_VersionDirectiveExists(const char* source)
|
||||
{
|
||||
return strncmp(source, "#version", 8) == 0;
|
||||
}
|
||||
|
||||
static char* HWR_PrependVersionDirective(const char* source, UINT32 version_index)
|
||||
{
|
||||
const UINT32 version_len = sizeof(version_directives[version_index]) - 1;
|
||||
const UINT32 source_len = strlen(source);
|
||||
|
||||
char* result = Z_Malloc(source_len + version_len + 1, PU_STATIC, NULL);
|
||||
strcpy(result, version_directives[version_index]);
|
||||
strcpy(result + version_len, source);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void HWR_ReplaceVersionInplace(char* shader, UINT32 version_index)
|
||||
{
|
||||
shader[9] = version_directives[version_index][9];
|
||||
shader[10] = version_directives[version_index][10];
|
||||
shader[11] = version_directives[version_index][11];
|
||||
}
|
||||
|
||||
static boolean HWR_CheckVersionDirectives(const char* vert, const char* frag)
|
||||
{
|
||||
return HWR_VersionDirectiveExists(vert) && HWR_VersionDirectiveExists(frag);
|
||||
}
|
||||
|
||||
static void HWR_TryToCompileShaderWithImplicitVersion(INT32 shader_index, INT32 shaderxlat_id)
|
||||
{
|
||||
char* vert_shader = gl_shaders[shader_index].vertex;
|
||||
char* frag_shader = gl_shaders[shader_index].fragment;
|
||||
|
||||
boolean vert_shader_version_exists = HWR_VersionDirectiveExists(vert_shader);
|
||||
boolean frag_shader_version_exists = HWR_VersionDirectiveExists(frag_shader);
|
||||
|
||||
if(!vert_shader_version_exists) {
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: vertex shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id));
|
||||
}
|
||||
|
||||
if(!frag_shader_version_exists) {
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: fragment shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id));
|
||||
}
|
||||
|
||||
// try to compile as is
|
||||
HWR_CompileShader(shader_index);
|
||||
if (gl_shaders[shader_index].compiled)
|
||||
return;
|
||||
|
||||
// try each version directive
|
||||
for(UINT32 i = 0; i < sizeof(version_directives) / sizeof(version_directives[0]); ++i) {
|
||||
CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Trying %s\n", version_directives[i]);
|
||||
|
||||
if(!vert_shader_version_exists) {
|
||||
// first time reallocation would have to be made
|
||||
|
||||
if(i == 0) {
|
||||
void* old = (void*)gl_shaders[shader_index].vertex;
|
||||
vert_shader = gl_shaders[shader_index].vertex = HWR_PrependVersionDirective(vert_shader, i);
|
||||
Z_Free(old);
|
||||
} else {
|
||||
HWR_ReplaceVersionInplace(vert_shader, i);
|
||||
}
|
||||
}
|
||||
|
||||
if(!frag_shader_version_exists) {
|
||||
if(i == 0) {
|
||||
void* old = (void*)gl_shaders[shader_index].fragment;
|
||||
frag_shader = gl_shaders[shader_index].fragment = HWR_PrependVersionDirective(frag_shader, i);
|
||||
Z_Free(old);
|
||||
} else {
|
||||
HWR_ReplaceVersionInplace(frag_shader, i);
|
||||
}
|
||||
}
|
||||
|
||||
HWR_CompileShader(shader_index);
|
||||
if (gl_shaders[shader_index].compiled) {
|
||||
CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Compiled with %s\n",
|
||||
version_directives[i]);
|
||||
CONS_Alert(CONS_WARNING, "Implicit GLSL version is used. Correct behavior is not guaranteed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
|
||||
{
|
||||
UINT16 lump;
|
||||
|
@ -610,7 +705,13 @@ skip_field:
|
|||
gl_shaders[shader_index].fragment = Z_StrDup(gl_shadersources[i].fragment);
|
||||
if (!gl_shaders[shader_index].vertex)
|
||||
gl_shaders[shader_index].vertex = Z_StrDup(gl_shadersources[i].vertex);
|
||||
HWR_CompileShader(shader_index);
|
||||
|
||||
if(!HWR_CheckVersionDirectives(gl_shaders[shader_index].vertex, gl_shaders[shader_index].fragment)) {
|
||||
HWR_TryToCompileShaderWithImplicitVersion(shader_index, i);
|
||||
} else {
|
||||
HWR_CompileShader(shader_index);
|
||||
}
|
||||
|
||||
if (!gl_shaders[shader_index].compiled)
|
||||
CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: A compilation error occured for the %s shader in file %s. See the console messages above for more information.\n", shaderxlat[i].type, wadfiles[wadnum]->filename);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2021 by Sonic Team Junior.
|
||||
// Copyright (C) 2021-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
129
src/hu_stuff.c
129
src/hu_stuff.c
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -29,7 +29,7 @@
|
|||
#include "i_video.h"
|
||||
#include "i_system.h"
|
||||
|
||||
#include "st_stuff.h" // ST_HEIGHT
|
||||
#include "st_stuff.h"
|
||||
#include "r_local.h"
|
||||
|
||||
#include "keys.h"
|
||||
|
@ -204,7 +204,7 @@ void HU_LoadGraphics(void)
|
|||
HU_SetFontProperties(&hu_font, 0, 4, 8, 12);
|
||||
HU_SetFontProperties(&tny_font, 0, 2, 4, 12);
|
||||
HU_SetFontProperties(&cred_font, 0, 16, 16, 16);
|
||||
HU_SetFontProperties(<_font, 0, 16, 20, 20);
|
||||
HU_SetFontProperties(<_font, 0, 16, 20, 16);
|
||||
HU_SetFontProperties(&ntb_font, 2, 4, 20, 21);
|
||||
HU_SetFontProperties(&nto_font, 0, 4, 20, 21);
|
||||
|
||||
|
@ -587,8 +587,8 @@ static void Command_CSay_f(void)
|
|||
DoSayCommand(0, 1, HU_CSAY);
|
||||
}
|
||||
|
||||
static tic_t spam_tokens[MAXPLAYERS] = { 1 }; // fill the buffer with 1 so the motd can be sent.
|
||||
static tic_t spam_tics[MAXPLAYERS];
|
||||
UINT8 spam_tokens[MAXPLAYERS] = { 1 }; // fill the buffer with 1 so the motd can be sent.
|
||||
tic_t spam_tics[MAXPLAYERS];
|
||||
|
||||
/** Receives a message, processing an ::XD_SAY command.
|
||||
* \sa DoSayCommand
|
||||
|
@ -599,6 +599,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
|||
SINT8 target;
|
||||
UINT8 flags;
|
||||
const char *dispname;
|
||||
char buf[HU_MAXMSGLEN + 1];
|
||||
char *msg;
|
||||
boolean action = false;
|
||||
char *ptr;
|
||||
|
@ -608,8 +609,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
|||
|
||||
target = READSINT8(*p);
|
||||
flags = READUINT8(*p);
|
||||
msg = (char *)*p;
|
||||
SKIPSTRINGL(*p, HU_MAXMSGLEN + 1);
|
||||
msg = buf;
|
||||
READSTRINGL(*p, msg, HU_MAXMSGLEN + 1);
|
||||
|
||||
if ((cv_mute.value || players[playernum].muted || flags & (HU_CSAY|HU_SERVER_SAY)) && playernum != serverplayer && !(IsPlayerAdmin(playernum)))
|
||||
{
|
||||
|
@ -649,14 +650,12 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
|||
else
|
||||
spam_tokens[playernum] -= 1;
|
||||
|
||||
// run the lua hook even if we were supposed to eat the msg, netgame consistency goes first.
|
||||
if (spam_eatmsg)
|
||||
return; // don't proceed if we were supposed to eat the message.
|
||||
|
||||
if (LUA_HookPlayerMsg(playernum, target, flags, msg))
|
||||
return;
|
||||
|
||||
if (spam_eatmsg)
|
||||
return; // don't proceed if we were supposed to eat the message.
|
||||
|
||||
// If it's a CSAY, just CECHO and be done with it.
|
||||
if (flags & HU_CSAY)
|
||||
{
|
||||
|
@ -1218,27 +1217,36 @@ static void HU_drawMiniChat(void)
|
|||
INT32 charwidth = 4, charheight = 6;
|
||||
INT32 boxw = cv_chatwidth.value;
|
||||
INT32 dx = 0, dy = 0;
|
||||
boolean prev_linereturn = false;
|
||||
|
||||
if (!chat_nummsg_min)
|
||||
return; // needless to say it's useless to do anything if we don't have anything to draw.
|
||||
|
||||
for (size_t i = chat_nummsg_min; i > 0; i--)
|
||||
{
|
||||
char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||
char *msg = V_ChatWordWrap(0, boxw-charwidth-2, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE|V_MONOSPACE, chat_mini[i-1]);
|
||||
for(size_t j = 0; msg[j]; j++) // iterate through msg
|
||||
{
|
||||
if (msg[j] == '\n') // get back down.
|
||||
{
|
||||
chatheight += charheight;
|
||||
dx = 0;
|
||||
if (!prev_linereturn)
|
||||
{
|
||||
chatheight += charheight;
|
||||
dx = 0;
|
||||
}
|
||||
prev_linereturn = true;
|
||||
}
|
||||
else if (msg[j] >= FONTSTART)
|
||||
{
|
||||
prev_linereturn = false;
|
||||
|
||||
dx += charwidth;
|
||||
if (dx >= boxw)
|
||||
|
||||
if (dx >= boxw-charwidth-2)
|
||||
{
|
||||
dx = 0;
|
||||
chatheight += charheight;
|
||||
prev_linereturn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1250,35 +1258,43 @@ static void HU_drawMiniChat(void)
|
|||
}
|
||||
|
||||
y = chaty - (chatheight + charheight);
|
||||
prev_linereturn = false;
|
||||
|
||||
for (size_t i = 0; i < chat_nummsg_min; i++) // iterate through our hot messages
|
||||
{
|
||||
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
|
||||
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
|
||||
char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
char *msg = V_ChatWordWrap(0, boxw-charwidth-2, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE|V_MONOSPACE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
|
||||
for(size_t j = 0; msg[j]; j++) // iterate through msg
|
||||
{
|
||||
if (msg[j] == '\n') // get back down.
|
||||
{
|
||||
dy += charheight;
|
||||
dx = 0;
|
||||
if (!prev_linereturn)
|
||||
{
|
||||
dy += charheight;
|
||||
dx = 0;
|
||||
}
|
||||
prev_linereturn = true;
|
||||
}
|
||||
else if (msg[j] & 0x80) // get colormap
|
||||
colormap = V_GetStringColormap(((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK);
|
||||
else if (msg[j] >= FONTSTART)
|
||||
{
|
||||
prev_linereturn = false;
|
||||
|
||||
if (cv_chatbacktint.value) // on request of wolfy
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, true, colormap);
|
||||
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_MONOSPACE|transflag, true, colormap);
|
||||
dx += charwidth;
|
||||
if (dx >= boxw)
|
||||
|
||||
if (dx >= boxw-charwidth-2)
|
||||
{
|
||||
dx = 0;
|
||||
dy += charheight;
|
||||
prev_linereturn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1303,6 +1319,7 @@ static void HU_drawChatLog(INT32 offset)
|
|||
UINT32 i = 0;
|
||||
INT32 chat_topy, chat_bottomy;
|
||||
boolean atbottom = false;
|
||||
boolean prev_linereturn = false;
|
||||
|
||||
// make sure that our scroll position isn't "illegal";
|
||||
if (chat_scroll > chat_maxscroll)
|
||||
|
@ -1335,27 +1352,38 @@ static void HU_drawChatLog(INT32 offset)
|
|||
|
||||
for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog
|
||||
{
|
||||
char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||
char *msg = V_ChatWordWrap(0, boxw-charwidth-2, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE|V_MONOSPACE, chat_log[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
for(size_t j = 0; msg[j]; j++) // iterate through msg
|
||||
{
|
||||
if (msg[j] == '\n') // get back down.
|
||||
{
|
||||
dy += charheight;
|
||||
dx = 0;
|
||||
if (!prev_linereturn)
|
||||
{
|
||||
dy += charheight;
|
||||
dx = 0;
|
||||
}
|
||||
prev_linereturn = true;
|
||||
}
|
||||
else if (msg[j] & 0x80) // get colormap
|
||||
colormap = V_GetStringColormap(((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK);
|
||||
else if (msg[j] >= FONTSTART)
|
||||
else
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, true, colormap);
|
||||
prev_linereturn = false;
|
||||
|
||||
dx += charwidth;
|
||||
if (dx >= boxw-charwidth-2 && i<chat_nummsg_log) // end of message shouldn't count, nor should invisible characters!!!!
|
||||
if (msg[j] >= FONTSTART)
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_MONOSPACE, true, colormap);
|
||||
|
||||
dx += charwidth;
|
||||
}
|
||||
|
||||
if (dx >= boxw-charwidth-2 && i < chat_nummsg_log) // end of message shouldn't count, nor should invisible characters!!!!
|
||||
{
|
||||
dx = 0;
|
||||
dy += charheight;
|
||||
prev_linereturn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2463,53 +2491,20 @@ static inline void HU_DrawSpectatorTicker(void)
|
|||
{
|
||||
int i;
|
||||
int length = 0, height = 174;
|
||||
int totallength = 0, templength = 0;
|
||||
int totallength = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].spectator)
|
||||
totallength += (signed)strlen(player_names[i]) * 8 + 16;
|
||||
|
||||
length -= (leveltime % (totallength + BASEVIDWIDTH));
|
||||
length += BASEVIDWIDTH;
|
||||
length -= (leveltime % (totallength + (vid.width / vid.dup)));
|
||||
length += (vid.width / vid.dup);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].spectator)
|
||||
{
|
||||
char *pos;
|
||||
char initial[MAXPLAYERNAME+1];
|
||||
char current[MAXPLAYERNAME+1];
|
||||
|
||||
strcpy(initial, player_names[i]);
|
||||
pos = initial;
|
||||
|
||||
if (length >= -((signed)strlen(player_names[i]) * 8 + 16) && length <= BASEVIDWIDTH)
|
||||
{
|
||||
if (length < 0)
|
||||
{
|
||||
UINT8 eatenchars = (UINT8)(abs(length) / 8 + 1);
|
||||
|
||||
if (eatenchars <= strlen(initial))
|
||||
{
|
||||
// Eat one letter off the left side,
|
||||
// then compensate the drawing position.
|
||||
pos += eatenchars;
|
||||
strcpy(current, pos);
|
||||
templength = length % 8 + 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(current, " ");
|
||||
templength = length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(current, initial);
|
||||
templength = length;
|
||||
}
|
||||
|
||||
V_DrawString(templength, height + 8, V_TRANSLUCENT|V_ALLOWLOWERCASE, current);
|
||||
}
|
||||
if (length >= -((signed)strlen(player_names[i]) * 8 + 16) && length <= (vid.width / vid.dup))
|
||||
V_DrawString(length, height + 8, V_TRANSLUCENT|V_ALLOWLOWERCASE|V_SNAPTOLEFT, player_names[i]);
|
||||
|
||||
length += (signed)strlen(player_names[i]) * 8 + 16;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -79,6 +79,9 @@ void HU_AddChatText(const char *text, boolean playsound);
|
|||
// set true when entering a chat message
|
||||
extern boolean chat_on;
|
||||
|
||||
extern UINT8 spam_tokens[MAXPLAYERS];
|
||||
extern tic_t spam_tics[MAXPLAYERS];
|
||||
|
||||
extern patch_t *emeraldpics[3][8];
|
||||
extern patch_t *rflagico;
|
||||
extern patch_t *bflagico;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
22
src/info.c
22
src/info.c
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -1784,8 +1784,8 @@ state_t states[NUMSTATES] =
|
|||
{SPR_RING, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_RING, 0}, // S_RING
|
||||
|
||||
// Blue Sphere for special stages
|
||||
{SPR_SPHR, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL, 0}, // S_BLUESPHERE
|
||||
{SPR_SPHR, FF_FULLBRIGHT
|
||||
{SPR_SPHR, FF_SEMIBRIGHT, -1, {NULL}, 0, 0, S_NULL, 0}, // S_BLUESPHERE
|
||||
{SPR_SPHR, FF_SEMIBRIGHT
|
||||
#ifdef MANIASPHERES
|
||||
|FF_ANIMATE|FF_RANDOMANIM
|
||||
#endif
|
||||
|
@ -1794,13 +1794,13 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// Bomb Sphere
|
||||
{SPR_SPHR, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_BOMBSPHERE2, 0}, // S_BOMBSPHERE1
|
||||
{SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3, 0}, // S_BOMBSPHERE2
|
||||
{SPR_SPHR, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4, 0}, // S_BOMBSPHERE3
|
||||
{SPR_SPHR, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1, 0}, // S_BOMBSPHERE4
|
||||
{SPR_SPHR, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE3, 0}, // S_BOMBSPHERE2
|
||||
{SPR_SPHR, FF_SEMIBRIGHT|5, 2, {NULL}, 0, 0, S_BOMBSPHERE4, 0}, // S_BOMBSPHERE3
|
||||
{SPR_SPHR, FF_SEMIBRIGHT|4, 1, {NULL}, 0, 0, S_BOMBSPHERE1, 0}, // S_BOMBSPHERE4
|
||||
|
||||
// NiGHTS Chip
|
||||
{SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 15, 2, S_NULL, 0}, // S_NIGHTSCHIP
|
||||
{SPR_NCHP, FF_FULLBRIGHT|FF_ANIMATE|16, -1, {NULL}, 15, 2, S_NULL, 0}, // S_NIGHTSCHIPBONUS
|
||||
{SPR_NCHP, FF_SEMIBRIGHT|FF_ANIMATE, -1, {NULL}, 15, 2, S_NULL, 0}, // S_NIGHTSCHIP
|
||||
{SPR_NCHP, FF_SEMIBRIGHT|FF_ANIMATE|16, -1, {NULL}, 15, 2, S_NULL, 0}, // S_NIGHTSCHIPBONUS
|
||||
|
||||
// NiGHTS Star
|
||||
{SPR_NSTR, FF_ANIMATE, -1, {NULL}, 14, 2, S_NULL, 0}, // S_NIGHTSSTAR
|
||||
|
@ -1858,9 +1858,9 @@ state_t states[NUMSTATES] =
|
|||
{SPR_CEMG, FF_FULLBRIGHT|6, -1, {NULL}, 0, 0, S_NULL, 0}, // S_CEMG7
|
||||
|
||||
// Emerald hunt shards
|
||||
{SPR_SHRD, 0, -1, {NULL}, 0, 0, S_NULL, 0}, // S_SHRD1
|
||||
{SPR_SHRD, 1, -1, {NULL}, 0, 0, S_NULL, 0}, // S_SHRD2
|
||||
{SPR_SHRD, 2, -1, {NULL}, 0, 0, S_NULL, 0}, // S_SHRD3
|
||||
{SPR_SHRD, FF_SEMIBRIGHT, -1, {NULL}, 0, 0, S_NULL, 0}, // S_SHRD1
|
||||
{SPR_SHRD, FF_SEMIBRIGHT|1, -1, {NULL}, 0, 0, S_NULL, 0}, // S_SHRD2
|
||||
{SPR_SHRD, FF_SEMIBRIGHT|2, -1, {NULL}, 0, 0, S_NULL, 0}, // S_SHRD3
|
||||
|
||||
// Bubble Source
|
||||
{SPR_BBLS, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2, 0}, // S_BUBBLES1
|
||||
|
|
540
src/info.h
540
src/info.h
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -298,276 +298,278 @@ enum actionnum
|
|||
NUMACTIONS
|
||||
};
|
||||
|
||||
struct mobj_s;
|
||||
|
||||
// IMPORTANT NOTE: If you add/remove from this list of action
|
||||
// functions, don't forget to update them in deh_tables.c!
|
||||
void A_Explode();
|
||||
void A_Pain();
|
||||
void A_Fall();
|
||||
void A_MonitorPop();
|
||||
void A_GoldMonitorPop();
|
||||
void A_GoldMonitorRestore();
|
||||
void A_GoldMonitorSparkle();
|
||||
void A_Look();
|
||||
void A_Chase();
|
||||
void A_FaceStabChase();
|
||||
void A_FaceStabRev();
|
||||
void A_FaceStabHurl();
|
||||
void A_FaceStabMiss();
|
||||
void A_StatueBurst();
|
||||
void A_FaceTarget();
|
||||
void A_FaceTracer();
|
||||
void A_Scream();
|
||||
void A_BossDeath();
|
||||
void A_SetShadowScale();
|
||||
void A_ShadowScream(); // MARIA!!!!!!
|
||||
void A_CustomPower(); // Use this for a custom power
|
||||
void A_GiveWeapon(); // Gives the player weapon(s)
|
||||
void A_RingBox(); // Obtained Ring Box Tails
|
||||
void A_Invincibility(); // Obtained Invincibility Box
|
||||
void A_SuperSneakers(); // Obtained Super Sneakers Box
|
||||
void A_BunnyHop(); // have bunny hop tails
|
||||
void A_BubbleSpawn(); // Randomly spawn bubbles
|
||||
void A_FanBubbleSpawn();
|
||||
void A_BubbleRise(); // Bubbles float to surface
|
||||
void A_BubbleCheck(); // Don't draw if not underwater
|
||||
void A_AwardScore();
|
||||
void A_ExtraLife(); // Extra Life
|
||||
void A_GiveShield(); // Obtained Shield
|
||||
void A_GravityBox();
|
||||
void A_ScoreRise(); // Rise the score logo
|
||||
void A_AttractChase(); // Ring Chase
|
||||
void A_DropMine(); // Drop Mine from Skim or Jetty-Syn Bomber
|
||||
void A_FishJump(); // Fish Jump
|
||||
void A_ThrownRing(); // Sparkle trail for red ring
|
||||
void A_SetSolidSteam();
|
||||
void A_UnsetSolidSteam();
|
||||
void A_SignSpin();
|
||||
void A_SignPlayer();
|
||||
void A_OverlayThink();
|
||||
void A_JetChase();
|
||||
void A_JetbThink(); // Jetty-Syn Bomber Thinker
|
||||
void A_JetgThink(); // Jetty-Syn Gunner Thinker
|
||||
void A_JetgShoot(); // Jetty-Syn Shoot Function
|
||||
void A_ShootBullet(); // JetgShoot without reactiontime setting
|
||||
void A_MinusDigging();
|
||||
void A_MinusPopup();
|
||||
void A_MinusCheck();
|
||||
void A_ChickenCheck();
|
||||
void A_MouseThink(); // Mouse Thinker
|
||||
void A_DetonChase(); // Deton Chaser
|
||||
void A_CapeChase(); // Fake little Super Sonic cape
|
||||
void A_RotateSpikeBall(); // Spike ball rotation
|
||||
void A_SlingAppear();
|
||||
void A_UnidusBall();
|
||||
void A_RockSpawn();
|
||||
void A_SetFuse();
|
||||
void A_CrawlaCommanderThink(); // Crawla Commander
|
||||
void A_SmokeTrailer();
|
||||
void A_RingExplode();
|
||||
void A_OldRingExplode();
|
||||
void A_MixUp();
|
||||
void A_RecyclePowers();
|
||||
void A_BossScream();
|
||||
void A_Boss2TakeDamage();
|
||||
void A_GoopSplat();
|
||||
void A_Boss2PogoSFX();
|
||||
void A_Boss2PogoTarget();
|
||||
void A_EggmanBox();
|
||||
void A_TurretFire();
|
||||
void A_SuperTurretFire();
|
||||
void A_TurretStop();
|
||||
void A_JetJawRoam();
|
||||
void A_JetJawChomp();
|
||||
void A_PointyThink();
|
||||
void A_CheckBuddy();
|
||||
void A_HoodFire();
|
||||
void A_HoodThink();
|
||||
void A_HoodFall();
|
||||
void A_ArrowBonks();
|
||||
void A_SnailerThink();
|
||||
void A_SharpChase();
|
||||
void A_SharpSpin();
|
||||
void A_SharpDecel();
|
||||
void A_CrushstaceanWalk();
|
||||
void A_CrushstaceanPunch();
|
||||
void A_CrushclawAim();
|
||||
void A_CrushclawLaunch();
|
||||
void A_VultureVtol();
|
||||
void A_VultureCheck();
|
||||
void A_VultureHover();
|
||||
void A_VultureBlast();
|
||||
void A_VultureFly();
|
||||
void A_SkimChase();
|
||||
void A_SkullAttack();
|
||||
void A_LobShot();
|
||||
void A_FireShot();
|
||||
void A_SuperFireShot();
|
||||
void A_BossFireShot();
|
||||
void A_Boss7FireMissiles();
|
||||
void A_Boss1Laser();
|
||||
void A_FocusTarget();
|
||||
void A_Boss4Reverse();
|
||||
void A_Boss4SpeedUp();
|
||||
void A_Boss4Raise();
|
||||
void A_SparkFollow();
|
||||
void A_BuzzFly();
|
||||
void A_GuardChase();
|
||||
void A_EggShield();
|
||||
void A_SetReactionTime();
|
||||
void A_Boss1Spikeballs();
|
||||
void A_Boss3TakeDamage();
|
||||
void A_Boss3Path();
|
||||
void A_Boss3ShockThink();
|
||||
void A_Shockwave();
|
||||
void A_LinedefExecute();
|
||||
void A_LinedefExecuteFromArg();
|
||||
void A_PlaySeeSound();
|
||||
void A_PlayAttackSound();
|
||||
void A_PlayActiveSound();
|
||||
void A_1upThinker();
|
||||
void A_BossZoom(); //Unused
|
||||
void A_Boss1Chase();
|
||||
void A_Boss2Chase();
|
||||
void A_Boss2Pogo();
|
||||
void A_Boss7Chase();
|
||||
void A_BossJetFume();
|
||||
void A_SpawnObjectAbsolute();
|
||||
void A_SpawnObjectRelative();
|
||||
void A_ChangeAngleRelative();
|
||||
void A_ChangeAngleAbsolute();
|
||||
void A_RollAngle();
|
||||
void A_ChangeRollAngleRelative();
|
||||
void A_ChangeRollAngleAbsolute();
|
||||
void A_PlaySound();
|
||||
void A_FindTarget();
|
||||
void A_FindTracer();
|
||||
void A_SetTics();
|
||||
void A_SetRandomTics();
|
||||
void A_ChangeColorRelative();
|
||||
void A_ChangeColorAbsolute();
|
||||
void A_Dye();
|
||||
void A_SetTranslation();
|
||||
void A_MoveRelative();
|
||||
void A_MoveAbsolute();
|
||||
void A_Thrust();
|
||||
void A_ZThrust();
|
||||
void A_SetTargetsTarget();
|
||||
void A_SetObjectFlags();
|
||||
void A_SetObjectFlags2();
|
||||
void A_RandomState();
|
||||
void A_RandomStateRange();
|
||||
void A_StateRangeByAngle();
|
||||
void A_StateRangeByParameter();
|
||||
void A_DualAction();
|
||||
void A_RemoteAction();
|
||||
void A_ToggleFlameJet();
|
||||
void A_OrbitNights();
|
||||
void A_GhostMe();
|
||||
void A_SetObjectState();
|
||||
void A_SetObjectTypeState();
|
||||
void A_KnockBack();
|
||||
void A_PushAway();
|
||||
void A_RingDrain();
|
||||
void A_SplitShot();
|
||||
void A_MissileSplit();
|
||||
void A_MultiShot();
|
||||
void A_InstaLoop();
|
||||
void A_Custom3DRotate();
|
||||
void A_SearchForPlayers();
|
||||
void A_CheckRandom();
|
||||
void A_CheckTargetRings();
|
||||
void A_CheckRings();
|
||||
void A_CheckTotalRings();
|
||||
void A_CheckHealth();
|
||||
void A_CheckRange();
|
||||
void A_CheckHeight();
|
||||
void A_CheckTrueRange();
|
||||
void A_CheckThingCount();
|
||||
void A_CheckAmbush();
|
||||
void A_CheckCustomValue();
|
||||
void A_CheckCusValMemo();
|
||||
void A_SetCustomValue();
|
||||
void A_UseCusValMemo();
|
||||
void A_RelayCustomValue();
|
||||
void A_CusValAction();
|
||||
void A_ForceStop();
|
||||
void A_ForceWin();
|
||||
void A_SpikeRetract();
|
||||
void A_InfoState();
|
||||
void A_Repeat();
|
||||
void A_SetScale();
|
||||
void A_RemoteDamage();
|
||||
void A_HomingChase();
|
||||
void A_TrapShot();
|
||||
void A_VileTarget();
|
||||
void A_VileAttack();
|
||||
void A_VileFire();
|
||||
void A_BrakChase();
|
||||
void A_BrakFireShot();
|
||||
void A_BrakLobShot();
|
||||
void A_NapalmScatter();
|
||||
void A_SpawnFreshCopy();
|
||||
void A_FlickySpawn();
|
||||
void A_FlickyCenter();
|
||||
void A_FlickyAim();
|
||||
void A_FlickyFly();
|
||||
void A_FlickySoar();
|
||||
void A_FlickyCoast();
|
||||
void A_FlickyHop();
|
||||
void A_FlickyFlounder();
|
||||
void A_FlickyCheck();
|
||||
void A_FlickyHeightCheck();
|
||||
void A_FlickyFlutter();
|
||||
void A_FlameParticle();
|
||||
void A_FadeOverlay();
|
||||
void A_Boss5Jump();
|
||||
void A_LightBeamReset();
|
||||
void A_MineExplode();
|
||||
void A_MineRange();
|
||||
void A_ConnectToGround();
|
||||
void A_SpawnParticleRelative();
|
||||
void A_MultiShotDist();
|
||||
void A_WhoCaresIfYourSonIsABee();
|
||||
void A_ParentTriesToSleep();
|
||||
void A_CryingToMomma();
|
||||
void A_CheckFlags2();
|
||||
void A_Boss5FindWaypoint();
|
||||
void A_DoNPCSkid();
|
||||
void A_DoNPCPain();
|
||||
void A_PrepareRepeat();
|
||||
void A_Boss5ExtraRepeat();
|
||||
void A_Boss5Calm();
|
||||
void A_Boss5CheckOnGround();
|
||||
void A_Boss5CheckFalling();
|
||||
void A_Boss5PinchShot();
|
||||
void A_Boss5MakeItRain();
|
||||
void A_Boss5MakeJunk();
|
||||
void A_LookForBetter();
|
||||
void A_Boss5BombExplode();
|
||||
void A_DustDevilThink();
|
||||
void A_TNTExplode();
|
||||
void A_DebrisRandom();
|
||||
void A_TrainCameo();
|
||||
void A_TrainCameo2();
|
||||
void A_CanarivoreGas();
|
||||
void A_KillSegments();
|
||||
void A_SnapperSpawn();
|
||||
void A_SnapperThinker();
|
||||
void A_SaloonDoorSpawn();
|
||||
void A_MinecartSparkThink();
|
||||
void A_ModuloToState();
|
||||
void A_LavafallRocks();
|
||||
void A_LavafallLava();
|
||||
void A_FallingLavaCheck();
|
||||
void A_FireShrink();
|
||||
void A_SpawnPterabytes();
|
||||
void A_PterabyteHover();
|
||||
void A_RolloutSpawn();
|
||||
void A_RolloutRock();
|
||||
void A_DragonbomberSpawn();
|
||||
void A_DragonWing();
|
||||
void A_DragonSegment();
|
||||
void A_ChangeHeight();
|
||||
void A_Explode(struct mobj_s *actor);
|
||||
void A_Pain(struct mobj_s *actor);
|
||||
void A_Fall(struct mobj_s *actor);
|
||||
void A_MonitorPop(struct mobj_s *actor);
|
||||
void A_GoldMonitorPop(struct mobj_s *actor);
|
||||
void A_GoldMonitorRestore(struct mobj_s *actor);
|
||||
void A_GoldMonitorSparkle(struct mobj_s *actor);
|
||||
void A_Look(struct mobj_s *actor);
|
||||
void A_Chase(struct mobj_s *actor);
|
||||
void A_FaceStabChase(struct mobj_s *actor);
|
||||
void A_FaceStabRev(struct mobj_s *actor);
|
||||
void A_FaceStabHurl(struct mobj_s *actor);
|
||||
void A_FaceStabMiss(struct mobj_s *actor);
|
||||
void A_StatueBurst(struct mobj_s *actor);
|
||||
void A_FaceTarget(struct mobj_s *actor);
|
||||
void A_FaceTracer(struct mobj_s *actor);
|
||||
void A_Scream(struct mobj_s *actor);
|
||||
void A_BossDeath(struct mobj_s *actor);
|
||||
void A_SetShadowScale(struct mobj_s *actor);
|
||||
void A_ShadowScream(struct mobj_s *actor); // MARIA!!!!!!
|
||||
void A_CustomPower(struct mobj_s *actor); // Use this for a custom power
|
||||
void A_GiveWeapon(struct mobj_s *actor); // Gives the player weapon(s)
|
||||
void A_RingBox(struct mobj_s *actor); // Obtained Ring Box Tails
|
||||
void A_Invincibility(struct mobj_s *actor); // Obtained Invincibility Box
|
||||
void A_SuperSneakers(struct mobj_s *actor); // Obtained Super Sneakers Box
|
||||
void A_BunnyHop(struct mobj_s *actor); // have bunny hop tails
|
||||
void A_BubbleSpawn(struct mobj_s *actor); // Randomly spawn bubbles
|
||||
void A_FanBubbleSpawn(struct mobj_s *actor);
|
||||
void A_BubbleRise(struct mobj_s *actor); // Bubbles float to surface
|
||||
void A_BubbleCheck(struct mobj_s *actor); // Don't draw if not underwater
|
||||
void A_AwardScore(struct mobj_s *actor);
|
||||
void A_ExtraLife(struct mobj_s *actor); // Extra Life
|
||||
void A_GiveShield(struct mobj_s *actor); // Obtained Shield
|
||||
void A_GravityBox(struct mobj_s *actor);
|
||||
void A_ScoreRise(struct mobj_s *actor); // Rise the score logo
|
||||
void A_AttractChase(struct mobj_s *actor); // Ring Chase
|
||||
void A_DropMine(struct mobj_s *actor); // Drop Mine from Skim or Jetty-Syn Bomber
|
||||
void A_FishJump(struct mobj_s *actor); // Fish Jump
|
||||
void A_ThrownRing(struct mobj_s *actor); // Sparkle trail for red ring
|
||||
void A_SetSolidSteam(struct mobj_s *actor);
|
||||
void A_UnsetSolidSteam(struct mobj_s *actor);
|
||||
void A_SignSpin(struct mobj_s *actor);
|
||||
void A_SignPlayer(struct mobj_s *actor);
|
||||
void A_OverlayThink(struct mobj_s *actor);
|
||||
void A_JetChase(struct mobj_s *actor);
|
||||
void A_JetbThink(struct mobj_s *actor); // Jetty-Syn Bomber Thinker
|
||||
void A_JetgThink(struct mobj_s *actor); // Jetty-Syn Gunner Thinker
|
||||
void A_JetgShoot(struct mobj_s *actor); // Jetty-Syn Shoot Function
|
||||
void A_ShootBullet(struct mobj_s *actor); // JetgShoot without reactiontime setting
|
||||
void A_MinusDigging(struct mobj_s *actor);
|
||||
void A_MinusPopup(struct mobj_s *actor);
|
||||
void A_MinusCheck(struct mobj_s *actor);
|
||||
void A_ChickenCheck(struct mobj_s *actor);
|
||||
void A_MouseThink(struct mobj_s *actor); // Mouse Thinker
|
||||
void A_DetonChase(struct mobj_s *actor); // Deton Chaser
|
||||
void A_CapeChase(struct mobj_s *actor); // Fake little Super Sonic cape
|
||||
void A_RotateSpikeBall(struct mobj_s *actor); // Spike ball rotation
|
||||
void A_SlingAppear(struct mobj_s *actor);
|
||||
void A_UnidusBall(struct mobj_s *actor);
|
||||
void A_RockSpawn(struct mobj_s *actor);
|
||||
void A_SetFuse(struct mobj_s *actor);
|
||||
void A_CrawlaCommanderThink(struct mobj_s *actor); // Crawla Commander
|
||||
void A_SmokeTrailer(struct mobj_s *actor);
|
||||
void A_RingExplode(struct mobj_s *actor);
|
||||
void A_OldRingExplode(struct mobj_s *actor);
|
||||
void A_MixUp(struct mobj_s *actor);
|
||||
void A_RecyclePowers(struct mobj_s *actor);
|
||||
void A_BossScream(struct mobj_s *actor);
|
||||
void A_Boss2TakeDamage(struct mobj_s *actor);
|
||||
void A_GoopSplat(struct mobj_s *actor);
|
||||
void A_Boss2PogoSFX(struct mobj_s *actor);
|
||||
void A_Boss2PogoTarget(struct mobj_s *actor);
|
||||
void A_EggmanBox(struct mobj_s *actor);
|
||||
void A_TurretFire(struct mobj_s *actor);
|
||||
void A_SuperTurretFire(struct mobj_s *actor);
|
||||
void A_TurretStop(struct mobj_s *actor);
|
||||
void A_JetJawRoam(struct mobj_s *actor);
|
||||
void A_JetJawChomp(struct mobj_s *actor);
|
||||
void A_PointyThink(struct mobj_s *actor);
|
||||
void A_CheckBuddy(struct mobj_s *actor);
|
||||
void A_HoodFire(struct mobj_s *actor);
|
||||
void A_HoodThink(struct mobj_s *actor);
|
||||
void A_HoodFall(struct mobj_s *actor);
|
||||
void A_ArrowBonks(struct mobj_s *actor);
|
||||
void A_SnailerThink(struct mobj_s *actor);
|
||||
void A_SharpChase(struct mobj_s *actor);
|
||||
void A_SharpSpin(struct mobj_s *actor);
|
||||
void A_SharpDecel(struct mobj_s *actor);
|
||||
void A_CrushstaceanWalk(struct mobj_s *actor);
|
||||
void A_CrushstaceanPunch(struct mobj_s *actor);
|
||||
void A_CrushclawAim(struct mobj_s *actor);
|
||||
void A_CrushclawLaunch(struct mobj_s *actor);
|
||||
void A_VultureVtol(struct mobj_s *actor);
|
||||
void A_VultureCheck(struct mobj_s *actor);
|
||||
void A_VultureHover(struct mobj_s *actor);
|
||||
void A_VultureBlast(struct mobj_s *actor);
|
||||
void A_VultureFly(struct mobj_s *actor);
|
||||
void A_SkimChase(struct mobj_s *actor);
|
||||
void A_SkullAttack(struct mobj_s *actor);
|
||||
void A_LobShot(struct mobj_s *actor);
|
||||
void A_FireShot(struct mobj_s *actor);
|
||||
void A_SuperFireShot(struct mobj_s *actor);
|
||||
void A_BossFireShot(struct mobj_s *actor);
|
||||
void A_Boss7FireMissiles(struct mobj_s *actor);
|
||||
void A_Boss1Laser(struct mobj_s *actor);
|
||||
void A_FocusTarget(struct mobj_s *actor);
|
||||
void A_Boss4Reverse(struct mobj_s *actor);
|
||||
void A_Boss4SpeedUp(struct mobj_s *actor);
|
||||
void A_Boss4Raise(struct mobj_s *actor);
|
||||
void A_SparkFollow(struct mobj_s *actor);
|
||||
void A_BuzzFly(struct mobj_s *actor);
|
||||
void A_GuardChase(struct mobj_s *actor);
|
||||
void A_EggShield(struct mobj_s *actor);
|
||||
void A_SetReactionTime(struct mobj_s *actor);
|
||||
void A_Boss1Spikeballs(struct mobj_s *actor);
|
||||
void A_Boss3TakeDamage(struct mobj_s *actor);
|
||||
void A_Boss3Path(struct mobj_s *actor);
|
||||
void A_Boss3ShockThink(struct mobj_s *actor);
|
||||
void A_Shockwave(struct mobj_s *actor);
|
||||
void A_LinedefExecute(struct mobj_s *actor);
|
||||
void A_LinedefExecuteFromArg(struct mobj_s *actor);
|
||||
void A_PlaySeeSound(struct mobj_s *actor);
|
||||
void A_PlayAttackSound(struct mobj_s *actor);
|
||||
void A_PlayActiveSound(struct mobj_s *actor);
|
||||
void A_1upThinker(struct mobj_s *actor);
|
||||
void A_BossZoom(struct mobj_s *actor); //Unused
|
||||
void A_Boss1Chase(struct mobj_s *actor);
|
||||
void A_Boss2Chase(struct mobj_s *actor);
|
||||
void A_Boss2Pogo(struct mobj_s *actor);
|
||||
void A_Boss7Chase(struct mobj_s *actor);
|
||||
void A_BossJetFume(struct mobj_s *actor);
|
||||
void A_SpawnObjectAbsolute(struct mobj_s *actor);
|
||||
void A_SpawnObjectRelative(struct mobj_s *actor);
|
||||
void A_ChangeAngleRelative(struct mobj_s *actor);
|
||||
void A_ChangeAngleAbsolute(struct mobj_s *actor);
|
||||
void A_RollAngle(struct mobj_s *actor);
|
||||
void A_ChangeRollAngleRelative(struct mobj_s *actor);
|
||||
void A_ChangeRollAngleAbsolute(struct mobj_s *actor);
|
||||
void A_PlaySound(struct mobj_s *actor);
|
||||
void A_FindTarget(struct mobj_s *actor);
|
||||
void A_FindTracer(struct mobj_s *actor);
|
||||
void A_SetTics(struct mobj_s *actor);
|
||||
void A_SetRandomTics(struct mobj_s *actor);
|
||||
void A_ChangeColorRelative(struct mobj_s *actor);
|
||||
void A_ChangeColorAbsolute(struct mobj_s *actor);
|
||||
void A_Dye(struct mobj_s *actor);
|
||||
void A_SetTranslation(struct mobj_s *actor);
|
||||
void A_MoveRelative(struct mobj_s *actor);
|
||||
void A_MoveAbsolute(struct mobj_s *actor);
|
||||
void A_Thrust(struct mobj_s *actor);
|
||||
void A_ZThrust(struct mobj_s *actor);
|
||||
void A_SetTargetsTarget(struct mobj_s *actor);
|
||||
void A_SetObjectFlags(struct mobj_s *actor);
|
||||
void A_SetObjectFlags2(struct mobj_s *actor);
|
||||
void A_RandomState(struct mobj_s *actor);
|
||||
void A_RandomStateRange(struct mobj_s *actor);
|
||||
void A_StateRangeByAngle(struct mobj_s *actor);
|
||||
void A_StateRangeByParameter(struct mobj_s *actor);
|
||||
void A_DualAction(struct mobj_s *actor);
|
||||
void A_RemoteAction(struct mobj_s *actor);
|
||||
void A_ToggleFlameJet(struct mobj_s *actor);
|
||||
void A_OrbitNights(struct mobj_s *actor);
|
||||
void A_GhostMe(struct mobj_s *actor);
|
||||
void A_SetObjectState(struct mobj_s *actor);
|
||||
void A_SetObjectTypeState(struct mobj_s *actor);
|
||||
void A_KnockBack(struct mobj_s *actor);
|
||||
void A_PushAway(struct mobj_s *actor);
|
||||
void A_RingDrain(struct mobj_s *actor);
|
||||
void A_SplitShot(struct mobj_s *actor);
|
||||
void A_MissileSplit(struct mobj_s *actor);
|
||||
void A_MultiShot(struct mobj_s *actor);
|
||||
void A_InstaLoop(struct mobj_s *actor);
|
||||
void A_Custom3DRotate(struct mobj_s *actor);
|
||||
void A_SearchForPlayers(struct mobj_s *actor);
|
||||
void A_CheckRandom(struct mobj_s *actor);
|
||||
void A_CheckTargetRings(struct mobj_s *actor);
|
||||
void A_CheckRings(struct mobj_s *actor);
|
||||
void A_CheckTotalRings(struct mobj_s *actor);
|
||||
void A_CheckHealth(struct mobj_s *actor);
|
||||
void A_CheckRange(struct mobj_s *actor);
|
||||
void A_CheckHeight(struct mobj_s *actor);
|
||||
void A_CheckTrueRange(struct mobj_s *actor);
|
||||
void A_CheckThingCount(struct mobj_s *actor);
|
||||
void A_CheckAmbush(struct mobj_s *actor);
|
||||
void A_CheckCustomValue(struct mobj_s *actor);
|
||||
void A_CheckCusValMemo(struct mobj_s *actor);
|
||||
void A_SetCustomValue(struct mobj_s *actor);
|
||||
void A_UseCusValMemo(struct mobj_s *actor);
|
||||
void A_RelayCustomValue(struct mobj_s *actor);
|
||||
void A_CusValAction(struct mobj_s *actor);
|
||||
void A_ForceStop(struct mobj_s *actor);
|
||||
void A_ForceWin(struct mobj_s *actor);
|
||||
void A_SpikeRetract(struct mobj_s *actor);
|
||||
void A_InfoState(struct mobj_s *actor);
|
||||
void A_Repeat(struct mobj_s *actor);
|
||||
void A_SetScale(struct mobj_s *actor);
|
||||
void A_RemoteDamage(struct mobj_s *actor);
|
||||
void A_HomingChase(struct mobj_s *actor);
|
||||
void A_TrapShot(struct mobj_s *actor);
|
||||
void A_VileTarget(struct mobj_s *actor);
|
||||
void A_VileAttack(struct mobj_s *actor);
|
||||
void A_VileFire(struct mobj_s *actor);
|
||||
void A_BrakChase(struct mobj_s *actor);
|
||||
void A_BrakFireShot(struct mobj_s *actor);
|
||||
void A_BrakLobShot(struct mobj_s *actor);
|
||||
void A_NapalmScatter(struct mobj_s *actor);
|
||||
void A_SpawnFreshCopy(struct mobj_s *actor);
|
||||
void A_FlickySpawn(struct mobj_s *actor);
|
||||
void A_FlickyCenter(struct mobj_s *actor);
|
||||
void A_FlickyAim(struct mobj_s *actor);
|
||||
void A_FlickyFly(struct mobj_s *actor);
|
||||
void A_FlickySoar(struct mobj_s *actor);
|
||||
void A_FlickyCoast(struct mobj_s *actor);
|
||||
void A_FlickyHop(struct mobj_s *actor);
|
||||
void A_FlickyFlounder(struct mobj_s *actor);
|
||||
void A_FlickyCheck(struct mobj_s *actor);
|
||||
void A_FlickyHeightCheck(struct mobj_s *actor);
|
||||
void A_FlickyFlutter(struct mobj_s *actor);
|
||||
void A_FlameParticle(struct mobj_s *actor);
|
||||
void A_FadeOverlay(struct mobj_s *actor);
|
||||
void A_Boss5Jump(struct mobj_s *actor);
|
||||
void A_LightBeamReset(struct mobj_s *actor);
|
||||
void A_MineExplode(struct mobj_s *actor);
|
||||
void A_MineRange(struct mobj_s *actor);
|
||||
void A_ConnectToGround(struct mobj_s *actor);
|
||||
void A_SpawnParticleRelative(struct mobj_s *actor);
|
||||
void A_MultiShotDist(struct mobj_s *actor);
|
||||
void A_WhoCaresIfYourSonIsABee(struct mobj_s *actor);
|
||||
void A_ParentTriesToSleep(struct mobj_s *actor);
|
||||
void A_CryingToMomma(struct mobj_s *actor);
|
||||
void A_CheckFlags2(struct mobj_s *actor);
|
||||
void A_Boss5FindWaypoint(struct mobj_s *actor);
|
||||
void A_DoNPCSkid(struct mobj_s *actor);
|
||||
void A_DoNPCPain(struct mobj_s *actor);
|
||||
void A_PrepareRepeat(struct mobj_s *actor);
|
||||
void A_Boss5ExtraRepeat(struct mobj_s *actor);
|
||||
void A_Boss5Calm(struct mobj_s *actor);
|
||||
void A_Boss5CheckOnGround(struct mobj_s *actor);
|
||||
void A_Boss5CheckFalling(struct mobj_s *actor);
|
||||
void A_Boss5PinchShot(struct mobj_s *actor);
|
||||
void A_Boss5MakeItRain(struct mobj_s *actor);
|
||||
void A_Boss5MakeJunk(struct mobj_s *actor);
|
||||
void A_LookForBetter(struct mobj_s *actor);
|
||||
void A_Boss5BombExplode(struct mobj_s *actor);
|
||||
void A_DustDevilThink(struct mobj_s *actor);
|
||||
void A_TNTExplode(struct mobj_s *actor);
|
||||
void A_DebrisRandom(struct mobj_s *actor);
|
||||
void A_TrainCameo(struct mobj_s *actor);
|
||||
void A_TrainCameo2(struct mobj_s *actor);
|
||||
void A_CanarivoreGas(struct mobj_s *actor);
|
||||
void A_KillSegments(struct mobj_s *actor);
|
||||
void A_SnapperSpawn(struct mobj_s *actor);
|
||||
void A_SnapperThinker(struct mobj_s *actor);
|
||||
void A_SaloonDoorSpawn(struct mobj_s *actor);
|
||||
void A_MinecartSparkThink(struct mobj_s *actor);
|
||||
void A_ModuloToState(struct mobj_s *actor);
|
||||
void A_LavafallRocks(struct mobj_s *actor);
|
||||
void A_LavafallLava(struct mobj_s *actor);
|
||||
void A_FallingLavaCheck(struct mobj_s *actor);
|
||||
void A_FireShrink(struct mobj_s *actor);
|
||||
void A_SpawnPterabytes(struct mobj_s *actor);
|
||||
void A_PterabyteHover(struct mobj_s *actor);
|
||||
void A_RolloutSpawn(struct mobj_s *actor);
|
||||
void A_RolloutRock(struct mobj_s *actor);
|
||||
void A_DragonbomberSpawn(struct mobj_s *actor);
|
||||
void A_DragonWing(struct mobj_s *actor);
|
||||
void A_DragonSegment(struct mobj_s *actor);
|
||||
void A_ChangeHeight(struct mobj_s *actor);
|
||||
|
||||
extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION];
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -184,8 +184,10 @@ static const struct {
|
|||
{META_SKIN, "skin_t"},
|
||||
{META_POWERS, "player_t.powers"},
|
||||
{META_SOUNDSID, "skin_t.soundsid"},
|
||||
{META_SKINSPRITES, "skin_t.sprites"},
|
||||
{META_SKINSPRITESLIST, "skin_t.sprites[]"},
|
||||
|
||||
{META_SKINSPRITES, "skin_t.skinsprites"},
|
||||
{META_SKINSPRITESLIST, "skin_t.skinsprites[]"},
|
||||
{META_SKINSPRITESCOMPAT, "skin_t.sprites"}, // TODO: 2.3: Delete
|
||||
|
||||
{META_VERTEX, "vertex_t"},
|
||||
{META_LINE, "line_t"},
|
||||
|
@ -653,7 +655,7 @@ static int lib_pSpawnMobj(lua_State *L)
|
|||
NOHUD
|
||||
INLEVEL
|
||||
NOSPAWNNULL
|
||||
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ);
|
||||
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type, NULL), META_MOBJ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1728,12 +1730,11 @@ static int lib_pResetCamera(lua_State *L)
|
|||
static int lib_pSuperReady(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
boolean transform = (boolean)lua_opttrueboolean(L, 2);
|
||||
//HUDSAFE
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
lua_pushboolean(L, P_SuperReady(player, transform));
|
||||
lua_pushboolean(L, P_SuperReady(player));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3876,7 +3877,7 @@ static int lib_gAddPlayer(lua_State *L)
|
|||
player_t *newplayer;
|
||||
SINT8 skinnum = 0, bot;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
for (i = 1; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
break;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2021-2022 by "Lactozilla".
|
||||
// Copyright (C) 2014-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2021-2024 by Lactozilla.
|
||||
// Copyright (C) 2014-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -31,11 +31,27 @@ return luaL_error(L, "HUD rendering code should not call this function!");
|
|||
|
||||
static consvar_t *this_cvar;
|
||||
|
||||
static void clear_lua_stack(void)
|
||||
{
|
||||
if (gL) // check if Lua is actually turned on first, you dummmy -- Monster Iestyn 04/07/18
|
||||
lua_settop(gL, 0); // clear stack
|
||||
}
|
||||
|
||||
void Got_Luacmd(UINT8 **cp, INT32 playernum)
|
||||
{
|
||||
UINT8 i, argc, flags;
|
||||
const char *argv[256];
|
||||
char buf[256];
|
||||
|
||||
argc = READUINT8(*cp);
|
||||
argv[0] = (const char*)*cp;
|
||||
SKIPSTRINGN(*cp, 255);
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
argv[i] = (const char*)*cp;
|
||||
SKIPSTRINGN(*cp, 255);
|
||||
}
|
||||
|
||||
// don't use I_Assert here, goto the deny code below
|
||||
// to clean up and kick people who try nefarious exploits
|
||||
// like sending random junk lua commands to crash the server
|
||||
|
@ -48,8 +64,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
|
|||
lua_getfield(gL, LUA_REGISTRYINDEX, "COM_Command"); // push COM_Command
|
||||
if (!lua_istable(gL, -1)) goto deny;
|
||||
|
||||
argc = READUINT8(*cp);
|
||||
READSTRINGN(*cp, buf, 255);
|
||||
strlcpy(buf, argv[0], 255);
|
||||
strlwr(buf); // must lowercase buffer
|
||||
lua_getfield(gL, -1, buf); // push command info table
|
||||
if (!lua_istable(gL, -1)) goto deny;
|
||||
|
@ -75,10 +90,17 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
lua_remove(gL, -2); // pop command info table
|
||||
|
||||
if (!lua_checkstack(gL, argc)) // player + command arguments
|
||||
{
|
||||
clear_lua_stack();
|
||||
CONS_Alert(CONS_WARNING, "lua command stack overflow from %s (%d, need %d more)\n", player_names[playernum], lua_gettop(gL), argc);
|
||||
return;
|
||||
}
|
||||
|
||||
LUA_PushUserdata(gL, &players[playernum], META_PLAYER);
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
READSTRINGN(*cp, buf, 255);
|
||||
strlcpy(buf, argv[i], 255);
|
||||
lua_pushstring(gL, buf);
|
||||
}
|
||||
LUA_Call(gL, (int)argc, 0, 1); // argc is 1-based, so this will cover the player we passed too.
|
||||
|
@ -86,8 +108,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
deny:
|
||||
//must be hacked/buggy client
|
||||
if (gL) // check if Lua is actually turned on first, you dummmy -- Monster Iestyn 04/07/18
|
||||
lua_settop(gL, 0); // clear stack
|
||||
clear_lua_stack();
|
||||
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
|
@ -173,6 +194,11 @@ void COM_Lua_f(void)
|
|||
I_Assert(lua_isfunction(gL, -1));
|
||||
lua_remove(gL, -2); // pop command info table
|
||||
|
||||
if (!lua_checkstack(gL, COM_Argc() + 1))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "lua command stack overflow (%d, need %s more)\n", lua_gettop(gL), sizeu1(COM_Argc() + 1));
|
||||
return;
|
||||
}
|
||||
LUA_PushUserdata(gL, &players[playernum], META_PLAYER);
|
||||
for (i = 1; i < COM_Argc(); i++)
|
||||
lua_pushstring(gL, COM_Argv(i));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -498,7 +498,25 @@ static int call_string_hooks(Hook_State *hook)
|
|||
|
||||
static int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type)
|
||||
{
|
||||
return call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
|
||||
int numCalls = call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]);
|
||||
|
||||
if (numCalls > 0 && mobj_type == MT_NULL && (
|
||||
hook->hook_type == MOBJ_HOOK(MobjThinker )
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjCollide )
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjLineCollide)
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjMoveCollide)
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjFuse )
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjThinker )
|
||||
|| hook->hook_type == MOBJ_HOOK(BossThinker )
|
||||
|| hook->hook_type == MOBJ_HOOK(MobjMoveBlocked)
|
||||
|| hook->hook_type == MOBJ_HOOK(FollowMobj )
|
||||
))
|
||||
LUA_UsageWarning(L, va(
|
||||
"%s hooks not attached to a specific mobj type are deprecated and will be removed.",
|
||||
mobjHookNames[hook->hook_type])
|
||||
);
|
||||
|
||||
return numCalls;
|
||||
}
|
||||
|
||||
static void call_hud_hooks
|
||||
|
@ -751,7 +769,7 @@ static void hook_think_frame(int type)
|
|||
PS_SetThinkFrameHookInfo(hook_index, time_taken, ar.short_src);
|
||||
else if (type == 6)
|
||||
PS_SetPostThinkFrameHookInfo(hook_index, time_taken, ar.short_src);
|
||||
|
||||
|
||||
hook_index++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2014-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2014-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2014-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2014-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2014-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2014-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2014-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2014-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2014-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -42,8 +42,9 @@ extern boolean ignoregameinputs;
|
|||
#define META_SKIN "SKIN_T*"
|
||||
#define META_POWERS "PLAYER_T*POWERS"
|
||||
#define META_SOUNDSID "SKIN_T*SOUNDSID"
|
||||
#define META_SKINSPRITES "SKIN_T*SPRITES"
|
||||
#define META_SKINSPRITESLIST "SKIN_T*SPRITES[]"
|
||||
#define META_SKINSPRITES "SKIN_T*SKINSPRITES"
|
||||
#define META_SKINSPRITESLIST "SKIN_T*SKINSPRITES[]"
|
||||
#define META_SKINSPRITESCOMPAT "SKIN_T*SPRITES" // TODO: 2.3: Delete
|
||||
|
||||
#define META_VERTEX "VERTEX_T*"
|
||||
#define META_LINE "LINE_T*"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -213,6 +213,14 @@ enum side_e {
|
|||
side_sector,
|
||||
side_special,
|
||||
side_repeatcnt,
|
||||
side_light,
|
||||
side_light_top,
|
||||
side_light_mid,
|
||||
side_light_bottom,
|
||||
side_lightabsolute,
|
||||
side_lightabsolute_top,
|
||||
side_lightabsolute_mid,
|
||||
side_lightabsolute_bottom,
|
||||
side_text
|
||||
};
|
||||
|
||||
|
@ -241,6 +249,14 @@ static const char *const side_opt[] = {
|
|||
"sector",
|
||||
"special",
|
||||
"repeatcnt",
|
||||
"light",
|
||||
"light_top",
|
||||
"light_mid",
|
||||
"light_bottom",
|
||||
"lightabsolute",
|
||||
"lightabsolute_top",
|
||||
"lightabsolute_mid",
|
||||
"lightabsolute_bottom",
|
||||
"text",
|
||||
NULL};
|
||||
|
||||
|
@ -1311,6 +1327,30 @@ static int side_get(lua_State *L)
|
|||
case side_repeatcnt:
|
||||
lua_pushinteger(L, side->repeatcnt);
|
||||
return 1;
|
||||
case side_light:
|
||||
lua_pushinteger(L, side->light);
|
||||
return 1;
|
||||
case side_light_top:
|
||||
lua_pushinteger(L, side->light_top);
|
||||
return 1;
|
||||
case side_light_mid:
|
||||
lua_pushinteger(L, side->light_mid);
|
||||
return 1;
|
||||
case side_light_bottom:
|
||||
lua_pushinteger(L, side->light_bottom);
|
||||
return 1;
|
||||
case side_lightabsolute:
|
||||
lua_pushboolean(L, side->lightabsolute);
|
||||
return 1;
|
||||
case side_lightabsolute_top:
|
||||
lua_pushboolean(L, side->lightabsolute_top);
|
||||
return 1;
|
||||
case side_lightabsolute_mid:
|
||||
lua_pushboolean(L, side->lightabsolute_mid);
|
||||
return 1;
|
||||
case side_lightabsolute_bottom:
|
||||
lua_pushboolean(L, side->lightabsolute_bottom);
|
||||
return 1;
|
||||
// TODO: 2.3: Delete
|
||||
case side_text:
|
||||
{
|
||||
|
@ -1413,6 +1453,30 @@ static int side_set(lua_State *L)
|
|||
case side_repeatcnt:
|
||||
side->repeatcnt = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case side_light:
|
||||
side->light = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case side_light_top:
|
||||
side->light_top = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case side_light_mid:
|
||||
side->light_mid = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case side_light_bottom:
|
||||
side->light_bottom = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case side_lightabsolute:
|
||||
side->lightabsolute = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case side_lightabsolute_top:
|
||||
side->lightabsolute_top = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case side_lightabsolute_mid:
|
||||
side->lightabsolute_mid = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case side_lightabsolute_bottom:
|
||||
side->lightabsolute_bottom = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -69,6 +69,7 @@ enum mobj_e {
|
|||
mobj_color,
|
||||
mobj_translation,
|
||||
mobj_blendmode,
|
||||
mobj_alpha,
|
||||
mobj_bnext,
|
||||
mobj_bprev,
|
||||
mobj_hnext,
|
||||
|
@ -150,6 +151,7 @@ static const char *const mobj_opt[] = {
|
|||
"color",
|
||||
"translation",
|
||||
"blendmode",
|
||||
"alpha",
|
||||
"bnext",
|
||||
"bprev",
|
||||
"hnext",
|
||||
|
@ -354,6 +356,9 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_blendmode:
|
||||
lua_pushinteger(L, mo->blendmode);
|
||||
break;
|
||||
case mobj_alpha:
|
||||
lua_pushfixed(L, mo->alpha);
|
||||
break;
|
||||
case mobj_bnext:
|
||||
if (mo->blocknode && mo->blocknode->bnext) {
|
||||
LUA_PushUserdata(L, mo->blocknode->bnext->mobj, META_MOBJ);
|
||||
|
@ -733,6 +738,16 @@ static int mobj_set(lua_State *L)
|
|||
mo->blendmode = blendmode;
|
||||
break;
|
||||
}
|
||||
case mobj_alpha:
|
||||
{
|
||||
fixed_t alpha = luaL_checkfixed(L, 3);
|
||||
if (alpha < 0)
|
||||
alpha = 0;
|
||||
else if (alpha > FRACUNIT)
|
||||
alpha = FRACUNIT;
|
||||
mo->alpha = alpha;
|
||||
break;
|
||||
}
|
||||
case mobj_bnext:
|
||||
return NOSETPOS;
|
||||
case mobj_bprev:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
283
src/lua_script.c
283
src/lua_script.c
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -1098,7 +1098,7 @@ static UINT8 GetUserdataArchType(int index)
|
|||
return ARCH_NULL;
|
||||
}
|
||||
|
||||
static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
||||
static UINT8 ArchiveValue(save_t *save_p, int TABLESINDEX, int myindex)
|
||||
{
|
||||
if (myindex < 0)
|
||||
myindex = lua_gettop(gL)+1+myindex;
|
||||
|
@ -1106,34 +1106,34 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
case LUA_TNONE:
|
||||
case LUA_TNIL:
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
break;
|
||||
// This might be a problem. D:
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
case LUA_TTHREAD:
|
||||
case LUA_TFUNCTION:
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
return 2;
|
||||
case LUA_TBOOLEAN:
|
||||
WRITEUINT8(save_p, lua_toboolean(gL, myindex) ? ARCH_TRUE : ARCH_FALSE);
|
||||
P_WriteUINT8(save_p, lua_toboolean(gL, myindex) ? ARCH_TRUE : ARCH_FALSE);
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
{
|
||||
lua_Integer number = lua_tointeger(gL, myindex);
|
||||
if (number >= INT8_MIN && number <= INT8_MAX)
|
||||
{
|
||||
WRITEUINT8(save_p, ARCH_INT8);
|
||||
WRITESINT8(save_p, number);
|
||||
P_WriteUINT8(save_p, ARCH_INT8);
|
||||
P_WriteSINT8(save_p, number);
|
||||
}
|
||||
else if (number >= INT16_MIN && number <= INT16_MAX)
|
||||
{
|
||||
WRITEUINT8(save_p, ARCH_INT16);
|
||||
WRITEINT16(save_p, number);
|
||||
P_WriteUINT8(save_p, ARCH_INT16);
|
||||
P_WriteINT16(save_p, number);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT8(save_p, ARCH_INT32);
|
||||
WRITEFIXED(save_p, number);
|
||||
P_WriteUINT8(save_p, ARCH_INT32);
|
||||
P_WriteFixed(save_p, number);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1144,23 +1144,23 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
UINT32 i = 0;
|
||||
// if you're wondering why we're writing a string to save_p this way,
|
||||
// it turns out that Lua can have embedded zeros ('\0') in the strings,
|
||||
// so we can't use WRITESTRING as that cuts off when it finds a '\0'.
|
||||
// so we can't use P_WriteString as that cuts off when it finds a '\0'.
|
||||
// Saving the size of the string also allows us to get the size of the string on the other end,
|
||||
// fixing the awful crashes previously encountered for reading strings longer than 1024
|
||||
// (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?)
|
||||
// -- Monster Iestyn 05/08/18
|
||||
if (len < 255)
|
||||
{
|
||||
WRITEUINT8(save_p, ARCH_SMALLSTRING);
|
||||
WRITEUINT8(save_p, len); // save size of string
|
||||
P_WriteUINT8(save_p, ARCH_SMALLSTRING);
|
||||
P_WriteUINT8(save_p, len); // save size of string
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITEUINT8(save_p, ARCH_LARGESTRING);
|
||||
WRITEUINT32(save_p, len); // save size of string
|
||||
P_WriteUINT8(save_p, ARCH_LARGESTRING);
|
||||
P_WriteUINT32(save_p, len); // save size of string
|
||||
}
|
||||
while (i < len)
|
||||
WRITECHAR(save_p, s[i++]); // write chars individually, including the embedded zeros
|
||||
P_WriteChar(save_p, s[i++]); // write chars individually, including the embedded zeros
|
||||
break;
|
||||
}
|
||||
case LUA_TTABLE:
|
||||
|
@ -1186,13 +1186,13 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
if (t == 0)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Too many tables to archive!\n");
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
WRITEUINT8(save_p, ARCH_TABLE);
|
||||
WRITEUINT16(save_p, t);
|
||||
P_WriteUINT8(save_p, ARCH_TABLE);
|
||||
P_WriteUINT16(save_p, t);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
|
@ -1208,25 +1208,25 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
case ARCH_MOBJINFO:
|
||||
{
|
||||
mobjinfo_t *info = *((mobjinfo_t **)lua_touserdata(gL, myindex));
|
||||
WRITEUINT8(save_p, ARCH_MOBJINFO);
|
||||
WRITEUINT16(save_p, info - mobjinfo);
|
||||
P_WriteUINT8(save_p, ARCH_MOBJINFO);
|
||||
P_WriteUINT16(save_p, info - mobjinfo);
|
||||
break;
|
||||
}
|
||||
case ARCH_STATE:
|
||||
{
|
||||
state_t *state = *((state_t **)lua_touserdata(gL, myindex));
|
||||
WRITEUINT8(save_p, ARCH_STATE);
|
||||
WRITEUINT16(save_p, state - states);
|
||||
P_WriteUINT8(save_p, ARCH_STATE);
|
||||
P_WriteUINT16(save_p, state - states);
|
||||
break;
|
||||
}
|
||||
case ARCH_MOBJ:
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)lua_touserdata(gL, myindex));
|
||||
if (!mobj)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_MOBJ);
|
||||
WRITEUINT32(save_p, mobj->mobjnum);
|
||||
P_WriteUINT8(save_p, ARCH_MOBJ);
|
||||
P_WriteUINT32(save_p, mobj->mobjnum);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1234,10 +1234,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
player_t *player = *((player_t **)lua_touserdata(gL, myindex));
|
||||
if (!player)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_PLAYER);
|
||||
WRITEUINT8(save_p, player - players);
|
||||
P_WriteUINT8(save_p, ARCH_PLAYER);
|
||||
P_WriteUINT8(save_p, player - players);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1245,10 +1245,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
mapthing_t *mapthing = *((mapthing_t **)lua_touserdata(gL, myindex));
|
||||
if (!mapthing)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_MAPTHING);
|
||||
WRITEUINT16(save_p, mapthing - mapthings);
|
||||
P_WriteUINT8(save_p, ARCH_MAPTHING);
|
||||
P_WriteUINT16(save_p, mapthing - mapthings);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1256,10 +1256,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
vertex_t *vertex = *((vertex_t **)lua_touserdata(gL, myindex));
|
||||
if (!vertex)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_VERTEX);
|
||||
WRITEUINT16(save_p, vertex - vertexes);
|
||||
P_WriteUINT8(save_p, ARCH_VERTEX);
|
||||
P_WriteUINT16(save_p, vertex - vertexes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1267,10 +1267,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
line_t *line = *((line_t **)lua_touserdata(gL, myindex));
|
||||
if (!line)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_LINE);
|
||||
WRITEUINT16(save_p, line - lines);
|
||||
P_WriteUINT8(save_p, ARCH_LINE);
|
||||
P_WriteUINT16(save_p, line - lines);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1278,10 +1278,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
side_t *side = *((side_t **)lua_touserdata(gL, myindex));
|
||||
if (!side)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_SIDE);
|
||||
WRITEUINT16(save_p, side - sides);
|
||||
P_WriteUINT8(save_p, ARCH_SIDE);
|
||||
P_WriteUINT16(save_p, side - sides);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1289,10 +1289,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
subsector_t *subsector = *((subsector_t **)lua_touserdata(gL, myindex));
|
||||
if (!subsector)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_SUBSECTOR);
|
||||
WRITEUINT16(save_p, subsector - subsectors);
|
||||
P_WriteUINT8(save_p, ARCH_SUBSECTOR);
|
||||
P_WriteUINT16(save_p, subsector - subsectors);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1300,10 +1300,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
sector_t *sector = *((sector_t **)lua_touserdata(gL, myindex));
|
||||
if (!sector)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_SECTOR);
|
||||
WRITEUINT16(save_p, sector - sectors);
|
||||
P_WriteUINT8(save_p, ARCH_SECTOR);
|
||||
P_WriteUINT16(save_p, sector - sectors);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1312,10 +1312,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
seg_t *seg = *((seg_t **)lua_touserdata(gL, myindex));
|
||||
if (!seg)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_SEG);
|
||||
WRITEUINT16(save_p, seg - segs);
|
||||
P_WriteUINT8(save_p, ARCH_SEG);
|
||||
P_WriteUINT16(save_p, seg - segs);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1323,10 +1323,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
node_t *node = *((node_t **)lua_touserdata(gL, myindex));
|
||||
if (!node)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_NODE);
|
||||
WRITEUINT16(save_p, node - nodes);
|
||||
P_WriteUINT8(save_p, ARCH_NODE);
|
||||
P_WriteUINT16(save_p, node - nodes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1335,16 +1335,16 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
ffloor_t *rover = *((ffloor_t **)lua_touserdata(gL, myindex));
|
||||
if (!rover)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
UINT16 i = P_GetFFloorID(rover);
|
||||
if (i == UINT16_MAX) // invalid ID
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else
|
||||
{
|
||||
WRITEUINT8(save_p, ARCH_FFLOOR);
|
||||
WRITEUINT16(save_p, rover->target - sectors);
|
||||
WRITEUINT16(save_p, i);
|
||||
P_WriteUINT8(save_p, ARCH_FFLOOR);
|
||||
P_WriteUINT16(save_p, rover->target - sectors);
|
||||
P_WriteUINT16(save_p, i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1353,10 +1353,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
polyobj_t *polyobj = *((polyobj_t **)lua_touserdata(gL, myindex));
|
||||
if (!polyobj)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_POLYOBJ);
|
||||
WRITEUINT16(save_p, polyobj-PolyObjects);
|
||||
P_WriteUINT8(save_p, ARCH_POLYOBJ);
|
||||
P_WriteUINT16(save_p, polyobj-PolyObjects);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1364,10 +1364,10 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex));
|
||||
if (!slope)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_SLOPE);
|
||||
WRITEUINT16(save_p, slope->id);
|
||||
P_WriteUINT8(save_p, ARCH_SLOPE);
|
||||
P_WriteUINT16(save_p, slope->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1375,36 +1375,36 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
{
|
||||
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
|
||||
if (!header)
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
else {
|
||||
WRITEUINT8(save_p, ARCH_MAPHEADER);
|
||||
WRITEUINT16(save_p, header - *mapheaderinfo);
|
||||
P_WriteUINT8(save_p, ARCH_MAPHEADER);
|
||||
P_WriteUINT16(save_p, header - *mapheaderinfo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARCH_SKINCOLOR:
|
||||
{
|
||||
skincolor_t *info = *((skincolor_t **)lua_touserdata(gL, myindex));
|
||||
WRITEUINT8(save_p, ARCH_SKINCOLOR);
|
||||
WRITEUINT16(save_p, info - skincolors);
|
||||
P_WriteUINT8(save_p, ARCH_SKINCOLOR);
|
||||
P_WriteUINT16(save_p, info - skincolors);
|
||||
break;
|
||||
}
|
||||
case ARCH_MOUSE:
|
||||
{
|
||||
mouse_t *m = *((mouse_t **)lua_touserdata(gL, myindex));
|
||||
WRITEUINT8(save_p, ARCH_MOUSE);
|
||||
WRITEUINT8(save_p, m == &mouse ? 1 : 2);
|
||||
P_WriteUINT8(save_p, ARCH_MOUSE);
|
||||
P_WriteUINT8(save_p, m == &mouse ? 1 : 2);
|
||||
break;
|
||||
}
|
||||
case ARCH_SKIN:
|
||||
{
|
||||
skin_t *skin = *((skin_t **)lua_touserdata(gL, myindex));
|
||||
WRITEUINT8(save_p, ARCH_SKIN);
|
||||
WRITEUINT8(save_p, skin->skinnum); // UINT8 because MAXSKINS must be <= 256
|
||||
P_WriteUINT8(save_p, ARCH_SKIN);
|
||||
P_WriteUINT8(save_p, skin->skinnum); // UINT8 because MAXSKINS must be <= 256
|
||||
break;
|
||||
}
|
||||
default:
|
||||
WRITEUINT8(save_p, ARCH_NULL);
|
||||
P_WriteUINT8(save_p, ARCH_NULL);
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
|
@ -1412,14 +1412,14 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ArchiveExtVars(void *pointer, const char *ptype)
|
||||
static void ArchiveExtVars(save_t *save_p, void *pointer, const char *ptype)
|
||||
{
|
||||
int TABLESINDEX;
|
||||
UINT16 i;
|
||||
|
||||
if (!gL) {
|
||||
if (fastcmp(ptype,"player")) // players must always be included, even if no vars
|
||||
WRITEUINT16(save_p, 0);
|
||||
P_WriteUINT16(save_p, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1435,7 +1435,7 @@ static void ArchiveExtVars(void *pointer, const char *ptype)
|
|||
{ // no extra values table
|
||||
lua_pop(gL, 1);
|
||||
if (fastcmp(ptype,"player")) // players must always be included, even if no vars
|
||||
WRITEUINT16(save_p, 0);
|
||||
P_WriteUINT16(save_p, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1447,20 +1447,20 @@ static void ArchiveExtVars(void *pointer, const char *ptype)
|
|||
if (i == 0)
|
||||
{
|
||||
if (fastcmp(ptype,"player")) // always include players even if they have no extra variables
|
||||
WRITEUINT16(save_p, 0);
|
||||
P_WriteUINT16(save_p, 0);
|
||||
lua_pop(gL, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fastcmp(ptype,"mobj")) // mobjs must write their mobjnum as a header
|
||||
WRITEUINT32(save_p, ((mobj_t *)pointer)->mobjnum);
|
||||
WRITEUINT16(save_p, i);
|
||||
P_WriteUINT32(save_p, ((mobj_t *)pointer)->mobjnum);
|
||||
P_WriteUINT16(save_p, i);
|
||||
lua_pushnil(gL);
|
||||
while (lua_next(gL, -2))
|
||||
{
|
||||
I_Assert(lua_type(gL, -2) == LUA_TSTRING);
|
||||
WRITESTRING(save_p, lua_tostring(gL, -2));
|
||||
if (ArchiveValue(TABLESINDEX, -1) == 2)
|
||||
P_WriteString(save_p, lua_tostring(gL, -2));
|
||||
if (ArchiveValue(save_p, TABLESINDEX, -1) == 2)
|
||||
CONS_Alert(CONS_ERROR, "Type of value for %s entry '%s' (%s) could not be archived!\n", ptype, lua_tostring(gL, -2), luaL_typename(gL, -1));
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
|
@ -1468,16 +1468,19 @@ static void ArchiveExtVars(void *pointer, const char *ptype)
|
|||
lua_pop(gL, 1);
|
||||
}
|
||||
|
||||
// FIXME: remove and pass as local variable
|
||||
static save_t *lua_save_p;
|
||||
|
||||
static int NetArchive(lua_State *L)
|
||||
{
|
||||
int TABLESINDEX = lua_upvalueindex(1);
|
||||
int i, n = lua_gettop(L);
|
||||
for (i = 1; i <= n; i++)
|
||||
ArchiveValue(TABLESINDEX, i);
|
||||
ArchiveValue(lua_save_p, TABLESINDEX, i);
|
||||
return n;
|
||||
}
|
||||
|
||||
static void ArchiveTables(void)
|
||||
static void ArchiveTables(save_t *save_p)
|
||||
{
|
||||
int TABLESINDEX;
|
||||
UINT16 i, n;
|
||||
|
@ -1496,14 +1499,14 @@ static void ArchiveTables(void)
|
|||
while (lua_next(gL, -2))
|
||||
{
|
||||
// Write key
|
||||
e = ArchiveValue(TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this.
|
||||
e = ArchiveValue(save_p, TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this.
|
||||
if (e == 1)
|
||||
n++; // the table contained a new table we'll have to archive. :(
|
||||
else if (e == 2) // invalid key type (function, thread, lightuserdata, or anything we don't recognise)
|
||||
CONS_Alert(CONS_ERROR, "Index '%s' (%s) of table %d could not be archived!\n", lua_tostring(gL, -2), luaL_typename(gL, -2), i);
|
||||
|
||||
// Write value
|
||||
e = ArchiveValue(TABLESINDEX, -1);
|
||||
e = ArchiveValue(save_p, TABLESINDEX, -1);
|
||||
if (e == 1)
|
||||
n++; // the table contained a new table we'll have to archive. :(
|
||||
else if (e == 2) // invalid value type
|
||||
|
@ -1511,7 +1514,7 @@ static void ArchiveTables(void)
|
|||
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
WRITEUINT8(save_p, ARCH_TEND);
|
||||
P_WriteUINT8(save_p, ARCH_TEND);
|
||||
|
||||
// Write metatable ID
|
||||
if (lua_getmetatable(gL, -1))
|
||||
|
@ -1520,19 +1523,19 @@ static void ArchiveTables(void)
|
|||
lua_getfield(gL, LUA_REGISTRYINDEX, LREG_METATABLES);
|
||||
lua_pushvalue(gL, -2);
|
||||
lua_gettable(gL, -2);
|
||||
WRITEUINT16(save_p, lua_isnil(gL, -1) ? 0 : lua_tointeger(gL, -1));
|
||||
P_WriteUINT16(save_p, lua_isnil(gL, -1) ? 0 : lua_tointeger(gL, -1));
|
||||
lua_pop(gL, 3);
|
||||
}
|
||||
else
|
||||
WRITEUINT16(save_p, 0);
|
||||
P_WriteUINT16(save_p, 0);
|
||||
|
||||
lua_pop(gL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 UnArchiveValue(int TABLESINDEX)
|
||||
static UINT8 UnArchiveValue(save_t *save_p, int TABLESINDEX)
|
||||
{
|
||||
UINT8 type = READUINT8(save_p);
|
||||
UINT8 type = P_ReadUINT8(save_p);
|
||||
switch (type)
|
||||
{
|
||||
case ARCH_NULL:
|
||||
|
@ -1545,13 +1548,13 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
lua_pushboolean(gL, false);
|
||||
break;
|
||||
case ARCH_INT8:
|
||||
lua_pushinteger(gL, READSINT8(save_p));
|
||||
lua_pushinteger(gL, P_ReadSINT8(save_p));
|
||||
break;
|
||||
case ARCH_INT16:
|
||||
lua_pushinteger(gL, READINT16(save_p));
|
||||
lua_pushinteger(gL, P_ReadINT16(save_p));
|
||||
break;
|
||||
case ARCH_INT32:
|
||||
lua_pushinteger(gL, READFIXED(save_p));
|
||||
lua_pushinteger(gL, P_ReadFixed(save_p));
|
||||
break;
|
||||
case ARCH_SMALLSTRING:
|
||||
case ARCH_LARGESTRING:
|
||||
|
@ -1562,23 +1565,23 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
|
||||
// See my comments in the ArchiveValue function;
|
||||
// it's much the same for reading strings as writing them!
|
||||
// (i.e. we can't use READSTRING either)
|
||||
// (i.e. we can't use P_ReadString either)
|
||||
// -- Monster Iestyn 05/08/18
|
||||
if (type == ARCH_SMALLSTRING)
|
||||
len = READUINT8(save_p); // length of string, including embedded zeros
|
||||
len = P_ReadUINT8(save_p); // length of string, including embedded zeros
|
||||
else
|
||||
len = READUINT32(save_p); // length of string, including embedded zeros
|
||||
len = P_ReadUINT32(save_p); // length of string, including embedded zeros
|
||||
value = malloc(len); // make temp buffer of size len
|
||||
// now read the actual string
|
||||
while (i < len)
|
||||
value[i++] = READCHAR(save_p); // read chars individually, including the embedded zeros
|
||||
value[i++] = P_ReadChar(save_p); // read chars individually, including the embedded zeros
|
||||
lua_pushlstring(gL, value, len); // push the string (note: this function supports embedded zeros)
|
||||
free(value); // free the buffer
|
||||
break;
|
||||
}
|
||||
case ARCH_TABLE:
|
||||
{
|
||||
UINT16 tid = READUINT16(save_p);
|
||||
UINT16 tid = P_ReadUINT16(save_p);
|
||||
lua_rawgeti(gL, TABLESINDEX, tid);
|
||||
if (lua_isnil(gL, -1))
|
||||
{
|
||||
|
@ -1591,69 +1594,69 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
break;
|
||||
}
|
||||
case ARCH_MOBJINFO:
|
||||
LUA_PushUserdata(gL, &mobjinfo[READUINT16(save_p)], META_MOBJINFO);
|
||||
LUA_PushUserdata(gL, &mobjinfo[P_ReadUINT16(save_p)], META_MOBJINFO);
|
||||
break;
|
||||
case ARCH_STATE:
|
||||
LUA_PushUserdata(gL, &states[READUINT16(save_p)], META_STATE);
|
||||
LUA_PushUserdata(gL, &states[P_ReadUINT16(save_p)], META_STATE);
|
||||
break;
|
||||
case ARCH_MOBJ:
|
||||
LUA_PushUserdata(gL, P_FindNewPosition(READUINT32(save_p)), META_MOBJ);
|
||||
LUA_PushUserdata(gL, P_FindNewPosition(P_ReadUINT32(save_p)), META_MOBJ);
|
||||
break;
|
||||
case ARCH_PLAYER:
|
||||
LUA_PushUserdata(gL, &players[READUINT8(save_p)], META_PLAYER);
|
||||
LUA_PushUserdata(gL, &players[P_ReadUINT8(save_p)], META_PLAYER);
|
||||
break;
|
||||
case ARCH_MAPTHING:
|
||||
LUA_PushUserdata(gL, &mapthings[READUINT16(save_p)], META_MAPTHING);
|
||||
LUA_PushUserdata(gL, &mapthings[P_ReadUINT16(save_p)], META_MAPTHING);
|
||||
break;
|
||||
case ARCH_VERTEX:
|
||||
LUA_PushUserdata(gL, &vertexes[READUINT16(save_p)], META_VERTEX);
|
||||
LUA_PushUserdata(gL, &vertexes[P_ReadUINT16(save_p)], META_VERTEX);
|
||||
break;
|
||||
case ARCH_LINE:
|
||||
LUA_PushUserdata(gL, &lines[READUINT16(save_p)], META_LINE);
|
||||
LUA_PushUserdata(gL, &lines[P_ReadUINT16(save_p)], META_LINE);
|
||||
break;
|
||||
case ARCH_SIDE:
|
||||
LUA_PushUserdata(gL, &sides[READUINT16(save_p)], META_SIDE);
|
||||
LUA_PushUserdata(gL, &sides[P_ReadUINT16(save_p)], META_SIDE);
|
||||
break;
|
||||
case ARCH_SUBSECTOR:
|
||||
LUA_PushUserdata(gL, &subsectors[READUINT16(save_p)], META_SUBSECTOR);
|
||||
LUA_PushUserdata(gL, &subsectors[P_ReadUINT16(save_p)], META_SUBSECTOR);
|
||||
break;
|
||||
case ARCH_SECTOR:
|
||||
LUA_PushUserdata(gL, §ors[READUINT16(save_p)], META_SECTOR);
|
||||
LUA_PushUserdata(gL, §ors[P_ReadUINT16(save_p)], META_SECTOR);
|
||||
break;
|
||||
#ifdef HAVE_LUA_SEGS
|
||||
case ARCH_SEG:
|
||||
LUA_PushUserdata(gL, &segs[READUINT16(save_p)], META_SEG);
|
||||
LUA_PushUserdata(gL, &segs[P_ReadUINT16(save_p)], META_SEG);
|
||||
break;
|
||||
case ARCH_NODE:
|
||||
LUA_PushUserdata(gL, &nodes[READUINT16(save_p)], META_NODE);
|
||||
LUA_PushUserdata(gL, &nodes[P_ReadUINT16(save_p)], META_NODE);
|
||||
break;
|
||||
#endif
|
||||
case ARCH_FFLOOR:
|
||||
{
|
||||
sector_t *sector = §ors[READUINT16(save_p)];
|
||||
UINT16 id = READUINT16(save_p);
|
||||
sector_t *sector = §ors[P_ReadUINT16(save_p)];
|
||||
UINT16 id = P_ReadUINT16(save_p);
|
||||
ffloor_t *rover = P_GetFFloorByID(sector, id);
|
||||
if (rover)
|
||||
LUA_PushUserdata(gL, rover, META_FFLOOR);
|
||||
break;
|
||||
}
|
||||
case ARCH_POLYOBJ:
|
||||
LUA_PushUserdata(gL, &PolyObjects[READUINT16(save_p)], META_POLYOBJ);
|
||||
LUA_PushUserdata(gL, &PolyObjects[P_ReadUINT16(save_p)], META_POLYOBJ);
|
||||
break;
|
||||
case ARCH_SLOPE:
|
||||
LUA_PushUserdata(gL, P_SlopeById(READUINT16(save_p)), META_SLOPE);
|
||||
LUA_PushUserdata(gL, P_SlopeById(P_ReadUINT16(save_p)), META_SLOPE);
|
||||
break;
|
||||
case ARCH_MAPHEADER:
|
||||
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(save_p)], META_MAPHEADER);
|
||||
LUA_PushUserdata(gL, mapheaderinfo[P_ReadUINT16(save_p)], META_MAPHEADER);
|
||||
break;
|
||||
case ARCH_SKINCOLOR:
|
||||
LUA_PushUserdata(gL, &skincolors[READUINT16(save_p)], META_SKINCOLOR);
|
||||
LUA_PushUserdata(gL, &skincolors[P_ReadUINT16(save_p)], META_SKINCOLOR);
|
||||
break;
|
||||
case ARCH_MOUSE:
|
||||
LUA_PushUserdata(gL, READUINT16(save_p) == 1 ? &mouse : &mouse2, META_MOUSE);
|
||||
LUA_PushUserdata(gL, P_ReadUINT16(save_p) == 1 ? &mouse : &mouse2, META_MOUSE);
|
||||
break;
|
||||
case ARCH_SKIN:
|
||||
LUA_PushUserdata(gL, skins[READUINT8(save_p)], META_SKIN);
|
||||
LUA_PushUserdata(gL, skins[P_ReadUINT8(save_p)], META_SKIN);
|
||||
break;
|
||||
case ARCH_TEND:
|
||||
return 1;
|
||||
|
@ -1661,10 +1664,10 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void UnArchiveExtVars(void *pointer)
|
||||
static void UnArchiveExtVars(save_t *save_p, void *pointer)
|
||||
{
|
||||
int TABLESINDEX;
|
||||
UINT16 field_count = READUINT16(save_p);
|
||||
UINT16 field_count = P_ReadUINT16(save_p);
|
||||
UINT16 i;
|
||||
char field[1024];
|
||||
|
||||
|
@ -1677,8 +1680,8 @@ static void UnArchiveExtVars(void *pointer)
|
|||
|
||||
for (i = 0; i < field_count; i++)
|
||||
{
|
||||
READSTRING(save_p, field);
|
||||
UnArchiveValue(TABLESINDEX);
|
||||
P_ReadString(save_p, field);
|
||||
UnArchiveValue(save_p, TABLESINDEX);
|
||||
lua_setfield(gL, -2, field);
|
||||
}
|
||||
|
||||
|
@ -1695,11 +1698,11 @@ static int NetUnArchive(lua_State *L)
|
|||
int TABLESINDEX = lua_upvalueindex(1);
|
||||
int i, n = lua_gettop(L);
|
||||
for (i = 1; i <= n; i++)
|
||||
UnArchiveValue(TABLESINDEX);
|
||||
UnArchiveValue(lua_save_p, TABLESINDEX);
|
||||
return n;
|
||||
}
|
||||
|
||||
static void UnArchiveTables(void)
|
||||
static void UnArchiveTables(save_t *save_p)
|
||||
{
|
||||
int TABLESINDEX;
|
||||
UINT16 i, n;
|
||||
|
@ -1716,13 +1719,13 @@ static void UnArchiveTables(void)
|
|||
lua_rawgeti(gL, TABLESINDEX, i);
|
||||
while (true)
|
||||
{
|
||||
UINT8 e = UnArchiveValue(TABLESINDEX); // read key
|
||||
UINT8 e = UnArchiveValue(save_p, TABLESINDEX); // read key
|
||||
if (e == 1) // End of table
|
||||
break;
|
||||
else if (e == 2) // Key contains a new table
|
||||
n++;
|
||||
|
||||
if (UnArchiveValue(TABLESINDEX) == 2) // read value
|
||||
if (UnArchiveValue(save_p, TABLESINDEX) == 2) // read value
|
||||
n++;
|
||||
|
||||
if (lua_isnil(gL, -2)) // if key is nil (if a function etc was accidentally saved)
|
||||
|
@ -1734,7 +1737,7 @@ static void UnArchiveTables(void)
|
|||
lua_rawset(gL, -3);
|
||||
}
|
||||
|
||||
metatableid = READUINT16(save_p);
|
||||
metatableid = P_ReadUINT16(save_p);
|
||||
if (metatableid)
|
||||
{
|
||||
// setmetatable(table, registry.metatables[metatableid])
|
||||
|
@ -1758,7 +1761,7 @@ void LUA_Step(void)
|
|||
lua_gc(gL, LUA_GCSTEP, 1);
|
||||
}
|
||||
|
||||
void LUA_Archive(void)
|
||||
void LUA_Archive(save_t *save_p)
|
||||
{
|
||||
INT32 i;
|
||||
thinker_t *th;
|
||||
|
@ -1771,7 +1774,7 @@ void LUA_Archive(void)
|
|||
if (!playeringame[i] && i > 0) // dedicated servers...
|
||||
continue;
|
||||
// all players in game will be archived, even if they just add a 0.
|
||||
ArchiveExtVars(&players[i], "player");
|
||||
ArchiveExtVars(save_p, &players[i], "player");
|
||||
}
|
||||
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
|
@ -1781,19 +1784,20 @@ void LUA_Archive(void)
|
|||
|
||||
// archive function will determine when to skip mobjs,
|
||||
// and write mobjnum in otherwise.
|
||||
ArchiveExtVars(th, "mobj");
|
||||
ArchiveExtVars(save_p, th, "mobj");
|
||||
}
|
||||
|
||||
WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.
|
||||
P_WriteUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.
|
||||
|
||||
lua_save_p = save_p;
|
||||
LUA_HookNetArchive(NetArchive); // call the NetArchive hook in archive mode
|
||||
ArchiveTables();
|
||||
ArchiveTables(save_p);
|
||||
|
||||
if (gL)
|
||||
lua_pop(gL, 1); // pop tables
|
||||
}
|
||||
|
||||
void LUA_UnArchive(void)
|
||||
void LUA_UnArchive(save_t *save_p)
|
||||
{
|
||||
UINT32 mobjnum;
|
||||
INT32 i;
|
||||
|
@ -1806,23 +1810,24 @@ void LUA_UnArchive(void)
|
|||
{
|
||||
if (!playeringame[i] && i > 0) // dedicated servers...
|
||||
continue;
|
||||
UnArchiveExtVars(&players[i]);
|
||||
UnArchiveExtVars(save_p, &players[i]);
|
||||
}
|
||||
|
||||
do {
|
||||
mobjnum = READUINT32(save_p); // read a mobjnum
|
||||
mobjnum = P_ReadUINT32(save_p); // read a mobjnum
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
continue;
|
||||
if (((mobj_t *)th)->mobjnum != mobjnum) // find matching mobj
|
||||
continue;
|
||||
UnArchiveExtVars(th); // apply variables
|
||||
UnArchiveExtVars(save_p, th); // apply variables
|
||||
}
|
||||
} while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker.
|
||||
|
||||
lua_save_p = save_p;
|
||||
LUA_HookNetArchive(NetUnArchive); // call the NetArchive hook in unarchive mode
|
||||
UnArchiveTables();
|
||||
UnArchiveTables(save_p);
|
||||
|
||||
if (gL)
|
||||
lua_pop(gL, 1); // pop tables
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -13,6 +13,7 @@
|
|||
#ifndef LUA_SCRIPT_H
|
||||
#define LUA_SCRIPT_H
|
||||
|
||||
#include "p_saveg.h"
|
||||
#include "m_fixed.h"
|
||||
#include "doomtype.h"
|
||||
#include "d_player.h"
|
||||
|
@ -52,8 +53,8 @@ void LUA_DumpFile(const char *filename);
|
|||
#endif
|
||||
fixed_t LUA_EvalMath(const char *word);
|
||||
void LUA_Step(void);
|
||||
void LUA_Archive(void);
|
||||
void LUA_UnArchive(void);
|
||||
void LUA_Archive(save_t *save_p);
|
||||
void LUA_UnArchive(save_t *save_p);
|
||||
int LUA_PushGlobals(lua_State *L, const char *word);
|
||||
int LUA_CheckGlobals(lua_State *L, const char *word);
|
||||
void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2014-2016 by John "JTE" Muniz.
|
||||
// Copyright (C) 2014-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2014-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -54,7 +54,8 @@ enum skin {
|
|||
skin_contspeed,
|
||||
skin_contangle,
|
||||
skin_soundsid,
|
||||
skin_sprites,
|
||||
skin_sprites, // TODO: 2.3: Delete
|
||||
skin_skinsprites,
|
||||
skin_supersprites,
|
||||
skin_natkcolor
|
||||
};
|
||||
|
@ -95,7 +96,8 @@ static const char *const skin_opt[] = {
|
|||
"contspeed",
|
||||
"contangle",
|
||||
"soundsid",
|
||||
"sprites",
|
||||
"sprites", // TODO: 2.3: Delete
|
||||
"skinsprites",
|
||||
"supersprites",
|
||||
"natkcolor",
|
||||
NULL};
|
||||
|
@ -219,7 +221,10 @@ static int skin_get(lua_State *L)
|
|||
case skin_soundsid:
|
||||
LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID);
|
||||
break;
|
||||
case skin_sprites:
|
||||
case skin_sprites: // TODO: 2.3: Delete
|
||||
LUA_PushUserdata(L, skin->sprites_compat, META_SKINSPRITESCOMPAT);
|
||||
break;
|
||||
case skin_skinsprites:
|
||||
LUA_PushUserdata(L, skin->sprites, META_SKINSPRITES);
|
||||
break;
|
||||
case skin_supersprites:
|
||||
|
@ -338,15 +343,7 @@ static int soundsid_num(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
enum spritesopt {
|
||||
numframes = 0
|
||||
};
|
||||
|
||||
static const char *const sprites_opt[] = {
|
||||
"numframes",
|
||||
NULL};
|
||||
|
||||
// skin.sprites[i] -> sprites[i]
|
||||
// skin.skinsprites[i] -> sprites[i]
|
||||
static int lib_getSkinSprite(lua_State *L)
|
||||
{
|
||||
spritedef_t *sksprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES);
|
||||
|
@ -359,13 +356,43 @@ static int lib_getSkinSprite(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// #skin.sprites -> NUMPLAYERSPRITES
|
||||
// #skin.skinsprites -> NUMPLAYERSPRITES
|
||||
static int lib_numSkinsSprites(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, NUMPLAYERSPRITES);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: 2.3: Delete
|
||||
// skin.sprites[i] -> sprites[i]
|
||||
static int lib_getSkinSpriteCompat(lua_State *L)
|
||||
{
|
||||
spritedef_t *sksprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITESCOMPAT);
|
||||
playersprite_t i = luaL_checkinteger(L, 2);
|
||||
|
||||
if (i < 0 || i >= NUMPLAYERSPRITES*2)
|
||||
return luaL_error(L, "skin sprites index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1);
|
||||
|
||||
LUA_PushUserdata(L, &sksprites[i], META_SKINSPRITESLIST);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: 2.3: Delete
|
||||
// #skin.sprites -> NUMPLAYERSPRITES*2
|
||||
static int lib_numSkinsSpritesCompat(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, NUMPLAYERSPRITES*2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum spritesopt {
|
||||
numframes = 0
|
||||
};
|
||||
|
||||
static const char *const sprites_opt[] = {
|
||||
"numframes",
|
||||
NULL};
|
||||
|
||||
static int sprite_get(lua_State *L)
|
||||
{
|
||||
spritedef_t *sprite = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITESLIST);
|
||||
|
@ -387,6 +414,7 @@ int LUA_SkinLib(lua_State *L)
|
|||
LUA_RegisterUserdataMetatable(L, META_SOUNDSID, soundsid_get, NULL, soundsid_num);
|
||||
LUA_RegisterUserdataMetatable(L, META_SKINSPRITES, lib_getSkinSprite, NULL, lib_numSkinsSprites);
|
||||
LUA_RegisterUserdataMetatable(L, META_SKINSPRITESLIST, sprite_get, NULL, NULL);
|
||||
LUA_RegisterUserdataMetatable(L, META_SKINSPRITESCOMPAT, lib_getSkinSpriteCompat, NULL, lib_numSkinsSpritesCompat); // TODO: 2.3: Delete
|
||||
|
||||
skin_fields_ref = Lua_CreateFieldTable(L, skin_opt);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2013-2016 by Matthew "Kaito Sinclaire" Walsh.
|
||||
// Copyright (C) 2013 by "Ninji".
|
||||
// Copyright (C) 2013-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2013-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh.
|
||||
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2012-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -494,6 +494,12 @@ UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data)
|
|||
|
||||
UINT8 M_CampaignWarpIsCheat(INT32 gt, INT32 mapnum, gamedata_t *data)
|
||||
{
|
||||
if (dedicated)
|
||||
{
|
||||
// See M_MapLocked; don't make dedicated servers annoying.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (M_MapLocked(mapnum, data) == true)
|
||||
{
|
||||
// Warping to locked maps is definitely always a cheat
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2020-2023 by Jaime "Lactozilla" Passos.
|
||||
// Copyright (C) 2020-2023 by Lactozilla.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2020-2023 by Jaime "Lactozilla" Passos.
|
||||
// Copyright (C) 2020-2023 by Lactozilla.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
// Copyright (C) 2009 by Stephen McGranahan.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
272
src/m_menu.c
272
src/m_menu.c
|
@ -3,7 +3,7 @@
|
|||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -140,6 +140,7 @@ static char *char_notes = NULL;
|
|||
|
||||
boolean menuactive = false;
|
||||
boolean fromlevelselect = false;
|
||||
tic_t shieldprompt_timer = 0; // Show a prompt about the new Shield button for old configs // TODO: 2.3: Remove
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -3161,6 +3162,7 @@ static void Command_Manual_f(void)
|
|||
if (modeattacking)
|
||||
return;
|
||||
M_StartControlPanel();
|
||||
if (shieldprompt_timer) return; // TODO: 2.3: Delete this line
|
||||
currentMenu = &MISC_HelpDef;
|
||||
itemOn = 0;
|
||||
}
|
||||
|
@ -3340,6 +3342,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (modeattacking)
|
||||
return true;
|
||||
M_StartControlPanel();
|
||||
if (shieldprompt_timer) return true; // TODO: 2.3: Delete this line
|
||||
M_Options(0);
|
||||
// Uncomment the below if you want the menu to reset to the top each time like before. M_SetupNextMenu will fix it automatically.
|
||||
//OP_SoundOptionsDef.lastOn = 0;
|
||||
|
@ -3350,6 +3353,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (modeattacking)
|
||||
return true;
|
||||
M_StartControlPanel();
|
||||
if (shieldprompt_timer) return true; // TODO: 2.3: Delete this line
|
||||
M_Options(0);
|
||||
M_VideoModeMenu(0);
|
||||
return true;
|
||||
|
@ -3361,6 +3365,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (modeattacking)
|
||||
return true;
|
||||
M_StartControlPanel();
|
||||
if (shieldprompt_timer) return true; // TODO: 2.3: Delete this line
|
||||
M_Options(0);
|
||||
M_SetupNextMenu(&OP_MainDef);
|
||||
return true;
|
||||
|
@ -3631,6 +3636,230 @@ void M_Drawer(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Handle the "Do you want to assign Shield Ability now?" pop-up for old configs // TODO: 2.3: Remove this line...
|
||||
static UINT8 shieldprompt_currentchoice = 0; // ...and this line...
|
||||
|
||||
static void M_ShieldPromptUseDefaults(void) // ...and this function
|
||||
{
|
||||
// With a default config from v2.2.10 to v2.2.13, the B button will be set to Custom 1,
|
||||
// and Controls per Key defaults to "One", so it will override the default Shield button.
|
||||
// A default config from v2.2.0 to v2.2.9 has Next Weapon on B, so it suffers from this too.
|
||||
|
||||
// So for "Use default Shield Ability buttons", we should update old configs to mitigate gamepad conflicts
|
||||
// (even with "Several" Controls per Key!), and show a message with the default bindings
|
||||
|
||||
for (setupcontrols = gamecontrol; true; setupcontrols = gamecontrolbis) // Do stuff for both P1 and P2
|
||||
{
|
||||
INT32 JOY1 = (setupcontrols == gamecontrol) ? KEY_JOY1 : KEY_2JOY1; // Is this for P1 or for P2?
|
||||
|
||||
if ((setupcontrols[GC_CUSTOM1][0] == JOY1+1 || setupcontrols[GC_CUSTOM1][1] == JOY1+1)
|
||||
&& (setupcontrols[GC_CUSTOM2][0] == JOY1+3 || setupcontrols[GC_CUSTOM2][1] == JOY1+3)
|
||||
&& (setupcontrols[GC_CUSTOM3][0] == JOY1+8 || setupcontrols[GC_CUSTOM3][1] == JOY1+8))
|
||||
{
|
||||
// If the player has v2.2.13's default gamepad Custom 1/2/3 buttons,
|
||||
// shuffle Custom 1/2/3 around to make room for Shield Ability on B
|
||||
UINT8 shield_slot = (setupcontrols[GC_SHIELD ][0] == KEY_NULL ) ? 0 : 1;
|
||||
UINT8 custom1_slot = (setupcontrols[GC_CUSTOM1][0] == JOY1+1) ? 0 : 1;
|
||||
UINT8 custom2_slot = (setupcontrols[GC_CUSTOM2][0] == JOY1+3) ? 0 : 1;
|
||||
UINT8 custom3_slot = (setupcontrols[GC_CUSTOM3][0] == JOY1+8) ? 0 : 1;
|
||||
|
||||
setupcontrols[GC_SHIELD ][shield_slot ] = JOY1+1; // Assign Shield Ability to B
|
||||
setupcontrols[GC_CUSTOM1][custom1_slot] = JOY1+3; // Move Custom 1 from B to Y
|
||||
setupcontrols[GC_CUSTOM2][custom2_slot] = JOY1+8; // Move Custom 2 from Y to LS
|
||||
setupcontrols[GC_CUSTOM3][custom3_slot] = KEY_NULL; // Unassign Custom 3 from LS...
|
||||
// (The alternative would be to check and update the ENTIRE gamepad layout.
|
||||
// That'd be nice, but it would mess with people that are used to the old defaults.)
|
||||
}
|
||||
else if ((setupcontrols[GC_WEAPONNEXT][0] == JOY1+1 || setupcontrols[GC_WEAPONNEXT][1] == JOY1+1)
|
||||
&& (setupcontrols[GC_WEAPONPREV][0] == JOY1+2 || setupcontrols[GC_WEAPONPREV][1] == JOY1+2))
|
||||
{
|
||||
// Or if the user has a default config from v2.2.0 to v2.2.9,
|
||||
// the B button will be Next Weapon, and X will be Previous Weapon.
|
||||
// It's "safe" to discard one of them, you just have to press X multiple times to select in the other direction
|
||||
UINT8 shield_slot = (setupcontrols[GC_SHIELD ][0] == KEY_NULL ) ? 0 : 1;
|
||||
UINT8 nweapon_slot = (setupcontrols[GC_WEAPONNEXT][0] == JOY1+1) ? 0 : 1;
|
||||
UINT8 pweapon_slot = (setupcontrols[GC_WEAPONPREV][0] == JOY1+2) ? 0 : 1;
|
||||
|
||||
setupcontrols[GC_SHIELD ][shield_slot ] = JOY1+1; // Assign Shield Ability to B
|
||||
setupcontrols[GC_WEAPONNEXT][nweapon_slot] = JOY1+3; // Move Next Weapon from B to X
|
||||
setupcontrols[GC_WEAPONPREV][pweapon_slot] = KEY_NULL; // Unassign Previous Weapon from X
|
||||
}
|
||||
|
||||
if (setupcontrols == gamecontrolbis) // If we've already updated both players, break out
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Now, show a message about the default Shield Ability bindings
|
||||
if ((gamecontrol[GC_SHIELD][0] == KEY_LALT && gamecontrol[GC_SHIELD][1] == KEY_JOY1+1)
|
||||
|| (gamecontrol[GC_SHIELD][0] == KEY_JOY1+1 && gamecontrol[GC_SHIELD][1] == KEY_LALT))
|
||||
{
|
||||
// Left Alt and the B button are both assigned
|
||||
M_StartMessage(M_GetText("Shield Ability defaults to\nthe \x82""Left Alt\x80"" key on keyboard,\nand the \x85""B button\x80"" on gamepads."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 43; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 27;
|
||||
}
|
||||
else if (gamecontrol[GC_SHIELD][0] == KEY_LALT || gamecontrol[GC_SHIELD][1] == KEY_LALT)
|
||||
{
|
||||
// Left Alt is assigned, but the B button isn't.
|
||||
M_StartMessage(M_GetText("Shield Ability defaults to\nthe \x82""Left Alt\x80"" key on keyboard.\nThe \x85""B button\x80"" on gamepads was taken."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 24; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 32;
|
||||
}
|
||||
else if (gamecontrol[GC_SHIELD][0] == KEY_JOY1+1 || gamecontrol[GC_SHIELD][1] == KEY_JOY1+1)
|
||||
{
|
||||
// The B button is assigned, but Left Alt isn't
|
||||
M_StartMessage(M_GetText("Shield Ability defaults to\nthe \x85""B button\x80"" on gamepads.\nThe \x82""Left Alt\x80"" key on keyboard was taken."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 8; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 36;
|
||||
}
|
||||
else if (gamecontrol[GC_SHIELD][0] == KEY_NULL && gamecontrol[GC_SHIELD][1] == KEY_NULL)
|
||||
{
|
||||
// Neither Left Alt nor the B button are assigned
|
||||
M_StartMessage(M_GetText("Shield Ability is unassigned!\nThe \x82""Left Alt\x80"" key on keyboard and\nthe \x85""B button\x80"" on gamepads were taken."
|
||||
"\n\nYou should assign Shield Ability\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 19; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 33;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Neither Left Alt nor the B button are assigned... but something else is???
|
||||
// (This can technically happen if you edit your config or use setcontrol in the console before opening the menu)
|
||||
char keystr[16+16+2+7+1]; // Two 16-char keys + two colour codes + "' and '" + null
|
||||
|
||||
if (gamecontrol[GC_SHIELD][0] != KEY_NULL && gamecontrol[GC_SHIELD][1] != KEY_NULL)
|
||||
STRBUFCPY(keystr, va("%s\x80""' and '\x82""%s",
|
||||
G_KeyNumToName(gamecontrol[GC_SHIELD][0]),
|
||||
G_KeyNumToName(gamecontrol[GC_SHIELD][1])));
|
||||
else if (gamecontrol[GC_SHIELD][0] != KEY_NULL)
|
||||
STRBUFCPY(keystr, G_KeyNumToName(gamecontrol[GC_SHIELD][0]));
|
||||
else //if (gamecontrol[GC_SHIELD][1] != KEY_NULL)
|
||||
STRBUFCPY(keystr, G_KeyNumToName(gamecontrol[GC_SHIELD][1]));
|
||||
|
||||
M_StartMessage(va("Shield Ability is assigned to\n'\x82""%s\x80""'."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n",
|
||||
keystr), NULL, MM_NOTHING);
|
||||
MessageDef.x = 23; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 32;
|
||||
}
|
||||
}
|
||||
|
||||
static void M_HandleShieldPromptMenu(INT32 choice) // TODO: 2.3: Remove
|
||||
{
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_ESCAPE:
|
||||
if (I_GetTime() <= shieldprompt_timer) // Don't mash past the pop-up by accident!
|
||||
break;
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
noFurtherInput = true;
|
||||
shieldprompt_timer = 0;
|
||||
M_ShieldPromptUseDefaults();
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
if (I_GetTime() <= shieldprompt_timer) // Don't mash past the pop-up by accident!
|
||||
break;
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
noFurtherInput = true;
|
||||
shieldprompt_timer = 0;
|
||||
|
||||
if (shieldprompt_currentchoice == 0)
|
||||
{
|
||||
OP_ChangeControlsDef.lastOn = 8; // Highlight Shield Ability in the controls menu
|
||||
M_Setup1PControlsMenu(0); // Set up P1's controls menu and call M_SetupNextMenu
|
||||
}
|
||||
else if (shieldprompt_currentchoice == 1) // Copy the Spin buttons to the Shield buttons
|
||||
{
|
||||
CV_SetValue(&cv_controlperkey, 2); // Make sure that Controls per Key is "Several"
|
||||
|
||||
gamecontrol [GC_SHIELD][0] = gamecontrol [GC_SPIN][0];
|
||||
gamecontrol [GC_SHIELD][1] = gamecontrol [GC_SPIN][1];
|
||||
gamecontrolbis[GC_SHIELD][0] = gamecontrolbis[GC_SPIN][0];
|
||||
gamecontrolbis[GC_SHIELD][1] = gamecontrolbis[GC_SPIN][1];
|
||||
CV_SetValue(&cv_shieldaxis, cv_spinaxis.value);
|
||||
CV_SetValue(&cv_shieldaxis2, cv_spinaxis2.value);
|
||||
|
||||
M_StartMessage(M_GetText("Spin and Shield Ability are now\nthe same button."
|
||||
"\n\nYou can always reassign them\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 36; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 29;
|
||||
}
|
||||
else
|
||||
M_ShieldPromptUseDefaults();
|
||||
break;
|
||||
|
||||
case KEY_UPARROW:
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
shieldprompt_currentchoice = (shieldprompt_currentchoice+2)%3;
|
||||
break;
|
||||
|
||||
case KEY_DOWNARROW:
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
shieldprompt_currentchoice = (shieldprompt_currentchoice+1)%3;
|
||||
break;
|
||||
}
|
||||
|
||||
MessageDef.prevMenu = &MainDef;
|
||||
}
|
||||
|
||||
static void M_DrawShieldPromptMenu(void) // TODO: 2.3: Remove
|
||||
{
|
||||
INT16 cursorx = (BASEVIDWIDTH/2) - 24;
|
||||
|
||||
V_DrawFill(10-3, 68-3, 300+6, 40+6, 159);
|
||||
// V_DrawCenteredString doesn't centre newlines, so we have to draw each line separately
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 68, V_ALLOWLOWERCASE, "Welcome back! Since you last played,");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 76, V_ALLOWLOWERCASE, "Spin has been split into separate");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 84, V_ALLOWLOWERCASE, "\"Spin\" and \"Shield Ability\" controls.");
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 98, V_ALLOWLOWERCASE, "Do you want to assign Shield Ability now?");
|
||||
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 164,
|
||||
(shieldprompt_currentchoice == 0) ? V_YELLOWMAP : 0, "Open Control Setup");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 172,
|
||||
(shieldprompt_currentchoice == 1) ? V_YELLOWMAP : 0, "Keep the old behaviour");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 180,
|
||||
(shieldprompt_currentchoice == 2) ? V_YELLOWMAP : 0, "Use default Shield Ability buttons");
|
||||
|
||||
switch (shieldprompt_currentchoice)
|
||||
{
|
||||
case 0: cursorx -= V_StringWidth("Open Control Setup", 0)/2; break;
|
||||
case 1: cursorx -= V_StringWidth("Keep the old behaviour", 0)/2; break;
|
||||
default: cursorx -= V_StringWidth("Use default Shield Ability buttons", 0)/2; break;
|
||||
}
|
||||
V_DrawScaledPatch(cursorx, 164 + (shieldprompt_currentchoice*8), 0, W_CachePatchName("M_CURSOR", PU_PATCH));
|
||||
}
|
||||
|
||||
static menuitem_t OP_ShieldPromptMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleShieldPromptMenu, 0}}; // TODO: 2.3: Remove
|
||||
|
||||
menu_t OP_ShieldPromptDef = { // TODO: 2.3: Remove
|
||||
MN_SPECIAL,
|
||||
NULL,
|
||||
1,
|
||||
&MainDef,
|
||||
OP_ShieldPromptMenu,
|
||||
M_DrawShieldPromptMenu,
|
||||
0, 0, 0, NULL
|
||||
};
|
||||
|
||||
//
|
||||
// M_StartControlPanel
|
||||
//
|
||||
|
@ -3662,6 +3891,15 @@ void M_StartControlPanel(void)
|
|||
currentMenu = &MainDef;
|
||||
itemOn = singleplr;
|
||||
M_UpdateItemOn();
|
||||
|
||||
if (shieldprompt_timer) // For old configs, show a pop-up about the new Shield button // TODO: 2.3: Remove
|
||||
{
|
||||
S_StartSound(NULL, sfx_strpst);
|
||||
noFurtherInput = true;
|
||||
shieldprompt_timer = I_GetTime() + TICRATE; // Don't mash past the pop-up by accident!
|
||||
|
||||
M_SetupNextMenu(&OP_ShieldPromptDef);
|
||||
}
|
||||
}
|
||||
else if (modeattacking)
|
||||
{
|
||||
|
@ -8372,7 +8610,7 @@ static void M_DrawLoadGameData(void)
|
|||
if (savegameinfo[savetodraw].lives == -42)
|
||||
col = 26;
|
||||
else if (savegameinfo[savetodraw].botskin == 3) // & knuckles
|
||||
col = 105;
|
||||
col = 106;
|
||||
else if (savegameinfo[savetodraw].botskin) // tailsbot or custom
|
||||
col = 134;
|
||||
else
|
||||
|
@ -8432,7 +8670,17 @@ static void M_DrawLoadGameData(void)
|
|||
if (savegameinfo[savetodraw].lives == -42)
|
||||
V_DrawRightAlignedThinString(x + 79, y, V_GRAYMAP, "NEW GAME");
|
||||
else if (savegameinfo[savetodraw].lives == -666)
|
||||
V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "CAN'T LOAD!");
|
||||
{
|
||||
if (savegameinfo[savetodraw].continuescore == -62)
|
||||
{
|
||||
V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "ADDON NOT LOADED");
|
||||
V_DrawRightAlignedThinString(x + 79, y-10, V_REDMAP, savegameinfo[savetodraw].skinname);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "CAN'T LOAD!");
|
||||
}
|
||||
}
|
||||
else if (savegameinfo[savetodraw].gamemap & 8192)
|
||||
V_DrawRightAlignedThinString(x + 79, y, V_GREENMAP, "CLEAR!");
|
||||
else
|
||||
|
@ -8665,6 +8913,7 @@ static void M_LoadSelect(INT32 choice)
|
|||
}
|
||||
|
||||
#define VERSIONSIZE 16
|
||||
#define MISSING { savegameinfo[slot].continuescore = -62; savegameinfo[slot].lives = -666; Z_Free(savebuffer); return; }
|
||||
#define BADSAVE { savegameinfo[slot].lives = -666; Z_Free(savebuffer); return; }
|
||||
#define CHECKPOS if (sav_p >= end_p) BADSAVE
|
||||
// Reads the save file to list lives, level, player, etc.
|
||||
|
@ -8761,10 +9010,11 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
|||
CHECKPOS
|
||||
READSTRINGN(sav_p, ourSkinName, SKINNAMESIZE);
|
||||
savegameinfo[slot].skinnum = R_SkinAvailable(ourSkinName);
|
||||
STRBUFCPY(savegameinfo[slot].skinname, ourSkinName);
|
||||
|
||||
if (savegameinfo[slot].skinnum >= numskins
|
||||
|| !R_SkinUsable(-1, savegameinfo[slot].skinnum))
|
||||
BADSAVE
|
||||
MISSING
|
||||
|
||||
CHECKPOS
|
||||
READSTRINGN(sav_p, botSkinName, SKINNAMESIZE);
|
||||
|
@ -8772,7 +9022,7 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
|||
|
||||
if (savegameinfo[slot].botskin-1 >= numskins
|
||||
|| !R_SkinUsable(-1, savegameinfo[slot].botskin-1))
|
||||
BADSAVE
|
||||
MISSING
|
||||
}
|
||||
|
||||
CHECKPOS
|
||||
|
@ -8817,6 +9067,7 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
|||
}
|
||||
#undef CHECKPOS
|
||||
#undef BADSAVE
|
||||
#undef MISSING
|
||||
|
||||
//
|
||||
// M_ReadSaveStrings
|
||||
|
@ -10211,9 +10462,12 @@ void M_DrawNightsAttackMenu(void)
|
|||
color = skins[skinnumber]->prefcolor;
|
||||
|
||||
angle_t fa = (FixedAngle(((FixedInt(ntsatkdrawtimer * 4)) % 360)<<FRACBITS)>>ANGLETOFINESHIFT) & FINEMASK;
|
||||
fixed_t scale = skins[skinnumber]->highresscale;
|
||||
if (skins[skinnumber]->shieldscale)
|
||||
scale = FixedDiv(scale, skins[skinnumber]->shieldscale);
|
||||
|
||||
V_DrawFixedPatch(270<<FRACBITS, (186<<FRACBITS) - 8*FINESINE(fa),
|
||||
FixedDiv(skins[skinnumber]->highresscale, skins[skinnumber]->shieldscale),
|
||||
scale,
|
||||
(sprframe->flip & 1<<6) ? V_FLIP : 0,
|
||||
natksprite,
|
||||
R_GetTranslationColormap(TC_BLINK, color, GTC_CACHE));
|
||||
|
@ -12300,7 +12554,9 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
if (multi_frame >= sprdef->numframes)
|
||||
multi_frame = 0;
|
||||
|
||||
scale = FixedDiv(skins[setupm_fakeskin]->highresscale, skins[setupm_fakeskin]->shieldscale);
|
||||
scale = skins[setupm_fakeskin]->highresscale;
|
||||
if (skins[setupm_fakeskin]->shieldscale)
|
||||
scale = FixedDiv(scale, skins[setupm_fakeskin]->shieldscale);
|
||||
|
||||
#define chary (y+64)
|
||||
|
||||
|
@ -12333,7 +12589,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
V_DrawFixedPatch(
|
||||
x<<FRACBITS,
|
||||
chary<<FRACBITS,
|
||||
FixedDiv(skins[setupm_fakeskin]->highresscale, skins[setupm_fakeskin]->shieldscale),
|
||||
scale,
|
||||
flags, patch, colormap);
|
||||
|
||||
goto colordraw;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -176,6 +176,7 @@ typedef struct
|
|||
extern menupres_t menupres[NUMMENUTYPES];
|
||||
extern UINT32 prevMenuId;
|
||||
extern UINT32 activeMenuId;
|
||||
extern tic_t shieldprompt_timer; // Show a prompt about the new Shield button for old configs // TODO: 2.3: Remove
|
||||
|
||||
void M_InitMenuPresTables(void);
|
||||
UINT8 M_GetYoungestChildMenu(void);
|
||||
|
@ -421,6 +422,7 @@ typedef struct
|
|||
{
|
||||
char levelname[32];
|
||||
UINT8 skinnum;
|
||||
char skinname [SKINNAMESIZE+1];
|
||||
UINT8 botskin;
|
||||
UINT8 numemeralds;
|
||||
UINT8 numgameovers;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -560,6 +560,11 @@ void M_FirstLoadConfig(void)
|
|||
COM_BufInsertText(va("exec \"%s\"\n", configfile));
|
||||
// no COM_BufExecute() needed; that does it right away
|
||||
|
||||
// For configs loaded at startup only, check for pre-Shield-button configs // TODO: 2.3: Remove
|
||||
if (GETMAJOREXECVERSION(cv_execversion.value) < 55 // Pre-v2.2.14 configs
|
||||
&& cv_execversion.value != 25) // Make sure that the config exists, too
|
||||
shieldprompt_timer = 1;
|
||||
|
||||
// don't filter anymore vars and don't let this convsvar be changed
|
||||
COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, EXECVERSION));
|
||||
CV_ToggleExecVersion(false);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2013-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2013-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2013-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 2013-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -21,6 +21,32 @@ void DVector3_Load(dvector3_t *vec, double x, double y, double z)
|
|||
vec->z = z;
|
||||
}
|
||||
|
||||
void DVector3_Copy(dvector3_t *a_o, const dvector3_t *a_i)
|
||||
{
|
||||
memcpy(a_o, a_i, sizeof(dvector3_t));
|
||||
}
|
||||
|
||||
void DVector3_Add(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o)
|
||||
{
|
||||
a_o->x = a_i->x + a_c->x;
|
||||
a_o->y = a_i->y + a_c->y;
|
||||
a_o->z = a_i->z + a_c->z;
|
||||
}
|
||||
|
||||
void DVector3_Subtract(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o)
|
||||
{
|
||||
a_o->x = a_i->x - a_c->x;
|
||||
a_o->y = a_i->y - a_c->y;
|
||||
a_o->z = a_i->z - a_c->z;
|
||||
}
|
||||
|
||||
void DVector3_Multiply(const dvector3_t *a_i, double a_c, dvector3_t *a_o)
|
||||
{
|
||||
a_o->x = a_i->x * a_c;
|
||||
a_o->y = a_i->y * a_c;
|
||||
a_o->z = a_i->z * a_c;
|
||||
}
|
||||
|
||||
double DVector3_Magnitude(const dvector3_t *a_normal)
|
||||
{
|
||||
double xs = a_normal->x * a_normal->x;
|
||||
|
|
|
@ -19,6 +19,10 @@ typedef struct
|
|||
} dvector3_t;
|
||||
|
||||
void DVector3_Load(dvector3_t *vec, double x, double y, double z);
|
||||
void DVector3_Copy(dvector3_t *a_o, const dvector3_t *a_i);
|
||||
void DVector3_Add(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o);
|
||||
void DVector3_Subtract(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o);
|
||||
void DVector3_Multiply(const dvector3_t *a_i, double a_c, dvector3_t *a_o);
|
||||
double DVector3_Magnitude(const dvector3_t *a_normal);
|
||||
double DVector3_Normalize(dvector3_t *a_normal);
|
||||
void DVector3_Negate(dvector3_t *a_o);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -113,8 +113,11 @@ consvar_t cv_blamecfail = CVAR_INIT ("blamecfail", "Off", CV_SAVE|CV_NETVAR, CV_
|
|||
static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_playbackspeed = CVAR_INIT ("playbackspeed", "1", 0, playbackspeed_cons_t, NULL);
|
||||
|
||||
consvar_t cv_idletime = CVAR_INIT ("idletime", "0", CV_SAVE, CV_Unsigned, NULL);
|
||||
consvar_t cv_dedicatedidletime = CVAR_INIT ("dedicatedidletime", "10", CV_SAVE, CV_Unsigned, NULL);
|
||||
consvar_t cv_dedicatedidletime = CVAR_INIT ("dedicatedidletime", "10", CV_SAVE|CV_NETVAR, CV_Unsigned, NULL);
|
||||
|
||||
static CV_PossibleValue_t idleaction_cons_t[] = {{1, "Kick"}, {2, "Spectate"}, {0, NULL}};
|
||||
consvar_t cv_idleaction = CVAR_INIT ("idleaction", "Spectate", CV_SAVE|CV_NETVAR, idleaction_cons_t, NULL);
|
||||
consvar_t cv_idletime = CVAR_INIT ("idletime", "3", CV_SAVE|CV_NETVAR, CV_Unsigned, NULL);
|
||||
|
||||
consvar_t cv_httpsource = CVAR_INIT ("http_source", "", CV_SAVE, NULL, NULL);
|
||||
|
||||
|
@ -1360,19 +1363,33 @@ static void IdleUpdate(void)
|
|||
if (!server || !netgame)
|
||||
return;
|
||||
|
||||
for (i = 1; i < MAXPLAYERS; i++)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (cv_idletime.value && playeringame[i] && playernode[i] != UINT8_MAX && !players[i].quittime && !players[i].spectator && !players[i].bot && !IsPlayerAdmin(i) && i != serverplayer && gamestate == GS_LEVEL)
|
||||
if (playeringame[i] && playernode[i] != UINT8_MAX && !players[i].quittime && !players[i].spectator && !players[i].bot && gamestate == GS_LEVEL)
|
||||
{
|
||||
if (players[i].cmd.forwardmove || players[i].cmd.sidemove || players[i].cmd.buttons)
|
||||
players[i].lastinputtime = 0;
|
||||
else
|
||||
players[i].lastinputtime++;
|
||||
|
||||
if (players[i].lastinputtime > (tic_t)cv_idletime.value * TICRATE * 60)
|
||||
if (cv_idletime.value && !IsPlayerAdmin(i) && i != serverplayer && !(players[i].pflags & PF_FINISHED) && players[i].lastinputtime > (tic_t)cv_idletime.value * TICRATE * 60)
|
||||
{
|
||||
players[i].lastinputtime = 0;
|
||||
SendKick(i, KICK_MSG_IDLE | KICK_MSG_KEEP_BODY);
|
||||
if (cv_idleaction.value == 2 && G_GametypeHasSpectators())
|
||||
{
|
||||
changeteam_union NetPacket;
|
||||
UINT16 usvalue;
|
||||
NetPacket.value.l = NetPacket.value.b = 0;
|
||||
NetPacket.packet.newteam = 0;
|
||||
NetPacket.packet.playernum = i;
|
||||
NetPacket.packet.verification = true; // This signals that it's a server change
|
||||
usvalue = SHORT(NetPacket.value.l|NetPacket.value.b);
|
||||
SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue));
|
||||
}
|
||||
else if (cv_idleaction.value == 1)
|
||||
{
|
||||
SendKick(i, KICK_MSG_IDLE | KICK_MSG_KEEP_BODY);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1399,6 +1416,83 @@ static void IdleUpdate(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void DedicatedIdleUpdate(INT32 *realtics)
|
||||
{
|
||||
const tic_t dedicatedidletime = cv_dedicatedidletime.value * TICRATE;
|
||||
static tic_t dedicatedidletimeprev = 0;
|
||||
static tic_t dedicatedidle = 0;
|
||||
|
||||
if (!server || !dedicated || gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
if (dedicatedidletime > 0)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
boolean empty = true;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
{
|
||||
empty = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (empty)
|
||||
{
|
||||
if (leveltime == 2)
|
||||
{
|
||||
// On next tick...
|
||||
dedicatedidle = dedicatedidletime - 1;
|
||||
}
|
||||
else if (dedicatedidle >= dedicatedidletime)
|
||||
{
|
||||
if (D_GetExistingTextcmd(gametic, 0) || D_GetExistingTextcmd(gametic + 1, 0))
|
||||
{
|
||||
CONS_Printf("DEDICATED: Awakening from idle (Netxcmd detected...)\n");
|
||||
dedicatedidle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*realtics) = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dedicatedidle += (*realtics);
|
||||
|
||||
if (dedicatedidle >= dedicatedidletime)
|
||||
{
|
||||
const char *idlereason = "at round start";
|
||||
if (leveltime > 3)
|
||||
idlereason = va("for %d seconds", dedicatedidle / TICRATE);
|
||||
|
||||
CONS_Printf("DEDICATED: No players %s, idling...\n", idlereason);
|
||||
(*realtics) = 0;
|
||||
dedicatedidle = dedicatedidletime;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dedicatedidle >= dedicatedidletime)
|
||||
{
|
||||
CONS_Printf("DEDICATED: Awakening from idle (Player detected...)\n");
|
||||
}
|
||||
dedicatedidle = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dedicatedidletimeprev > 0 && dedicatedidle >= dedicatedidletimeprev)
|
||||
{
|
||||
CONS_Printf("DEDICATED: Awakening from idle (Idle disabled...)\n");
|
||||
}
|
||||
dedicatedidle = 0;
|
||||
}
|
||||
|
||||
dedicatedidletimeprev = dedicatedidletime;
|
||||
}
|
||||
|
||||
// Handle timeouts to prevent definitive freezes from happenning
|
||||
static void HandleNodeTimeouts(void)
|
||||
{
|
||||
|
@ -1475,69 +1569,7 @@ void NetUpdate(void)
|
|||
realtics = 5;
|
||||
}
|
||||
|
||||
if (server && dedicated && gamestate == GS_LEVEL)
|
||||
{
|
||||
const tic_t dedicatedidletime = cv_dedicatedidletime.value * TICRATE;
|
||||
static tic_t dedicatedidletimeprev = 0;
|
||||
static tic_t dedicatedidle = 0;
|
||||
|
||||
if (dedicatedidletime > 0)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 1; i < MAXNETNODES; ++i)
|
||||
if (netnodes[i].ingame)
|
||||
{
|
||||
if (dedicatedidle >= dedicatedidletime)
|
||||
{
|
||||
CONS_Printf("DEDICATED: Awakening from idle (Node %d detected...)\n", i);
|
||||
dedicatedidle = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAXNETNODES)
|
||||
{
|
||||
if (leveltime == 2)
|
||||
{
|
||||
// On next tick...
|
||||
dedicatedidle = dedicatedidletime-1;
|
||||
}
|
||||
else if (dedicatedidle >= dedicatedidletime)
|
||||
{
|
||||
if (D_GetExistingTextcmd(gametic, 0) || D_GetExistingTextcmd(gametic+1, 0))
|
||||
{
|
||||
CONS_Printf("DEDICATED: Awakening from idle (Netxcmd detected...)\n");
|
||||
dedicatedidle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
realtics = 0;
|
||||
}
|
||||
}
|
||||
else if ((dedicatedidle += realtics) >= dedicatedidletime)
|
||||
{
|
||||
const char *idlereason = "at round start";
|
||||
if (leveltime > 3)
|
||||
idlereason = va("for %d seconds", dedicatedidle/TICRATE);
|
||||
|
||||
CONS_Printf("DEDICATED: No nodes %s, idling...\n", idlereason);
|
||||
realtics = 0;
|
||||
dedicatedidle = dedicatedidletime;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dedicatedidletimeprev > 0 && dedicatedidle >= dedicatedidletimeprev)
|
||||
{
|
||||
CONS_Printf("DEDICATED: Awakening from idle (Idle disabled...)\n");
|
||||
}
|
||||
dedicatedidle = 0;
|
||||
}
|
||||
|
||||
dedicatedidletimeprev = dedicatedidletime;
|
||||
}
|
||||
DedicatedIdleUpdate(&realtics);
|
||||
|
||||
gametime = nowtime;
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ extern UINT32 realpingtable[MAXPLAYERS];
|
|||
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||
extern tic_t servermaxping;
|
||||
|
||||
extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed, cv_idletime, cv_dedicatedidletime;
|
||||
extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed, cv_idletime, cv_idleaction, cv_dedicatedidletime;
|
||||
extern consvar_t cv_httpsource;
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -62,9 +62,6 @@ static doomdata_t reboundstore[MAXREBOUND];
|
|||
static INT16 reboundsize[MAXREBOUND];
|
||||
static INT32 rebound_head, rebound_tail;
|
||||
|
||||
/// \brief bandwith of netgame
|
||||
INT32 net_bandwidth;
|
||||
|
||||
/// \brief max length per packet
|
||||
INT16 hardware_MAXPACKETLENGTH;
|
||||
|
||||
|
@ -1189,10 +1186,7 @@ void D_SetDoomcom(void)
|
|||
{
|
||||
if (doomcom) return;
|
||||
doomcom = Z_Calloc(sizeof (doomcom_t), PU_STATIC, NULL);
|
||||
doomcom->id = DOOMCOM_ID;
|
||||
doomcom->numslots = doomcom->numnodes = 1;
|
||||
doomcom->gametype = 0;
|
||||
doomcom->consoleplayer = 0;
|
||||
doomcom->extratics = 0;
|
||||
}
|
||||
|
||||
|
@ -1217,7 +1211,6 @@ boolean D_CheckNetGame(void)
|
|||
I_NetMakeNodewPort = NULL;
|
||||
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
net_bandwidth = 30000;
|
||||
// I_InitNetwork sets doomcom and netgame
|
||||
// check and initialize the network driver
|
||||
multiplayer = false;
|
||||
|
@ -1237,7 +1230,6 @@ boolean D_CheckNetGame(void)
|
|||
server = true; // WTF? server always true???
|
||||
// no! The deault mode is server. Client is set elsewhere
|
||||
// when the client executes connect command.
|
||||
doomcom->ticdup = 1;
|
||||
|
||||
if (M_CheckParm("-extratic"))
|
||||
{
|
||||
|
@ -1248,21 +1240,6 @@ boolean D_CheckNetGame(void)
|
|||
CONS_Printf(M_GetText("Set extratics to %d\n"), doomcom->extratics);
|
||||
}
|
||||
|
||||
if (M_CheckParm("-bandwidth"))
|
||||
{
|
||||
if (M_IsNextParm())
|
||||
{
|
||||
net_bandwidth = atoi(M_GetNextParm());
|
||||
if (net_bandwidth < 1000)
|
||||
net_bandwidth = 1000;
|
||||
if (net_bandwidth > 100000)
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
CONS_Printf(M_GetText("Network bandwidth set to %d\n"), net_bandwidth);
|
||||
}
|
||||
else
|
||||
I_Error("usage: -bandwidth <byte_per_sec>");
|
||||
}
|
||||
|
||||
software_MAXPACKETLENGTH = hardware_MAXPACKETLENGTH;
|
||||
if (M_CheckParm("-packetsize"))
|
||||
{
|
||||
|
@ -1282,8 +1259,6 @@ boolean D_CheckNetGame(void)
|
|||
if (netgame)
|
||||
multiplayer = true;
|
||||
|
||||
if (doomcom->id != DOOMCOM_ID)
|
||||
I_Error("Doomcom buffer invalid!");
|
||||
if (doomcom->numnodes > MAXNETNODES)
|
||||
I_Error("Too many nodes (%d), max:%d", doomcom->numnodes, MAXNETNODES);
|
||||
|
||||
|
@ -1293,7 +1268,7 @@ boolean D_CheckNetGame(void)
|
|||
if (M_CheckParm("-debugfile"))
|
||||
{
|
||||
char filename[21];
|
||||
INT32 k = doomcom->consoleplayer - 1;
|
||||
INT32 k = consoleplayer - 1;
|
||||
if (M_IsNextParm())
|
||||
k = atoi(M_GetNextParm()) - 1;
|
||||
while (!debugfile && k < MAXPLAYERS)
|
||||
|
|
|
@ -620,6 +620,7 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_blamecfail);
|
||||
CV_RegisterVar(&cv_dedicatedidletime);
|
||||
CV_RegisterVar(&cv_idletime);
|
||||
CV_RegisterVar(&cv_idleaction);
|
||||
CV_RegisterVar(&cv_httpsource);
|
||||
|
||||
COM_AddCommand("ping", Command_Ping_f, COM_LUA);
|
||||
|
@ -2510,11 +2511,11 @@ static void MutePlayer(boolean mute)
|
|||
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("muteplayer <playernum>: mute a player\n"));
|
||||
CONS_Printf(M_GetText("muteplayer <playername/playernum>: mute a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
data[0] = atoi(COM_Argv(1));
|
||||
data[0] = nametonum(COM_Argv(1));
|
||||
if (data[0] >= MAXPLAYERS || !playeringame[data[0]])
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("There is no player %u!\n"), (unsigned int)data[0]);
|
||||
|
@ -2603,11 +2604,11 @@ static void Command_ServerTeamChange_f(void)
|
|||
if (COM_Argc() < 3)
|
||||
{
|
||||
if (G_TagGametype())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "it, notit, playing, or spectator");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "it, notit, playing, or spectator");
|
||||
else if (G_GametypeHasTeams())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "red, blue or spectator");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "red, blue or spectator");
|
||||
else if (G_GametypeHasSpectators())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "spectator or playing");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "spectator or playing");
|
||||
else
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("This command cannot be used in this gametype.\n"));
|
||||
return;
|
||||
|
@ -2655,19 +2656,19 @@ static void Command_ServerTeamChange_f(void)
|
|||
if (error)
|
||||
{
|
||||
if (G_TagGametype())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "it, notit, playing, or spectator");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "it, notit, playing, or spectator");
|
||||
else if (G_GametypeHasTeams())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "red, blue or spectator");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "red, blue or spectator");
|
||||
else if (G_GametypeHasSpectators())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "spectator or playing");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "spectator or playing");
|
||||
return;
|
||||
}
|
||||
|
||||
NetPacket.packet.playernum = atoi(COM_Argv(1));
|
||||
NetPacket.packet.playernum = nametonum(COM_Argv(1));
|
||||
|
||||
if (!playeringame[NetPacket.packet.playernum])
|
||||
if (NetPacket.packet.playernum == -1 || !playeringame[NetPacket.packet.playernum])
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("There is no player %d!\n"), NetPacket.packet.playernum);
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("There is no player %s!\n"), COM_Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3106,13 +3107,16 @@ static void Command_Verify_f(void)
|
|||
|
||||
if (COM_Argc() != 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("promote <playernum>: give admin privileges to a player\n"));
|
||||
CONS_Printf(M_GetText("promote <playername/playernum>: give admin privileges to a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
strlcpy(buf, COM_Argv(1), sizeof (buf));
|
||||
|
||||
playernum = atoi(buf);
|
||||
playernum = nametonum(COM_Argv(1));
|
||||
if (playernum == -1)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("There is no player %s!\n"), COM_Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
temp = buf;
|
||||
|
||||
|
@ -3156,13 +3160,16 @@ static void Command_RemoveAdmin_f(void)
|
|||
|
||||
if (COM_Argc() != 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("demote <playernum>: remove admin privileges from a player\n"));
|
||||
CONS_Printf(M_GetText("demote <playername/playernum>: remove admin privileges from a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
strlcpy(buf, COM_Argv(1), sizeof(buf));
|
||||
|
||||
playernum = atoi(buf);
|
||||
playernum = nametonum(COM_Argv(1));
|
||||
if (playernum == -1)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("There is no player %s!\n"), COM_Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
temp = buf;
|
||||
|
||||
|
@ -4792,12 +4799,11 @@ static void Command_Togglemodified_f(void)
|
|||
modifiedgame = !modifiedgame;
|
||||
}
|
||||
|
||||
extern UINT8 *save_p;
|
||||
static void Command_Archivetest_f(void)
|
||||
{
|
||||
UINT8 *buf;
|
||||
UINT32 i, wrote;
|
||||
thinker_t *th;
|
||||
save_t savebuffer;
|
||||
if (gamestate != GS_LEVEL)
|
||||
{
|
||||
CONS_Printf("This command only works in-game, you dummy.\n");
|
||||
|
@ -4811,28 +4817,29 @@ static void Command_Archivetest_f(void)
|
|||
((mobj_t *)th)->mobjnum = i++;
|
||||
|
||||
// allocate buffer
|
||||
buf = save_p = ZZ_Alloc(1024);
|
||||
savebuffer.size = 1024;
|
||||
savebuffer.buf = malloc(savebuffer.size);
|
||||
savebuffer.pos = 0;
|
||||
|
||||
// test archive
|
||||
CONS_Printf("LUA_Archive...\n");
|
||||
LUA_Archive();
|
||||
WRITEUINT8(save_p, 0x7F);
|
||||
wrote = (UINT32)(save_p-buf);
|
||||
LUA_Archive(&savebuffer);
|
||||
P_WriteUINT8(&savebuffer, 0x7F);
|
||||
wrote = savebuffer.pos;
|
||||
|
||||
// clear Lua state, so we can really see what happens!
|
||||
CONS_Printf("Clearing state!\n");
|
||||
LUA_ClearExtVars();
|
||||
|
||||
// test unarchive
|
||||
save_p = buf;
|
||||
CONS_Printf("LUA_UnArchive...\n");
|
||||
LUA_UnArchive();
|
||||
i = READUINT8(save_p);
|
||||
if (i != 0x7F || wrote != (UINT32)(save_p-buf))
|
||||
CONS_Printf("Savegame corrupted. (write %u, read %u)\n", wrote, (UINT32)(save_p-buf));
|
||||
LUA_UnArchive(&savebuffer);
|
||||
i = P_ReadUINT8(&savebuffer);
|
||||
if (i != 0x7F || wrote != (UINT32)(savebuffer.pos))
|
||||
CONS_Printf("Savegame corrupted. (write %u, read %u)\n", wrote, (UINT32)(savebuffer.pos));
|
||||
|
||||
// free buffer
|
||||
Z_Free(buf);
|
||||
free(savebuffer.buf);
|
||||
CONS_Printf("Done. No crash.\n");
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
|
|
@ -1033,7 +1033,6 @@ void FileSendTicker(void)
|
|||
|
||||
netbuffer->packettype = PT_FILEFRAGMENT;
|
||||
|
||||
// (((sendbytes-nowsentbyte)*TICRATE)/(I_GetTime()-starttime)<(UINT32)net_bandwidth)
|
||||
while (packetsent-- && filestosend != 0)
|
||||
{
|
||||
for (i = currentnode, j = 0; j < MAXNETNODES;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -54,30 +54,25 @@ boolean SV_ResendingSavegameToAnyone(void)
|
|||
void SV_SendSaveGame(INT32 node, boolean resending)
|
||||
{
|
||||
size_t length, compressedlen;
|
||||
UINT8 *savebuffer;
|
||||
save_t savebuffer;
|
||||
UINT8 *compressedsave;
|
||||
UINT8 *buffertosend;
|
||||
|
||||
// first save it in a malloced buffer
|
||||
savebuffer = (UINT8 *)malloc(SAVEGAMESIZE);
|
||||
if (!savebuffer)
|
||||
savebuffer.size = SAVEGAMESIZE;
|
||||
savebuffer.buf = (UINT8 *)malloc(savebuffer.size);
|
||||
if (!savebuffer.buf)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Leave room for the uncompressed length.
|
||||
save_p = savebuffer + sizeof(UINT32);
|
||||
savebuffer.pos = sizeof(UINT32);
|
||||
|
||||
P_SaveNetGame(resending);
|
||||
P_SaveNetGame(&savebuffer, resending);
|
||||
|
||||
length = save_p - savebuffer;
|
||||
if (length > SAVEGAMESIZE)
|
||||
{
|
||||
free(savebuffer);
|
||||
save_p = NULL;
|
||||
I_Error("Savegame buffer overrun");
|
||||
}
|
||||
length = savebuffer.pos;
|
||||
|
||||
// Allocate space for compressed save: one byte fewer than for the
|
||||
// uncompressed data to ensure that the compression is worthwhile.
|
||||
|
@ -85,15 +80,16 @@ void SV_SendSaveGame(INT32 node, boolean resending)
|
|||
if (!compressedsave)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
free(savebuffer.buf);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attempt to compress it.
|
||||
if((compressedlen = lzf_compress(savebuffer + sizeof(UINT32), length - sizeof(UINT32), compressedsave + sizeof(UINT32), length - sizeof(UINT32) - 1)))
|
||||
if((compressedlen = lzf_compress(savebuffer.buf + sizeof(UINT32), length - sizeof(UINT32), compressedsave + sizeof(UINT32), length - sizeof(UINT32) - 1)))
|
||||
{
|
||||
// Compressing succeeded; send compressed data
|
||||
|
||||
free(savebuffer);
|
||||
free(savebuffer.buf);
|
||||
|
||||
// State that we're compressed.
|
||||
buffertosend = compressedsave;
|
||||
|
@ -107,12 +103,12 @@ void SV_SendSaveGame(INT32 node, boolean resending)
|
|||
free(compressedsave);
|
||||
|
||||
// State that we're not compressed
|
||||
buffertosend = savebuffer;
|
||||
WRITEUINT32(savebuffer, 0);
|
||||
buffertosend = savebuffer.buf;
|
||||
savebuffer.pos = 0;
|
||||
P_WriteUINT32(&savebuffer, 0);
|
||||
}
|
||||
|
||||
AddRamToSendQueue(node, buffertosend, length, SF_RAM, 0);
|
||||
save_p = NULL;
|
||||
|
||||
// Remember when we started sending the savegame so we can handle timeouts
|
||||
netnodes[node].sendingsavegame = true;
|
||||
|
@ -125,8 +121,7 @@ static consvar_t cv_dumpconsistency = CVAR_INIT ("dumpconsistency", "Off", CV_SA
|
|||
|
||||
void SV_SavedGame(void)
|
||||
{
|
||||
size_t length;
|
||||
UINT8 *savebuffer;
|
||||
save_t savebuffer;
|
||||
char tmpsave[256];
|
||||
|
||||
if (!cv_dumpconsistency.value)
|
||||
|
@ -135,29 +130,22 @@ void SV_SavedGame(void)
|
|||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
// first save it in a malloced buffer
|
||||
save_p = savebuffer = (UINT8 *)malloc(SAVEGAMESIZE);
|
||||
if (!save_p)
|
||||
savebuffer.size = SAVEGAMESIZE;
|
||||
savebuffer.buf = (UINT8 *)malloc(savebuffer.size);
|
||||
if (!savebuffer.buf)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
return;
|
||||
}
|
||||
savebuffer.pos = 0;
|
||||
|
||||
P_SaveNetGame(false);
|
||||
|
||||
length = save_p - savebuffer;
|
||||
if (length > SAVEGAMESIZE)
|
||||
{
|
||||
free(savebuffer);
|
||||
save_p = NULL;
|
||||
I_Error("Savegame buffer overrun");
|
||||
}
|
||||
P_SaveNetGame(&savebuffer, false);
|
||||
|
||||
// then save it!
|
||||
if (!FIL_WriteFile(tmpsave, savebuffer, length))
|
||||
if (!FIL_WriteFile(tmpsave, savebuffer.buf, savebuffer.pos))
|
||||
CONS_Printf(M_GetText("Didn't save %s for netgame"), tmpsave);
|
||||
|
||||
free(savebuffer);
|
||||
save_p = NULL;
|
||||
free(savebuffer.pos);
|
||||
}
|
||||
|
||||
#undef TMPSAVENAME
|
||||
|
@ -167,33 +155,34 @@ void SV_SavedGame(void)
|
|||
|
||||
void CL_LoadReceivedSavegame(boolean reloading)
|
||||
{
|
||||
UINT8 *savebuffer = NULL;
|
||||
size_t length, decompressedlen;
|
||||
save_t savebuffer;
|
||||
size_t decompressedlen;
|
||||
char tmpsave[256];
|
||||
|
||||
FreeFileNeeded();
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
length = FIL_ReadFile(tmpsave, &savebuffer);
|
||||
savebuffer.size = FIL_ReadFile(tmpsave, &savebuffer.buf);
|
||||
savebuffer.pos = 0;
|
||||
|
||||
CONS_Printf(M_GetText("Loading savegame length %s\n"), sizeu1(length));
|
||||
if (!length)
|
||||
CONS_Printf(M_GetText("Loading savegame length %s\n"), sizeu1(savebuffer.size));
|
||||
if (!savebuffer.size)
|
||||
{
|
||||
I_Error("Can't read savegame sent");
|
||||
return;
|
||||
}
|
||||
|
||||
save_p = savebuffer;
|
||||
|
||||
// Decompress saved game if necessary.
|
||||
decompressedlen = READUINT32(save_p);
|
||||
decompressedlen = P_ReadUINT32(&savebuffer);
|
||||
if(decompressedlen > 0)
|
||||
{
|
||||
UINT8 *decompressedbuffer = Z_Malloc(decompressedlen, PU_STATIC, NULL);
|
||||
lzf_decompress(save_p, length - sizeof(UINT32), decompressedbuffer, decompressedlen);
|
||||
Z_Free(savebuffer);
|
||||
save_p = savebuffer = decompressedbuffer;
|
||||
lzf_decompress(savebuffer.buf + sizeof(UINT32), savebuffer.size - sizeof(UINT32), decompressedbuffer, decompressedlen);
|
||||
Z_Free(savebuffer.buf);
|
||||
savebuffer.buf = decompressedbuffer;
|
||||
savebuffer.size = decompressedlen;
|
||||
savebuffer.pos = 0;
|
||||
}
|
||||
|
||||
paused = false;
|
||||
|
@ -203,7 +192,7 @@ void CL_LoadReceivedSavegame(boolean reloading)
|
|||
automapactive = false;
|
||||
|
||||
// load a base level
|
||||
if (P_LoadNetGame(reloading))
|
||||
if (P_LoadNetGame(&savebuffer, reloading))
|
||||
{
|
||||
const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
|
||||
CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap));
|
||||
|
@ -219,8 +208,7 @@ void CL_LoadReceivedSavegame(boolean reloading)
|
|||
}
|
||||
|
||||
// done
|
||||
Z_Free(savebuffer);
|
||||
save_p = NULL;
|
||||
Z_Free(savebuffer.buf);
|
||||
if (unlink(tmpsave) == -1)
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
|
||||
consistancy[gametic%BACKUPTICS] = Consistancy();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -32,7 +32,6 @@
|
|||
#define INETPACKETLENGTH 1024
|
||||
|
||||
extern INT16 hardware_MAXPACKETLENGTH;
|
||||
extern INT32 net_bandwidth; // in byte/s
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
|
@ -40,36 +39,17 @@ extern INT32 net_bandwidth; // in byte/s
|
|||
|
||||
typedef struct
|
||||
{
|
||||
/// Supposed to be DOOMCOM_ID
|
||||
INT32 id;
|
||||
|
||||
/// SRB2 executes an INT32 to execute commands.
|
||||
INT16 intnum;
|
||||
/// Communication between SRB2 and the driver.
|
||||
/// Is CMD_SEND or CMD_GET.
|
||||
INT16 command;
|
||||
/// Is dest for send, set by get (-1 = no packet).
|
||||
INT16 remotenode;
|
||||
|
||||
/// Number of bytes in doomdata to be sent
|
||||
INT16 datalength;
|
||||
|
||||
/// Info common to all nodes.
|
||||
/// Console is always node 0.
|
||||
INT16 numnodes;
|
||||
/// Flag: 1 = no duplication, 2-5 = dup for slow nets.
|
||||
INT16 ticdup;
|
||||
/// Flag: 1 = send a backup tic in every packet.
|
||||
INT16 extratics;
|
||||
/// kind of game
|
||||
INT16 gametype;
|
||||
/// Flag: -1 = new game, 0-5 = load savegame
|
||||
INT16 savegame;
|
||||
/// currect map
|
||||
INT16 map;
|
||||
|
||||
/// Info specific to this node.
|
||||
INT16 consoleplayer;
|
||||
/// Number of "slots": the highest player number in use plus one.
|
||||
INT16 numslots;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -37,6 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../z_zone.h"
|
||||
|
||||
#ifdef USE_WINSOCK1
|
||||
#include <winsock.h>
|
||||
|
@ -87,6 +88,10 @@
|
|||
#undef EHOSTUNREACH
|
||||
#endif
|
||||
#define EHOSTUNREACH WSAEHOSTUNREACH
|
||||
#ifdef ENETUNREACH
|
||||
#undef ENETUNREACH
|
||||
#endif
|
||||
#define ENETUNREACH WSAENETUNREACH
|
||||
#ifndef IOC_VENDOR
|
||||
#define IOC_VENDOR 0x18000000
|
||||
#endif
|
||||
|
@ -120,8 +125,6 @@ typedef union
|
|||
static boolean UPNP_support = true;
|
||||
#endif // HAVE_MINIUPNC
|
||||
|
||||
#define MAXBANS 100
|
||||
|
||||
#include "../i_system.h"
|
||||
#include "i_net.h"
|
||||
#include "d_net.h"
|
||||
|
@ -169,8 +172,8 @@ static mysockaddr_t clientaddress[MAXNETNODES+1];
|
|||
static mysockaddr_t broadcastaddress[MAXNETNODES+1];
|
||||
static size_t broadcastaddresses = 0;
|
||||
static boolean nodeconnected[MAXNETNODES+1];
|
||||
static mysockaddr_t banned[MAXBANS];
|
||||
static UINT8 bannedmask[MAXBANS];
|
||||
static mysockaddr_t *banned;
|
||||
static UINT8 *bannedmask;
|
||||
|
||||
static size_t numbans = 0;
|
||||
static boolean SOCK_bannednode[MAXNETNODES+1]; /// \note do we really need the +1?
|
||||
|
@ -317,7 +320,11 @@ init_upnpc_once(struct upnpdata *upnpuserdata)
|
|||
I_OutputMsg(M_GetText("Found UPnP device:\n desc: %s\n st: %s\n"),
|
||||
dev->descURL, dev->st);
|
||||
|
||||
#if (MINIUPNPC_API_VERSION >= 18)
|
||||
UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr), NULL, 0);
|
||||
#else
|
||||
UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
|
||||
#endif
|
||||
I_OutputMsg(M_GetText("Local LAN IP address: %s\n"), lanaddr);
|
||||
descXML = miniwget(dev->descURL, &descXMLsize, scope_id, &status_code);
|
||||
if (descXML)
|
||||
|
@ -681,7 +688,6 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
|
|||
socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
socklen_t d, da = (socklen_t)sizeof(mysockaddr_t);
|
||||
ssize_t status;
|
||||
|
||||
switch (sockaddr->any.sa_family)
|
||||
{
|
||||
|
@ -692,14 +698,11 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
|
|||
default: d = da; break;
|
||||
}
|
||||
|
||||
status = sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d);
|
||||
if (status == -1)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Unable to send packet to %s: %s\n", SOCK_AddrToStr(sockaddr), strerror(errno));
|
||||
}
|
||||
return status;
|
||||
return sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d);
|
||||
}
|
||||
|
||||
#define ALLOWEDERROR(x) ((x) == ECONNREFUSED || (x) == EWOULDBLOCK || (x) == EHOSTUNREACH || (x) == ENETUNREACH)
|
||||
|
||||
static void SOCK_Send(void)
|
||||
{
|
||||
ssize_t c = ERRSOCKET;
|
||||
|
@ -714,19 +717,25 @@ static void SOCK_Send(void)
|
|||
for (size_t j = 0; j < broadcastaddresses; j++)
|
||||
{
|
||||
if (myfamily[i] == broadcastaddress[j].any.sa_family)
|
||||
SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
|
||||
{
|
||||
c = SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
|
||||
if (c == ERRSOCKET && !ALLOWEDERROR(errno))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (nodesocket[doomcom->remotenode] == (SOCKET_TYPE)ERRSOCKET)
|
||||
{
|
||||
for (size_t i = 0; i < mysocketses; i++)
|
||||
{
|
||||
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
|
||||
SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
|
||||
{
|
||||
c = SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
|
||||
if (c == ERRSOCKET && !ALLOWEDERROR(errno))
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -736,12 +745,14 @@ static void SOCK_Send(void)
|
|||
if (c == ERRSOCKET)
|
||||
{
|
||||
int e = errno; // save error code so it can't be modified later
|
||||
if (e != ECONNREFUSED && e != EWOULDBLOCK && e != EHOSTUNREACH)
|
||||
if (!ALLOWEDERROR(e))
|
||||
I_Error("SOCK_Send, error sending to node %d (%s) #%u: %s", doomcom->remotenode,
|
||||
SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e));
|
||||
}
|
||||
}
|
||||
|
||||
#undef ALLOWEDERROR
|
||||
|
||||
static void SOCK_FreeNodenum(INT32 numnode)
|
||||
{
|
||||
// can't disconnect from self :)
|
||||
|
@ -1256,9 +1267,9 @@ static boolean SOCK_Ban(INT32 node)
|
|||
{
|
||||
if (node > MAXNETNODES)
|
||||
return false;
|
||||
if (numbans == MAXBANS)
|
||||
return false;
|
||||
|
||||
banned = Z_Realloc(banned, sizeof(*banned) * (numbans+1), PU_STATIC, NULL);
|
||||
bannedmask = Z_Realloc(bannedmask, sizeof(*bannedmask) * (numbans+1), PU_STATIC, NULL);
|
||||
M_Memcpy(&banned[numbans], &clientaddress[node], sizeof (mysockaddr_t));
|
||||
if (banned[numbans].any.sa_family == AF_INET)
|
||||
{
|
||||
|
@ -1281,7 +1292,7 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask)
|
|||
struct my_addrinfo *ai, *runp, hints;
|
||||
int gaie;
|
||||
|
||||
if (numbans == MAXBANS || !address)
|
||||
if (!address)
|
||||
return false;
|
||||
|
||||
memset(&hints, 0x00, sizeof(hints));
|
||||
|
@ -1296,8 +1307,10 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask)
|
|||
|
||||
runp = ai;
|
||||
|
||||
while(runp != NULL && numbans != MAXBANS)
|
||||
while(runp != NULL)
|
||||
{
|
||||
banned = Z_Realloc(banned, sizeof(*banned) * (numbans+1), PU_STATIC, NULL);
|
||||
bannedmask = Z_Realloc(bannedmask, sizeof(*bannedmask) * (numbans+1), PU_STATIC, NULL);
|
||||
memcpy(&banned[numbans], runp->ai_addr, runp->ai_addrlen);
|
||||
|
||||
if (mask)
|
||||
|
@ -1327,6 +1340,10 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask)
|
|||
static void SOCK_ClearBans(void)
|
||||
{
|
||||
numbans = 0;
|
||||
Z_Free(banned);
|
||||
banned = NULL;
|
||||
Z_Free(bannedmask);
|
||||
bannedmask = NULL;
|
||||
}
|
||||
|
||||
boolean I_InitTcpNetwork(void)
|
||||
|
@ -1381,7 +1398,6 @@ boolean I_InitTcpNetwork(void)
|
|||
// FIXME:
|
||||
// ??? and now ?
|
||||
// server on a big modem ??? 4*isdn
|
||||
net_bandwidth = 16000;
|
||||
hardware_MAXPACKETLENGTH = INETPACKETLENGTH;
|
||||
|
||||
ret = true;
|
||||
|
@ -1410,7 +1426,6 @@ boolean I_InitTcpNetwork(void)
|
|||
// so we're on a LAN
|
||||
COM_BufAddText("connect any\n");
|
||||
|
||||
net_bandwidth = 800000;
|
||||
hardware_MAXPACKETLENGTH = MAXPACKETLENGTH;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
// Copyright (C) 2020-2023 by James R.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
|
@ -50,6 +50,8 @@ static void Command_Listserv_f(void);
|
|||
|
||||
#endif/*MASTERSERVER*/
|
||||
|
||||
static boolean ServerName_CanChange (const char*);
|
||||
|
||||
static void Update_parameters (void);
|
||||
|
||||
static void MasterServer_OnChange(void);
|
||||
|
@ -61,7 +63,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
|||
};
|
||||
|
||||
consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ds.ms.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange);
|
||||
consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters);
|
||||
consvar_t cv_servername = CVAR_INIT_WITH_CALLBACKS ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters, ServerName_CanChange);
|
||||
|
||||
consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters);
|
||||
|
||||
|
@ -497,6 +499,15 @@ Set_api (const char *api)
|
|||
|
||||
#endif/*MASTERSERVER*/
|
||||
|
||||
static boolean ServerName_CanChange(const char* newvalue)
|
||||
{
|
||||
if (strlen(newvalue) < MAXSERVERNAME)
|
||||
return true;
|
||||
|
||||
CONS_Alert(CONS_NOTICE, "The server name must be shorter than %d characters\n", MAXSERVERNAME);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
Update_parameters (void)
|
||||
{
|
||||
|
|
272
src/p_enemy.c
272
src/p_enemy.c
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -54,276 +54,6 @@ static dirtype_t diags[] =
|
|||
DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST
|
||||
};
|
||||
|
||||
//Real Prototypes to A_*
|
||||
void A_Fall(mobj_t *actor);
|
||||
void A_Look(mobj_t *actor);
|
||||
void A_Chase(mobj_t *actor);
|
||||
void A_FaceStabChase(mobj_t *actor);
|
||||
void A_FaceStabRev(mobj_t *actor);
|
||||
void A_FaceStabHurl(mobj_t *actor);
|
||||
void A_FaceStabMiss(mobj_t *actor);
|
||||
void A_StatueBurst(mobj_t *actor);
|
||||
void A_JetJawRoam(mobj_t *actor);
|
||||
void A_JetJawChomp(mobj_t *actor);
|
||||
void A_PointyThink(mobj_t *actor);
|
||||
void A_CheckBuddy(mobj_t *actor);
|
||||
void A_HoodFire(mobj_t *actor);
|
||||
void A_HoodThink(mobj_t *actor);
|
||||
void A_HoodFall(mobj_t *actor);
|
||||
void A_ArrowBonks(mobj_t *actor);
|
||||
void A_SnailerThink(mobj_t *actor);
|
||||
void A_SharpChase(mobj_t *actor);
|
||||
void A_SharpSpin(mobj_t *actor);
|
||||
void A_SharpDecel(mobj_t *actor);
|
||||
void A_CrushstaceanWalk(mobj_t *actor);
|
||||
void A_CrushstaceanPunch(mobj_t *actor);
|
||||
void A_CrushclawAim(mobj_t *actor);
|
||||
void A_CrushclawLaunch(mobj_t *actor);
|
||||
void A_VultureVtol(mobj_t *actor);
|
||||
void A_VultureCheck(mobj_t *actor);
|
||||
void A_VultureHover(mobj_t *actor);
|
||||
void A_VultureBlast(mobj_t *actor);
|
||||
void A_VultureFly(mobj_t *actor);
|
||||
void A_SkimChase(mobj_t *actor);
|
||||
void A_FaceTarget(mobj_t *actor);
|
||||
void A_FaceTracer(mobj_t *actor);
|
||||
void A_LobShot(mobj_t *actor);
|
||||
void A_FireShot(mobj_t *actor);
|
||||
void A_SuperFireShot(mobj_t *actor);
|
||||
void A_BossFireShot(mobj_t *actor);
|
||||
void A_Boss7FireMissiles(mobj_t *actor);
|
||||
void A_Boss1Laser(mobj_t *actor);
|
||||
void A_FocusTarget(mobj_t *actor);
|
||||
void A_Boss4Reverse(mobj_t *actor);
|
||||
void A_Boss4SpeedUp(mobj_t *actor);
|
||||
void A_Boss4Raise(mobj_t *actor);
|
||||
void A_SkullAttack(mobj_t *actor);
|
||||
void A_BossZoom(mobj_t *actor);
|
||||
void A_BossScream(mobj_t *actor);
|
||||
void A_Scream(mobj_t *actor);
|
||||
void A_Pain(mobj_t *actor);
|
||||
void A_1upThinker(mobj_t *actor);
|
||||
void A_MonitorPop(mobj_t *actor);
|
||||
void A_GoldMonitorPop(mobj_t *actor);
|
||||
void A_GoldMonitorRestore(mobj_t *actor);
|
||||
void A_GoldMonitorSparkle(mobj_t *actor);
|
||||
void A_Explode(mobj_t *actor);
|
||||
void A_BossDeath(mobj_t *actor);
|
||||
void A_SetShadowScale(mobj_t *actor);
|
||||
void A_ShadowScream(mobj_t *actor);
|
||||
void A_CustomPower(mobj_t *actor);
|
||||
void A_GiveWeapon(mobj_t *actor);
|
||||
void A_RingBox(mobj_t *actor);
|
||||
void A_Invincibility(mobj_t *actor);
|
||||
void A_SuperSneakers(mobj_t *actor);
|
||||
void A_AwardScore(mobj_t *actor);
|
||||
void A_ExtraLife(mobj_t *actor);
|
||||
void A_GiveShield(mobj_t *actor);
|
||||
void A_GravityBox(mobj_t *actor);
|
||||
void A_ScoreRise(mobj_t *actor);
|
||||
void A_BunnyHop(mobj_t *actor);
|
||||
void A_BubbleSpawn(mobj_t *actor);
|
||||
void A_FanBubbleSpawn(mobj_t *actor);
|
||||
void A_BubbleRise(mobj_t *actor);
|
||||
void A_BubbleCheck(mobj_t *actor);
|
||||
void A_AttractChase(mobj_t *actor);
|
||||
void A_DropMine(mobj_t *actor);
|
||||
void A_FishJump(mobj_t *actor);
|
||||
void A_ThrownRing(mobj_t *actor);
|
||||
void A_SetSolidSteam(mobj_t *actor);
|
||||
void A_UnsetSolidSteam(mobj_t *actor);
|
||||
void A_SignSpin(mobj_t *actor);
|
||||
void A_SignPlayer(mobj_t *actor);
|
||||
void A_OverlayThink(mobj_t *actor);
|
||||
void A_JetChase(mobj_t *actor);
|
||||
void A_JetbThink(mobj_t *actor);
|
||||
void A_JetgShoot(mobj_t *actor);
|
||||
void A_JetgThink(mobj_t *actor);
|
||||
void A_ShootBullet(mobj_t *actor);
|
||||
void A_MinusDigging(mobj_t *actor);
|
||||
void A_MinusPopup(mobj_t *actor);
|
||||
void A_MinusCheck(mobj_t *actor);
|
||||
void A_ChickenCheck(mobj_t *actor);
|
||||
void A_MouseThink(mobj_t *actor);
|
||||
void A_DetonChase(mobj_t *actor);
|
||||
void A_CapeChase(mobj_t *actor);
|
||||
void A_RotateSpikeBall(mobj_t *actor);
|
||||
void A_SlingAppear(mobj_t *actor);
|
||||
void A_UnidusBall(mobj_t *actor);
|
||||
void A_RockSpawn(mobj_t *actor);
|
||||
void A_SetFuse(mobj_t *actor);
|
||||
void A_CrawlaCommanderThink(mobj_t *actor);
|
||||
void A_RingExplode(mobj_t *actor);
|
||||
void A_OldRingExplode(mobj_t *actor);
|
||||
void A_MixUp(mobj_t *actor);
|
||||
void A_RecyclePowers(mobj_t *actor);
|
||||
void A_Boss2TakeDamage(mobj_t *actor);
|
||||
void A_Boss7Chase(mobj_t *actor);
|
||||
void A_GoopSplat(mobj_t *actor);
|
||||
void A_Boss2PogoSFX(mobj_t *actor);
|
||||
void A_Boss2PogoTarget(mobj_t *actor);
|
||||
void A_EggmanBox(mobj_t *actor);
|
||||
void A_TurretFire(mobj_t *actor);
|
||||
void A_SuperTurretFire(mobj_t *actor);
|
||||
void A_TurretStop(mobj_t *actor);
|
||||
void A_SparkFollow(mobj_t *actor);
|
||||
void A_BuzzFly(mobj_t *actor);
|
||||
void A_GuardChase(mobj_t *actor);
|
||||
void A_EggShield(mobj_t *actor);
|
||||
void A_SetReactionTime(mobj_t *actor);
|
||||
void A_Boss1Spikeballs(mobj_t *actor);
|
||||
void A_Boss3TakeDamage(mobj_t *actor);
|
||||
void A_Boss3Path(mobj_t *actor);
|
||||
void A_Boss3ShockThink(mobj_t *actor);
|
||||
void A_Shockwave(mobj_t *actor);
|
||||
void A_LinedefExecute(mobj_t *actor);
|
||||
void A_LinedefExecuteFromArg(mobj_t *actor);
|
||||
void A_PlaySeeSound(mobj_t *actor);
|
||||
void A_PlayAttackSound(mobj_t *actor);
|
||||
void A_PlayActiveSound(mobj_t *actor);
|
||||
void A_SmokeTrailer(mobj_t *actor);
|
||||
void A_SpawnObjectAbsolute(mobj_t *actor);
|
||||
void A_SpawnObjectRelative(mobj_t *actor);
|
||||
void A_ChangeAngleRelative(mobj_t *actor);
|
||||
void A_ChangeAngleAbsolute(mobj_t *actor);
|
||||
void A_RollAngle(mobj_t *actor);
|
||||
void A_ChangeRollAngleRelative(mobj_t *actor);
|
||||
void A_ChangeRollAngleAbsolute(mobj_t *actor);
|
||||
void A_PlaySound(mobj_t *actor);
|
||||
void A_FindTarget(mobj_t *actor);
|
||||
void A_FindTracer(mobj_t *actor);
|
||||
void A_SetTics(mobj_t *actor);
|
||||
void A_SetRandomTics(mobj_t *actor);
|
||||
void A_ChangeColorRelative(mobj_t *actor);
|
||||
void A_ChangeColorAbsolute(mobj_t *actor);
|
||||
void A_Dye(mobj_t *actor);
|
||||
void A_SetTranslation(mobj_t *actor);
|
||||
void A_MoveRelative(mobj_t *actor);
|
||||
void A_MoveAbsolute(mobj_t *actor);
|
||||
void A_Thrust(mobj_t *actor);
|
||||
void A_ZThrust(mobj_t *actor);
|
||||
void A_SetTargetsTarget(mobj_t *actor);
|
||||
void A_SetObjectFlags(mobj_t *actor);
|
||||
void A_SetObjectFlags2(mobj_t *actor);
|
||||
void A_RandomState(mobj_t *actor);
|
||||
void A_RandomStateRange(mobj_t *actor);
|
||||
void A_StateRangeByAngle(mobj_t *actor);
|
||||
void A_StateRangeByParameter(mobj_t *actor);
|
||||
void A_DualAction(mobj_t *actor);
|
||||
void A_RemoteAction(mobj_t *actor);
|
||||
void A_ToggleFlameJet(mobj_t *actor);
|
||||
void A_OrbitNights(mobj_t *actor);
|
||||
void A_GhostMe(mobj_t *actor);
|
||||
void A_SetObjectState(mobj_t *actor);
|
||||
void A_SetObjectTypeState(mobj_t *actor);
|
||||
void A_KnockBack(mobj_t *actor);
|
||||
void A_PushAway(mobj_t *actor);
|
||||
void A_RingDrain(mobj_t *actor);
|
||||
void A_SplitShot(mobj_t *actor);
|
||||
void A_MissileSplit(mobj_t *actor);
|
||||
void A_MultiShot(mobj_t *actor);
|
||||
void A_InstaLoop(mobj_t *actor);
|
||||
void A_Custom3DRotate(mobj_t *actor);
|
||||
void A_SearchForPlayers(mobj_t *actor);
|
||||
void A_CheckRandom(mobj_t *actor);
|
||||
void A_CheckTargetRings(mobj_t *actor);
|
||||
void A_CheckRings(mobj_t *actor);
|
||||
void A_CheckTotalRings(mobj_t *actor);
|
||||
void A_CheckHealth(mobj_t *actor);
|
||||
void A_CheckRange(mobj_t *actor);
|
||||
void A_CheckHeight(mobj_t *actor);
|
||||
void A_CheckTrueRange(mobj_t *actor);
|
||||
void A_CheckThingCount(mobj_t *actor);
|
||||
void A_CheckAmbush(mobj_t *actor);
|
||||
void A_CheckCustomValue(mobj_t *actor);
|
||||
void A_CheckCusValMemo(mobj_t *actor);
|
||||
void A_SetCustomValue(mobj_t *actor);
|
||||
void A_UseCusValMemo(mobj_t *actor);
|
||||
void A_RelayCustomValue(mobj_t *actor);
|
||||
void A_CusValAction(mobj_t *actor);
|
||||
void A_ForceStop(mobj_t *actor);
|
||||
void A_ForceWin(mobj_t *actor);
|
||||
void A_SpikeRetract(mobj_t *actor);
|
||||
void A_InfoState(mobj_t *actor);
|
||||
void A_Repeat(mobj_t *actor);
|
||||
void A_SetScale(mobj_t *actor);
|
||||
void A_RemoteDamage(mobj_t *actor);
|
||||
void A_HomingChase(mobj_t *actor);
|
||||
void A_TrapShot(mobj_t *actor);
|
||||
void A_Boss1Chase(mobj_t *actor);
|
||||
void A_Boss2Chase(mobj_t *actor);
|
||||
void A_Boss2Pogo(mobj_t *actor);
|
||||
void A_BossJetFume(mobj_t *actor);
|
||||
void A_VileTarget(mobj_t *actor);
|
||||
void A_VileAttack(mobj_t *actor);
|
||||
void A_VileFire(mobj_t *actor);
|
||||
void A_BrakChase(mobj_t *actor);
|
||||
void A_BrakFireShot(mobj_t *actor);
|
||||
void A_BrakLobShot(mobj_t *actor);
|
||||
void A_NapalmScatter(mobj_t *actor);
|
||||
void A_SpawnFreshCopy(mobj_t *actor);
|
||||
void A_FlickySpawn(mobj_t *actor);
|
||||
void A_FlickyCenter(mobj_t *actor);
|
||||
void A_FlickyAim(mobj_t *actor);
|
||||
void A_FlickyFly(mobj_t *actor);
|
||||
void A_FlickySoar(mobj_t *actor);
|
||||
void A_FlickyCoast(mobj_t *actor);
|
||||
void A_FlickyHop(mobj_t *actor);
|
||||
void A_FlickyFlounder(mobj_t *actor);
|
||||
void A_FlickyCheck(mobj_t *actor);
|
||||
void A_FlickyHeightCheck(mobj_t *actor);
|
||||
void A_FlickyFlutter(mobj_t *actor);
|
||||
void A_FlameParticle(mobj_t *actor);
|
||||
void A_FadeOverlay(mobj_t *actor);
|
||||
void A_Boss5Jump(mobj_t *actor);
|
||||
void A_LightBeamReset(mobj_t *actor);
|
||||
void A_MineExplode(mobj_t *actor);
|
||||
void A_MineRange(mobj_t *actor);
|
||||
void A_ConnectToGround(mobj_t *actor);
|
||||
void A_SpawnParticleRelative(mobj_t *actor);
|
||||
void A_MultiShotDist(mobj_t *actor);
|
||||
void A_WhoCaresIfYourSonIsABee(mobj_t *actor);
|
||||
void A_ParentTriesToSleep(mobj_t *actor);
|
||||
void A_CryingToMomma(mobj_t *actor);
|
||||
void A_CheckFlags2(mobj_t *actor);
|
||||
void A_Boss5FindWaypoint(mobj_t *actor);
|
||||
void A_DoNPCSkid(mobj_t *actor);
|
||||
void A_DoNPCPain(mobj_t *actor);
|
||||
void A_PrepareRepeat(mobj_t *actor);
|
||||
void A_Boss5ExtraRepeat(mobj_t *actor);
|
||||
void A_Boss5Calm(mobj_t *actor);
|
||||
void A_Boss5CheckOnGround(mobj_t *actor);
|
||||
void A_Boss5CheckFalling(mobj_t *actor);
|
||||
void A_Boss5PinchShot(mobj_t *actor);
|
||||
void A_Boss5MakeItRain(mobj_t *actor);
|
||||
void A_Boss5MakeJunk(mobj_t *actor);
|
||||
void A_LookForBetter(mobj_t *actor);
|
||||
void A_Boss5BombExplode(mobj_t *actor);
|
||||
void A_DustDevilThink(mobj_t *actor);
|
||||
void A_TNTExplode(mobj_t *actor);
|
||||
void A_DebrisRandom(mobj_t *actor);
|
||||
void A_TrainCameo(mobj_t *actor);
|
||||
void A_TrainCameo2(mobj_t *actor);
|
||||
void A_CanarivoreGas(mobj_t *actor);
|
||||
void A_KillSegments(mobj_t *actor);
|
||||
void A_SnapperSpawn(mobj_t *actor);
|
||||
void A_SnapperThinker(mobj_t *actor);
|
||||
void A_SaloonDoorSpawn(mobj_t *actor);
|
||||
void A_MinecartSparkThink(mobj_t *actor);
|
||||
void A_ModuloToState(mobj_t *actor);
|
||||
void A_LavafallRocks(mobj_t *actor);
|
||||
void A_LavafallLava(mobj_t *actor);
|
||||
void A_FallingLavaCheck(mobj_t *actor);
|
||||
void A_FireShrink(mobj_t *actor);
|
||||
void A_SpawnPterabytes(mobj_t *actor);
|
||||
void A_PterabyteHover(mobj_t *actor);
|
||||
void A_RolloutSpawn(mobj_t *actor);
|
||||
void A_RolloutRock(mobj_t *actor);
|
||||
void A_DragonbomberSpawn(mobj_t *actor);
|
||||
void A_DragonWing(mobj_t *actor);
|
||||
void A_DragonSegment(mobj_t *actor);
|
||||
void A_ChangeHeight(mobj_t *actor);
|
||||
|
||||
//for p_enemy.c
|
||||
|
||||
//
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||
// Copyright (C) 1999-2024 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
|
@ -3786,6 +3786,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
if (player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS damage handling
|
||||
{
|
||||
if (player->powers[pw_flashing])
|
||||
return false;
|
||||
if (!force)
|
||||
{
|
||||
if (source == target)
|
||||
|
@ -3803,6 +3805,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
if (G_IsSpecialStage(gamemap) && !(damagetype & DMG_DEATHMASK))
|
||||
{
|
||||
if (player->powers[pw_flashing])
|
||||
return false;
|
||||
if (LUA_HookMobjDamage(target, inflictor, source, damage, damagetype))
|
||||
return true;
|
||||
P_SpecialStageDamage(player, inflictor, source);
|
||||
return true;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue