Merge remote-tracking branch 'origin/master' into map-by-name

This commit is contained in:
James R 2019-04-21 23:13:58 -07:00
commit 51cb3c9008
106 changed files with 2648 additions and 1959 deletions

View file

@ -3,7 +3,7 @@ jobs:
build:
working_directory: /root/SRB2
docker:
- image: debian:jessie
- image: debian:stretch
environment:
CC: ccache gcc -m32
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
@ -36,14 +36,20 @@ jobs:
- v1-SRB2-APT
- run:
name: Install SDK
command: apt-get -qq -y install git build-essential nasm libpng12-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx
command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx openssh-client
- save_cache:
key: v1-SRB2-APT
paths:
- /var/cache/apt/archives
- checkout
- run:
name: Clean build
name: Compile without network support and BLUA
command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1 NO_LUA=1
- run:
name: wipe build
command: make -C src LINUX=1 cleandep
- run:
name: rebuild depend
command: make -C src LINUX=1 clean
- restore_cache:
keys:

View file

@ -26,6 +26,7 @@ matrix:
- p7zip-full
- gcc-4.4
compiler: gcc-4.4
env: GCC44=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
- os: linux
@ -39,6 +40,7 @@ matrix:
- p7zip-full
- gcc-4.6
compiler: gcc-4.6
env: GCC46=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
- os: linux
@ -52,10 +54,12 @@ matrix:
- p7zip-full
- gcc-4.7
compiler: gcc-4.7
env: GCC47=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.7
- os: linux
compiler: gcc
env: GCC48=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
- os: linux
@ -71,6 +75,7 @@ matrix:
- p7zip-full
- gcc-4.8
compiler: gcc-4.8
env: GCC48=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
- os: linux
@ -86,7 +91,7 @@ matrix:
- p7zip-full
- gcc-7
compiler: gcc-7
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough"
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough" GCC72=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802
- os: linux
@ -102,7 +107,7 @@ matrix:
- p7zip-full
- gcc-8
compiler: gcc-8
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow"
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow" GCC81=1
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0
- os: linux
@ -249,17 +254,21 @@ matrix:
# osx_image: xcode7.2
# if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
# #Apple LLVM version 7.0.2 (clang-700.1.81)
# - os: osx
# osx_image: xcode7.3
# #Apple LLVM version 7.3.0 (clang-703.0.31)
# - os: osx
# osx_image: xcode7.3
# #Apple LLVM version 7.3.0 (clang-703.0.31)
- os: osx
osx_image: xcode7.3
if: env(DPL_ENABLED) != "1" OR env(DPL_TERMINATE_TESTS) != "1" OR NOT branch =~ /^.*deployer.*$/
#Apple LLVM version 7.3.0 (clang-703.0.31)
#Default: macOS 10.13 and Xcode 9.4.1
################################
# Deployer Buildbots - OSX
################################
- os: osx
osx_image: xcode7.3
if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1")
AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1"))
AND env(DPL_TERMINATE_MAIN) != "1"
@ -559,6 +568,16 @@ addons:
- libgme-dev
- zlib1g-dev
- p7zip-full
homebrew:
taps:
- mazmazz/srb2
packages:
- sdl2_mixer
- game-music-emu
- p7zip
- cmake
update: true
before_install:
@ -591,18 +610,10 @@ install:
# * `sdl2_mixer` requires options from the formula tap https://github.com/mazmazz/homebrew-srb2
# * `brew postinstall` runs post-install scripts after building a bottle
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
brew update;
brew tap mazmazz/srb2;
fi;
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
if [[ "$__DPL_ACTIVE" != "1" ]]; then
brew install sdl2 sdl2_mixer game-music-emu p7zip;
brew install cmake||true;
else
brew install --build-bottle sdl2 game-music-emu p7zip;
if [[ "$__DPL_ACTIVE" == "1" ]]; then
brew install --build-bottle sdl2 game-music-emu;
brew install --build-bottle mazmazz/srb2/sdl2_mixer --with-flac --with-mpg123;
brew postinstall sdl2 game-music-emu p7zip mazmazz/srb2/sdl2_mixer;
brew install cmake||true;
brew postinstall sdl2 game-music-emu mazmazz/srb2/sdl2_mixer;
fi;
fi
- mkdir -p $HOME/srb2_cache
@ -667,7 +678,6 @@ before_script:
-DCPACK_PACKAGE_VENDOR="${PROGRAM_VENDOR}"
-DSRB2_SDL2_EXE_NAME="${PROGRAM_FILENAME}"
script:
# Build our Makefile from Cmake!
- if [[ "$__DPL_ACTIVE" == "1" ]]; then

View file

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
# Version change is fine.
project(SRB2
VERSION 1.0.2
VERSION 1.0.4
LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
@ -56,13 +56,19 @@ macro(copy_files_to_build_dir target dlllist_var)
endif()
endmacro()
# 64-bit check
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
# bitness check
set(SRB2_SYSTEM_BITS 0)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
message(STATUS "Target is 64-bit")
set(SRB2_SYSTEM_BITS 64)
else()
endif()
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
message(STATUS "Target is 32-bit")
set(SRB2_SYSTEM_BITS 32)
endif()
if(${SRB2_SYSTEM_BITS} EQUAL 0)
message(STATUS "Target bitness is unknown")
endif()
# OS macros
if (UNIX)

View file

@ -1,4 +1,4 @@
version: 1.0.2.{branch}-{build}
version: 1.0.4.{branch}-{build}
os: MinGW
environment:
@ -29,7 +29,7 @@ environment:
##############################
DPL_ENABLED: 0
DPL_TAG_ENABLED: 0
DPL_INSTALLER_NAME: srb2kart-v102
DPL_INSTALLER_NAME: srb2kart-v104
# Asset handling is barebones vs. Travis Deployer. We operate on 7z only.
# Include the README files and the OpenGL batch in the main and patch archives.
# The x86/x64 archives contain the DLL binaries.

Binary file not shown.

Binary file not shown.

View file

@ -4,7 +4,7 @@ project(libgme)
include (CheckCXXCompilerFlag)
# When version is changed, also change the one in gme/gme.h to match
set(GME_VERSION 0.6.0 CACHE INTERNAL "libgme Version")
set(GME_VERSION 0.6.2 CACHE INTERNAL "libgme Version")
# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't.
# Of course, 2.4 might work, in which case you're welcome to drop
@ -57,6 +57,8 @@ if (USE_GME_NSFE AND NOT USE_GME_NSF)
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
endif()
option(BUILD_SHARED_LIBS "Build shared library (set to OFF for static library)" ON)
# Check for GCC "visibility" support.
if (CMAKE_COMPILER_IS_GNUCXX)
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
@ -79,10 +81,10 @@ if (CMAKE_COMPILER_IS_GNUCXX)
endif()
endif()
endif() # test visibility
endif (CMAKE_COMPILER_IS_GNUCXX)
# Cache this result
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
# Cache this result
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
endif (CMAKE_COMPILER_IS_GNUCXX)
# Shared library defined here
add_subdirectory(gme)

View file

@ -1,262 +1,5 @@
Game_Music_Emu Change Log
-------------------------
Game_Music_Emu 0.6.0
--------------------
- Note: A 0.5.6 release was referenced but never tagged or packaged.
- SPC improvements:
- Switched to newer snes_spc 0.9.0 for SPC emulation. Uses fast DSP.
- Fixed Spc_Emu::gain().
- Fixed support for files <0x10200 bytes.
- Other bugfixes:
- Fixed a couple of GBS bugs, one involving access of memory after
realloc.
- Blip_Buffer works on systems where 'double' is a single-precision
floating-point type.
- Fix uninitialized buffer size in dual_resampler.
- Compilation warnings squashed out as of clang 3.3-pre and gcc 4.7.2.
- API changes/additions:
- Removed documentation of C++ interface, as the C interface in gme.h is
the only supported one.
- Added gme_enable_accuracy() for enabling more accurate sound emulation
options (currently affects SPC only).
- Build system improvements:
- Add pkg_config support.
- Fix build on case-insensitive systems.
- Allow for install on Cygwin.
- Fix install on multilib systems, such as many 64-bit distros (CMake must
be able to figure out your system's libsuffix, if any).
- C++ implementation symbols are not leaked into the resultant library
file (requires symbol visibility support).
- Sample player improvements:
- Can toggle fast/accurate emulation (with the 'A' key).
Game_Music_Emu 0.5.5
--------------------
- CMake build support has been added. You can build Game_Music_Emu as
a shared library and install it so that you do not have to include your
own copy if you know libgme will be present on your target system.
Requires CMake 2.6 or higher.
Game_Music_Emu 0.5.2
--------------------
- *TONS* of changes and improvements. You should re-read the new header
files and documentation as the changes will allow you to simplify your
code a lot (it might even be simpler to just rewrite it). Existing code
should continue to work without changes in most cases (see Deprecated
features in gme.txt).
- New file formats: AY, HES, KSS, SAP, NSFE
- All-new comprehensive C interface (also usable from C++). Simplifies
many things, especially file loading, and brings everything together in
one header file (gme.h).
- Information tags and track names and times can be accessed for all
game music formats
- New features supported by all emulators: end of track fading,
automatic silence detection, adjustable song tempo, seek to new time in
track
- Updated mini player example to support track names and times, echo,
tempo, and channel muting, and added visual waveform display
- Improved configuration to use blargg_config.h, which you can modify
and keep when you update to a newer libary version. Includes flag for
library to automatically handle gzipped files using zlib (so you don't
need to use Gzip_File_Reader anymore).
- GBS: Fixed wave channel to not reset waveform when APU is powered off
(affected Garfield). Also improved invalid bank selection (affected Game
& Watch and others).
- VGM: Added support for alternate noise shifter register
configurations, used by other systems like the BBC Micro.
- SPC: Removed IPL ROM dump from emulator, as none of the SPC files I
scanned needed it, and an SPC file can include a copy if necessary. Also
re-enabled supposed clamping in gaussian interpolation between the third
and fourth lookups, though I don't know whether it matters
- Added Music_Emu::load_mem() to use music data already in memory
(without copying it)
- Added Music_Emu::warning(), which reports minor problems when loading
and playing a music file
- Added Music_Emu::set_gain() for uniform adjustment of gain. Can only
be set during initialization, so not useful as a general volume control.
- Added custom operator new to ensure that no exceptions are thrown in
the library (I'd use std::nothrow if it were part of pre-ISO (ARM) C++)
- Added BLIP_BUFFER_FAST flag to blargg_config.h to use a lower quality
bandlimited synthesis in "classic" emulators, which might help
performance on ancient processors (measure first!). Don't use this
unless absolutely necessary, as quality suffers.
- Improved performance a bit for x86 platforms
- Text files now in DOS newline format so they will open in Notepad
properly
- Removed requirement that file header structures not have any padding
added to the end
- Fixed common bug in all CPU emulators where negative program counter
could crash emulator (occurred during a negative branch from the
beginning of memory). Also fixed related bug in Z80 emulator for
IX/IY+displacement mode.
- Eliminated all warnings when compiling on gcc 4.0. The following
generates no diagnostics:
gcc -S gme/*.cpp -o /dev/null -ansi -fno-gnu-keywords
-fno-nonansi-builtins -pedantic -W -Wabi -Wall -Wcast-align
-Wcast-qual -Wchar-subscripts -Wdisabled-optimization -Werror
-Winline -Wlong-long -Wmultichar -Winvalid-offsetof
-Wnon-virtual-dtor -Woverloaded-virtual -Wparentheses
-Wpointer-arith -Wredundant-decls -Wreorder -Wsign-compare
-Wsign-promo -Wunknown-pragmas -Wwrite-strings
Game_Music_Emu 0.3.0
--------------------
- Added more demos, including music player using the SDL multimedia
library for sound, and improved documentation
- All: Improved interface to emulators to allow simpler setup and
loading. Instead of various init() functions, all now support
set_sample_rate( long rate ) and load( const char* file_path ).
- All: Removed error return from start_track() and play(), and added
error_count() to get the total number of emulation errors since the
track was last started. See demos for examples of new usage.
- All: Fixed mute_voices() muting to be preserved after loading files
and starting tracks, instead of being cleared as it was whenever a track
was started
- VGM: Rewrote Vgm_Emu to support Sega Genesis/Mega Drive FM sound at
any sample rate with optional FM oversampling, support for alternate
YM2612 sound cores, and support for optional YM2413
- VGM: Added tempo control, useful for slowing 60Hz NTSC Sega Genesis
music to 50Hz PAL
- VGM: Removed Vgm_Emu::track_data(), since I realized that this
information is already present in the VGM header (oops!)
- GYM: Changed Gym_Emu::track_length() operation (see Gym_Emu.h)
- NSF: Added support for Sunsoft FME-7 sound chip used by Gimmick
soundtrack
- NSF: Fixed Namco 106 problems with Final Lap and others
- Moved library sources to gme/ directory to reduce clutter, and merged
boost/ functionality into blargg_common.h
- Added Gzip_File_Reader for transparently using gzipped files
Game_Music_Emu 0.2.4
--------------------
- Created a discussion forum for problems and feedback:
http://groups-beta.google.com/group/blargg-sound-libs
- Changed error return value of Blip_Buffer::sample_rate() (also for
Stereo_Buffer, Effects_Buffer, etc.) to blargg_err_t (defined in
blargg_common.h), to make error reporting consistent with other
functions. This means the "no error" return value is the opposite of
what it was before, which will break current code which checks the error
return value:
// current code (broken)
if ( !buf.sample_rate( samples_per_sec ) )
out_of_memory();
// quick-and-dirty fix (just remove the ! operation)
if ( buf.sample_rate( samples_per_sec ) )
out_of_memory();
// proper fix
blargg_err_t error = buf.sample_rate( samples_per_sec );
if ( error )
report_error( error );
- Implemented workaround for MSVC++ 6 compiler limitations, allowing it
to work on that compiler again
- Added sample clamping to avoid wrap-around at high volumes, allowing
higher volume with little distortion
- Added to-do list and design notes
- Added Music_Emu::skip( long sample_count ) to skip ahead in current
track
- Added Gym_Emu::track_length() and Vgm_Emu::track_length() for
determining the length of non-looped GYM and VGM files
- Partially implemented DMC non-linearity when its value is directly set
using $4011, which reduces previously over-emphasized "popping" of
percussion on some games (TMNT II in particular)
- Fixed Fir_Resampler, used for SPC and GYM playback (was incorrectly
using abs() instead of fabs()...argh)
- Fixed SPC emulation bugs: eliminated clicks in Plok! soundtrack and
now stops sample slightly earlier than the end, as the SNES does. Fixed
a totally broken CPU addressing mode.
- Fixed Konami VRC6 saw wave (was very broken before). Now VRC6 music
sounds decent
- Fixed a minor GBS emulation bug
- Fixed GYM loop point bug when track was restarted before loop point
had been reached
- Made default GBS frequency equalization less muffled
- Added pseudo-surround effect removal for SPC files
- Added Music_Emu::voice_names() which returns names for each voice.
- Added BLARGG_SOURCE_BEGIN which allows custom compiler options to be
easily set for library sources
- Changed assignment of expansion sound chips in Nsf_Emu to be spread
more evenly when using Effects_Buffer
- Changed 'size_t' values in Blip_Buffer interface to 'long'
- Changed demo to generate a WAVE sound file rather than an AIFF file
Game_Music_Emu 0.2.0
--------------------
- Redid framework and rewrote/cleaned up emulators
- Changed licensing to GNU Lesser General Public License (LGPL)
- Added Sega Genesis GYM and Super Nintendo SPC emulators
- Added Namco-106 and Konami VRC6 sound chip support to NSF emulator
- Eliminated use of static mutable data in emulators, allowing
multi-instance safety
Game_Music_Emu 0.1.0
--------------------
- First release
Please see the git version history (e.g. git shortlog tags/0.6.0..tags/0.6.1)
for the accurate change log.

View file

@ -1,7 +1,5 @@
/* C example that opens a game music file and records 10 seconds to "out.wav" */
static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
#include "gme/gme.h"
#include "Wave_Writer.h" /* wave_ functions for writing sound file */
@ -10,10 +8,15 @@ static char filename [] = "test.nsf"; /* opens this file (can be any music type)
void handle_error( const char* str );
int main()
int main(int argc, char *argv[])
{
const char *filename = "test.nsf"; /* Default file to open */
if ( argc >= 2 )
filename = argv[1];
long sample_rate = 44100; /* number of samples per second */
int track = 0; /* index of track to play (0 = first) */
/* index of track to play (0 = first) */
int track = argc >= 3 ? atoi(argv[2]) : 0;
/* Open music file in new emulator */
Music_Emu* emu;

View file

@ -1,7 +1,5 @@
// C++ example that opens a game music file and records 10 seconds to "out.wav"
static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
#include "gme/Music_Emu.h"
#include "Wave_Writer.h"
@ -10,10 +8,15 @@ static char filename [] = "test.nsf"; /* opens this file (can be any music type)
void handle_error( const char* str );
int main()
int main(int argc, char *argv[])
{
const char *filename = "test.nsf"; /* Default file to open */
if ( argc >= 2 )
filename = argv[1];
long sample_rate = 44100; // number of samples per second
int track = 0; // index of track to play (0 = first)
// index of track to play (0 = first)
int track = argc >= 3 ? atoi(argv[2]) : 0;
// Determine file type
gme_type_t file_type;

View file

@ -1,10 +1,10 @@
Game_Music_Emu 0.6.0
Game_Music_Emu 0.6.2
--------------------
Author : Shay Green <gblargg@gmail.com>
Website: http://www.slack.net/~ant/libs/
Forum : http://groups.google.com/group/blargg-sound-libs
Source : https://code.google.com/p/game-music-emu/
License: GNU Lesser General Public License (LGPL)
Author : Shay Green <gblargg@gmail.com>
Maintainer : Michael Pyne <mpyne@purinchu.net>
Website : https://bitbucket.org/mpyne/game-music-emu/
Source : https://bitbucket.org/mpyne/game-music-emu/
License : GNU Lesser General Public License (LGPL), see LICENSE.txt
Contents
--------

View file

@ -143,7 +143,7 @@ add_definitions(-DBLARGG_BUILD_DLL)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Add library to be compiled.
add_library(gme SHARED ${libgme_SRCS})
add_library(gme ${libgme_SRCS})
# The version is the release. The "soversion" is the API version. As long
# as only build fixes are performed (i.e. no backwards-incompatible changes
@ -159,4 +159,4 @@ install(TARGETS gme LIBRARY DESTINATION lib${LIB_SUFFIX}
ARCHIVE DESTINATION lib) # DLL platforms
install(FILES ${EXPORTED_HEADERS} DESTINATION include/gme)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib/pkgconfig)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig)

View file

@ -22,8 +22,13 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
const char Data_Reader::eof_error [] = "Unexpected end of file";
#define RETURN_VALIDITY_CHECK( cond ) \
do { if ( unlikely( !(cond) ) ) return "Corrupt file"; } while(0)
blargg_err_t Data_Reader::read( void* p, long s )
{
RETURN_VALIDITY_CHECK( s > 0 );
long result = read_avail( p, s );
if ( result != s )
{
@ -38,6 +43,8 @@ blargg_err_t Data_Reader::read( void* p, long s )
blargg_err_t Data_Reader::skip( long count )
{
RETURN_VALIDITY_CHECK( count >= 0 );
char buf [512];
while ( count )
{
@ -54,7 +61,8 @@ long File_Reader::remain() const { return size() - tell(); }
blargg_err_t File_Reader::skip( long n )
{
assert( n >= 0 );
RETURN_VALIDITY_CHECK( n >= 0 );
if ( !n )
return 0;
return seek( tell() + n );
@ -67,13 +75,14 @@ Subset_Reader::Subset_Reader( Data_Reader* dr, long size )
in = dr;
remain_ = dr->remain();
if ( remain_ > size )
remain_ = size;
remain_ = max( 0l, size );
}
long Subset_Reader::remain() const { return remain_; }
long Subset_Reader::read_avail( void* p, long s )
{
s = max( 0l, s );
if ( s > remain_ )
s = remain_;
remain_ -= s;
@ -85,7 +94,7 @@ long Subset_Reader::read_avail( void* p, long s )
Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
{
header = (char const*) h;
header_end = header + size;
header_end = header + max( 0l, size );
in = r;
}
@ -93,6 +102,7 @@ long Remaining_Reader::remain() const { return header_end - header + in->remain(
long Remaining_Reader::read_first( void* out, long count )
{
count = max( 0l, count );
long first = header_end - header;
if ( first )
{
@ -107,8 +117,9 @@ long Remaining_Reader::read_first( void* out, long count )
long Remaining_Reader::read_avail( void* out, long count )
{
count = max( 0l, count );
long first = read_first( out, count );
long second = count - first;
long second = max( 0l, count - first );
if ( second )
{
second = in->read_avail( (char*) out + first, second );
@ -120,8 +131,9 @@ long Remaining_Reader::read_avail( void* out, long count )
blargg_err_t Remaining_Reader::read( void* out, long count )
{
count = max( 0l, count );
long first = read_first( out, count );
long second = count - first;
long second = max( 0l, count - first );
if ( !second )
return 0;
return in->read( (char*) out + first, second );
@ -131,7 +143,7 @@ blargg_err_t Remaining_Reader::read( void* out, long count )
Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
begin( (const char*) p ),
size_( s )
size_( max( 0l, s ) )
{
pos = 0;
}
@ -141,6 +153,7 @@ long Mem_File_Reader::size() const { return size_; }
long Mem_File_Reader::read_avail( void* p, long s )
{
long r = remain();
s = max( 0l, s );
if ( s > r )
s = r;
memcpy( p, begin + pos, s );
@ -152,6 +165,7 @@ long Mem_File_Reader::tell() const { return pos; }
blargg_err_t Mem_File_Reader::seek( long n )
{
RETURN_VALIDITY_CHECK( n >= 0 );
if ( n > size_ )
return eof_error;
pos = n;
@ -164,7 +178,7 @@ Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) :
callback( c ),
data( d )
{
remain_ = size;
remain_ = max( 0l, size );
}
long Callback_Reader::remain() const { return remain_; }
@ -173,13 +187,14 @@ long Callback_Reader::read_avail( void* out, long count )
{
if ( count > remain_ )
count = remain_;
if ( Callback_Reader::read( out, count ) )
if ( count < 0 || Callback_Reader::read( out, count ) )
count = -1;
return count;
}
blargg_err_t Callback_Reader::read( void* out, long count )
{
RETURN_VALIDITY_CHECK( count >= 0 );
if ( count > remain_ )
return eof_error;
return callback( data, out, count );
@ -210,11 +225,12 @@ long Std_File_Reader::size() const
long Std_File_Reader::read_avail( void* p, long s )
{
return fread( p, 1, s, (FILE*) file_ );
return fread( p, 1, max( 0l, s ), (FILE*) file_ );
}
blargg_err_t Std_File_Reader::read( void* p, long s )
{
RETURN_VALIDITY_CHECK( s > 0 );
if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
return 0;
if ( feof( (FILE*) file_ ) )

View file

@ -129,6 +129,8 @@ private:
};
#ifdef HAVE_ZLIB_H
#include <zlib.h>
// Gzip compressed file reader
class Gzip_File_Reader : public File_Reader {
public:
@ -143,7 +145,7 @@ public:
long tell() const;
blargg_err_t seek( long );
private:
void* file_;
gzFile file_;
long size_;
};
#endif

View file

@ -178,6 +178,11 @@ blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
}
long Music_Emu::tell_samples() const
{
return out_time;
}
long Music_Emu::tell() const
{
blargg_long rate = sample_rate() * stereo;
@ -185,14 +190,18 @@ long Music_Emu::tell() const
return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
}
blargg_err_t Music_Emu::seek( long msec )
blargg_err_t Music_Emu::seek_samples( long time )
{
blargg_long time = msec_to_samples( msec );
if ( time < out_time )
RETURN_ERR( start_track( current_track_ ) );
return skip( time - out_time );
}
blargg_err_t Music_Emu::seek( long msec )
{
return seek_samples( msec_to_samples( msec ) );
}
blargg_err_t Music_Emu::skip( long count )
{
require( current_track() >= 0 ); // start_track() must have been called already

View file

@ -41,9 +41,15 @@ public:
// Number of milliseconds (1000 msec = 1 second) played since beginning of track
long tell() const;
// Number of samples generated since beginning of track
long tell_samples() const;
// Seek to new time in track. Seeking backwards or far forward can take a while.
blargg_err_t seek( long msec );
// Equivalent to restarting track then skipping n samples
blargg_err_t seek_samples( long n );
// Skip n samples
blargg_err_t skip( long n );

View file

@ -134,6 +134,9 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu )
RETURN_ERR( in.read( block_header, sizeof block_header ) );
blargg_long size = get_le32( block_header [0] );
blargg_long tag = get_le32( block_header [1] );
if ( size <= 0 )
return "Corrupt file";
//debug_printf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) );

View file

@ -433,9 +433,7 @@ void Snes_Spc::cpu_write( int data, int addr, rel_time_t time )
#endif
// Registers other than $F2 and $F4-$F7
//if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 )
// TODO: this is a bit on the fragile side
if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36%
if ( reg != 2 && (reg < 4 || reg > 7) ) // 36%
cpu_write_smp_reg( data, time, reg );
}
// High mem/address wrap-around

View file

@ -76,8 +76,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
// TODO: remove non-wrapping versions?
#define SPC_NO_SP_WRAPAROUND 0
#define SET_SP( v ) (sp = ram + 0x101 + (v))
#define GET_SP() (sp - 0x101 - ram)
#define SET_SP( v ) (sp = ram + 0x101 + ((uint8_t) v))
#define GET_SP() (uint8_t (sp - 0x101 - ram))
#if SPC_NO_SP_WRAPAROUND
#define PUSH16( v ) (sp -= 2, SET_LE16( sp, v ))
@ -485,7 +485,7 @@ loop:
case 0xAF: // MOV (X)+,A
WRITE_DP( 0, x, a + no_read_before_write );
x++;
x = (uint8_t) (x + 1);
goto loop;
// 5. 8-BIT LOGIC OPERATION COMMANDS
@ -808,7 +808,7 @@ loop:
unsigned temp = y * a;
a = (uint8_t) temp;
nz = ((temp >> 1) | temp) & 0x7F;
y = temp >> 8;
y = (uint8_t) (temp >> 8);
nz |= y;
goto loop;
}
@ -838,6 +838,7 @@ loop:
nz = (uint8_t) a;
a = (uint8_t) a;
y = (uint8_t) y;
goto loop;
}
@ -1004,7 +1005,7 @@ loop:
case 0x7F: // RET1
temp = *sp;
SET_PC( GET_LE16( sp + 1 ) );
sp += 3;
SET_SP( GET_SP() + 3 );
goto set_psw;
case 0x8E: // POP PSW
POP( temp );

View file

@ -18,6 +18,19 @@ all other #include lines. */
#undef require
#define require( expr ) assert( expr )
// Use to provide hints to compiler for optimized code layout in situations where we
// can almost always expect a conditional to go one way or the other. Should only be
// used in situations where an unexpected branch is truly exceptional though!
#undef likely
#undef unlikely
#ifdef __GNUC__
#define likely( x ) __builtin_expect(x, 1)
#define unlikely( x ) __builtin_expect(x, 0)
#else
#define likely( x ) (x)
#define unlikely( x ) (x)
#endif
// Like printf() except output goes to debug log file. Might be defined to do
// nothing (not even evaluate its arguments).
// void debug_printf( const char* format, ... );

View file

@ -337,7 +337,9 @@ BLARGG_EXPORT gme_err_t gme_play ( Music_Emu* me, int n, short* p )
BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
BLARGG_EXPORT int gme_tell_samples ( Music_Emu const* me ) { return me->tell_samples(); }
BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
BLARGG_EXPORT gme_err_t gme_seek_samples ( Music_Emu* me, int n ) { return me->seek_samples( n ); }
BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }

View file

@ -1,6 +1,6 @@
/* Game music emulator library C interface (also usable from C++) */
/* Game_Music_Emu 0.6.0 */
/* Game_Music_Emu 0.6.1 */
#ifndef GME_H
#define GME_H
@ -8,7 +8,7 @@
extern "C" {
#endif
#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */
#define GME_VERSION 0x000601 /* 1 byte major, 1 byte minor, 1 byte patch-level */
/* Error string returned by library functions, or NULL if no error (success) */
typedef const char* gme_err_t;
@ -47,9 +47,15 @@ int gme_track_ended( Music_Emu const* );
/* Number of milliseconds (1000 = one second) played since beginning of track */
int gme_tell( Music_Emu const* );
/* Number of samples generated since beginning of track */
int gme_tell_samples( Music_Emu const* );
/* Seek to new time in track. Seeking backwards or far forward can take a while. */
gme_err_t gme_seek( Music_Emu*, int msec );
/* Equivalent to restarting track then skipping n samples */
gme_err_t gme_seek_samples( Music_Emu*, int n );
/******** Informational ********/

View file

@ -3,7 +3,7 @@
# later are used by pkg-config.
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
lib_suffix=
lib_suffix=@LIB_SUFFIX@
libdir=${exec_prefix}/lib${lib_suffix}
includedir=${prefix}/include
@ -13,3 +13,4 @@ URL: http://code.google.com/p/game-music-emu/
Version: @GME_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lgme
Libs.private: -lstdc++

View file

@ -1,6 +1,6 @@
/* Game music emulator library C interface (also usable from C++) */
/* Game_Music_Emu 0.6.0 */
/* Game_Music_Emu 0.6.1 */
#ifndef GME_H
#define GME_H
@ -8,7 +8,7 @@
extern "C" {
#endif
#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */
#define GME_VERSION 0x000601 /* 1 byte major, 1 byte minor, 1 byte patch-level */
/* Error string returned by library functions, or NULL if no error (success) */
typedef const char* gme_err_t;
@ -47,9 +47,15 @@ int gme_track_ended( Music_Emu const* );
/* Number of milliseconds (1000 = one second) played since beginning of track */
int gme_tell( Music_Emu const* );
/* Number of samples generated since beginning of track */
int gme_tell_samples( Music_Emu const* );
/* Seek to new time in track. Seeking backwards or far forward can take a while. */
gme_err_t gme_seek( Music_Emu*, int msec );
/* Equivalent to restarting track then skipping n samples */
gme_err_t gme_seek_samples( Music_Emu*, int n );
/******** Informational ********/

View file

@ -1,4 +1,4 @@
Game_Music_Emu 0.6.0: Game Music Emulators
Game_Music_Emu 0.6.2: Game Music Emulators
------------------------------------------
Game_Music_Emu is a collection of video game music file emulators that
support the following formats and systems:
@ -34,30 +34,45 @@ several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
GP2X, and Nintendo DS.
Author : Shay Green <gblargg@gmail.com>
Website: http://www.slack.net/~ant/
Forum : http://groups.google.com/group/blargg-sound-libs
Website: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
License: GNU Lesser General Public License (LGPL)
Current Maintainer: Michael Pyne <mpyne@purinchu.net>
Getting Started
---------------
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
all source files in gme/. If you have CMake 2.6 or later, execute
all source files in gme/.
run cmake
cd demo
run make
Or, if you have CMake 2.6 or later, execute at a command prompt (from the
extracted source directory):
Be sure "test.nsf" is in the same directory as the program. Running it
mkdir build
cd build
cmake ../ # <-- Pass any needed CMake flags here
make # To build the library
cd demo
make # To build the demo itself
Be sure "test.nsf" is in the same directory as the demo program. Running it
should generate the recording "out.wav".
You can use "make install" to install the library. To choose where to install
the library to, use the CMake argument "-DCMAKE_INSTALL_PREFIX=/usr/local"
(and replace /usr/local with the base path you wish to use). Alternately, you
can specify the base path to install to when you run "make install" by passing
'DESTDIR=/usr/local' on the make install command line (again, replace
/usr/local as appropriate).
To build a static library instead of shared (the default), pass
-DBUILD_SHARED_LIBS=OFF to the cmake command when running cmake.
A slightly more extensive demo application is available in the player/
directory. It requires SDL to build.
Read gme.txt for more information. Post to the discussion forum for
assistance.
Files
-----
gme.txt General notes about the library

Binary file not shown.

Binary file not shown.

View file

@ -7,6 +7,10 @@
# and other things
#
ifdef GCC81
GCC80=1
endif
ifdef GCC80
GCC72=1
endif
@ -116,6 +120,7 @@ WFLAGS+=-Wfloat-equal
#WFLAGS+=-Wtraditional
ifdef VCHELP
WFLAGS+=-Wdeclaration-after-statement
WFLAGS+=-Wno-error=declaration-after-statement
endif
WFLAGS+=-Wundef
ifndef GCC295
@ -189,12 +194,6 @@ ifdef GCC46
WFLAGS+=-Wno-suggest-attribute=noreturn
endif
ifndef MINGW
ifdef GCC45
WFLAGS+=-Wunsuffixed-float-constants
endif
endif
ifdef NOLDWARNING
LDFLAGS+=-Wl,--as-needed
endif
@ -208,6 +207,9 @@ WFLAGS+=$(OLDWFLAGS)
ifdef GCC43
#WFLAGS+=-Wno-error=clobbered
endif
ifdef GCC44
WFLAGS+=-Wno-error=array-bounds
endif
ifdef GCC46
WFLAGS+=-Wno-error=suggest-attribute=noreturn
endif

View file

@ -1254,7 +1254,8 @@ found:
var->string = var->zstring = Z_StrDup(valstr);
if (override)
if (var->flags & CV_PASSWORD); // Don't change value for password field
else if (override)
var->value = overrideval;
else if (var->flags & CV_FLOAT)
{

View file

@ -95,7 +95,8 @@ typedef enum
CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console
// can only be set when we have the pointer to it
// used on menus
CV_CHEAT = 2048 // Don't let this be used in multiplayer unless cheats are on.
CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on.
CV_PASSWORD = 4096 // Password field
} cvflags_t;
typedef struct CV_PossibleValue_s

View file

@ -37,7 +37,7 @@
* Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb
* Last updated 2018 / 12 / 23 - SRB2 v2.1.22 - patch.dta
* Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets
* Last updated 2019 / 02 / 04 - Kart v1.0.3 - patch.kart
* Last updated 2019 / 03 / 11 - Kart v1.0.4 - patch.kart
*/
// Base SRB2 hashes
@ -52,7 +52,7 @@
#define ASSET_HASH_CHARS_KART "e2c428347dde52858a3dacd29fc5b964"
#define ASSET_HASH_MAPS_KART "1335cd064656aedca359cfbb5233ac4a"
#ifdef USE_PATCH_KART
#define ASSET_HASH_PATCH_KART "e06c1c90e5645c886026311964f8e1f5"
#define ASSET_HASH_PATCH_KART "b5f48e1abccfa47a5745199182e2fef4"
#endif
#endif

View file

@ -544,6 +544,22 @@ static void CON_MoveConsole(void)
}
}
INT32 CON_ShiftChar(INT32 ch)
{
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
{
if (shiftdown ^ capslock)
ch = shiftxform[ch];
}
else // if we're holding shift we should still shift non letter symbols
{
if (shiftdown)
ch = shiftxform[ch];
}
return ch;
}
// Clear time of console heads up messages
//
void CON_ClearHUD(void)
@ -1084,16 +1100,6 @@ boolean CON_Responder(event_t *ev)
else if (key == KEY_KPADSLASH)
key = '/';
// capslock
if (key == KEY_CAPSLOCK) // it's a toggle.
{
if (capslock)
capslock = false;
else
capslock = true;
return true;
}
// same capslock code as hu_stuff.c's HU_responder. Check there for details.
if ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z'))
{

View file

@ -44,6 +44,8 @@ extern UINT8 *yellowmap, *purplemap, *greenmap, *bluemap, *graymap, *redmap, *or
// Console bg color (auto updated to match)
extern UINT8 *consolebgmap;
INT32 CON_ShiftChar(INT32 ch);
void CON_SetupBackColormap(void);
void CON_ClearHUD(void); // clear heads up messages

View file

@ -22,6 +22,7 @@
#include "i_video.h"
#include "d_net.h"
#include "d_main.h"
#include "d_event.h"
#include "g_game.h"
#include "hu_stuff.h"
#include "keys.h"
@ -72,6 +73,7 @@
#define PREDICTIONQUEUE BACKUPTICS
#define PREDICTIONMASK (PREDICTIONQUEUE-1)
#define MAX_REASONLENGTH 30
#define FORCECLOSE 0x8000
boolean server = true; // true or false but !server == client
#define client (!server)
@ -93,6 +95,7 @@ static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the
UINT16 pingmeasurecount = 1;
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
tic_t servermaxping = 800; // server's max ping. Defaults to 800
#endif
SINT8 nodetoplayer[MAXNETNODES];
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen)
@ -648,6 +651,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->jointime = (tic_t)LONG(players[i].jointime);
rsp->splitscreenindex = players[i].splitscreenindex;
rsp->hasmo = false;
//Transfer important mo information if the player has a body.
//This lets us resync players even if they are dead.
@ -783,6 +788,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].jointime = (tic_t)LONG(rsp->jointime);
players[i].splitscreenindex = rsp->splitscreenindex;
//We get a packet for each player in game.
if (!playeringame[i])
return;
@ -1121,12 +1128,22 @@ typedef enum
CL_DOWNLOADSAVEGAME,
#endif
CL_CONNECTED,
CL_ABORTED
CL_ABORTED,
CL_ASKDOWNLOADFILES,
CL_WAITDOWNLOADFILESRESPONSE,
CL_CHALLENGE
} cl_mode_t;
static void GetPackets(void);
static cl_mode_t cl_mode = CL_SEARCHING;
static boolean cl_needsdownload = false;
static UINT8 cl_challengenum = 0;
static UINT8 cl_challengequestion[MD5_LEN+1];
static char cl_challengepassword[65];
static UINT8 cl_challengeanswer[MD5_LEN+1];
static UINT8 cl_challengeattempted = 0;
// Player name send/load
@ -1163,6 +1180,8 @@ static void CV_LoadPlayerNames(UINT8 **p)
}
#ifdef CLIENT_LOADINGSCREEN
static UINT32 SL_SearchServer(INT32 node);
//
// CL_DrawConnectionStatus
//
@ -1186,11 +1205,42 @@ static inline void CL_DrawConnectionStatus(void)
// 15 pal entries total.
const char *cltext;
for (i = 0; i < 16; ++i)
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15));
if (cl_mode != CL_CHALLENGE)
for (i = 0; i < 16; ++i)
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15));
switch (cl_mode)
{
case CL_CHALLENGE:
{
char asterisks[33];
size_t sl = min(32, strlen(cl_challengepassword));
UINT32 serverid;
memset(asterisks, '*', sl);
memset(asterisks+sl, 0, 33-sl);
V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_MONOSPACE|V_ALLOWLOWERCASE, asterisks);
V_DrawFixedPatch((BASEVIDWIDTH/2) << FRACBITS, (BASEVIDHEIGHT/2) << FRACBITS, FRACUNIT, 0, W_CachePatchName("BSRVLOCK", PU_CACHE), NULL);
serverid = SL_SearchServer(servernode);
if (serverid == UINT32_MAX)
{
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT/2-8, 32, 1);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, V_REDMAP, M_GetText("This server is password protected."));
}
else
{
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT/2-8, 32, 3);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, V_REDMAP, M_GetText("This server,"));
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2+8, V_ALLOWLOWERCASE, serverlist[serverid].info.servername);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2+16, V_REDMAP, M_GetText("is password protected."));
}
cltext = M_GetText(cl_challengeattempted ? "Incorrect password. Please try again." : "Please enter the server password.");
}
break;
#ifdef JOININGAME
case CL_DOWNLOADSAVEGAME:
if (lastfilenum != -1)
@ -1210,6 +1260,9 @@ static inline void CL_DrawConnectionStatus(void)
case CL_WAITJOINRESPONSE:
cltext = M_GetText("Requesting to join...");
break;
case CL_ASKDOWNLOADFILES:
case CL_WAITDOWNLOADFILESRESPONSE:
cltext = M_GetText("Waiting to download files...");
default:
cltext = M_GetText("Connecting to server...");
break;
@ -1287,6 +1340,9 @@ static boolean CL_SendJoin(void)
netbuffer->u.clientcfg.localplayers = localplayers;
netbuffer->u.clientcfg.version = VERSION;
netbuffer->u.clientcfg.subversion = SUBVERSION;
netbuffer->u.clientcfg.needsdownload = cl_needsdownload;
netbuffer->u.clientcfg.challengenum = cl_challengenum;
memcpy(netbuffer->u.clientcfg.challengeanswer, cl_challengeanswer, MD5_LEN);
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
}
@ -1307,7 +1363,13 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.gametype = (UINT8)(G_BattleGametype() ? VANILLA_GT_MATCH : VANILLA_GT_RACE); // SRB2Kart: Vanilla's gametype constants for MS support
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated;
netbuffer->u.serverinfo.kartvars = (UINT8) (
(cv_kartspeed.value & SV_SPEEDMASK) |
(dedicated ? SV_DEDICATED : 0) |
(D_IsJoinPasswordOn() ? SV_PASSWORD : 0)
);
strncpy(netbuffer->u.serverinfo.servername, cv_servername.string,
MAXSERVERNAME);
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
@ -1389,33 +1451,13 @@ static void SV_SendPlayerInfo(INT32 node)
continue;
}
netbuffer->u.playerinfo[i].node = (UINT8)playernode[i];
netbuffer->u.playerinfo[i].node = i;
strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
//fetch IP address
{
const char *claddress;
UINT32 numericaddress[4];
memset(netbuffer->u.playerinfo[i].address, 0, 4);
if (playernode[i] == 0)
{
//127.0.0.1
netbuffer->u.playerinfo[i].address[0] = 127;
netbuffer->u.playerinfo[i].address[3] = 1;
}
else if (playernode[i] > 0 && I_GetNodeAddress && (claddress = I_GetNodeAddress(playernode[i])) != NULL)
{
if (sscanf(claddress, "%d.%d.%d.%d", &numericaddress[0], &numericaddress[1], &numericaddress[2], &numericaddress[3]) < 4)
goto badaddress;
netbuffer->u.playerinfo[i].address[0] = (UINT8)numericaddress[0];
netbuffer->u.playerinfo[i].address[1] = (UINT8)numericaddress[1];
netbuffer->u.playerinfo[i].address[2] = (UINT8)numericaddress[2];
netbuffer->u.playerinfo[i].address[3] = (UINT8)numericaddress[3];
}
}
badaddress:
//No, don't do that, you fuckface.
memset(netbuffer->u.playerinfo[i].address, 0, 4);
if (G_GametypeHasTeams())
{
@ -1740,8 +1782,6 @@ static void SendAskInfo(INT32 node, boolean viams)
serverelem_t serverlist[MAXSERVERLIST];
UINT32 serverlistcount = 0;
#define FORCECLOSE 0x8000
static void SL_ClearServerList(INT32 connectedserver)
{
UINT32 i;
@ -1867,7 +1907,7 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
/** Called by CL_ServerConnectionTicker
*
* \param viams ???
* \param asksent ???
* \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit.
* \return False if the connection was aborted
* \sa CL_ServerConnectionTicker
* \sa CL_ConnectToServer
@ -1960,9 +2000,12 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
), NULL, MM_NOTHING);
return false;
}
cl_mode = CL_ASKDOWNLOADFILES;
// no problem if can't send packet, we will retry later
if (CL_SendRequestFile())
cl_mode = CL_DOWNLOADFILES;
//if (CL_SendRequestFile())
// cl_mode = CL_DOWNLOADFILES;
}
}
else
@ -1992,7 +2035,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
* \param viams ???
* \param tmpsave The name of the gamestate file???
* \param oldtic Used for knowing when to poll events and redraw
* \param asksent ???
* \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit.
* \return False if the connection was aborted
* \sa CL_ServerConnectionSearchTicker
* \sa CL_ConnectToServer
@ -2030,6 +2073,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
/* FALLTHRU */
case CL_ASKJOIN:
cl_needsdownload = false;
CL_LoadServerFiles();
#ifdef JOININGAME
// prepare structures to save the file
@ -2038,9 +2082,23 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
CL_PrepareDownloadSaveGame(tmpsave);
#endif
if (CL_SendJoin())
{
*asksent = I_GetTime();
cl_mode = CL_WAITJOINRESPONSE;
}
break;
case CL_ASKDOWNLOADFILES:
cl_needsdownload = true;
if (CL_SendJoin())
{
*asksent = I_GetTime();
cl_mode = CL_WAITDOWNLOADFILESRESPONSE;
}
break;
#ifdef JOININGAME
case CL_DOWNLOADSAVEGAME:
// At this state, the first (and only) needed file is the gamestate
@ -2054,7 +2112,19 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
break;
#endif
case CL_CHALLENGE:
(*asksent) = I_GetTime() - NEWTICRATE; // Send password immediately upon entering
break;
case CL_WAITJOINRESPONSE:
case CL_WAITDOWNLOADFILESRESPONSE:
if (*asksent + NEWTICRATE < I_GetTime() && CL_SendJoin())
{
*asksent = I_GetTime();
}
break;
case CL_CONNECTED:
default:
break;
@ -2072,20 +2142,10 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
// Call it only once by tic
if (*oldtic != I_GetTime())
{
INT32 key;
I_OsPolling();
key = I_GetKey();
// Only ESC and non-keyboard keys abort connection
if (key == KEY_ESCAPE || key >= KEY_MOUSE1)
{
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
// M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
D_QuitNetGame();
CL_Reset();
D_StartTitle();
D_ProcessEvents();
if (gamestate != GS_WAITINGPLAYERS)
return false;
}
// why are these here? this is for servers, we're a client
//if (key == 's' && server)
@ -2114,6 +2174,71 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
return true;
}
boolean CL_Responder(event_t *ev)
{
size_t len;
INT32 ch;
if (!(client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED))
return false; // Don't do anything outside of the connection screen
if (ev->type != ev_keydown)
return false;
ch = (INT32)ev->data1;
// Only ESC and non-keyboard keys abort connection
if (ch == KEY_ESCAPE || ch >= KEY_MOUSE1)
{
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
//M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
D_QuitNetGame();
CL_Reset();
D_StartTitle();
return true;
}
if (cl_mode != CL_CHALLENGE)
return false;
if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART])
|| ch == ' ') // Allow spaces, of course
{
len = strlen(cl_challengepassword);
if (len < 64)
{
cl_challengepassword[len+1] = 0;
cl_challengepassword[len] = CON_ShiftChar(ch);
}
cl_challengeattempted = 0;
}
else if (ch == KEY_BACKSPACE)
{
len = strlen(cl_challengepassword);
if (len > 0)
cl_challengepassword[len-1] = 0;
cl_challengeattempted = 0;
}
else if (ch == KEY_ENTER)
{
netgame = true;
multiplayer = true;
#ifndef NONET
SL_ClearServerList(servernode);
#endif
cl_mode = CL_SEARCHING;
D_ComputeChallengeAnswer(cl_challengequestion, cl_challengepassword, cl_challengeanswer);
cl_challengeattempted = 1;
}
return true;
}
/** Use adaptive send using net_bandwidth and stat.sendbytes
*
* \param viams ???
@ -2134,6 +2259,7 @@ static void CL_ConnectToServer(boolean viams)
#endif
cl_mode = CL_SEARCHING;
cl_challengenum = 0;
#ifdef CLIENT_LOADINGSCREEN
lastfilenum = -1;
@ -2191,6 +2317,8 @@ static void CL_ConnectToServer(boolean viams)
SL_ClearServerList(servernode);
#endif
cl_challengeattempted = 0;
do
{
// If the connection was aborted for some reason, leave
@ -2542,6 +2670,8 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
#ifdef HAVE_BLUA
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
#else
(void)reason;
#endif
// Reset player data
@ -2725,7 +2855,10 @@ static void Command_Ban(void)
else
{
if (server) // only the server is allowed to do this right now
{
Ban_Add(COM_Argv(2));
D_SaveBan(); // save the ban list
}
if (COM_Argc() == 2)
{
@ -2756,6 +2889,42 @@ static void Command_Ban(void)
}
static void Command_BanIP(void)
{
if (COM_Argc() < 2)
{
CONS_Printf(M_GetText("banip <ip> <reason>: ban an ip address\n"));
return;
}
if (server) // Only the server can use this, otherwise does nothing.
{
const char *address = (COM_Argv(1));
const char *reason;
if (COM_Argc() == 2)
reason = NULL;
else
reason = COM_Argv(2);
if (I_SetBanAddress && I_SetBanAddress(address, NULL))
{
if (reason)
CONS_Printf("Banned IP address %s for: %s\n", address, reason);
else
CONS_Printf("Banned IP address %s\n", address);
Ban_Add(reason);
D_SaveBan();
}
else
{
return;
}
}
}
static void Command_Kick(void)
{
if (COM_Argc() < 2)
@ -3062,6 +3231,7 @@ void D_ClientServerInit(void)
COM_AddCommand("getplayernum", Command_GetPlayerNum);
COM_AddCommand("kick", Command_Kick);
COM_AddCommand("ban", Command_Ban);
COM_AddCommand("banip", Command_BanIP);
COM_AddCommand("clearbans", Command_ClearBans);
COM_AddCommand("showbanlist", Command_ShowBan);
COM_AddCommand("reloadbans", Command_ReloadBan);
@ -3095,6 +3265,9 @@ void D_ClientServerInit(void)
gametic = 0;
localgametic = 0;
memset(cl_challengequestion, 0x00, MD5_LEN+1);
memset(cl_challengeanswer, 0x00, MD5_LEN+1);
// do not send anything before the real begin
SV_StopServer();
SV_ResetServer();
@ -3316,6 +3489,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
addedtogame = true;
}
players[newplayernum].splitscreenindex = splitscreenplayer;
if (netgame)
{
if (server && cv_showjoinaddress.value)
@ -3582,6 +3757,33 @@ static void HandleConnect(SINT8 node)
boolean newnode = false;
#endif
if (node != servernode && !nodeingame[node] && D_IsJoinPasswordOn())
{
// Ensure node sent the correct password challenge
boolean passed = false;
if (netbuffer->u.clientcfg.challengenum && D_VerifyJoinPasswordChallenge(netbuffer->u.clientcfg.challengenum, netbuffer->u.clientcfg.challengeanswer))
passed = true;
if (!passed)
{
D_MakeJoinPasswordChallenge(&netbuffer->u.joinchallenge.challengenum, netbuffer->u.joinchallenge.question);
netbuffer->packettype = PT_JOINCHALLENGE;
HSendPacket(node, true, 0, sizeof(joinchallenge_pak));
Net_CloseConnection(node);
return;
}
}
if (netbuffer->u.clientcfg.needsdownload)
{
netbuffer->packettype = PT_DOWNLOADFILESOKAY;
HSendPacket(node, true, 0, 0);
return;
}
// client authorised to join
nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]);
if (!nodeingame[node])
@ -3590,6 +3792,7 @@ static void HandleConnect(SINT8 node)
#ifndef NONET
newnode = true;
#endif
SV_AddNode(node);
/// \note Wait what???
@ -3745,6 +3948,43 @@ static void HandlePacketFromAwayNode(SINT8 node)
Net_CloseConnection(node);
break;
case PT_JOINCHALLENGE:
if (server && serverrunning)
{ // But wait I thought I'm the server?
Net_CloseConnection(node);
break;
}
SERVERONLY
if (cl_mode == CL_WAITJOINRESPONSE || cl_mode == CL_WAITDOWNLOADFILESRESPONSE)
{
cl_challengenum = netbuffer->u.joinchallenge.challengenum;
memcpy(cl_challengequestion, netbuffer->u.joinchallenge.question, 16);
Net_CloseConnection(node|FORCECLOSE); // Don't need to stay connected while challenging
cl_mode = CL_CHALLENGE;
switch (cl_challengeattempted)
{
case 2:
// We already sent a correct password, so throw it back up again.
D_ComputeChallengeAnswer(cl_challengequestion, cl_challengepassword, cl_challengeanswer);
cl_mode = CL_ASKJOIN;
break;
case 1:
// We entered the wrong password!
S_StartSound(NULL, sfx_s26d);
break;
default:
// First entry to the password screen.
S_StartSound(NULL, sfx_s224);
break;
}
}
break;
case PT_SERVERREFUSE: // Negative response of client join request
if (server && serverrunning)
{ // But wait I thought I'm the server?
@ -3773,6 +4013,41 @@ static void HandlePacketFromAwayNode(SINT8 node)
}
break;
case PT_DOWNLOADFILESOKAY:
if (server && serverrunning)
{ // But wait I thought I'm the server?
Net_CloseConnection(node);
break;
}
SERVERONLY
// This should've already been checked, but just to be safe...
if (!CL_CheckDownloadable())
{
D_QuitNetGame();
CL_Reset();
D_StartTitle();
M_StartMessage(M_GetText(
"You cannot connect to this server\n"
"because you cannot download the files\n"
"that you are missing from the server.\n\n"
"See the console or log file for\n"
"more details.\n\n"
"Press ESC\n"
), NULL, MM_NOTHING);
break;
}
if (cl_challengeattempted == 1) // Successful password noise.
S_StartSound(NULL, sfx_s221);
cl_challengeattempted = 2;
CONS_Printf("trying to download\n");
if (CL_SendRequestFile())
cl_mode = CL_DOWNLOADFILES;
break;
case PT_SERVERCFG: // Positive response of client join request
{
INT32 j;
@ -3788,6 +4063,9 @@ static void HandlePacketFromAwayNode(SINT8 node)
if (cl_mode != CL_WAITJOINRESPONSE)
break;
if (cl_challengeattempted == 1) // Successful password noise.
S_StartSound(NULL, sfx_s221);
if (client)
{
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
@ -4353,10 +4631,12 @@ FILESTAMP
//Update client ping table from the server.
if (client)
{
INT32 i;
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
servermaxping = (tic_t)netbuffer->u.pingtable[MAXPLAYERS];
}
break;
@ -4999,6 +5279,18 @@ void TryRunTics(tic_t realtics)
}
#ifdef NEWPING
/* Ping Update except better:
We call this once per second and check for people's pings. If their ping happens to be too high, we increment some timer and kick them out.
If they're not lagging, decrement the timer by 1. Of course, reset all of this if they leave.
Why do we do that? Well, I'm a person with unfortunately sometimes unstable internet and happen to keep getting kicked very unconveniently for very short high spikes. (700+ ms)
Because my spikes are so high, the average ping is exponentially higher too (700s really add up...!) which leads me to getting kicked for a short burst of spiking.
With this change here, this doesn't happen anymore as it checks if my ping has been CONSISTENTLY bad for long enough before killing me.
*/
static INT32 pingtimeout[MAXPLAYERS];
static inline void PingUpdate(void)
{
INT32 i;
@ -5019,6 +5311,9 @@ static inline void PingUpdate(void)
laggers[i] = true;
numlaggers++;
}
else
pingtimeout[i] = 0;
}
//kick lagging players... unless everyone but the server's ping sucks.
@ -5029,12 +5324,20 @@ static inline void PingUpdate(void)
{
if (playeringame[i] && laggers[i])
{
XBOXSTATIC char buf[2];
pingtimeout[i]++;
if (pingtimeout[i] > cv_pingtimeout.value) // ok your net has been bad for too long, you deserve to die.
{
XBOXSTATIC char buf[2];
buf[0] = (char)i;
buf[1] = KICK_MSG_PING_HIGH;
SendNetXCmd(XD_KICK, &buf, 2);
pingtimeout[i] = 0;
buf[0] = (char)i;
buf[1] = KICK_MSG_PING_HIGH;
SendNetXCmd(XD_KICK, &buf, 2);
}
}
else // you aren't lagging, but you aren't free yet. In case you'll keep spiking, we just make the timer go back down. (Very unstable net must still get kicked).
pingtimeout[i] = (pingtimeout[i] == 0 ? 0 : pingtimeout[i]-1);
}
}
}
@ -5049,10 +5352,13 @@ static inline void PingUpdate(void)
realpingtable[i] = 0; //Reset each as we go.
}
// send the server's maxping as last element of our ping table. This is useful to let us know when we're about to get kicked.
netbuffer->u.pingtable[MAXPLAYERS] = cv_maxping.value;
//send out our ping packets
for (i = 0; i < MAXNETNODES; i++)
if (nodeingame[i])
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1));
pingmeasurecount = 1; //Reset count
}
@ -5066,7 +5372,7 @@ static void UpdatePingTable(void)
INT32 i;
if (server)
{
if (netgame && !(gametime % 255))
if (netgame && !(gametime % 35)) // update once per second.
PingUpdate();
// update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++)

View file

@ -13,11 +13,14 @@
#ifndef __D_CLISRV__
#define __D_CLISRV__
#include "d_event.h"
#include "d_ticcmd.h"
#include "d_netcmd.h"
#include "tables.h"
#include "d_player.h"
#include "md5.h"
// Network play related stuff.
// There is a data struct that stores network
// communication related stuff, and another
@ -73,6 +76,9 @@ typedef enum
PT_CLIENT4MIS,
PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
PT_JOINCHALLENGE, // You must give a password to joinnnnn
PT_DOWNLOADFILESOKAY, // You can download files from the server....
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
// allows HSendPacket(*, true, *, *) to return false.
// In addition, this packet can't occupy all the available slots.
@ -283,6 +289,8 @@ typedef struct
tic_t jointime;
UINT8 splitscreenindex;
//player->mo stuff
UINT8 hasmo; // Boolean
@ -351,9 +359,21 @@ typedef struct
UINT8 version; // Different versions don't work
UINT8 subversion; // Contains build version
UINT8 localplayers;
UINT8 mode;
UINT8 needsdownload;
UINT8 challengenum; // Non-zero if trying to join with a password attempt
UINT8 challengeanswer[MD5_LEN]; // Join challenge
} ATTRPACK clientconfig_pak;
typedef struct
{
UINT8 challengenum; // Number to send back in join attempt
UINT8 question[MD5_LEN]; // Challenge data to be manipulated and answered with
} ATTRPACK joinchallenge_pak;
#define SV_SPEEDMASK 0x03
#define SV_DEDICATED 0x40
#define SV_PASSWORD 0x80
#define MAXSERVERNAME 32
#define MAXFILENEEDED 915
// This packet is too large
@ -366,7 +386,7 @@ typedef struct
UINT8 gametype;
UINT8 modifiedgame;
UINT8 cheatsenabled;
UINT8 isdedicated;
UINT8 kartvars; // Previously isdedicated, now appropriated for our own nefarious purposes
UINT8 fileneedednum;
SINT8 adminplayer;
tic_t time;
@ -445,15 +465,16 @@ typedef struct
UINT8 resynchgot; //
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
filetx_pak filetxpak; // 139 bytes
clientconfig_pak clientcfg; // 136 bytes
clientconfig_pak clientcfg; // 153 bytes
joinchallenge_pak joinchallenge; // 17 bytes
serverinfo_pak serverinfo; // 1024 bytes
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
askinfo_pak askinfo; // 61 bytes
msaskinfo_pak msaskinfo; // 22 bytes
plrinfo playerinfo[MAXPLAYERS]; // 1152 bytes (I'd say 36~38)
plrconfig playerconfig[MAXPLAYERS]; // (up to) 896 bytes (welp they ARE)
plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?)
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
#ifdef NEWPING
UINT32 pingtable[MAXPLAYERS]; // 128 bytes
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
#endif
} u; // This is needed to pack diff packet types data together
} ATTRPACK doomdata_t;
@ -519,6 +540,7 @@ extern tic_t jointimeout;
extern UINT16 pingmeasurecount;
extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
#endif
extern consvar_t
@ -552,6 +574,7 @@ void CL_RemoveSplitscreenPlayer(UINT8 p);
void CL_Reset(void);
void CL_ClearPlayer(INT32 playernum);
void CL_UpdateServerList(boolean internetsearch, INT32 room);
boolean CL_Responder(event_t *ev);
// Is there a game running
boolean Playing(void);

View file

@ -111,6 +111,7 @@ UINT8 window_notinfocus = false;
//static INT32 demosequence;
static const char *pagename = "MAP1PIC";
static char *startupwadfiles[MAX_WADFILES];
static char *startuppwads[MAX_WADFILES];
boolean devparm = false; // started game with -devparm
@ -203,6 +204,8 @@ static inline void D_ModifierKeyResponder(event_t *ev)
case KEY_RCTRL: ctrldown |= 0x2; return;
case KEY_LALT: altdown |= 0x1; return;
case KEY_RALT: altdown |= 0x2; return;
case KEY_CAPSLOCK: capslock = !capslock; return;
default: return;
}
else if (ev->type == ev_keyup) switch (ev->data1)
@ -236,6 +239,9 @@ void D_ProcessEvents(void)
if (M_ScreenshotResponder(ev))
continue; // ate the event
if (CL_Responder(ev))
continue;
if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN)
{
if (cht_Responder(ev))
@ -824,12 +830,12 @@ void D_StartTitle(void)
//
// D_AddFile
//
static void D_AddFile(const char *file)
static void D_AddFile(const char *file, char **filearray)
{
size_t pnumwadfiles;
char *newfile;
for (pnumwadfiles = 0; startupwadfiles[pnumwadfiles]; pnumwadfiles++)
for (pnumwadfiles = 0; filearray[pnumwadfiles]; pnumwadfiles++)
;
newfile = malloc(strlen(file) + 1);
@ -839,16 +845,16 @@ static void D_AddFile(const char *file)
}
strcpy(newfile, file);
startupwadfiles[pnumwadfiles] = newfile;
filearray[pnumwadfiles] = newfile;
}
static inline void D_CleanFile(void)
static inline void D_CleanFile(char **filearray)
{
size_t pnumwadfiles;
for (pnumwadfiles = 0; startupwadfiles[pnumwadfiles]; pnumwadfiles++)
for (pnumwadfiles = 0; filearray[pnumwadfiles]; pnumwadfiles++)
{
free(startupwadfiles[pnumwadfiles]);
startupwadfiles[pnumwadfiles] = NULL;
free(filearray[pnumwadfiles]);
filearray[pnumwadfiles] = NULL;
}
}
@ -908,9 +914,9 @@ static void IdentifyVersion(void)
// Load the IWAD
if (srb2wad2 != NULL && FIL_ReadFileOK(srb2wad2))
D_AddFile(srb2wad2);
D_AddFile(srb2wad2, startupwadfiles);
else if (srb2wad1 != NULL && FIL_ReadFileOK(srb2wad1))
D_AddFile(srb2wad1);
D_AddFile(srb2wad1, startupwadfiles);
else
I_Error("SRB2.SRB/SRB2.WAD not found! Expected in %s, ss files: %s or %s\n", srb2waddir, srb2wad1, srb2wad2);
@ -927,12 +933,12 @@ static void IdentifyVersion(void)
D_AddFile(va(pandf,srb2waddir,"patch.dta"));
#endif
D_AddFile(va(pandf,srb2waddir,"gfx.kart"));
D_AddFile(va(pandf,srb2waddir,"textures.kart"));
D_AddFile(va(pandf,srb2waddir,"chars.kart"));
D_AddFile(va(pandf,srb2waddir,"maps.kart"));
D_AddFile(va(pandf,srb2waddir,"gfx.kart"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"textures.kart"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"chars.kart"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"maps.kart"), startupwadfiles);
#ifdef USE_PATCH_KART
D_AddFile(va(pandf,srb2waddir,"patch.kart"));
D_AddFile(va(pandf,srb2waddir,"patch.kart"), startupwadfiles);
#endif
#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
@ -941,7 +947,7 @@ static void IdentifyVersion(void)
const char *musicpath = va(pandf,srb2waddir,str);\
int ms = W_VerifyNMUSlumps(musicpath); \
if (ms == 1) \
D_AddFile(musicpath); \
D_AddFile(musicpath, startupwadfiles); \
else if (ms == 0) \
I_Error("File "str" has been modified with non-music/sound lumps"); \
}
@ -1006,9 +1012,12 @@ static inline void D_MakeTitleString(char *s)
//
void D_SRB2Main(void)
{
INT32 p;
INT32 p, i;
char srb2[82]; // srb2 title banner
char title[82];
lumpinfo_t *lumpinfo;
UINT16 wadnum;
char *name;
INT32 pstartmap = 1;
boolean autostart = false;
@ -1160,11 +1169,7 @@ void D_SRB2Main(void)
const char *s = M_GetNextParm();
if (s) // Check for NULL?
{
if (!W_VerifyNMUSlumps(s))
G_SetGameModified(true, false);
D_AddFile(s);
}
D_AddFile(s, startuppwads);
}
}
}
@ -1214,13 +1219,13 @@ void D_SRB2Main(void)
// load wad, including the main wad file
CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n");
if (!W_InitMultipleFiles(startupwadfiles))
if (!W_InitMultipleFiles(startupwadfiles, false))
#ifdef _DEBUG
CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
#else
I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
#endif
D_CleanFile();
D_CleanFile(startupwadfiles);
mainwads = 0;
@ -1234,7 +1239,7 @@ void D_SRB2Main(void)
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_KART); // gfx.kart
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_TEXTURES_KART); // textures.kart
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_KART); // chars.kart
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_KART); // maps.kart
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_KART); // maps.kart -- 4 - If you touch this, make sure to touch up the majormods stuff below.
#ifdef USE_PATCH_KART
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_KART); // patch.kart
#endif
@ -1254,6 +1259,66 @@ void D_SRB2Main(void)
mainwadstally = packetsizetally;
//
// search for maps
//
for (wadnum = 4; wadnum < 6; wadnum++) // fucking arbitrary numbers
{
lumpinfo = wadfiles[wadnum]->lumpinfo;
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
{
name = lumpinfo->name;
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
{
INT16 num;
if (name[5] != '\0')
continue;
num = (INT16)M_MapNumber(name[3], name[4]);
// we want to record whether this map exists. if it doesn't have a header, we can assume it's not relephant
if (num <= NUMMAPS && mapheaderinfo[num - 1])
{
mapheaderinfo[num - 1]->menuflags |= LF2_EXISTSHACK;
}
}
}
}
if (!W_InitMultipleFiles(startuppwads, true))
CONS_Error("A PWAD file was not found or not valid.\nCheck the log to see which ones.\n");
D_CleanFile(startuppwads);
//
// search for maps... again.
//
for (wadnum = mainwads+1; wadnum < numwadfiles; wadnum++)
{
lumpinfo = wadfiles[wadnum]->lumpinfo;
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
{
name = lumpinfo->name;
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
{
INT16 num;
if (name[5] != '\0')
continue;
num = (INT16)M_MapNumber(name[3], name[4]);
// we want to record whether this map exists. if it doesn't have a header, we can assume it's not relephant
if (num <= NUMMAPS && mapheaderinfo[num - 1])
{
if (mapheaderinfo[num - 1]->menuflags & LF2_EXISTSHACK)
G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
mapheaderinfo[num - 1]->menuflags |= LF2_EXISTSHACK;
}
CONS_Printf("%s\n", name);
}
}
}
cht_Init();
//---------------------------------------------------- READY SCREEN

View file

@ -821,10 +821,6 @@ static const char *packettypename[NUMPACKETTYPE] =
"CLIENTMIS",
"CLIENT2CMD",
"CLIENT2MIS",
"CLIENT3CMD",
"CLIENT3MIS",
"CLIENT4CMD",
"CLIENT4MIS",
"NODEKEEPALIVE",
"NODEKEEPALIVEMIS",
"SERVERTICS",
@ -841,6 +837,15 @@ static const char *packettypename[NUMPACKETTYPE] =
"RESYNCHEND",
"RESYNCHGET",
"CLIENT3CMD",
"CLIENT3MIS",
"CLIENT4CMD",
"CLIENT4MIS",
"BASICKEEPALIVE",
"JOINCHALLENGE",
"DOWNLOADFILESOKAY",
"FILEFRAGMENT",
"TEXTCMD",
"TEXTCMD2",
@ -868,7 +873,7 @@ static void DebugPrintpacket(const char *header)
break;
case PT_CLIENTJOIN:
fprintf(debugfile, " number %d mode %d\n", netbuffer->u.clientcfg.localplayers,
netbuffer->u.clientcfg.mode);
netbuffer->u.clientcfg.needsdownload);
break;
case PT_SERVERTICS:
{

View file

@ -19,7 +19,7 @@
#define __D_NET__
// Max computers in a game
#define MAXNETNODES 16
#define MAXNETNODES (MAXPLAYERS+4)
#define BROADCASTADDR MAXNETNODES
#define MAXSPLITSCREENPLAYERS 4 // Max number of players on a single computer
#define NETSPLITSCREEN // Kart's splitscreen netgame feature

View file

@ -169,6 +169,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum);
static void Got_Removal(UINT8 **cp, INT32 playernum);
static void Command_Verify_f(void);
static void Command_RemoveAdmin_f(void);
static void Command_ChangeJoinPassword_f(void);
static void Command_MotD_f(void);
static void Got_MotD_f(UINT8 **cp, INT32 playernum);
@ -378,6 +379,7 @@ consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|C
consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugnodes = {"kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugcolorize = {"kartdebugcolorize", "Off", CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
consvar_t cv_votetime = {"votetime", "20", CV_NETVAR, votetime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -435,6 +437,14 @@ consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_co
#ifdef NEWPING
static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}};
consvar_t cv_maxping = {"maxping", "800", CV_SAVE, maxping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t pingtimeout_cons_t[] = {{8, "MIN"}, {120, "MAX"}, {0, NULL}};
consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// show your ping on the HUD next to framerate. Defaults to warning only (shows up if your ping is > maxping)
static CV_PossibleValue_t showping_cons_t[] = {{0, "Off"}, {1, "Always"}, {2, "Warning"}, {0, NULL}};
consvar_t cv_showping = {"showping", "Always", CV_SAVE, showping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
// Intermission time Tails 04-19-2002
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
@ -525,6 +535,8 @@ void D_RegisterServerCommands(void)
RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd);
// Remote Administration
CV_RegisterVar(&cv_dummyjoinpassword);
COM_AddCommand("joinpassword", Command_ChangeJoinPassword_f);
COM_AddCommand("password", Command_Changepassword_f);
RegisterNetXCmd(XD_LOGIN, Got_Login);
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
@ -664,6 +676,8 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_sleep);
#ifdef NEWPING
CV_RegisterVar(&cv_maxping);
CV_RegisterVar(&cv_pingtimeout);
CV_RegisterVar(&cv_showping);
#endif
#ifdef SEENAMES
@ -807,6 +821,8 @@ void D_RegisterClientCommands(void)
//CV_RegisterVar(&cv_alwaysfreelook2);
//CV_RegisterVar(&cv_chasefreelook);
//CV_RegisterVar(&cv_chasefreelook2);
CV_RegisterVar(&cv_showfocuslost);
CV_RegisterVar(&cv_pauseifunfocused);
// g_input.c
CV_RegisterVar(&cv_turnaxis);
@ -3504,6 +3520,7 @@ static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt,
if (len > 256-sl)
len = 256-sl;
memcpy(tmpbuf, buffer, len);
memmove(&tmpbuf[len], salt, sl);
//strcpy(&tmpbuf[len], salt);
@ -3517,7 +3534,7 @@ static void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt,
}
#define BASESALT "basepasswordstorage"
static UINT8 adminpassmd5[16];
static UINT8 adminpassmd5[MD5_LEN];
static boolean adminpasswordset = false;
void D_SetPassword(const char *pw)
@ -3556,7 +3573,7 @@ static void Command_Login_f(void)
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
#else
XBOXSTATIC UINT8 finalmd5[16];
XBOXSTATIC UINT8 finalmd5[MD5_LEN];
const char *pw;
if (!netgame)
@ -3579,11 +3596,11 @@ static void Command_Login_f(void)
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &finalmd5);
// Do the final pass to get the comparison the server will come up with
D_MD5PasswordPass(finalmd5, 16, va("PNUM%02d", consoleplayer), &finalmd5);
D_MD5PasswordPass(finalmd5, MD5_LEN, va("PNUM%02d", consoleplayer), &finalmd5);
CONS_Printf(M_GetText("Sending login... (Notice only given if password is correct.)\n"));
SendNetXCmd(XD_LOGIN, finalmd5, 16);
SendNetXCmd(XD_LOGIN, finalmd5, MD5_LEN);
#endif
}
@ -3594,9 +3611,9 @@ static void Got_Login(UINT8 **cp, INT32 playernum)
(void)cp;
(void)playernum;
#else
UINT8 sentmd5[16], finalmd5[16];
UINT8 sentmd5[MD5_LEN], finalmd5[MD5_LEN];
READMEM(*cp, sentmd5, 16);
READMEM(*cp, sentmd5, MD5_LEN);
if (client)
return;
@ -3608,9 +3625,9 @@ static void Got_Login(UINT8 **cp, INT32 playernum)
}
// Do the final pass to compare with the sent md5
D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", playernum), &finalmd5);
D_MD5PasswordPass(adminpassmd5, MD5_LEN, va("PNUM%02d", playernum), &finalmd5);
if (!memcmp(sentmd5, finalmd5, 16))
if (!memcmp(sentmd5, finalmd5, MD5_LEN))
{
CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[playernum]);
COM_BufInsertText(va("promote %d\n", playernum)); // do this immediately
@ -3779,6 +3796,131 @@ static void Got_Removal(UINT8 **cp, INT32 playernum)
CONS_Printf(M_GetText("You are no longer a server administrator.\n"));
}
// Join password stuff
consvar_t cv_dummyjoinpassword = {"dummyjoinpassword", "", CV_HIDEN|CV_NOSHOWHELP|CV_PASSWORD, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
#define NUMJOINCHALLENGES 32
static UINT8 joinpassmd5[MD5_LEN+1];
boolean joinpasswordset = false;
static UINT8 joinpasschallenges[NUMJOINCHALLENGES][MD5_LEN];
static tic_t joinpasschallengeson[NUMJOINCHALLENGES];
boolean D_IsJoinPasswordOn(void)
{
return joinpasswordset;
}
static inline void GetChallengeAnswer(UINT8 *question, UINT8 *passwordmd5, UINT8 *answer)
{
D_MD5PasswordPass(question, MD5_LEN, (char *) passwordmd5, answer);
}
void D_ComputeChallengeAnswer(UINT8 *question, const char *pw, UINT8 *answer)
{
static UINT8 passwordmd5[MD5_LEN+1];
memset(passwordmd5, 0x00, MD5_LEN+1);
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &passwordmd5);
GetChallengeAnswer(question, passwordmd5, answer);
}
void D_SetJoinPassword(const char *pw)
{
memset(joinpassmd5, 0x00, MD5_LEN+1);
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &joinpassmd5);
joinpasswordset = true;
}
boolean D_VerifyJoinPasswordChallenge(UINT8 num, UINT8 *answer)
{
boolean passed = false;
num %= NUMJOINCHALLENGES;
//@TODO use a constant-time memcmp....
if (joinpasschallengeson[num] > 0 && memcmp(answer, joinpasschallenges[num], MD5_LEN) == 0)
passed = true;
// Wipe and reset the challenge so that it can't be tried against again, as a small measure against brute-force attacks.
memset(joinpasschallenges[num], 0x00, MD5_LEN);
joinpasschallengeson[num] = 0;
return passed;
}
void D_MakeJoinPasswordChallenge(UINT8 *num, UINT8 *question)
{
size_t i;
for (i = 0; i < NUMJOINCHALLENGES; i++)
{
(*num) = M_RandomKey(NUMJOINCHALLENGES);
if (joinpasschallengeson[(*num)] == 0)
break;
}
if (joinpasschallengeson[(*num)] > 0)
{
// Ugh, all challenges are (probably) taken. Let's find the oldest one and overwrite it.
tic_t oldesttic = INT32_MAX;
for (i = 0; i < NUMJOINCHALLENGES; i++)
{
if (joinpasschallengeson[i] < oldesttic)
{
(*num) = i;
oldesttic = joinpasschallengeson[i];
}
}
}
joinpasschallengeson[(*num)] = I_GetTime();
memset(question, 0x00, MD5_LEN);
for (i = 0; i < MD5_LEN; i++)
question[i] = M_RandomByte();
// Store the answer in memory. What was the question again?
GetChallengeAnswer(question, joinpassmd5, joinpasschallenges[(*num)]);
// This ensures that num is always non-zero and will be valid when used for the answer
if ((*num) == 0)
(*num) = NUMJOINCHALLENGES;
}
// Remote Administration
static void Command_ChangeJoinPassword_f(void)
{
#ifdef NOMD5
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
#else
if (client) // cannot change remotely
{
CONS_Printf(M_GetText("Only the server can use this.\n"));
return;
}
if (COM_Argc() != 2)
{
CONS_Printf(M_GetText("joinpassword <password>: set a password to join the server\nUse -remove to disable the password.\n"));
return;
}
if (strcmp(COM_Argv(1), "-remove") == 0)
{
joinpasswordset = false;
CONS_Printf(M_GetText("Join password removed.\n"));
}
else
{
D_SetJoinPassword(COM_Argv(1));
CONS_Printf(M_GetText("Join password set.\n"));
}
#endif
}
static void Command_MotD_f(void)
{
size_t i, j;

View file

@ -126,7 +126,7 @@ extern consvar_t cv_karteliminatelast;
extern consvar_t cv_votetime;
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes;
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize;
extern consvar_t cv_itemfinder;
@ -145,6 +145,8 @@ extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionb
#ifdef NEWPING
extern consvar_t cv_maxping;
extern consvar_t cv_pingtimeout;
extern consvar_t cv_showping;
#endif
extern consvar_t cv_skipmapcheck;
@ -246,6 +248,14 @@ void RemoveAdminPlayer(INT32 playernum);
void ItemFinder_OnChange(void);
void D_SetPassword(const char *pw);
extern consvar_t cv_dummyjoinpassword;
extern boolean joinpasswordset;
boolean D_IsJoinPasswordOn(void);
void D_ComputeChallengeAnswer(UINT8 *question, const char *pw, UINT8 *answer);
void D_SetJoinPassword(const char *pw);
boolean D_VerifyJoinPasswordChallenge(UINT8 num, UINT8 *answer);
void D_MakeJoinPasswordChallenge(UINT8 *num, UINT8 *question);
// used for the player setup menu
UINT8 CanChangeSkin(INT32 playernum);

View file

@ -32,13 +32,7 @@
// Extra abilities/settings for skins (combinable stuff)
typedef enum
{
SF_SUPER = 1, // Can turn super in singleplayer/co-op mode.
SF_SUPERANIMS = 1<<1, // If super, use the super sonic animations
SF_SUPERSPIN = 1<<2, // Should spin frames be played while super?
SF_HIRES = 1<<3, // Draw the sprite 2x as small?
SF_NOSKID = 1<<4, // No skid particles etc
SF_NOSPEEDADJUST = 1<<5, // Skin-specific version of disablespeedadjust
SF_RUNONWATER = 1<<6, // Run on top of water FOFs?
SF_HIRES = 1, // Draw the sprite 2x as small?
} skinflags_t;
//Primary and secondary skin abilities
@ -275,6 +269,7 @@ typedef enum
k_nextcheck, // Next checkpoint distance; for p_user.c (was "pw_ncd")
k_waypoint, // Waypoints.
k_starpostwp, // Temporarily stores player waypoint for... some reason. Used when respawning and finishing.
k_starpostflip, // the last starpost we hit requires flipping?
k_respawn, // Timer for the DEZ laser respawn effect
k_dropdash, // Charge up for respawn Drop Dash
@ -354,6 +349,7 @@ typedef enum
k_getsparks, // Disable drift sparks at low speed, JUST enough to give acceleration the actual headstart above speed
k_jawztargetdelay, // Delay for Jawz target switching, to make it less twitchy
k_spectatewait, // How long have you been waiting as a spectator
k_growcancel, // Hold the item button down to cancel Grow
NUMKARTSTUFF
} kartstufftype_t;
@ -571,6 +567,8 @@ typedef struct player_s
UINT8 bot;
tic_t jointime; // Timer when player joins game to change skin/color
UINT8 splitscreenindex;
#ifdef HWRENDER
fixed_t fovadd; // adjust FOV for hw rendering
#endif

View file

@ -3108,11 +3108,6 @@ static void readmaincfg(MYFILE *f)
if (creditscutscene > 128)
creditscutscene = 128;
}
else if (fastcmp(word, "DISABLESPEEDADJUST"))
{
DEH_WriteUndoline(word, va("%d", disableSpeedAdjust), UNDO_NONE);
disableSpeedAdjust = (value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "NUMDEMOS"))
{
DEH_WriteUndoline(word, va("%d", numDemos), UNDO_NONE);
@ -7155,6 +7150,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_KARMAFIREWORK4",
"S_KARMAFIREWORKTRAIL",
// Opaque smoke version, to prevent lag
"S_OPAQUESMOKE1",
"S_OPAQUESMOKE2",
"S_OPAQUESMOKE3",
"S_OPAQUESMOKE4",
"S_OPAQUESMOKE5",
#ifdef SEENAMES
"S_NAMECHECK",
#endif
@ -8139,89 +8141,164 @@ static const char *const ML_LIST[16] = {
// This DOES differ from r_draw's Color_Names, unfortunately.
// Also includes Super colors
static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
"NONE", // 00 // SKINCOLOR_NONE
"WHITE", // 01 // SKINCOLOR_WHITE
"SILVER", // 02 // SKINCOLOR_SILVER
"GREY", // 03 // SKINCOLOR_GREY
"NICKEL", // 04 // SKINCOLOR_NICKEL
"BLACK", // 05 // SKINCOLOR_BLACK
"SEPIA", // 06 // SKINCOLOR_SEPIA
"BEIGE", // 07 // SKINCOLOR_BEIGE
"BROWN", // 08 // SKINCOLOR_BROWN
"LEATHER", // 09 // SKINCOLOR_LEATHER
"SALMON", // 10 // SKINCOLOR_SALMON
"PINK", // 11 // SKINCOLOR_PINK
"ROSE", // 12 // SKINCOLOR_ROSE
"RUBY", // 13 // SKINCOLOR_RUBY
"RASPBERRY", // 14 // SKINCOLOR_RASPBERRY
"RED", // 15 // SKINCOLOR_RED
"CRIMSON", // 16 // SKINCOLOR_CRIMSON
"KETCHUP", // 17 // SKINCOLOR_KETCHUP
"DAWN", // 18 // SKINCOLOR_DAWN
"CREAMSICLE", // 19 // SKINCOLOR_CREAMSICLE
"ORANGE", // 20 // SKINCOLOR_ORANGE
"PUMPKIN", // 21 // SKINCOLOR_PUMPKIN
"ROSEWOOD", // 22 // SKINCOLOR_ROSEWOOD
"BURGUNDY", // 23 // SKINCOLOR_BURGUNDY
"TANGERINE", // 24 // SKINCOLOR_TANGERINE
"PEACH", // 25 // SKINCOLOR_PEACH
"CARAMEL", // 26 // SKINCOLOR_CARAMEL
"GOLD", // 27 // SKINCOLOR_GOLD
"BRONZE", // 28 // SKINCOLOR_BRONZE
"YELLOW", // 29 // SKINCOLOR_YELLOW
"MUSTARD", // 30 // SKINCOLOR_MUSTARD
"OLIVE", // 31 // SKINCOLOR_OLIVE
"VOMIT", // 32 // SKINCOLOR_VOMIT
"GARDEN", // 33 // SKINCOLOR_GARDEN
"LIME", // 34 // SKINCOLOR_LIME
"TEA", // 35 // SKINCOLOR_TEA
"PISTACHIO", // 36 // SKINCOLOR_PISTACHIO
"ROBOHOOD", // 37 // SKINCOLOR_ROBOHOOD
"MOSS", // 38 // SKINCOLOR_MOSS
"MINT", // 39 // SKINCOLOR_MINT
"GREEN", // 40 // SKINCOLOR_GREEN
"PINETREE", // 41 // SKINCOLOR_PINETREE
"EMERALD", // 42 // SKINCOLOR_EMERALD
"SWAMP", // 43 // SKINCOLOR_SWAMP
"DREAM", // 44 // SKINCOLOR_DREAM
"AQUA", // 45 // SKINCOLOR_AQUA
"TEAL", // 46 // SKINCOLOR_TEAL
"CYAN", // 47 // SKINCOLOR_CYAN
"JAWZ", // 48 // SKINCOLOR_JAWZ
"CERULEAN", // 49 // SKINCOLOR_CERULEAN
"NAVY", // 50 // SKINCOLOR_NAVY
"SLATE", // 51 // SKINCOLOR_SLATE
"STEEL", // 52 // SKINCOLOR_STEEL
"JET", // 53 // SKINCOLOR_JET
"SAPPHIRE", // 54 // SKINCOLOR_SAPPHIRE
"PERIWINKLE", // 55 // SKINCOLOR_PERIWINKLE
"BLUE", // 56 // SKINCOLOR_BLUE
"BLUEBERRY", // 57 // SKINCOLOR_BLUEBERRY
"DUSK", // 58 // SKINCOLOR_DUSK
"PURPLE", // 59 // SKINCOLOR_PURPLE
"LAVENDER", // 60 // SKINCOLOR_LAVENDER
"BYZANTIUM", // 61 // SKINCOLOR_BYZANTIUM
"POMEGRANATE", // 62 // SKINCOLOR_POMEGRANATE
"LILAC", // 63 // SKINCOLOR_LILAC
"NONE", // SKINCOLOR_NONE
"WHITE", // SKINCOLOR_WHITE
"SILVER", // SKINCOLOR_SILVER
"GREY", // SKINCOLOR_GREY
"NICKEL", // SKINCOLOR_NICKEL
"BLACK", // SKINCOLOR_BLACK
"FAIRY", // SKINCOLOR_FAIRY
"POPCORN", // SKINCOLOR_POPCORN
"SEPIA", // SKINCOLOR_SEPIA
"BEIGE", // SKINCOLOR_BEIGE
"BROWN", // SKINCOLOR_BROWN
"LEATHER", // SKINCOLOR_LEATHER
"SALMON", // SKINCOLOR_SALMON
"PINK", // SKINCOLOR_PINK
"ROSE", // SKINCOLOR_ROSE
"BRICK", // SKINCOLOR_BRICK
"RUBY", // SKINCOLOR_RUBY
"RASPBERRY", // SKINCOLOR_RASPBERRY
"CHERRY", // SKINCOLOR_CHERRY
"RED", // SKINCOLOR_RED
"CRIMSON", // SKINCOLOR_CRIMSON
"MAROON", // SKINCOLOR_MAROON
"FLAME", // SKINCOLOR_FLAME
"SCARLET", // SKINCOLOR_SCARLET
"KETCHUP", // SKINCOLOR_KETCHUP
"DAWN", // SKINCOLOR_DAWN
"SUNSET", // SKINCOLOR_SUNSET
"CREAMSICLE", // SKINCOLOR_CREAMSICLE
"ORANGE", // SKINCOLOR_ORANGE
"PUMPKIN", // SKINCOLOR_PUMPKIN
"ROSEWOOD", // SKINCOLOR_ROSEWOOD
"BURGUNDY", // SKINCOLOR_BURGUNDY
"TANGERINE", // SKINCOLOR_TANGERINE
"PEACH", // SKINCOLOR_PEACH
"CARAMEL", // SKINCOLOR_CARAMEL
"CREAM", // SKINCOLOR_CREAM
"GOLD", // SKINCOLOR_GOLD
"ROYAL", // SKINCOLOR_ROYAL
"BRONZE", // SKINCOLOR_BRONZE
"COPPER", // SKINCOLOR_COPPER
"YELLOW", // SKINCOLOR_YELLOW
"MUSTARD", // SKINCOLOR_MUSTARD
"OLIVE", // SKINCOLOR_OLIVE
"VOMIT", // SKINCOLOR_VOMIT
"GARDEN", // SKINCOLOR_GARDEN
"LIME", // SKINCOLOR_LIME
"HANDHELD", // SKINCOLOR_HANDHELD
"TEA", // SKINCOLOR_TEA
"PISTACHIO", // SKINCOLOR_PISTACHIO
"MOSS", // SKINCOLOR_MOSS
"CAMOUFLAGE", // SKINCOLOR_CAMOUFLAGE
"ROBOHOOD", // SKINCOLOR_ROBOHOOD
"MINT", // SKINCOLOR_MINT
"GREEN", // SKINCOLOR_GREEN
"PINETREE", // SKINCOLOR_PINETREE
"EMERALD", // SKINCOLOR_EMERALD
"SWAMP", // SKINCOLOR_SWAMP
"DREAM", // SKINCOLOR_DREAM
"PLAGUE", // SKINCOLOR_PLAGUE
"ALGAE", // SKINCOLOR_ALGAE
"CARIBBEAN", // SKINCOLOR_CARIBBEAN
"AQUA", // SKINCOLOR_AQUA
"TEAL", // SKINCOLOR_TEAL
"CYAN", // SKINCOLOR_CYAN
"JAWZ", // SKINCOLOR_JAWZ
"CERULEAN", // SKINCOLOR_CERULEAN
"NAVY", // SKINCOLOR_NAVY
"PLATINUM", // SKINCOLOR_PLATINUM
"SLATE", // SKINCOLOR_SLATE
"STEEL", // SKINCOLOR_STEEL
"RUST", // SKINCOLOR_RUST
"JET", // SKINCOLOR_JET
"SAPPHIRE", // SKINCOLOR_SAPPHIRE
"PERIWINKLE", // SKINCOLOR_PERIWINKLE
"BLUE", // SKINCOLOR_BLUE
"BLUEBERRY", // SKINCOLOR_BLUEBERRY
"NOVA", // SKINCOLOR_NOVA
"PASTEL", // SKINCOLOR_PASTEL
"MOONSLAM", // SKINCOLOR_MOONSLAM
"ULTRAVIOLET", // SKINCOLOR_ULTRAVIOLET
"DUSK", // SKINCOLOR_DUSK
"BUBBLEGUM", // SKINCOLOR_BUBBLEGUM
"PURPLE", // SKINCOLOR_PURPLE
"FUCHSIA", // SKINCOLOR_FUCHSIA
"TOXIC", // SKINCOLOR_TOXIC
"MAUVE", // SKINCOLOR_MAUVE
"LAVENDER", // SKINCOLOR_LAVENDER
"BYZANTIUM", // SKINCOLOR_BYZANTIUM
"POMEGRANATE", // SKINCOLOR_POMEGRANATE
"LILAC", // SKINCOLOR_LILAC
// Super special awesome Super flashing colors!
"SUPER1", // SKINCOLOR_SUPER1
"SUPER2", // SKINCOLOR_SUPER2,
"SUPER3", // SKINCOLOR_SUPER3,
"SUPER4", // SKINCOLOR_SUPER4,
"SUPER5", // SKINCOLOR_SUPER5,
// Super Tails
"TSUPER1", // SKINCOLOR_TSUPER1,
"TSUPER2", // SKINCOLOR_TSUPER2,
"TSUPER3", // SKINCOLOR_TSUPER3,
"TSUPER4", // SKINCOLOR_TSUPER4,
"TSUPER5", // SKINCOLOR_TSUPER5,
// Super Knuckles
"KSUPER1", // SKINCOLOR_KSUPER1,
"KSUPER2", // SKINCOLOR_KSUPER2,
"KSUPER3", // SKINCOLOR_KSUPER3,
"KSUPER4", // SKINCOLOR_KSUPER4,
"KSUPER5" // SKINCOLOR_KSUPER5,
// Special super colors
// Super Sonic Yellow
"SUPER1", // SKINCOLOR_SUPER1
"SUPER2", // SKINCOLOR_SUPER2,
"SUPER3", // SKINCOLOR_SUPER3,
"SUPER4", // SKINCOLOR_SUPER4,
"SUPER5", // SKINCOLOR_SUPER5,
// Super Tails Orange
"TSUPER1", // SKINCOLOR_TSUPER1,
"TSUPER2", // SKINCOLOR_TSUPER2,
"TSUPER3", // SKINCOLOR_TSUPER3,
"TSUPER4", // SKINCOLOR_TSUPER4,
"TSUPER5", // SKINCOLOR_TSUPER5,
// Super Knuckles Red
"KSUPER1", // SKINCOLOR_KSUPER1,
"KSUPER2", // SKINCOLOR_KSUPER2,
"KSUPER3", // SKINCOLOR_KSUPER3,
"KSUPER4", // SKINCOLOR_KSUPER4,
"KSUPER5", // SKINCOLOR_KSUPER5,
// Hyper Sonic Pink
"PSUPER1", // SKINCOLOR_PSUPER1,
"PSUPER2", // SKINCOLOR_PSUPER2,
"PSUPER3", // SKINCOLOR_PSUPER3,
"PSUPER4", // SKINCOLOR_PSUPER4,
"PSUPER5", // SKINCOLOR_PSUPER5,
// Hyper Sonic Blue
"BSUPER1", // SKINCOLOR_BSUPER1,
"BSUPER2", // SKINCOLOR_BSUPER2,
"BSUPER3", // SKINCOLOR_BSUPER3,
"BSUPER4", // SKINCOLOR_BSUPER4,
"BSUPER5", // SKINCOLOR_BSUPER5,
// Aqua Super
"ASUPER1", // SKINCOLOR_ASUPER1,
"ASUPER2", // SKINCOLOR_ASUPER2,
"ASUPER3", // SKINCOLOR_ASUPER3,
"ASUPER4", // SKINCOLOR_ASUPER4,
"ASUPER5", // SKINCOLOR_ASUPER5,
// Hyper Sonic Green
"GSUPER1", // SKINCOLOR_GSUPER1,
"GSUPER2", // SKINCOLOR_GSUPER2,
"GSUPER3", // SKINCOLOR_GSUPER3,
"GSUPER4", // SKINCOLOR_GSUPER4,
"GSUPER5", // SKINCOLOR_GSUPER5,
// Hyper Sonic White
"WSUPER1", // SKINCOLOR_WSUPER1,
"WSUPER2", // SKINCOLOR_WSUPER2,
"WSUPER3", // SKINCOLOR_WSUPER3,
"WSUPER4", // SKINCOLOR_WSUPER4,
"WSUPER5", // SKINCOLOR_WSUPER5,
// Creamy Super (Shadow?)
"CSUPER1", // SKINCOLOR_CSUPER1,
"CSUPER2", // SKINCOLOR_CSUPER2,
"CSUPER3", // SKINCOLOR_CSUPER3,
"CSUPER4", // SKINCOLOR_CSUPER4,
"CSUPER5" // SKINCOLOR_CSUPER5,
};
static const char *const POWERS_LIST[] = {
@ -8259,6 +8336,7 @@ static const char *const POWERS_LIST[] = {
"INGOOP" // In goop
};
#ifdef HAVE_BLUA
static const char *const KARTSTUFF_LIST[] = {
"POSITION",
"OLDPOSITION",
@ -8267,6 +8345,7 @@ static const char *const KARTSTUFF_LIST[] = {
"NEXTCHECK",
"WAYPOINT",
"STARPOSTWP",
"STARPOSTFLIP",
"RESPAWN",
"DROPDASH",
@ -8340,8 +8419,10 @@ static const char *const KARTSTUFF_LIST[] = {
"ITEMBLINKMODE",
"GETSPARKS",
"JAWZTARGETDELAY",
"SPECTATEWAIT"
"SPECTATEWAIT",
"GROWCANCEL"
};
#endif
static const char *const HUDITEMS_LIST[] = {
"LIVESNAME",
@ -8564,13 +8645,7 @@ struct {
{"RW_RAIL",RW_RAIL},
// Character flags (skinflags_t)
{"SF_SUPER",SF_SUPER},
{"SF_SUPERANIMS",SF_SUPERANIMS},
{"SF_SUPERSPIN",SF_SUPERSPIN},
{"SF_HIRES",SF_HIRES},
{"SF_NOSKID",SF_NOSKID},
{"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST},
{"SF_RUNONWATER",SF_RUNONWATER},
// Character abilities!
// Primary
@ -9047,20 +9122,6 @@ static powertype_t get_power(const char *word)
return pw_invulnerability;
}
static kartstufftype_t get_kartstuff(const char *word)
{ // Returns the vlaue of k_ enumerations
kartstufftype_t i;
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("K_",word,2))
word += 2; // take off the k_
for (i = 0; i < NUMKARTSTUFF; i++)
if (fastcmp(word, KARTSTUFF_LIST[i]))
return i;
deh_warning("Couldn't find power named 'k_%s'",word);
return k_position;
}
/// \todo Make ANY of this completely over-the-top math craziness obey the order of operations.
static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; }
static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; }
@ -9857,6 +9918,9 @@ static inline int lib_getenum(lua_State *L)
} else if (fastcmp(word,"indirectitemcooldown")) {
lua_pushinteger(L, indirectitemcooldown);
return 1;
} else if (fastcmp(word,"hyubgone")) {
lua_pushinteger(L, hyubgone);
return 1;
} else if (fastcmp(word,"thwompsactive")) {
lua_pushboolean(L, thwompsactive);
return 1;

View file

@ -94,6 +94,9 @@ void I_FinishUpdate (void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
//blast it to the screen
// this code sucks
//memcpy(dascreen,screens[0],screenwidth*screenheight);

View file

@ -150,9 +150,9 @@ extern FILE *logstream;
// we use comprevision and compbranch instead.
#else
#define VERSION 100 // Game version
#define SUBVERSION 3 // more precise version number
#define VERSIONSTRING "v1.0.3"
#define VERSIONSTRINGW L"v1.0.3"
#define SUBVERSION 4 // more precise version number
#define VERSIONSTRING "v1.0.4"
#define VERSIONSTRINGW L"v1.0.4"
// Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates!
#endif
@ -221,7 +221,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 3
#define MODVERSION 4
// Filter consvars by version
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
@ -244,7 +244,7 @@ extern FILE *logstream;
// NOTE: it needs more than this to increase the number of players...
#define MAXPLAYERS 16
#define MAXSKINS 64
#define MAXSKINS 128
#define PLAYERSMASK (MAXPLAYERS-1)
#define MAXPLAYERNAME 21
@ -256,6 +256,8 @@ typedef enum
SKINCOLOR_GREY,
SKINCOLOR_NICKEL,
SKINCOLOR_BLACK,
SKINCOLOR_FAIRY,
SKINCOLOR_POPCORN,
SKINCOLOR_SEPIA,
SKINCOLOR_BEIGE,
SKINCOLOR_BROWN,
@ -263,12 +265,18 @@ typedef enum
SKINCOLOR_SALMON,
SKINCOLOR_PINK,
SKINCOLOR_ROSE,
SKINCOLOR_BRICK,
SKINCOLOR_RUBY,
SKINCOLOR_RASPBERRY,
SKINCOLOR_CHERRY,
SKINCOLOR_RED,
SKINCOLOR_CRIMSON,
SKINCOLOR_MAROON,
SKINCOLOR_FLAME,
SKINCOLOR_SCARLET,
SKINCOLOR_KETCHUP,
SKINCOLOR_DAWN,
SKINCOLOR_SUNSET,
SKINCOLOR_CREAMSICLE,
SKINCOLOR_ORANGE,
SKINCOLOR_PUMPKIN,
@ -277,68 +285,130 @@ typedef enum
SKINCOLOR_TANGERINE,
SKINCOLOR_PEACH,
SKINCOLOR_CARAMEL,
SKINCOLOR_CREAM,
SKINCOLOR_GOLD,
SKINCOLOR_ROYAL,
SKINCOLOR_BRONZE,
SKINCOLOR_COPPER,
SKINCOLOR_YELLOW,
SKINCOLOR_MUSTARD,
SKINCOLOR_OLIVE,
SKINCOLOR_VOMIT,
SKINCOLOR_GARDEN,
SKINCOLOR_LIME,
SKINCOLOR_HANDHELD,
SKINCOLOR_TEA,
SKINCOLOR_PISTACHIO,
SKINCOLOR_ROBOHOOD,
SKINCOLOR_MOSS,
SKINCOLOR_CAMOUFLAGE,
SKINCOLOR_ROBOHOOD,
SKINCOLOR_MINT,
SKINCOLOR_GREEN,
SKINCOLOR_PINETREE,
SKINCOLOR_EMERALD,
SKINCOLOR_SWAMP,
SKINCOLOR_DREAM,
SKINCOLOR_PLAGUE,
SKINCOLOR_ALGAE,
SKINCOLOR_CARIBBEAN,
SKINCOLOR_AQUA,
SKINCOLOR_TEAL,
SKINCOLOR_CYAN,
SKINCOLOR_JAWZ, // Oni's torment
SKINCOLOR_CERULEAN,
SKINCOLOR_NAVY,
SKINCOLOR_PLATINUM,
SKINCOLOR_SLATE,
SKINCOLOR_STEEL,
SKINCOLOR_RUST,
SKINCOLOR_JET,
SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave - slender aphrodite has overcome me with longing for a girl
SKINCOLOR_PERIWINKLE,
SKINCOLOR_BLUE,
SKINCOLOR_BLUEBERRY,
SKINCOLOR_NOVA,
SKINCOLOR_PASTEL,
SKINCOLOR_MOONSLAM,
SKINCOLOR_ULTRAVIOLET,
SKINCOLOR_DUSK,
SKINCOLOR_BUBBLEGUM,
SKINCOLOR_PURPLE,
SKINCOLOR_FUCHSIA,
SKINCOLOR_TOXIC,
SKINCOLOR_MAUVE,
SKINCOLOR_LAVENDER,
SKINCOLOR_BYZANTIUM,
SKINCOLOR_POMEGRANATE,
SKINCOLOR_LILAC,
// Careful! MAXSKINCOLORS cannot be greater than 0x40 -- Which it is now.
// "Careful! MAXSKINCOLORS cannot be greater than 0x40 -- Which it is now."
// (This comment is a dirty liar! This is only limited by the integer type, so 255 for UINT8.)
MAXSKINCOLORS,
// Super special awesome Super flashing colors!
// Super Sonic Yellow
SKINCOLOR_SUPER1 = MAXSKINCOLORS,
SKINCOLOR_SUPER2,
SKINCOLOR_SUPER3,
SKINCOLOR_SUPER4,
SKINCOLOR_SUPER5,
// Super Tails
// Super Tails Orange
SKINCOLOR_TSUPER1,
SKINCOLOR_TSUPER2,
SKINCOLOR_TSUPER3,
SKINCOLOR_TSUPER4,
SKINCOLOR_TSUPER5,
// Super Knuckles
// Super Knuckles Red
SKINCOLOR_KSUPER1,
SKINCOLOR_KSUPER2,
SKINCOLOR_KSUPER3,
SKINCOLOR_KSUPER4,
SKINCOLOR_KSUPER5,
// Hyper Sonic Pink
SKINCOLOR_PSUPER1,
SKINCOLOR_PSUPER2,
SKINCOLOR_PSUPER3,
SKINCOLOR_PSUPER4,
SKINCOLOR_PSUPER5,
// Hyper Sonic Blue
SKINCOLOR_BSUPER1,
SKINCOLOR_BSUPER2,
SKINCOLOR_BSUPER3,
SKINCOLOR_BSUPER4,
SKINCOLOR_BSUPER5,
// Aqua Super
SKINCOLOR_ASUPER1,
SKINCOLOR_ASUPER2,
SKINCOLOR_ASUPER3,
SKINCOLOR_ASUPER4,
SKINCOLOR_ASUPER5,
// Hyper Sonic Green
SKINCOLOR_GSUPER1,
SKINCOLOR_GSUPER2,
SKINCOLOR_GSUPER3,
SKINCOLOR_GSUPER4,
SKINCOLOR_GSUPER5,
// Hyper Sonic White
SKINCOLOR_WSUPER1,
SKINCOLOR_WSUPER2,
SKINCOLOR_WSUPER3,
SKINCOLOR_WSUPER4,
SKINCOLOR_WSUPER5,
// Creamy Super (Shadow?)
SKINCOLOR_CSUPER1,
SKINCOLOR_CSUPER2,
SKINCOLOR_CSUPER3,
SKINCOLOR_CSUPER4,
SKINCOLOR_CSUPER5,
MAXTRANSLATIONS
} skincolors_t;
@ -472,13 +542,17 @@ INT32 I_GetKey(void);
#define max(x, y) (((x) > (y)) ? (x) : (y))
#endif
#ifndef M_PIl
#define M_PIl 3.1415926535897932384626433832795029L
#endif
// Floating point comparison epsilons from float.h
#ifndef FLT_EPSILON
#define FLT_EPSILON 1.1920928955078125e-7f
#endif
#ifndef DBL_EPSILON
#define DBL_EPSILON 2.2204460492503131e-16
#define DBL_EPSILON 2.2204460492503131e-16l
#endif
// An assert-type mechanism.

View file

@ -57,7 +57,6 @@ extern boolean modifiedgame;
extern boolean majormods;
extern UINT16 mainwads;
extern boolean savemoddata; // This mod saves time/emblem data.
extern boolean disableSpeedAdjust; // Don't alter the duration of player states if true
extern boolean imcontinuing; // Temporary flag while continuing
extern boolean metalrecording;
@ -469,6 +468,7 @@ extern boolean comeback;
extern SINT8 battlewanted[4];
extern tic_t wantedcalcdelay;
extern tic_t indirectitemcooldown;
extern tic_t hyubgone;
extern tic_t mapreset;
extern UINT8 nospectategrief;
extern boolean thwompsactive;

View file

@ -611,7 +611,7 @@ void F_CreditDrawer(void)
if (credits_pics[i].colorize != SKINCOLOR_NONE)
{
colormap = R_GetTranslationColormap(TC_RAINBOW, credits_pics[i].colorize, 0);
colormap = R_GetTranslationColormap(TC_RAINBOW, credits_pics[i].colorize, GTC_MENUCACHE);
sc = FRACUNIT; // quick hack so I don't have to add another field to credits_pics
}
@ -643,16 +643,34 @@ void F_CreditDrawer(void)
if (((y>>FRACBITS) * vid.dupy) > vid.height)
break;
}
}
void F_CreditTicker(void)
{
// "Simulate" the drawing of the credits so that dedicated mode doesn't get stuck
UINT16 i;
fixed_t y = (80<<FRACBITS) - 5*(animtimer<<FRACBITS)/8;
// Draw credits text on top
for (i = 0; credits[i]; i++)
{
switch(credits[i][0])
{
case 0: y += 80<<FRACBITS; break;
case 1: y += 30<<FRACBITS; break;
default: y += 12<<FRACBITS; break;
}
if (FixedMul(y,vid.dupy) > vid.height)
break;
}
// Do this here rather than in the drawer you doofus! (this is why dedicated mode broke at credits)
if (!credits[i] && y <= 120<<FRACBITS && !finalecount)
{
timetonext = 5*TICRATE+1;
finalecount = 5*TICRATE;
}
}
void F_CreditTicker(void)
{
if (timetonext)
timetonext--;
else
@ -1103,6 +1121,10 @@ void F_StartWaitingPlayers(void)
finalecount = 0;
randskin = M_RandomKey(numskins);
if (waitcolormap)
Z_Free(waitcolormap);
waitcolormap = R_GetTranslationColormap(randskin, skins[randskin].prefcolor, 0);
for (i = 0; i < 2; i++)

View file

@ -92,7 +92,6 @@ boolean majormods = false; // Set if Lua/Gameplay SOC/replacement map has been a
boolean savemoddata = false;
UINT8 paused;
UINT8 modeattacking = ATTACKING_NONE;
boolean disableSpeedAdjust = true;
boolean imcontinuing = false;
boolean runemeraldmanager = false;
@ -267,6 +266,7 @@ SINT8 pickedvote; // What vote the host rolls
SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points
tic_t wantedcalcdelay; // Time before it recalculates WANTED
tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded
tic_t hyubgone; // Cooldown before hyudoro is allowed to be rerolled
tic_t mapreset; // Map reset delay when enough players have joined an empty game
UINT8 nospectategrief; // How many players need to be in-game to eliminate last; for preventing spectate griefing
boolean thwompsactive; // Thwomps activate on lap 2
@ -437,6 +437,9 @@ consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, N
static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}};
consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// Pause game upon window losing focus
consvar_t cv_pauseifunfocused = {"pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
// Display song credits
consvar_t cv_songcredits = {"songcredits", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -1820,80 +1823,6 @@ static INT32 spectatedelay, spectatedelay2, spectatedelay3, spectatedelay4 = 0;
//
boolean G_Responder(event_t *ev)
{
// allow spy mode changes even during the demo
if (gamestate == GS_LEVEL && ev->type == ev_keydown
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]))
{
if (splitscreen || !netgame)
displayplayer = consoleplayer;
else
{
UINT8 i = 0; // spy mode
for (i = 0; i < MAXPLAYERS; i++)
{
displayplayer++;
if (displayplayer == MAXPLAYERS)
displayplayer = 0;
if (displayplayer == consoleplayer)
break; // End loop
if (!playeringame[displayplayer])
continue;
if (players[displayplayer].spectator)
continue;
// SRB2Kart: Only go through players who are actually playing
if (players[displayplayer].exiting)
continue;
if (players[displayplayer].pflags & PF_TIMEOVER)
continue;
// I don't know if we want this actually, but I'll humor the suggestion anyway
if (G_BattleGametype())
{
if (players[displayplayer].kartstuff[k_bumper] <= 0)
continue;
}
// SRB2Kart: we have no team-based modes, YET...
/*if (G_GametypeHasTeams())
{
if (players[consoleplayer].ctfteam
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
continue;
}
else if (gametype == GT_HIDEANDSEEK)
{
if (players[consoleplayer].pflags & PF_TAGIT)
continue;
}
// Other Tag-based gametypes?
else if (G_TagGametype())
{
if (!players[consoleplayer].spectator
&& (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT))
continue;
}
else if (G_GametypeHasSpectators() && G_BattleGametype())
{
if (!players[consoleplayer].spectator)
continue;
}*/
break;
}
// change statusbar also if playing back demo
if (singledemo)
ST_changeDemoView();
return true;
}
}
// any other key pops up menu if in demos
if (gameaction == ga_nothing && !singledemo &&
((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN))
@ -1971,6 +1900,80 @@ boolean G_Responder(event_t *ev)
if (HU_Responder(ev))
return true; // chat ate the event
// allow spy mode changes even during the demo
if (gamestate == GS_LEVEL && ev->type == ev_keydown
&& (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1]))
{
if (splitscreen || !netgame)
displayplayer = consoleplayer;
else
{
UINT8 i = 0; // spy mode
for (i = 0; i < MAXPLAYERS; i++)
{
displayplayer++;
if (displayplayer == MAXPLAYERS)
displayplayer = 0;
if (displayplayer == consoleplayer)
break; // End loop
if (!playeringame[displayplayer])
continue;
if (players[displayplayer].spectator)
continue;
// SRB2Kart: Only go through players who are actually playing
if (players[displayplayer].exiting)
continue;
if (players[displayplayer].pflags & PF_TIMEOVER)
continue;
// I don't know if we want this actually, but I'll humor the suggestion anyway
if (G_BattleGametype())
{
if (players[displayplayer].kartstuff[k_bumper] <= 0)
continue;
}
// SRB2Kart: we have no team-based modes, YET...
/*if (G_GametypeHasTeams())
{
if (players[consoleplayer].ctfteam
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
continue;
}
else if (gametype == GT_HIDEANDSEEK)
{
if (players[consoleplayer].pflags & PF_TAGIT)
continue;
}
// Other Tag-based gametypes?
else if (G_TagGametype())
{
if (!players[consoleplayer].spectator
&& (players[consoleplayer].pflags & PF_TAGIT) != (players[displayplayer].pflags & PF_TAGIT))
continue;
}
else if (G_GametypeHasSpectators() && G_BattleGametype())
{
if (!players[consoleplayer].spectator)
continue;
}*/
break;
}
// change statusbar also if playing back demo
if (singledemo)
ST_changeDemoView();
return true;
}
}
// update keys current state
G_MapEventsToControls(ev);
@ -2162,7 +2165,7 @@ void G_Ticker(boolean run)
G_CopyTiccmd(cmd, &netcmds[buf][i], 1);
// Use the leveltime sent in the player's ticcmd to determine control lag
cmd->latency = modeattacking ? 0 : min((leveltime & 0xFF) - cmd->latency, MAXPREDICTTICS-1); //@TODO add a cvar to allow setting this max
cmd->latency = modeattacking ? 0 : min(((leveltime & 0xFF) - cmd->latency) & 0xFF, MAXPREDICTTICS-1); //@TODO add a cvar to allow setting this max
}
}
@ -2357,6 +2360,7 @@ void G_PlayerReborn(INT32 player)
UINT8 skincolor;
INT32 skin;
tic_t jointime;
UINT8 splitscreenindex;
boolean spectator;
INT16 bot;
SINT8 pity;
@ -2371,6 +2375,7 @@ void G_PlayerReborn(INT32 player)
INT32 bumper;
INT32 comebackpoints;
INT32 wanted;
INT32 respawnflip;
boolean songcredit = false;
score = players[player].score;
@ -2380,6 +2385,7 @@ void G_PlayerReborn(INT32 player)
ctfteam = players[player].ctfteam;
exiting = players[player].exiting;
jointime = players[player].jointime;
splitscreenindex = players[player].splitscreenindex;
spectator = players[player].spectator;
pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_ANALOGMODE|PF_WANTSTOJOIN));
@ -2411,6 +2417,7 @@ void G_PlayerReborn(INT32 player)
starposty = players[player].starposty;
starpostz = players[player].starpostz;
starpostnum = players[player].starpostnum;
respawnflip = players[player].kartstuff[k_starpostflip]; //SRB2KART
starpostangle = players[player].starpostangle;
jumpfactor = players[player].jumpfactor;
thokitem = players[player].thokitem;
@ -2476,6 +2483,7 @@ void G_PlayerReborn(INT32 player)
p->pflags = pflags;
p->ctfteam = ctfteam;
p->jointime = jointime;
p->splitscreenindex = splitscreenindex;
p->spectator = spectator;
// save player config truth reborn
@ -2530,6 +2538,7 @@ void G_PlayerReborn(INT32 player)
p->kartstuff[k_comebacktimer] = comebacktime;
p->kartstuff[k_wanted] = wanted;
p->kartstuff[k_eggmanblame] = -1;
p->kartstuff[k_starpostflip] = respawnflip;
// Don't do anything immediately
p->pflags |= PF_USEDOWN;
@ -4947,7 +4956,8 @@ void G_WriteGhostTic(mobj_t *ghost)
// GZT_XYZ is only useful if you've moved 256 FRACUNITS or more in a single tic.
if (abs(ghost->x-oldghost.x) > MAXMOM
|| abs(ghost->y-oldghost.y) > MAXMOM
|| abs(ghost->z-oldghost.z) > MAXMOM)
|| abs(ghost->z-oldghost.z) > MAXMOM
|| (leveltime & 255) == 1) // Hack to enable slightly nicer resyncing
{
oldghost.x = ghost->x;
oldghost.y = ghost->y;
@ -4961,8 +4971,8 @@ void G_WriteGhostTic(mobj_t *ghost)
{
// For moving normally:
// Store one full byte of movement, plus one byte of fractional movement.
INT16 momx = (INT16)((ghost->x-oldghost.x)>>8);
INT16 momy = (INT16)((ghost->y-oldghost.y)>>8);
INT16 momx = (INT16)((ghost->x-oldghost.x + (1<<4))>>8);
INT16 momy = (INT16)((ghost->y-oldghost.y + (1<<4))>>8);
if (momx != oldghost.momx
|| momy != oldghost.momy)
{
@ -4972,7 +4982,7 @@ void G_WriteGhostTic(mobj_t *ghost)
WRITEINT16(demo_p,momx);
WRITEINT16(demo_p,momy);
}
momx = (INT16)((ghost->z-oldghost.z)>>8);
momx = (INT16)((ghost->z-oldghost.z + (1<<4))>>8);
if (momx != oldghost.momz)
{
oldghost.momz = momx;
@ -5076,8 +5086,9 @@ void G_WriteGhostTic(mobj_t *ghost)
void G_ConsGhostTic(void)
{
UINT8 ziptic;
UINT16 px,py,pz,gx,gy,gz;
fixed_t px,py,pz,gx,gy,gz;
mobj_t *testmo;
fixed_t syncleeway;
boolean nightsfail = false;
if (!demo_p || !demo_start)
@ -5094,6 +5105,7 @@ void G_ConsGhostTic(void)
oldghost.x = READFIXED(demo_p);
oldghost.y = READFIXED(demo_p);
oldghost.z = READFIXED(demo_p);
syncleeway = 0;
}
else
{
@ -5107,6 +5119,7 @@ void G_ConsGhostTic(void)
oldghost.x += oldghost.momx;
oldghost.y += oldghost.momy;
oldghost.z += oldghost.momz;
syncleeway = FRACUNIT;
}
if (ziptic & GZT_ANGLE)
demo_p++;
@ -5172,14 +5185,14 @@ void G_ConsGhostTic(void)
}
// Re-synchronise
px = testmo->x>>FRACBITS;
py = testmo->y>>FRACBITS;
pz = testmo->z>>FRACBITS;
gx = oldghost.x>>FRACBITS;
gy = oldghost.y>>FRACBITS;
gz = oldghost.z>>FRACBITS;
px = testmo->x;
py = testmo->y;
pz = testmo->z;
gx = oldghost.x;
gy = oldghost.y;
gz = oldghost.z;
if (nightsfail || px != gx || py != gy || pz != gz)
if (nightsfail || abs(px-gx) > syncleeway || abs(py-gy) > syncleeway || abs(pz-gz) > syncleeway)
{
if (demosynced)
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
@ -5290,17 +5303,16 @@ void G_GhostTicker(void)
INT32 type = -1;
if (g->mo->skin)
{
skin_t *skin = (skin_t *)g->mo->skin;
switch (ziptic & EZT_THOKMASK)
{
case EZT_THOK:
type = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem;
type = (UINT32)mobjinfo[MT_PLAYER].painchance;
break;
case EZT_SPIN:
type = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem;
type = (UINT32)mobjinfo[MT_PLAYER].damage;
break;
case EZT_REV:
type = skin->revitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem;
type = (UINT32)mobjinfo[MT_PLAYER].raisestate;
break;
}
}

View file

@ -56,6 +56,7 @@ extern INT16 rw_maximums[NUM_WEAPONS];
// used in game menu
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection/*, cv_compactscoreboard*/;
extern consvar_t cv_songcredits;
extern consvar_t cv_pauseifunfocused;
//extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4;
extern consvar_t cv_invertmouse/*, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove*/;
extern consvar_t cv_invertmouse2/*, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2*/;

View file

@ -1239,6 +1239,8 @@ void G_ClearAllControlKeys(void)
{
G_ClearControlKeys(gamecontrol, i);
G_ClearControlKeys(gamecontrolbis, i);
G_ClearControlKeys(gamecontrol3, i);
G_ClearControlKeys(gamecontrol4, i);
}
}

View file

@ -201,7 +201,7 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
// (do not accept hit with the extensions)
num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx;
frac = num / den;
if (frac < 0.0 || frac > 1.0)
if (frac < 0.0l || frac > 1.0l)
return NULL;
// now get the frac along the BSP line

View file

@ -72,6 +72,7 @@
#include "../v_video.h"
#include "hw_clip.h"
#include "hw_glob.h"
#include "../r_main.h"
#include "../r_state.h"
#include "../tables.h"
#include "r_opengl/r_opengl.h"
@ -328,7 +329,7 @@ angle_t gld_FrustumAngle(void)
// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
float render_fov = FIXED_TO_FLOAT(cv_grfov.value);
float render_fov = FIXED_TO_FLOAT(cv_fov.value);
float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right?
float render_multiplier = 64.0f / render_fovratio / RMUL;

View file

@ -61,9 +61,6 @@ typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR;
// ==========================================================================
// Constants
#ifndef M_PIl
#define M_PIl 3.1415926535897932384626433832795029L
#endif
#define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360
void DBG_Printf(const char *lpFmt, ...) /*FUNCPRINTF*/;

View file

@ -86,12 +86,10 @@ static UINT32 atohex(const char *s);
static void CV_filtermode_ONChange(void);
static void CV_anisotropic_ONChange(void);
static void CV_FogDensity_ONChange(void);
static void CV_grFov_OnChange(void);
// ==========================================================================
// 3D ENGINE COMMANDS & CONSOLE VARS
// ==========================================================================
static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
{HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"},
@ -112,7 +110,6 @@ static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NUL
static float HWRWipeCounter = 1.0f;
consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grFov_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned,
CV_FogDensity_ONChange, 0, NULL, NULL, 0, 0, NULL};
@ -5907,7 +5904,7 @@ void HWR_SetViewSize(void)
// ==========================================================================
void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
{
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
postimg_t *type;
UINT8 ssplayer = 0;
@ -6073,7 +6070,7 @@ if (0)
viewangle = localaiming4;
// Handle stuff when you are looking farther up or down.
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT))
if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
{
dup_viewangle += ANGLE_90;
HWR_ClearClipSegs();
@ -6151,7 +6148,7 @@ if (0)
// ==========================================================================
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
{
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
postimg_t *type;
UINT8 ssplayer = 0;
@ -6332,7 +6329,7 @@ if (0)
viewangle = localaiming4;
// Handle stuff when you are looking farther up or down.
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT))
if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
{
dup_viewangle += ANGLE_90;
HWR_ClearClipSegs();
@ -6455,11 +6452,6 @@ static void HWR_FoggingOn(void)
// ==========================================================================
static void CV_grFov_OnChange(void)
{
if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT)
CV_Set(&cv_grfov, cv_grfov.defaultvalue);
}
static void Command_GrStats_f(void)
{
@ -6482,7 +6474,6 @@ static void Command_GrStats_f(void)
void HWR_AddCommands(void)
{
CV_RegisterVar(&cv_grrounddown);
CV_RegisterVar(&cv_grfov);
CV_RegisterVar(&cv_grfogdensity);
CV_RegisterVar(&cv_grfiltermode);
CV_RegisterVar(&cv_granisotropicmode);

View file

@ -80,7 +80,6 @@ extern consvar_t cv_grstaticlighting;
extern consvar_t cv_grcoronas;
extern consvar_t cv_grcoronasize;
#endif
extern consvar_t cv_grfov;
extern consvar_t cv_grmd2;
extern consvar_t cv_grfog;
extern consvar_t cv_grfogcolor;

View file

@ -2056,10 +2056,11 @@ EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransfor
EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
{
static boolean special_splitscreen;
GLdouble used_fov;
pglLoadIdentity();
if (stransform)
{
boolean fovx90;
used_fov = stransform->fovxangle;
// keep a trace of the transformation for md2
memcpy(&md2_transform, stransform, sizeof (md2_transform));
@ -2074,36 +2075,29 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f);
pglTranslatef(-stransform->x, -stransform->z, -stransform->y);
pglMatrixMode(GL_PROJECTION);
pglLoadIdentity();
fovx90 = stransform->fovxangle > 0.0f && fabsf(stransform->fovxangle - 90.0f) < 0.5f;
special_splitscreen = (stransform->splitscreen == 1 && fovx90);
if (special_splitscreen)
GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
else
GLPerspective(stransform->fovxangle, ASPECT_RATIO);
#ifndef MINI_GL_COMPATIBILITY
pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
#endif
pglMatrixMode(GL_MODELVIEW);
special_splitscreen = (stransform->splitscreen == 1);
}
else
{
//Hurdler: is "fov" correct?
used_fov = fov;
pglScalef(1.0f, 1.0f, -1.0f);
pglMatrixMode(GL_PROJECTION);
pglLoadIdentity();
if (special_splitscreen)
GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
else
//Hurdler: is "fov" correct?
GLPerspective(fov, ASPECT_RATIO);
#ifndef MINI_GL_COMPATIBILITY
pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
#endif
pglMatrixMode(GL_MODELVIEW);
}
pglMatrixMode(GL_PROJECTION);
pglLoadIdentity();
if (special_splitscreen)
{
used_fov = atan(tan(used_fov*M_PIl/360.0l)*0.8l)*360/M_PIl;
GLPerspective(used_fov, 2*ASPECT_RATIO);
}
else
GLPerspective(used_fov, ASPECT_RATIO);
#ifndef MINI_GL_COMPATIBILITY
pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
#endif
pglMatrixMode(GL_MODELVIEW);
#ifndef MINI_GL_COMPATIBILITY
pglGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer)
#endif

View file

@ -74,6 +74,14 @@ patch_t *nightsnum[10]; // 0-9
patch_t *lt_font[LT_FONTSIZE];
patch_t *cred_font[CRED_FONTSIZE];
// ping font
// Note: I'd like to adress that at this point we might *REALLY* want to work towards a common drawString function that can take any font we want because this is really turning into a MESS. :V -Lat'
patch_t *pingnum[10];
patch_t *pinggfx[5]; // small ping graphic
patch_t *framecounter;
patch_t *frameslash; // framerate stuff. Used in screen.c
static player_t *plr;
boolean chat_on; // entering a chat message?
static char w_chat[HU_MAXMSGLEN];
@ -263,6 +271,8 @@ void HU_LoadGraphics(void)
tallnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "NGTNUM%d", i);
nightsnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
sprintf(buffer, "PINGN%d", i);
pingnum[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
}
// minus for negative tallnums
@ -295,6 +305,17 @@ void HU_LoadGraphics(void)
tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX);
songcreditbg = W_CachePatchName("K_SONGCR", PU_HUDGFX);
// cache ping gfx:
for (i = 0; i < 5; i++)
{
sprintf(buffer, "PINGGFX%d", i+1);
pinggfx[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);
}
// fps stuff
framecounter = W_CachePatchName("FRAMER", PU_HUDGFX);
frameslash = W_CachePatchName("FRAMESL", PU_HUDGFX);;
}
// Initialise Heads up
@ -757,44 +778,139 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
}
}
else
{
{
const UINT8 color = players[playernum].skincolor;
cstart = "\x83";
if (color <= SKINCOLOR_SILVER || color == SKINCOLOR_SLATE)
cstart = "\x80"; // white
else if (color <= SKINCOLOR_BLACK || color == SKINCOLOR_JET)
cstart = "\x86"; // V_GRAYMAP
else if (color <= SKINCOLOR_LEATHER)
cstart = "\x8e"; // V_BROWNMAP
else if (color <= SKINCOLOR_ROSE || color == SKINCOLOR_LILAC)
cstart = "\x8d"; // V_PINKMAP
else if (color <= SKINCOLOR_KETCHUP)
cstart = "\x85"; // V_REDMAP
else if (color <= SKINCOLOR_TANGERINE)
cstart = "\x87"; // V_ORANGEMAP
else if (color <= SKINCOLOR_CARAMEL)
cstart = "\x8f"; // V_PEACHMAP
else if (color <= SKINCOLOR_BRONZE)
cstart = "\x8A"; // V_GOLDMAP
else if (color <= SKINCOLOR_OLIVE)
cstart = "\x82"; // V_YELLOWMAP
else if (color <= SKINCOLOR_PISTACHIO)
cstart = "\x8b"; // V_TEAMAP
else if (color <= SKINCOLOR_DREAM || color == SKINCOLOR_LIME)
cstart = "\x83"; // V_GREENMAP
else if (color <= SKINCOLOR_NAVY || color == SKINCOLOR_SAPPHIRE)
cstart = "\x88"; // V_SKYMAP
else if (color <= SKINCOLOR_STEEL)
cstart = "\x8c"; // V_STEELMAP
else if (color <= SKINCOLOR_BLUEBERRY)
cstart = "\x84"; // V_BLUEMAP
else if (color == SKINCOLOR_PURPLE)
cstart = "\x81"; // V_PURPLEMAP
else //if (color <= SKINCOLOR_POMEGRANATE)
cstart = "\x89"; // V_LAVENDERMAP
}
switch (color)
{
case SKINCOLOR_WHITE:
case SKINCOLOR_SILVER:
case SKINCOLOR_SLATE:
cstart = "\x80"; // White
break;
case SKINCOLOR_GREY:
case SKINCOLOR_NICKEL:
case SKINCOLOR_BLACK:
case SKINCOLOR_JET:
cstart = "\x86"; // V_GRAYMAP
break;
case SKINCOLOR_SEPIA:
case SKINCOLOR_BEIGE:
case SKINCOLOR_BROWN:
case SKINCOLOR_LEATHER:
case SKINCOLOR_RUST:
cstart = "\x8e"; // V_BROWNMAP
break;
case SKINCOLOR_FAIRY:
case SKINCOLOR_SALMON:
case SKINCOLOR_PINK:
case SKINCOLOR_ROSE:
case SKINCOLOR_BRICK:
case SKINCOLOR_BUBBLEGUM:
case SKINCOLOR_LILAC:
cstart = "\x8d"; // V_PINKMAP
break;
case SKINCOLOR_RUBY:
case SKINCOLOR_RASPBERRY:
case SKINCOLOR_CHERRY:
case SKINCOLOR_RED:
case SKINCOLOR_CRIMSON:
case SKINCOLOR_MAROON:
case SKINCOLOR_FLAME:
case SKINCOLOR_SCARLET:
case SKINCOLOR_KETCHUP:
cstart = "\x85"; // V_REDMAP
break;
case SKINCOLOR_DAWN:
case SKINCOLOR_SUNSET:
case SKINCOLOR_CREAMSICLE:
case SKINCOLOR_ORANGE:
case SKINCOLOR_PUMPKIN:
case SKINCOLOR_ROSEWOOD:
case SKINCOLOR_BURGUNDY:
case SKINCOLOR_TANGERINE:
cstart = "\x87"; // V_ORANGEMAP
break;
case SKINCOLOR_PEACH:
case SKINCOLOR_CARAMEL:
case SKINCOLOR_CREAM:
cstart = "\x8f"; // V_PEACHMAP
break;
case SKINCOLOR_GOLD:
case SKINCOLOR_ROYAL:
case SKINCOLOR_BRONZE:
case SKINCOLOR_COPPER:
cstart = "\x8A"; // V_GOLDMAP
break;
case SKINCOLOR_POPCORN:
case SKINCOLOR_YELLOW:
case SKINCOLOR_MUSTARD:
case SKINCOLOR_OLIVE:
cstart = "\x82"; // V_YELLOWMAP
break;
case SKINCOLOR_VOMIT:
case SKINCOLOR_GARDEN:
case SKINCOLOR_TEA:
case SKINCOLOR_PISTACHIO:
cstart = "\x8b"; // V_TEAMAP
break;
case SKINCOLOR_LIME:
case SKINCOLOR_HANDHELD:
case SKINCOLOR_MOSS:
case SKINCOLOR_CAMOUFLAGE:
case SKINCOLOR_ROBOHOOD:
case SKINCOLOR_MINT:
case SKINCOLOR_GREEN:
case SKINCOLOR_PINETREE:
case SKINCOLOR_EMERALD:
case SKINCOLOR_SWAMP:
case SKINCOLOR_DREAM:
case SKINCOLOR_PLAGUE:
case SKINCOLOR_ALGAE:
cstart = "\x83"; // V_GREENMAP
break;
case SKINCOLOR_CARIBBEAN:
case SKINCOLOR_AQUA:
case SKINCOLOR_TEAL:
case SKINCOLOR_CYAN:
case SKINCOLOR_JAWZ:
case SKINCOLOR_CERULEAN:
case SKINCOLOR_NAVY:
case SKINCOLOR_SAPPHIRE:
cstart = "\x88"; // V_SKYMAP
break;
case SKINCOLOR_PLATINUM:
case SKINCOLOR_STEEL:
cstart = "\x8c"; // V_STEELMAP
break;
case SKINCOLOR_PERIWINKLE:
case SKINCOLOR_BLUE:
case SKINCOLOR_BLUEBERRY:
case SKINCOLOR_NOVA:
cstart = "\x84"; // V_BLUEMAP
break;
case SKINCOLOR_ULTRAVIOLET:
case SKINCOLOR_PURPLE:
case SKINCOLOR_FUCHSIA:
cstart = "\x81"; // V_PURPLEMAP
break;
case SKINCOLOR_PASTEL:
case SKINCOLOR_MOONSLAM:
case SKINCOLOR_DUSK:
case SKINCOLOR_TOXIC:
case SKINCOLOR_MAUVE:
case SKINCOLOR_LAVENDER:
case SKINCOLOR_BYZANTIUM:
case SKINCOLOR_POMEGRANATE:
cstart = "\x89"; // V_LAVENDERMAP
break;
default:
break;
}
}
prefix = cstart;
// Give admins and remote admins their symbols.
@ -1109,8 +1225,6 @@ static INT16 typelines = 1; // number of drawfill lines we need when drawing the
//
boolean HU_Responder(event_t *ev)
{
INT32 c=0;
if (ev->type != ev_keydown)
return false;
@ -1136,18 +1250,6 @@ boolean HU_Responder(event_t *ev)
return false;
}
c = (INT32)ev->data1;
// capslock (now handled outside of chat on so that it works everytime......)
if (c && c == KEY_CAPSLOCK) // it's a toggle.
{
if (capslock)
capslock = false;
else
capslock = true;
return true;
}
#ifndef NONET
if (!chat_on)
{
@ -1175,6 +1277,7 @@ boolean HU_Responder(event_t *ev)
}
else // if chat_on
{
INT32 c = (INT32)ev->data1;
// Ignore modifier keys
// Note that we do this here so users can still set
@ -1190,20 +1293,7 @@ boolean HU_Responder(event_t *ev)
&& ev->data1 != gamecontrol[gc_talkkey][1]))
return false;
c = (INT32)ev->data1;
// I know this looks very messy but this works. If it ain't broke, don't fix it!
// shift LETTERS to uppercase if we have capslock or are holding shift
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
if (shiftdown ^ capslock)
c = shiftxform[c];
}
else // if we're holding shift we should still shift non letter symbols
{
if (shiftdown)
c = shiftxform[c];
}
c = CON_ShiftChar(c);
// pasting. pasting is cool. chat is a bit limited, though :(
if (((c == 'v' || c == 'V') && ctrldown) && !CHAT_MUTE)
@ -1612,9 +1702,9 @@ static void HU_drawChatLog(INT32 offset)
// draw arrows to indicate that we can (or not) scroll.
if (chat_scroll > 0)
V_DrawThinString(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight, "\x1A"); // up arrow
V_DrawCharacter(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1A', false); // up arrow
if (chat_scroll < chat_maxscroll)
V_DrawThinString(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight, "\x1B"); // down arrow
V_DrawCharacter(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight | '\x1B', false); // down arrow
justscrolleddown = false;
justscrolledup = false;
@ -2178,6 +2268,7 @@ static void HU_DrawSongCredits(void)
V_DrawRightAlignedThinString(cursongcredit.x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
}
// Heads up displays drawer, call each frame
//
void HU_Drawer(void)
@ -2369,36 +2460,25 @@ void HU_Erase(void)
//
// HU_drawPing
//
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags)
{
UINT8 numbars = 1; // how many ping bars do we draw?
UINT8 barcolor = 128; // color we use for the bars (green, yellow or red)
SINT8 i = 0;
SINT8 yoffset = 6;
INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2);
INT32 gfxnum = 4; // gfx to draw
UINT8 const *colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SALMON, GTC_CACHE);
if (ping < 128)
{
numbars = 3;
barcolor = 184;
}
if (ping < 76)
gfxnum = 0;
else if (ping < 137)
gfxnum = 1;
else if (ping < 256)
{
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103;
}
gfxnum = 2;
else if (ping < 500)
gfxnum = 3;
if (!notext || vid.width >= 640) // how sad, we're using a shit resolution.
V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping));
for (i=0; (i<3); i++) // Draw the ping bar
{
V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31);
if (i < numbars)
V_DrawFill(x+2 *(i-1), y+yoffset-3, 1, 8-yoffset-1, barcolor);
yoffset -= 2;
}
V_DrawScaledPatch(x, y, flags, pinggfx[gfxnum]);
if (servermaxping && ping > servermaxping && hu_tick < 4) // flash ping red if too high
V_DrawPingNum(x, y+9, flags, ping, colormap);
else
V_DrawPingNum(x, y+9, flags, ping, NULL);
}
//

View file

@ -80,7 +80,11 @@ extern boolean chat_on;
extern patch_t *hu_font[HU_FONTSIZE], *kart_font[KART_FONTSIZE], *tny_font[HU_FONTSIZE]; // SRB2kart
extern patch_t *tallnum[10];
extern patch_t *pingnum[10];
extern patch_t *pinggfx[5];
extern patch_t *nightsnum[10];
extern patch_t *framecounter;
extern patch_t *frameslash;
extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *emeraldpics[7];
@ -109,7 +113,7 @@ void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);
void HU_clearChatChars(void);
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard.
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, INT32 flags); // Lat': Ping drawer for scoreboard.
//void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
//void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);

View file

@ -612,7 +612,7 @@ static boolean SOCK_Get(void)
if (c != ERRSOCKET)
{
// find remote node number
for (j = 0; j <= MAXNETNODES; j++) //include LAN
for (j = 1; j <= MAXNETNODES; j++) //include LAN
{
if (SOCK_cmpaddr(&fromaddress, &clientaddress[j], 0))
{
@ -1340,8 +1340,12 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
while (runp != NULL)
{
// find ip of the server
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
runp = NULL;
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
{
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
break;
}
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
return newnode;

View file

@ -3140,11 +3140,11 @@ state_t states[NUMSTATES] =
{SPR_NULL, 0, 1, {A_FZBoomSmoke}, 1, 0, S_FZEROBOOM12}, // S_FZEROBOOM11
{SPR_NULL, 0, 1, {A_FZBoomSmoke}, 0, 0, S_NULL}, // S_FZEROBOOM12
{SPR_SMOK, FF_TRANS30, 30, {NULL}, 0, 0, S_FZSLOWSMOKE2}, // S_FZSLOWSMOKE1
{SPR_SMOK, FF_TRANS30|1, 30, {NULL}, 0, 0, S_FZSLOWSMOKE3}, // S_FZSLOWSMOKE2
{SPR_SMOK, FF_TRANS30|2, 30, {NULL}, 0, 0, S_FZSLOWSMOKE4}, // S_FZSLOWSMOKE3
{SPR_SMOK, FF_TRANS30|3, 30, {NULL}, 0, 0, S_FZSLOWSMOKE5}, // S_FZSLOWSMOKE4
{SPR_SMOK, FF_TRANS30|4, 30, {NULL}, 0, 0, S_NULL}, // S_FZSLOWSMOKE5
{SPR_SMOK, 0, 30, {NULL}, 0, 0, S_FZSLOWSMOKE2}, // S_FZSLOWSMOKE1
{SPR_SMOK, 1, 30, {NULL}, 0, 0, S_FZSLOWSMOKE3}, // S_FZSLOWSMOKE2
{SPR_SMOK, 2, 30, {NULL}, 0, 0, S_FZSLOWSMOKE4}, // S_FZSLOWSMOKE3
{SPR_SMOK, 3, 30, {NULL}, 0, 0, S_FZSLOWSMOKE5}, // S_FZSLOWSMOKE4
{SPR_SMOK, 4, 30, {NULL}, 0, 0, S_NULL}, // S_FZSLOWSMOKE5
// Various plants
{SPR_SBUS, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SONICBUSH
@ -3394,6 +3394,13 @@ state_t states[NUMSTATES] =
{SPR_FWRK, 3|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_KARMAFIREWORK1}, // S_KARMAFIREWORK4
{SPR_FWRK, 4|FF_FULLBRIGHT, TICRATE, {NULL}, 0, 0, S_NULL}, // S_KARMAFIREWORKTRAIL
// Opaque smoke
{SPR_SMOK, 0, 4, {NULL}, 0, 0, S_OPAQUESMOKE2}, // S_OPAQUESMOKE1
{SPR_SMOK, 1, 5, {NULL}, 0, 0, S_OPAQUESMOKE3}, // S_OPAQUESMOKE2
{SPR_SMOK, 2, 6, {NULL}, 0, 0, S_OPAQUESMOKE4}, // S_OPAQUESMOKE3
{SPR_SMOK, 3, 7, {NULL}, 0, 0, S_OPAQUESMOKE5}, // S_OPAQUESMOKE4
{SPR_SMOK, 4, 8, {NULL}, 0, 0, S_NULL}, // S_OPAQUESMOKE5
#ifdef SEENAMES
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
#endif
@ -15018,8 +15025,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_None, // deathsound
8, // speed
8*FRACUNIT, // radius
8*FRACUNIT, // height
32*FRACUNIT, // radius
64*FRACUNIT, // height
1, // display offset
100, // mass
0, // damage
@ -15574,7 +15581,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
1, // spawnhealth
S_NULL, // seestate
sfx_tossed, // seesound
6*TICRATE, // reactiontime
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
192*FRACUNIT, // painchance

View file

@ -4052,6 +4052,12 @@ typedef enum state
S_KARMAFIREWORK4,
S_KARMAFIREWORKTRAIL,
S_OPAQUESMOKE1,
S_OPAQUESMOKE2,
S_OPAQUESMOKE3,
S_OPAQUESMOKE4,
S_OPAQUESMOKE5,
#ifdef SEENAMES
S_NAMECHECK,
#endif

File diff suppressed because it is too large Load diff

View file

@ -11,7 +11,7 @@
#define KART_FULLTURN 800
UINT8 colortranslations[MAXSKINCOLORS][16];
UINT8 colortranslations[MAXTRANSLATIONS][16];
extern const char *KartColor_Names[MAXSKINCOLORS];
extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2];
void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor);
@ -23,6 +23,7 @@ void K_RegisterKartStuff(void);
boolean K_IsPlayerLosing(player_t *player);
boolean K_IsPlayerWanted(player_t *player);
void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid);
void K_FlipFromObject(mobj_t *mo, mobj_t *master);
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
void K_RespawnChecker(player_t *player);
void K_KartMoveAnimation(player_t *player);
@ -41,6 +42,7 @@ void K_SpawnBoostTrail(player_t *player);
void K_SpawnSparkleTrail(mobj_t *mo);
void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent);
void K_DriftDustHandling(mobj_t *spawner);
void K_PuntMine(mobj_t *mine, mobj_t *punter);
void K_DoSneaker(player_t *player, INT32 type);
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound);
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);

View file

@ -632,19 +632,6 @@ static int lib_pCheckSolidLava(lua_State *L)
return 1;
}
static int lib_pCanRunOnWater(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR));
//HUDSAFE
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (!rover)
return LUA_ErrInvalid(L, "ffloor_t");
lua_pushboolean(L, P_CanRunOnWater(player, rover));
return 1;
}
static int lib_pSpawnShadowMobj(lua_State *L)
{
mobj_t *caster = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -2627,7 +2614,6 @@ static luaL_Reg lib[] = {
{"P_InsideANonSolidFFloor",lib_pInsideANonSolidFFloor},
{"P_CheckDeathPitCollide",lib_pCheckDeathPitCollide},
{"P_CheckSolidLava",lib_pCheckSolidLava},
{"P_CanRunOnWater",lib_pCanRunOnWater},
{"P_SpawnShadowMobj",lib_pSpawnShadowMobj},
// p_user

View file

@ -410,6 +410,24 @@ static int libd_drawPaddedNum(lua_State *L)
return 0;
}
static int libd_drawPingNum(lua_State *L)
{
INT32 x, y, flags, num;
const UINT8 *colormap = NULL;
HUDONLY
x = luaL_checkinteger(L, 1);
y = luaL_checkinteger(L, 2);
num = luaL_checkinteger(L, 3);
flags = luaL_optinteger(L, 4, 0);
flags &= ~V_PARAMMASK; // Don't let crashes happen.
if (!lua_isnoneornil(L, 5))
colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP));
V_DrawPingNum(x, y, flags, num, colormap);
return 0;
}
static int libd_drawFill(lua_State *L)
{
INT32 x = luaL_optinteger(L, 1, 0);
@ -613,6 +631,7 @@ static luaL_Reg lib_draw[] = {
{"drawScaled", libd_drawScaled},
{"drawNum", libd_drawNum},
{"drawPaddedNum", libd_drawPaddedNum},
{"drawPingNum", libd_drawPingNum},
{"drawFill", libd_drawFill},
{"fadeScreen", libd_fadeScreen},
{"drawString", libd_drawString},

View file

@ -325,6 +325,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->bot);
else if (fastcmp(field,"jointime"))
lua_pushinteger(L, plr->jointime);
else if (fastcmp(field,"splitscreenindex"))
lua_pushinteger(L, plr->splitscreenindex);
#ifdef HWRENDER
else if (fastcmp(field,"fovadd"))
lua_pushfixed(L, plr->fovadd);
@ -613,6 +615,8 @@ static int player_set(lua_State *L)
return NOSET;
else if (fastcmp(field,"jointime"))
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"splitscreenindex"))
return NOSET;
#ifdef HWRENDER
else if (fastcmp(field,"fovadd"))
plr->fovadd = luaL_checkfixed(L, 3);
@ -739,6 +743,8 @@ static int ticcmd_get(lua_State *L)
lua_pushinteger(L, cmd->buttons);
else if (fastcmp(field,"driftturn"))
lua_pushinteger(L, cmd->driftturn);
else if (fastcmp(field,"latency"))
lua_pushinteger(L, cmd->latency);
else
return NOFIELD;

View file

@ -1020,7 +1020,7 @@ void LUA_Archive(void)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
if (!playeringame[i] && i > 0) // NEVER skip player 0, this is for dedi servs.
continue;
// all players in game will be archived, even if they just add a 0.
ArchiveExtVars(&players[i], "player");
@ -1056,7 +1056,7 @@ void LUA_UnArchive(void)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
if (!playeringame[i] && i > 0) // same here, this is to synch dediservs properly.
continue;
UnArchiveExtVars(&players[i]);
}

View file

@ -30,24 +30,10 @@ enum skin {
skin_facerank,
skin_facewant,
skin_facemmap,
skin_ability,
skin_ability2,
skin_thokitem,
skin_spinitem,
skin_revitem,
skin_actionspd,
skin_mindash,
skin_maxdash,
// SRB2kart
skin_kartspeed,
skin_kartweight,
//
skin_normalspeed,
skin_runspeed,
skin_thrustfactor,
skin_accelstart,
skin_acceleration,
skin_jumpfactor,
skin_starttranscolor,
skin_prefcolor,
skin_highresscale,
@ -64,24 +50,10 @@ static const char *const skin_opt[] = {
"facerank",
"facewant",
"facemmap",
"ability",
"ability2",
"thokitem",
"spinitem",
"revitem",
"actionspd",
"mindash",
"maxdash",
// SRB2kart
"kartspeed",
"kartweight",
//
"normalspeed",
"runspeed",
"thrustfactor",
"accelstart",
"acceleration",
"jumpfactor",
"starttranscolor",
"prefcolor",
"highresscale",
@ -139,30 +111,6 @@ static int skin_get(lua_State *L)
break;
lua_pushlstring(L, skin->facemmap, i);
break;
case skin_ability:
lua_pushinteger(L, skin->ability);
break;
case skin_ability2:
lua_pushinteger(L, skin->ability2);
break;
case skin_thokitem:
lua_pushinteger(L, skin->thokitem);
break;
case skin_spinitem:
lua_pushinteger(L, skin->spinitem);
break;
case skin_revitem:
lua_pushinteger(L, skin->revitem);
break;
case skin_actionspd:
lua_pushfixed(L, skin->actionspd);
break;
case skin_mindash:
lua_pushfixed(L, skin->mindash);
break;
case skin_maxdash:
lua_pushfixed(L, skin->maxdash);
break;
// SRB2kart
case skin_kartspeed:
lua_pushinteger(L, skin->kartspeed);
@ -171,24 +119,6 @@ static int skin_get(lua_State *L)
lua_pushinteger(L, skin->kartweight);
break;
//
case skin_normalspeed:
lua_pushfixed(L, skin->normalspeed);
break;
case skin_runspeed:
lua_pushfixed(L, skin->runspeed);
break;
case skin_thrustfactor:
lua_pushinteger(L, skin->thrustfactor);
break;
case skin_accelstart:
lua_pushinteger(L, skin->accelstart);
break;
case skin_acceleration:
lua_pushinteger(L, skin->acceleration);
break;
case skin_jumpfactor:
lua_pushfixed(L, skin->jumpfactor);
break;
case skin_starttranscolor:
lua_pushinteger(L, skin->starttranscolor);
break;

View file

@ -399,6 +399,8 @@ static void Dummystaff_OnChange(void);
// CONSOLE VARIABLES AND THEIR POSSIBLE VALUES GO HERE.
// ==========================================================================
consvar_t cv_showfocuslost = {"showfocuslost", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL };
static CV_PossibleValue_t map_cons_t[] = {
{0,"MIN"},
{NUMMAPS, "MAX"},
@ -948,14 +950,15 @@ static menuitem_t MP_MainMenu[] =
static menuitem_t MP_ServerMenu[] =
{
{IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 10},
{IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 20},
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 30},
{IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 0},
{IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 10},
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 20},
{IT_STRING|IT_CVAR|IT_CV_PASSWORD, NULL, "Password", &cv_dummyjoinpassword, 44},
{IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68},
{IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78},
{IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68},
{IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78},
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 130},
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 130},
};
#endif
@ -1249,7 +1252,7 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 10},
{IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 20},
{IT_STRING|IT_CVAR, NULL, "Field of View", &cv_grfov, 35},
{IT_STRING|IT_CVAR, NULL, "Field of View", &cv_fov, 35},
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 45},
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 55},
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 65},
@ -1316,6 +1319,9 @@ static menuitem_t OP_SoundOptionsMenu[] =
{IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 95},
{IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 110},
{IT_STRING|IT_CVAR, NULL, "Play Music While Unfocused", &cv_playmusicifunfocused, 125},
{IT_STRING|IT_CVAR, NULL, "Play SFX While Unfocused", &cv_playsoundifunfocused, 135},
};
/*static menuitem_t OP_DataOptionsMenu[] =
@ -1390,7 +1396,7 @@ static menuitem_t OP_HUDOptionsMenu[] =
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
NULL, "HUD Visibility", &cv_translucenthud, 20},
{IT_STRING | IT_SUBMENU, NULL, "Online chat options...",&OP_ChatOptionsDef, 35},
{IT_STRING | IT_SUBMENU, NULL, "Online HUD options...",&OP_ChatOptionsDef, 35},
{IT_STRING | IT_CVAR, NULL, "Background Glass", &cons_backcolor, 45},
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
@ -1402,8 +1408,11 @@ static menuitem_t OP_HUDOptionsMenu[] =
// highlight info - (GOOD HIGHLIGHT, WARNING HIGHLIGHT) - 105 (see M_DrawHUDOptions)
{IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 120},
{IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 135},
};
// Ok it's still called chatoptions but we'll put ping display in here to be clean
static menuitem_t OP_ChatOptionsMenu[] =
{
// will ANYONE who doesn't know how to use the console want to touch this one?
@ -1417,6 +1426,8 @@ static menuitem_t OP_ChatOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 50},
{IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 60},
{IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 70},
{IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 90}, // shows ping next to framerate if we want to.
};
static menuitem_t OP_GameOptionsMenu[] =
@ -1469,15 +1480,16 @@ static menuitem_t OP_AdvServerOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 40},
{IT_STRING | IT_CVAR, NULL, "Ping limit (ms)", &cv_maxping, 50},
{IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", &cv_nettimeout, 60},
{IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", &cv_jointimeout, 70},
{IT_STRING | IT_CVAR, NULL, "Ping timeout (s)", &cv_pingtimeout, 60},
{IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", &cv_nettimeout, 70},
{IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", &cv_jointimeout, 80},
{IT_STRING | IT_CVAR, NULL, "Max. file transfer send (KB)", &cv_maxsend, 90},
{IT_STRING | IT_CVAR, NULL, "File transfer packet rate", &cv_downloadspeed, 100},
{IT_STRING | IT_CVAR, NULL, "Max. file transfer send (KB)", &cv_maxsend, 100},
{IT_STRING | IT_CVAR, NULL, "File transfer packet rate", &cv_downloadspeed, 110},
{IT_STRING | IT_CVAR, NULL, "Log join addresses", &cv_showjoinaddress, 120},
{IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 130},
{IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 140},
{IT_STRING | IT_CVAR, NULL, "Log join addresses", &cv_showjoinaddress, 130},
{IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 140},
{IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 150},
};
#endif
@ -2379,6 +2391,9 @@ static void M_NextOpt(void)
{
INT16 oldItemOn = itemOn; // prevent infinite loop
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value = 0;
do
{
if (itemOn + 1 > currentMenu->numitems - 1)
@ -2392,6 +2407,9 @@ static void M_PrevOpt(void)
{
INT16 oldItemOn = itemOn; // prevent infinite loop
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value = 0;
do
{
if (!itemOn)
@ -2678,8 +2696,11 @@ boolean M_Responder(event_t *ev)
// BP: one of the more big hack i have never made
if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)
{
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING || (currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
{
if (ch == KEY_TAB && (currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value ^= 1;
if (shiftdown && ch >= 32 && ch <= 127)
ch = shiftxform[ch];
if (M_ChangeStringCvar(ch))
@ -2880,7 +2901,7 @@ void M_Drawer(void)
}
// focus lost notification goes on top of everything, even the former everything
if (window_notinfocus)
if (window_notinfocus && cv_showfocuslost.value)
{
M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2);
if (gamestate == GS_LEVEL && (P_AutoPause() || paused))
@ -3453,7 +3474,7 @@ static void M_DrawMapEmblems(INT32 mapnum, INT32 x, INT32 y)
if (emblem->collected)
V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE));
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_MENUCACHE));
else
V_DrawSmallScaledPatch(x, y, 0, W_CachePatchName("NEEDIT", PU_CACHE));
@ -3553,6 +3574,8 @@ static void M_DrawGenericMenu(void)
case IT_CVAR:
{
consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction;
char asterisks[MAXSTRINGLENGTH+1];
size_t sl;
switch (currentMenu->menuitems[i].status & IT_CVARTYPE)
{
case IT_CV_SLIDER:
@ -3560,6 +3583,27 @@ static void M_DrawGenericMenu(void)
case IT_CV_NOPRINT: // color use this
case IT_CV_INVISSLIDER: // monitor toggles use this
break;
case IT_CV_PASSWORD:
if (i == itemOn)
{
V_DrawRightAlignedThinString(x + MAXSTRINGLENGTH*8 + 10, y, V_ALLOWLOWERCASE, va(M_GetText("Tab: %s password"), cv->value ? "hide" : "show"));
}
if (!cv->value || i != itemOn)
{
sl = strlen(cv->string);
memset(asterisks, '*', sl);
memset(asterisks + sl, 0, MAXSTRINGLENGTH+1-sl);
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, asterisks);
if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(asterisks, 0), y + 12,
'_' | 0x80, false);
y += 16;
break;
}
/* fallthru */
case IT_CV_STRING:
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
@ -3767,7 +3811,7 @@ static void M_DrawPauseMenu(void)
if (emblem->collected)
V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE));
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_MENUCACHE));
else
V_DrawSmallScaledPatch(40, 44 + (i*8), 0, W_CachePatchName("NEEDIT", PU_CACHE));
@ -5315,7 +5359,7 @@ static void M_DrawEmblemHints(void)
{
collected = recommendedflags;
V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE));
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_MENUCACHE));
}
else
{
@ -5658,7 +5702,7 @@ static void M_DrawLoadGameData(void)
V_DrawScaledPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE));
else
{
UINT8 *colormap = R_GetTranslationColormap(savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor, 0);
UINT8 *colormap = R_GetTranslationColormap(savegameinfo[saveSlotSelected].skinnum, savegameinfo[saveSlotSelected].skincolor, GTC_MENUCACHE);
V_DrawMappedPatch(SP_LoadDef.x,144+8,0,W_CachePatchName(skins[savegameinfo[saveSlotSelected].skinnum].face, PU_CACHE), colormap);
}
@ -6348,7 +6392,7 @@ static void M_DrawStatsMaps(int location)
if (exemblem->collected)
V_DrawSmallMappedPatch(295, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetExtraEmblemColor(exemblem), GTC_CACHE));
R_GetTranslationColormap(TC_DEFAULT, M_GetExtraEmblemColor(exemblem), GTC_MENUCACHE));
else
V_DrawSmallScaledPatch(295, y, 0, W_CachePatchName("NEEDIT", PU_CACHE));
@ -6483,7 +6527,7 @@ void M_DrawTimeAttackMenu(void)
// Character face!
if (W_CheckNumForName(skins[cv_chooseskin.value-1].facewant) != LUMPERROR)
{
UINT8 *colormap = R_GetTranslationColormap(cv_chooseskin.value-1, cv_playercolor.value, 0);
UINT8 *colormap = R_GetTranslationColormap(cv_chooseskin.value-1, cv_playercolor.value, GTC_MENUCACHE);
V_DrawMappedPatch(BASEVIDWIDTH-x - SHORT(facewantprefix[cv_chooseskin.value-1]->width), y, 0, facewantprefix[cv_chooseskin.value-1], colormap);
}
@ -6608,7 +6652,7 @@ void M_DrawTimeAttackMenu(void)
if (em->collected)
V_DrawMappedPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE));
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_MENUCACHE));
else
V_DrawScaledPatch(BASEVIDWIDTH - 64 - 24, y+48, 0, W_CachePatchName("NEEDIT", PU_CACHE));
@ -6768,7 +6812,7 @@ static boolean M_QuitTimeAttackMenu(void)
if (em->collected)
V_DrawSmallMappedPatch(160+88, yHeight, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE));
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_MENUCACHE));
else
V_DrawSmallScaledPatch(160+88, yHeight, 0, W_CachePatchName("NEEDIT", PU_CACHE));
@ -7237,6 +7281,7 @@ static void M_DrawConnectMenu(void)
{
UINT16 i, j;
const char *gt = "Unknown";
const char *spd = "";
INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE;
for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++)
@ -7290,7 +7335,17 @@ static void M_DrawConnectMenu(void)
V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags,
va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer));
V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, va("Gametype: %s", gt));
V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt);
if (serverlist[slindex].info.gametype == GT_RACE)
{
spd = kartspeed_cons_t[serverlist[slindex].info.kartvars & SV_SPEEDMASK].strvalue;
V_DrawSmallString(currentMenu->x+132, S_LINEY(i)+8, globalflags, va("(%s Speed)", spd));
}
if (serverlist[slindex].info.kartvars & SV_PASSWORD)
V_DrawFixedPatch((currentMenu->x - 9) << FRACBITS, (S_LINEY(i)) << FRACBITS, FRACUNIT, globalflags & (~V_ALLOWLOWERCASE), W_CachePatchName("SERVLOCK", PU_CACHE), NULL);
MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL;
}
@ -7525,6 +7580,11 @@ static void M_StartServer(INT32 choice)
// Still need to reset devmode
cv_debug = 0;
if (strlen(cv_dummyjoinpassword.string) > 0)
D_SetJoinPassword(cv_dummyjoinpassword.string);
else
joinpasswordset = false;
if (demoplayback)
G_StopDemo();
if (metalrecording)
@ -7826,7 +7886,7 @@ Update the maxplayers label...
if (!trans && i > cv_splitplayers.value)
trans = V_TRANSLUCENT;
colmap = R_GetTranslationColormap(pskin, pcol, 0);
colmap = R_GetTranslationColormap(pskin, pcol, GTC_MENUCACHE);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, trans, facewantprefix[pskin], colmap);
@ -8137,7 +8197,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
statdot = W_CachePatchName("K_SDOT2", PU_CACHE); // coloured center
if (setupm_fakecolor)
V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, 0));
V_DrawFixedPatch(((BASEVIDWIDTH - mx - 80) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, R_GetTranslationColormap(0, setupm_fakecolor, GTC_MENUCACHE));
// 2.2 color bar backported with permission
#define charw 72
@ -8207,7 +8267,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
offx = 8;
offy = 8;
}
colmap = R_GetTranslationColormap(col, setupm_fakecolor, 0);
colmap = R_GetTranslationColormap(col, setupm_fakecolor, GTC_MENUCACHE);
V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, face, colmap);
if (scale == FRACUNIT) // bit of a hack
V_DrawFixedPatch((x+offx)<<FRACBITS, (my+28+offy)<<FRACBITS, FRACUNIT, 0, cursor, colmap);
@ -8253,7 +8313,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
// draw player sprite
if (setupm_fakecolor) // inverse should never happen
{
UINT8 *colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor, 0);
UINT8 *colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor, GTC_MENUCACHE);
if (skins[setupm_fakeskin].flags & SF_HIRES)
{
@ -8264,8 +8324,6 @@ static void M_DrawSetupMultiPlayerMenu(void)
}
else
V_DrawMappedPatch(mx+43, my+131, flags, patch, colormap);
Z_Free(colormap);
}
#undef charw
}

View file

@ -104,6 +104,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
#define IT_CV_NOPRINT 1536
#define IT_CV_NOMOD 2048
#define IT_CV_INVISSLIDER 2560
#define IT_CV_PASSWORD 3072
//call/submenu specific
// There used to be a lot more here but ...
@ -211,6 +212,7 @@ typedef struct
extern description_t description[32];
extern consvar_t cv_showfocuslost;
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
extern CV_PossibleValue_t gametype_cons_t[];

View file

@ -22,6 +22,8 @@
# include <limits.h>
#endif
#define MD5_LEN 16
/* The following contortions are an attempt to use the C preprocessor
to determine an unsigned integral type that is 32 bits wide. An
alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but

View file

@ -8640,6 +8640,7 @@ void A_LightningFollowPlayer(mobj_t *actor)
else // else just teleport to player directly
P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z);
K_MatchGenericExtraFlags(actor, actor->target); // copy our target for graviflip
actor->momx = actor->target->momx;
actor->momy = actor->target->momy;
actor->momz = actor->target->momz; // Give momentum since we don't teleport to our player literally every frame.

View file

@ -141,6 +141,9 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
|| (weapon != 3 && player->kartstuff[k_itemamount])
|| player->kartstuff[k_itemheld])
return false;
if (weapon == 3 && player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD)
return false; // No stacking thunder shields!
}
}
@ -411,6 +414,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->kartstuff[k_roulettetype] = 2;
}
#if 0
// Eggbox snipe!
if (special->type == MT_EGGMANITEM && special->health > 1)
S_StartSound(toucher, sfx_bsnipe);
#endif
{
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
S_StartSound(poof, special->info->deathsound);
@ -1468,6 +1477,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->starpostz = special->z>>FRACBITS;
player->starpostangle = special->angle;
player->starpostnum = special->health;
player->kartstuff[k_starpostflip] = special->spawnpoint->options & MTF_OBJECTFLIP; // store flipping
//S_StartSound(toucher, special->info->painsound);
return;
@ -2952,66 +2962,6 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
}
}
/*
static inline void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) // SRB2kart - unused.
{
fixed_t fallbackspeed;
angle_t ang;
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
if (player->mo->eflags & MFE_VERTICALFLIP)
player->mo->z--;
else
player->mo->z++;
if (player->mo->eflags & MFE_UNDERWATER)
P_SetObjectMomZ(player->mo, FixedDiv(10511*FRACUNIT,2600*FRACUNIT), false);
else
P_SetObjectMomZ(player->mo, FixedDiv(69*FRACUNIT,10*FRACUNIT), false);
ang = R_PointToAngle2(inflictor->x, inflictor->y, player->mo->x, player->mo->y);
// explosion and rail rings send you farther back, making it more difficult
// to recover
if (inflictor->flags2 & MF2_SCATTER && source)
{
fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z);
dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4;
if (dist < FixedMul(4*FRACUNIT, inflictor->scale))
dist = FixedMul(4*FRACUNIT, inflictor->scale);
fallbackspeed = dist;
}
else if (inflictor->flags2 & MF2_EXPLOSION)
{
if (inflictor->flags2 & MF2_RAILRING)
fallbackspeed = FixedMul(28*FRACUNIT, inflictor->scale); // 7x
else
fallbackspeed = FixedMul(20*FRACUNIT, inflictor->scale); // 5x
}
else if (inflictor->flags2 & MF2_RAILRING)
fallbackspeed = FixedMul(16*FRACUNIT, inflictor->scale); // 4x
else
fallbackspeed = FixedMul(4*FRACUNIT, inflictor->scale); // the usual amount of force
P_InstaThrust(player->mo, ang, fallbackspeed);
// SRB2kart - This shouldn't be reachable, but this frame is invalid.
//if (player->charflags & SF_SUPERANIMS)
// P_SetPlayerMobjState(player->mo, S_PLAY_SUPERHIT);
//else
P_SetPlayerMobjState(player->mo, player->mo->info->painstate);
P_ResetPlayer(player);
if (player->timeshit != UINT8_MAX)
++player->timeshit;
}
*/
void P_RemoveShield(player_t *player)
{
if (player->powers[pw_shield] & SH_FORCE)

View file

@ -274,8 +274,6 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab);
mobj_t *P_GetClosestAxis(mobj_t *source);
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover);
void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration);
#define PAL_WHITE 1
#define PAL_MIXUP 2

View file

@ -747,6 +747,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& !(tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD))
return true;
if (thing->player && thing->player->kartstuff[k_hyudorotimer])
return true; // no interaction
if (thing->type == MT_PLAYER)
{
// Player Damage
@ -850,7 +853,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_PLAYER)
{
S_StartSound(NULL, sfx_cgot); //let all players hear it.
S_StartSound(NULL, sfx_bsnipe); //let all players hear it.
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[thing->player-players]));
@ -912,6 +915,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_PLAYER)
{
// Banana snipe!
if (tmthing->type == MT_BANANA && tmthing->health > 1)
S_StartSound(thing, sfx_bsnipe);
// Player Damage
K_SpinPlayer(thing->player, tmthing->target, 0, tmthing, (tmthing->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD));
@ -980,7 +987,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_PLAYER)
{
P_KillMobj(tmthing, thing, thing);
// Bomb punting
if ((tmthing->state >= &states[S_SSMINE1] && tmthing->state <= &states[S_SSMINE4])
|| (tmthing->state >= &states[S_SSMINE_DEPLOY8] && tmthing->state <= &states[S_SSMINE_DEPLOY13]))
P_KillMobj(tmthing, thing, thing);
else
K_PuntMine(tmthing, thing);
}
else if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD
|| thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD)
@ -1021,6 +1033,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& !(thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD))
return true;
if (tmthing->player && tmthing->player->kartstuff[k_hyudorotimer]) // I thought about doing this for just the objects below but figured it should apply to everything.
return true; // no interaction
if (thing->type == MT_ORBINAUT_SHIELD || thing->type == MT_JAWZ_SHIELD
|| thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD)
{
@ -1056,6 +1071,10 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->health <= 0 || thing->health <= 0)
return true;
// Banana snipe!
if (thing->type == MT_BANANA && thing->health > 1)
S_StartSound(tmthing, sfx_bsnipe);
// Player Damage
K_SpinPlayer(tmthing->player, thing->target, 0, tmthing, (thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD));
@ -1079,7 +1098,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->health <= 0 || thing->health <= 0)
return true;
P_KillMobj(thing, tmthing, tmthing);
// Bomb punting
if ((thing->state >= &states[S_SSMINE1] && thing->state <= &states[S_SSMINE4])
|| (thing->state >= &states[S_SSMINE_DEPLOY8] && thing->state <= &states[S_SSMINE_DEPLOY13]))
P_KillMobj(thing, tmthing, tmthing);
else
K_PuntMine(thing, tmthing);
}
else if (thing->type == MT_MINEEXPLOSION && tmthing->player)
{
@ -2090,7 +2114,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
continue;
}
if (thing->player && (P_CheckSolidLava(thing, rover) || P_CanRunOnWater(thing->player, rover)))
if (thing->player && P_CheckSolidLava(thing, rover))
;
else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))
;
@ -2763,8 +2787,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
#ifdef ESLOPE
// HACK TO FIX DSZ2: apply only if slopes are involved
else if (tmceilingslope && tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
{
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
@ -2777,8 +2800,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
#ifdef ESLOPE
// HACK TO FIX DSZ2: apply only if slopes are involved
else if (tmfloorslope && tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
{
thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;

View file

@ -649,7 +649,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (!(rover->flags & FF_EXISTS))
continue;
if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover)))
if (mobj->player && P_CheckSolidLava(mobj, rover))
;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
@ -693,7 +693,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
if (!(rover->flags & FF_EXISTS))
continue;
if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover)))
if (mobj->player && P_CheckSolidLava(mobj, rover))
;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))

View file

@ -167,58 +167,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
I_Error("P_SetPlayerMobjState used for non-player mobj. Use P_SetMobjState instead!\n(Mobj type: %d, State: %d)", mobj->type, state);
#endif
// Catch state changes for Super Sonic
/* // SRB2kart - don't need
if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS))
{
switch (state)
{
case S_PLAY_STND:
case S_PLAY_TAP1:
case S_PLAY_TAP2:
case S_PLAY_GASP:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERSTAND);
return true;
case S_PLAY_FALL1:
case S_PLAY_SPRING:
case S_PLAY_RUN1:
case S_PLAY_RUN2:
case S_PLAY_RUN3:
case S_PLAY_RUN4:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERWALK1);
return true;
case S_PLAY_FALL2:
case S_PLAY_RUN5:
case S_PLAY_RUN6:
case S_PLAY_RUN7:
case S_PLAY_RUN8:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERWALK2);
return true;
case S_PLAY_SPD1:
case S_PLAY_SPD2:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERFLY1);
return true;
case S_PLAY_SPD3:
case S_PLAY_SPD4:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERFLY2);
return true;
case S_PLAY_TEETER1:
case S_PLAY_TEETER2:
P_SetPlayerMobjState(mobj, S_PLAY_SUPERTEETER);
return true;
case S_PLAY_ATK1:
case S_PLAY_ATK2:
case S_PLAY_ATK3:
case S_PLAY_ATK4:
if (!(player->charflags & SF_SUPERSPIN))
return true;
break;
default:
break;
}
}
// You were in pain state after taking a hit, and you're moving out of pain state now?
else */if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == K_GetKartFlashing(player) && state != mobj->info->painstate)
if (mobj->state == &states[mobj->info->painstate] && player->powers[pw_flashing] == K_GetKartFlashing(player) && state != mobj->info->painstate)
{
// Start flashing, since you've landed.
player->powers[pw_flashing] = K_GetKartFlashing(player)-1;
@ -260,51 +210,6 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
st = &states[state];
mobj->state = st;
mobj->tics = st->tics;
// Adjust the player's animation speed to match their velocity.
if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
{
fixed_t speed = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor)); // fixed_t speed = FixedDiv(player->speed, mobj->scale);
if (player->panim == PA_ROLL)
{
if (speed > 16<<FRACBITS)
mobj->tics = 1;
else
mobj->tics = 2;
}
else if (player->panim == PA_FALL)
{
speed = FixedDiv(abs(mobj->momz), mobj->scale);
if (speed < 10<<FRACBITS)
mobj->tics = 4;
else if (speed < 20<<FRACBITS)
mobj->tics = 3;
else if (speed < 30<<FRACBITS)
mobj->tics = 2;
else
mobj->tics = 1;
}
else if (P_IsObjectOnGround(mobj) || player->powers[pw_super]) // Only if on the ground or superflying.
{
if (player->panim == PA_WALK)
{
if (speed > 12<<FRACBITS)
mobj->tics = 2;
else if (speed > 6<<FRACBITS)
mobj->tics = 3;
else
mobj->tics = 4;
}
else if (player->panim == PA_RUN)
{
if (speed > 52<<FRACBITS)
mobj->tics = 1;
else
mobj->tics = 2;
}
}
}
mobj->sprite = st->sprite;
mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
@ -1404,11 +1309,14 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
break;
case MT_BANANA:
case MT_EGGMANITEM:
case MT_SSMINE:
case MT_SINK:
if (mo->extravalue2 > 0)
gravityadd *= mo->extravalue2;
/* FALLTHRU */
case MT_ORBINAUT:
case MT_JAWZ:
case MT_JAWZ_DUD:
case MT_SSMINE:
case MT_SINK:
gravityadd = (5*gravityadd)/2;
break;
case MT_SIGN:
@ -2099,7 +2007,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected
if (mo->player && P_CheckSolidLava(mo, rover)) // only the player should be affected
;
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
continue;
@ -3222,27 +3130,6 @@ static boolean P_SceneryZMovement(mobj_t *mo)
return true;
}
// P_CanRunOnWater
//
// Returns true if player can waterrun on the 3D floor
//
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
{
fixed_t topheight =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) :
#endif
*rover->topheight;
if (((player->charflags & SF_RUNONWATER) && player->mo->ceilingz-topheight >= player->mo->height)
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
&& !(player->pflags & PF_SLIDING)
&& abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
return true;
return false;
}
//
// P_MobjCheckWater
//
@ -3399,8 +3286,8 @@ void P_MobjCheckWater(mobj_t *mobj)
// skipping stone!
if (p && p->kartstuff[k_waterskip] < 2
&& ((p->speed/2 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water.
|| (p->speed > K_GetKartSpeed(p,false)/4 && p->kartstuff[k_waterskip])) // Already skipped once, so you can skip once more!
&& ((p->speed/3 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water.
|| (p->speed > K_GetKartSpeed(p,false)/3 && p->kartstuff[k_waterskip])) // Already skipped once, so you can skip once more!
&& ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop)
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom)))
{
@ -6637,7 +6524,7 @@ void P_MobjThinker(mobj_t *mobj)
case MT_SINK_SHIELD:
if ((mobj->health > 0
&& (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator))
|| (mobj->health <= 0 && mobj->z <= mobj->floorz)
|| (mobj->health <= 0 && P_IsObjectOnGround(mobj))
|| P_CheckDeathPitCollide(mobj)) // When in death state
{
P_RemoveMobj(mobj);
@ -6651,19 +6538,22 @@ void P_MobjThinker(mobj_t *mobj)
fixed_t y = P_RandomRange(-35, 35)*mobj->scale;
fixed_t z = P_RandomRange(0, 70)*mobj->scale;
mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE);
P_SetMobjState(smoke, S_OPAQUESMOKE1);
K_MatchGenericExtraFlags(smoke, mobj);
smoke->scale = mobj->scale * 2;
smoke->destscale = mobj->scale * 6;
smoke->momz = P_RandomRange(4, 9)*FRACUNIT;
smoke->momz = P_RandomRange(4, 9)*FRACUNIT*P_MobjFlip(smoke);
}
break;
case MT_BOOMPARTICLE:
{
fixed_t x = P_RandomRange(-16, 16)*mobj->scale;
fixed_t y = P_RandomRange(-16, 16)*mobj->scale;
fixed_t z = P_RandomRange(0, 32)*mobj->scale;
fixed_t z = P_RandomRange(0, 32)*mobj->scale*P_MobjFlip(mobj);
if (leveltime % 2 == 0)
{
mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_BOSSEXPLODE);
K_MatchGenericExtraFlags(smoke, mobj);
P_SetMobjState(smoke, S_QUICKBOOM1);
smoke->scale = mobj->scale/2;
smoke->destscale = mobj->scale;
@ -6672,6 +6562,8 @@ void P_MobjThinker(mobj_t *mobj)
else
{
mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE);
P_SetMobjState(smoke, S_OPAQUESMOKE1);
K_MatchGenericExtraFlags(smoke, mobj);
smoke->scale = mobj->scale;
smoke->destscale = mobj->scale*2;
}
@ -6777,7 +6669,7 @@ void P_MobjThinker(mobj_t *mobj)
}
else if ((mobj->health > 0
&& (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->player->health <= 0 || mobj->target->player->spectator))
|| (mobj->health <= 0 && mobj->z <= mobj->floorz)
|| (mobj->health <= 0 && P_IsObjectOnGround(mobj))
|| P_CheckDeathPitCollide(mobj)) // When in death state
{
P_RemoveMobj(mobj);
@ -7225,6 +7117,9 @@ void P_MobjThinker(mobj_t *mobj)
y = mobj->target->y;
z = mobj->target->z + (80*mapobjectscale);
}
if (mobj->target->eflags & MFE_VERTICALFLIP)
z += mobj->target->height - FixedMul(mobj->target->scale, mobj->height);
P_TeleportMove(mobj, x, y, z);
}
break;
@ -7420,7 +7315,7 @@ void P_MobjThinker(mobj_t *mobj)
case MT_BANANA:
case MT_EGGMANITEM:
case MT_SPB:
if (mobj->z <= mobj->floorz)
if (P_IsObjectOnGround(mobj))
{
P_RemoveMobj(mobj);
return;
@ -7433,7 +7328,7 @@ void P_MobjThinker(mobj_t *mobj)
break;
case MT_JAWZ:
case MT_JAWZ_DUD:
if (mobj->z <= mobj->floorz)
if (P_IsObjectOnGround(mobj))
P_SetMobjState(mobj, mobj->info->xdeathstate);
// fallthru
case MT_JAWZ_SHIELD:
@ -7467,7 +7362,7 @@ void P_MobjThinker(mobj_t *mobj)
/* FALLTHRU */
case MT_SMK_MOLE:
mobj->flags2 ^= MF2_DONTDRAW;
if (mobj->z <= mobj->floorz)
if (P_IsObjectOnGround(mobj))
{
P_RemoveMobj(mobj);
return;
@ -7488,7 +7383,7 @@ void P_MobjThinker(mobj_t *mobj)
}
mobj->flags2 ^= MF2_DONTDRAW;
if (mobj->z <= mobj->floorz)
if (P_IsObjectOnGround(mobj))
{
P_RemoveMobj(mobj);
return;
@ -8157,7 +8052,7 @@ void P_MobjThinker(mobj_t *mobj)
mobj->friction = ORIG_FRICTION/4;
if (mobj->momx || mobj->momy)
P_SpawnGhostMobj(mobj);
if (mobj->z <= mobj->floorz && mobj->health > 1)
if (P_IsObjectOnGround(mobj) && mobj->health > 1)
{
S_StartSound(mobj, mobj->info->activesound);
mobj->momx = mobj->momy = 0;
@ -8177,7 +8072,7 @@ void P_MobjThinker(mobj_t *mobj)
case MT_SINK:
if (mobj->momx || mobj->momy)
P_SpawnGhostMobj(mobj);
if (mobj->z <= mobj->floorz)
if (P_IsObjectOnGround(mobj))
{
S_StartSound(mobj, mobj->info->deathsound);
P_SetMobjState(mobj, S_NULL);
@ -8190,28 +8085,26 @@ void P_MobjThinker(mobj_t *mobj)
mobj->color = mobj->target->player->skincolor;
else
mobj->color = SKINCOLOR_KETCHUP;
if (mobj->momx || mobj->momy)
P_SpawnGhostMobj(mobj);
if (P_IsObjectOnGround(mobj))
if (P_IsObjectOnGround(mobj) && (mobj->state == &states[S_SSMINE_AIR1] || mobj->state == &states[S_SSMINE_AIR2]))
{
if (mobj->state == &states[S_SSMINE_AIR1] || mobj->state == &states[S_SSMINE_AIR2])
P_SetMobjState(mobj, S_SSMINE_DEPLOY1);
if (mobj->reactiontime >= mobj->info->reactiontime)
if (mobj->extravalue1 > 0)
mobj->extravalue1--;
else
{
mobj->momx = mobj->momy = 0;
S_StartSound(mobj, mobj->info->activesound);
mobj->reactiontime--;
P_SetMobjState(mobj, S_SSMINE_DEPLOY1);
}
}
if (mobj->reactiontime && mobj->reactiontime < mobj->info->reactiontime)
{
mobj->reactiontime--;
if (!mobj->reactiontime)
P_KillMobj(mobj, NULL, NULL);
}
if ((mobj->state >= &states[S_SSMINE1] && mobj->state <= &states[S_SSMINE4])
|| (mobj->state >= &states[S_SSMINE_DEPLOY8] && mobj->state <= &states[S_SSMINE_DEPLOY13]))
A_GrenadeRing(mobj);
if (mobj->threshold > 0)
mobj->threshold--;
break;
@ -8355,6 +8248,7 @@ void P_MobjThinker(mobj_t *mobj)
break;
case MT_INSTASHIELDB:
mobj->flags2 ^= MF2_DONTDRAW;
K_MatchGenericExtraFlags(mobj, mobj->target);
/* FALLTHRU */
case MT_INSTASHIELDA:
if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_instashield]))
@ -8363,6 +8257,7 @@ void P_MobjThinker(mobj_t *mobj)
return;
}
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
K_MatchGenericExtraFlags(mobj, mobj->target);
break;
case MT_BATTLEPOINT:
if (!mobj->target || P_MobjWasRemoved(mobj->target))
@ -8383,7 +8278,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->movefactor < mobj->target->height)
mobj->movefactor = mobj->target->height;
}
K_MatchGenericExtraFlags(mobj, mobj->target);
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor);
break;
case MT_THUNDERSHIELD:
@ -8508,6 +8403,10 @@ void P_MobjThinker(mobj_t *mobj)
mobj->flags2 &= ~MF2_DONTDRAW;
}
// Update mobj antigravity status:
mobj->eflags = (mobj->eflags & ~MFE_VERTICALFLIP)|(mobj->target->eflags & MFE_VERTICALFLIP);
mobj->flags2 = (mobj->flags2 & ~MF2_OBJECTFLIP)|(mobj->target->flags2 & MF2_OBJECTFLIP);
// Now for the wheels
{
const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->target->scale);
@ -8529,6 +8428,7 @@ void P_MobjThinker(mobj_t *mobj)
P_SetScale(cur, mobj->target->scale);
cur->color = mobj->target->color;
cur->colorized = true;
K_FlipFromObject(cur, mobj->target);
if (mobj->flags2 & MF2_DONTDRAW)
cur->flags2 |= MF2_DONTDRAW;
@ -11124,7 +11024,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
if (p->kartstuff[k_respawn])
z -= 128*FRACUNIT; // Too late for v1, but for later: 128*mapobjectscale;
z -= 128*mapobjectscale;
}
else
{
@ -11132,7 +11032,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
if (p->kartstuff[k_respawn])
z += 128*FRACUNIT; // Too late for v1, but for later: 128*mapobjectscale;
z += 128*mapobjectscale;
}
if (mthing->options & MTF_OBJECTFLIP) // flip the player!
@ -11193,7 +11093,14 @@ void P_MovePlayerToStarpost(INT32 playernum)
#endif
sector->ceilingheight;
z = (p->starpostz + 128) << FRACBITS; // Respawn off the ground
if (mobj->player->kartstuff[k_starpostflip])
z = (p->starpostz<<FRACBITS) - FixedMul(128<<FRACBITS, mapobjectscale) - mobj->height;
else
z = (p->starpostz<<FRACBITS) + FixedMul(128<<FRACBITS, mapobjectscale);
//z = (p->starpostz + 128) << FRACBITS; // reverse gravity exists, pls
mobj->player->kartstuff[k_starpostflip] = 0;
if (z < floor)
z = floor;
else if (z > ceiling - mobjinfo[MT_PLAYER].height)

View file

@ -249,6 +249,8 @@ static void P_NetArchivePlayers(void)
WRITEUINT32(save_p, players[i].jointime);
WRITEUINT8(save_p, players[i].splitscreenindex);
WRITEUINT16(save_p, flags);
if (flags & CAPSULE)
@ -426,6 +428,8 @@ static void P_NetUnArchivePlayers(void)
players[i].jointime = READUINT32(save_p);
players[i].splitscreenindex = READUINT8(save_p);
flags = READUINT16(save_p);
if (flags & CAPSULE)
@ -675,8 +679,6 @@ static void P_NetArchiveWorld(void)
WRITEUINT16(put, 0xffff);
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
// do lines
for (i = 0; i < numlines; i++, mld++, li++)
{
@ -695,13 +697,13 @@ static void P_NetArchiveWorld(void)
diff |= LD_S1TEXOFF;
//SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures.
if (R_CheckTextureNumForName(msd[li->sidenum[0]].toptexture) != -1
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[0]].toptexture))
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[0]].toptexture))
diff |= LD_S1TOPTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[0]].bottomtexture) != -1
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[0]].bottomtexture))
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[0]].bottomtexture))
diff |= LD_S1BOTTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[0]].midtexture) != -1
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[0]].midtexture))
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[0]].midtexture))
diff |= LD_S1MIDTEX;
}
if (li->sidenum[1] != 0xffff)
@ -710,13 +712,13 @@ static void P_NetArchiveWorld(void)
if (si->textureoffset != SHORT(msd[li->sidenum[1]].textureoffset)<<FRACBITS)
diff2 |= LD_S2TEXOFF;
if (R_CheckTextureNumForName(msd[li->sidenum[1]].toptexture) != -1
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[1]].toptexture))
&& si->toptexture != R_TextureNumForName(msd[li->sidenum[1]].toptexture))
diff2 |= LD_S2TOPTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[1]].bottomtexture) != -1
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[1]].bottomtexture))
&& si->bottomtexture != R_TextureNumForName(msd[li->sidenum[1]].bottomtexture))
diff2 |= LD_S2BOTTEX;
if (R_CheckTextureNumForName(msd[li->sidenum[1]].midtexture) != -1
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[1]].midtexture))
&& si->midtexture != R_TextureNumForName(msd[li->sidenum[1]].midtexture))
diff2 |= LD_S2MIDTEX;
if (diff2)
diff |= LD_DIFF2;
@ -3313,6 +3315,7 @@ static void P_NetArchiveMisc(void)
WRITEUINT32(save_p, wantedcalcdelay);
WRITEUINT32(save_p, indirectitemcooldown);
WRITEUINT32(save_p, hyubgone);
WRITEUINT32(save_p, mapreset);
WRITEUINT8(save_p, nospectategrief);
WRITEUINT8(save_p, thwompsactive);
@ -3421,6 +3424,7 @@ static inline boolean P_NetUnArchiveMisc(void)
wantedcalcdelay = READUINT32(save_p);
indirectitemcooldown = READUINT32(save_p);
hyubgone = READUINT32(save_p);
mapreset = READUINT32(save_p);
nospectategrief = READUINT8(save_p);
thwompsactive = (boolean)READUINT8(save_p);

View file

@ -3216,10 +3216,9 @@ boolean P_SetupLevel(boolean skipprecip)
if (!cv_analog4.changed)
CV_SetValue(&cv_analog4, 0);*/
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
CV_Set(&cv_grfov, cv_grfov.defaultvalue);
#endif
// Shouldn't be necessary with render parity?
/*if (rendermode != render_none)
CV_Set(&cv_fov, cv_fov.defaultvalue);*/
displayplayer = consoleplayer; // Start with your OWN view, please!
}
@ -3246,6 +3245,7 @@ boolean P_SetupLevel(boolean skipprecip)
wantedcalcdelay = wantedfrequency*2;
indirectitemcooldown = 0;
hyubgone = 0;
mapreset = 0;
nospectategrief = 0;
thwompsactive = false;

View file

@ -4247,13 +4247,14 @@ DoneSection2:
player->starpostx = player->mo->x>>FRACBITS;
player->starposty = player->mo->y>>FRACBITS;
player->starpostz = player->mo->floorz>>FRACBITS;
player->kartstuff[k_starpostflip] = player->mo->flags2 & MF2_OBJECTFLIP; // store flipping
player->starpostangle = player->mo->angle; //R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); torn; a momentum-based guess is less likely to be wrong in general, but when it IS wrong, it fucks you over entirely...
}
else
{
// SRB2kart 200117
// Reset starposts (checkpoints) info
player->starpostangle = player->starpostx = player->starposty = player->starpostz = 0;
player->starpostangle = player->starpostx = player->starposty = player->starpostz = player->kartstuff[k_starpostflip] = 0;
}
if (P_IsLocalPlayer(player))

View file

@ -680,6 +680,8 @@ void P_Ticker(boolean run)
if (indirectitemcooldown)
indirectitemcooldown--;
if (hyubgone)
hyubgone--;
if (G_BattleGametype())
{

View file

@ -172,7 +172,7 @@ boolean P_AutoPause(void)
if (netgame || modeattacking)
return false;
return (menuactive || window_notinfocus);
return (menuactive || ( window_notinfocus && cv_pauseifunfocused.value ));
}
//
@ -3634,165 +3634,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd) // SRB2kart - unused.
}
*/
#if 0
//
// P_DoSuperStuff()
//
// Handle related superform functionality.
//
static void P_DoSuperStuff(player_t *player)
{
mobj_t *spark;
ticcmd_t *cmd = &player->cmd;
//if (player->mo->state >= &states[S_PLAY_SUPERTRANS1] && player->mo->state <= &states[S_PLAY_SUPERTRANS9])
// return; // don't do anything right now, we're in the middle of transforming!
if (player->pflags & PF_NIGHTSMODE)
return; // NiGHTS Super doesn't mix with normal super
// Does player have all emeralds? If so, flag the "Ready For Super!"
/*if ((ALL7EMERALDS(emeralds) || ALL7EMERALDS(player->powers[pw_emeralds])) && player->health > 50)
player->pflags |= PF_SUPERREADY;
else
player->pflags &= ~PF_SUPERREADY;*/
if (player->powers[pw_super])
{
// If you're super and not Sonic, de-superize!
if (!((ALL7EMERALDS(emeralds)) && (player->charflags & SF_SUPER)) && !(ALL7EMERALDS(player->powers[pw_emeralds])))
{
player->powers[pw_super] = 0;
P_SetPlayerMobjState(player->mo, S_KART_STND1);
P_RestoreMusic(player);
P_SpawnShieldOrb(player);
// Restore color
if (player->powers[pw_shield] & SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = player->skincolor;
G_GhostAddColor(GHC_NORMAL);
}
if (gametype != GT_COOP)
{
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
return;
}
// Deplete one ring every second while super
if ((leveltime % TICRATE == 0) && !(player->exiting))
{
player->health--;
player->mo->health--;
}
// future todo: a skin option for this, and possibly more colors
switch (player->skin)
{
case 1: /* Tails */ player->mo->color = SKINCOLOR_TSUPER1; break;
case 2: /* Knux */ player->mo->color = SKINCOLOR_KSUPER1; break;
default: /* everyone */ player->mo->color = SKINCOLOR_SUPER1; break;
}
player->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN))
&& !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy))
{
spark = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SUPERSPARK);
spark->destscale = player->mo->scale;
P_SetScale(spark, player->mo->scale);
}
G_GhostAddColor(GHC_SUPER);
// Ran out of rings while super!
if (player->health <= 1 || player->exiting)
{
player->powers[pw_emeralds] = 0; // lost the power stones
P_SpawnGhostMobj(player->mo);
player->powers[pw_super] = 0;
// Restore color
if (player->powers[pw_shield] & SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = player->skincolor;
G_GhostAddColor(GHC_NORMAL);
}
if (gametype != GT_COOP)
player->powers[pw_flashing] = K_GetKartFlashing(player)-1;
/*
if (player->mo->health > 0)
{
if ((player->pflags & PF_JUMPED) || (player->pflags & PF_SPINNING))
P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
else if (player->panim == PA_RUN)
P_SetPlayerMobjState(player->mo, S_PLAY_SPD1);
else if (player->panim == PA_WALK)
P_SetPlayerMobjState(player->mo, S_PLAY_RUN1);
else
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
if (!player->exiting)
{
player->health = 1;
player->mo->health = 1;
}
}
*/
// Inform the netgame that the champion has fallen in the heat of battle.
if (gametype != GT_COOP)
{
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
// Resume normal music if you're the console player
P_RestoreMusic(player);
// If you had a shield, restore its visual significance.
P_SpawnShieldOrb(player);
}
}
}
#endif
//
// P_SuperReady
//
// Returns true if player is ready to turn super, duh
//
/*boolean P_SuperReady(player_t *player)
{
if ((player->pflags & PF_SUPERREADY) && !player->powers[pw_super] && !player->powers[pw_tailsfly]
&& !(player->powers[pw_shield] & SH_NOSTACK)
&& !player->powers[pw_invulnerability]
&& !(maptol & TOL_NIGHTS) // don't turn 'regular super' in nights levels
&& player->pflags & PF_JUMPED
&& ((player->charflags & SF_SUPER) || ALL7EMERALDS(player->powers[pw_emeralds])))
return true;
return false;
}*/
//
// P_DoJump
//
@ -6382,99 +6223,6 @@ void P_ElementalFireTrail(player_t *player)
}
}
/*static void P_SkidStuff(player_t *player)
{
fixed_t pmx = player->rmomx + player->cmomx;
fixed_t pmy = player->rmomy + player->cmomy;
// Knuckles glides into the dirt.
// SRB2kart - don't need
if (player->pflags & PF_GLIDING && player->skidtime)
{
// Fell off a ledge...
if (!onground)
{
player->skidtime = 0;
player->pflags &= ~(PF_GLIDING|PF_JUMPED);
P_SetPlayerMobjState(player->mo, S_PLAY_FALL1);
}
// Get up and brush yourself off, idiot.
else if (player->glidetime > 15)
{
P_ResetPlayer(player);
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
player->mo->momx = player->cmomx;
player->mo->momy = player->cmomy;
}
// Didn't stop yet? Skid FOREVER!
else if (player->skidtime == 1)
player->skidtime = 3*TICRATE+1;
// Spawn a particle every 3 tics.
else if (!(player->skidtime % 3))
{
mobj_t *particle = P_SpawnMobj(player->mo->x + P_RandomRange(-player->mo->radius, player->mo->radius), player->mo->y + P_RandomRange(-player->mo->radius, player->mo->radius),
player->mo->z + (player->mo->eflags & MFE_VERTICALFLIP ? player->mo->height - mobjinfo[MT_PARTICLE].height : 0),
MT_PARTICLE);
particle->tics = 10;
particle->eflags |= player->mo->eflags & MFE_VERTICALFLIP;
P_SetScale(particle, player->mo->scale >> 2);
particle->destscale = player->mo->scale << 2;
particle->scalespeed = FixedMul(particle->scalespeed, player->mo->scale); // scale the scaling speed!
P_SetObjectMomZ(particle, FRACUNIT, false);
S_StartSound(player->mo, sfx_s3k7e); // the proper "Knuckles eats dirt" sfx.
}
}
// Skidding!
elseif (onground && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID))
{
if (player->skidtime)
{
// Spawn a particle every 3 tics.
if (!(player->skidtime % 3))
{
mobj_t *particle = P_SpawnMobj(player->mo->x, player->mo->y,
player->mo->z + (player->mo->eflags & MFE_VERTICALFLIP ? player->mo->height - mobjinfo[MT_PARTICLE].height : 0),
MT_PARTICLE);
particle->tics = 10;
particle->eflags |= player->mo->eflags & MFE_VERTICALFLIP;
P_SetScale(particle, player->mo->scale >> 2);
particle->destscale = player->mo->scale << 2;
particle->scalespeed = FixedMul(particle->scalespeed, player->mo->scale); // scale the scaling speed!
P_SetObjectMomZ(particle, FRACUNIT, false);
}
}
else if (P_AproxDistance(pmx, pmy) >= FixedMul(player->runspeed/2, player->mo->scale) // if you were moving faster than half your run speed last frame
&& (player->mo->momx != pmx || player->mo->momy != pmy) // and you are moving differently this frame
&& P_GetPlayerControlDirection(player) == 2) // and your controls are pointing in the opposite direction to your movement
{ // check for skidding
angle_t mang = R_PointToAngle2(0,0,pmx,pmy); // movement angle
angle_t pang = R_PointToAngle2(pmx,pmy,player->mo->momx,player->mo->momy); // push angle
angle_t dang = mang - pang; // delta angle
if (dang > ANGLE_180) // Make delta angle always positive, invert it if it's negative.
dang = InvAngle(dang);
// If your push angle is more than this close to a full 180 degrees, trigger a skid.
if (dang > ANGLE_157h)
{
player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; //player->skidtime = TICRATE/2;
S_StartSound(player->mo, sfx_skid);
if (player->panim != PA_WALK)
P_SetPlayerMobjState(player->mo, S_KART_WALK2); // SRB2kart - was S_PLAY_RUN4
player->mo->tics = player->skidtime;
}
}
}
else {
if (player->skidtime) {
player->skidtime = 0;
S_StopSound(player->mo);
}
}
}*/
//
// P_MovePlayer
static void P_MovePlayer(player_t *player)
@ -6662,7 +6410,7 @@ static void P_MovePlayer(player_t *player)
//CONS_Printf("leftover turn (%s): %5d or %4d%%\n",
// player_names[player-players],
// (INT16) (cmd->angleturn - (player->mo->angle>>16)),
// (INT16) (cmd->angleturn - (player->mo->angle>>16)) * 100 / (angle_diff ?: 1));
// (INT16) (cmd->angleturn - (player->mo->angle>>16)) * 100 / (angle_diff ? angle_diff : 1));
}
}
@ -7654,12 +7402,14 @@ static void P_NukeAllPlayers(player_t *player)
//
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
{
const fixed_t ns = 60 << FRACBITS;
const fixed_t ns = 60 * mapobjectscale;
mobj_t *mo;
angle_t fa;
thinker_t *think;
INT32 i;
radius = FixedMul(radius, mapobjectscale);
for (i = 0; i < 16; i++)
{
fa = (i*(FINEANGLES/16));
@ -8295,9 +8045,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (mo->eflags & MFE_VERTICALFLIP)
camheight += thiscam->height;
if (splitscreen == 1)
camspeed = (3*camspeed)/4;
if (camspeed > FRACUNIT)
camspeed = FRACUNIT;
@ -8351,13 +8098,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
height -= FixedMul(height, player->kartstuff[k_boostcam]);
}
// in splitscreen modes, mess with the camera distances to make it feel proportional to how it feels normally
if (splitscreen == 1) // widescreen splits should get x1.5 distance
{
dist = FixedMul(dist, 3*FRACUNIT/2);
height = FixedMul(height, 3*FRACUNIT/2);
}
x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist);
@ -8623,10 +8363,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
{
thiscam->momx = x - thiscam->x;
thiscam->momy = y - thiscam->y;
if (splitscreen == 1) // Wide-screen needs to follow faster, due to a smaller vertical:horizontal ratio of screen space
thiscam->momz = FixedMul(z - thiscam->z, (3*camspeed)/4);
else
thiscam->momz = FixedMul(z - thiscam->z, camspeed/2);
thiscam->momz = FixedMul(z - thiscam->z, camspeed/2);
}
thiscam->pan = pan;

View file

@ -102,6 +102,8 @@ extern lumpnum_t viewborderlump[8];
// ------------------------------------------------
#define GTC_CACHE 1
#define GTC_MENUCACHE GTC_CACHE
//@TODO Add a separate caching mechanism for menu colormaps distinct from in-level GTC_CACHE. For now this is still preferable to memory leaks...
#define TC_DEFAULT -1
#define TC_BOSS -2

View file

@ -56,6 +56,7 @@ INT32 centerx, centery;
fixed_t centerxfrac, centeryfrac;
fixed_t projection;
fixed_t projectiony; // aspect ratio
fixed_t fovtan; // field of view
// just for profiling purposes
size_t framecount;
@ -134,11 +135,14 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = {
{1024, "1024"}, {1536, "1536"}, {2048, "2048"},
{0, "None"}, {0, NULL}};
static CV_PossibleValue_t fov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
//static CV_PossibleValue_t precipdensity_cons_t[] = {{0, "None"}, {1, "Light"}, {2, "Moderate"}, {4, "Heavy"}, {6, "Thick"}, {8, "V.Thick"}, {0, NULL}};
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
static void Fov_OnChange(void);
static void ChaseCam_OnChange(void);
static void ChaseCam2_OnChange(void);
static void ChaseCam3_OnChange(void);
@ -175,6 +179,7 @@ consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL,
//consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL};
// Okay, whoever said homremoval causes a performance hit should be shot.
consvar_t cv_homremoval = {"homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -227,6 +232,14 @@ void SplitScreen_OnChange(void)
}
}
}
static void Fov_OnChange(void)
{
// Shouldn't be needed with render parity?
//if ((netgame || multiplayer) && !cv_debug && cv_fov.value != 90*FRACUNIT)
// CV_Set(&cv_fov, cv_fov.defaultvalue);
R_SetViewSize();
}
static void ChaseCam_OnChange(void)
{
@ -517,7 +530,7 @@ static void R_InitTextureMapping(void)
//
// Calc focallength
// so FIELDOFVIEW angles covers SCREENWIDTH.
focallength = FixedDiv(centerxfrac,
focallength = FixedDiv(projection,
FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2));
#ifdef ESLOPE
@ -632,6 +645,7 @@ void R_ExecuteSetViewSize(void)
INT32 j;
INT32 level;
INT32 startmapl;
angle_t fov;
setsizeneeded = false;
@ -660,9 +674,12 @@ void R_ExecuteSetViewSize(void)
centerxfrac = centerx<<FRACBITS;
centeryfrac = centery<<FRACBITS;
projection = centerxfrac;
//projectiony = (((vid.height*centerx*BASEVIDWIDTH)/BASEVIDHEIGHT)/vid.width)<<FRACBITS;
projectiony = centerxfrac;
fov = FixedAngle(cv_fov.value/2) + ANGLE_90;
fovtan = FINETANGENT(fov >> ANGLETOFINESHIFT);
if (splitscreen == 1) // Splitscreen FOV should be adjusted to maintain expected vertical view
fovtan = 17*fovtan/10;
projection = projectiony = FixedDiv(centerxfrac, fovtan);
R_InitViewBuffer(scaledviewwidth, viewheight);
@ -688,7 +705,7 @@ void R_ExecuteSetViewSize(void)
for (i = 0; i < j; i++)
{
dy = ((i - viewheight*8)<<FRACBITS) + FRACUNIT/2;
dy = abs(dy);
dy = FixedMul(abs(dy), fovtan);
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
}
}
@ -803,7 +820,7 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
static mobj_t *viewmobj;
// WARNING: a should be unsigned but to add with 2048, it isn't!
#define AIMINGTODY(a) ((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS)
#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan)
// recalc necessary stuff for mouseaiming
// slopes are already calculated for the full possible view (which is 4*viewheight).
@ -1490,6 +1507,7 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_drawdist);
//CV_RegisterVar(&cv_drawdist_nights);
CV_RegisterVar(&cv_drawdist_precip);
CV_RegisterVar(&cv_fov);
CV_RegisterVar(&cv_chasecam);
CV_RegisterVar(&cv_chasecam2);

View file

@ -79,6 +79,7 @@ extern consvar_t cv_flipcam, cv_flipcam2, cv_flipcam3, cv_flipcam4;
extern consvar_t cv_shadow, cv_shadowoffs;
extern consvar_t cv_translucency;
extern consvar_t /*cv_precipdensity,*/ cv_drawdist, /*cv_drawdist_nights,*/ cv_drawdist_precip;
extern consvar_t cv_fov;
extern consvar_t cv_skybox;
extern consvar_t cv_tailspickup;

View file

@ -1051,7 +1051,7 @@ void R_DrawSinglePlane(visplane_t *pl)
temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy);
zeroheight = FIXED_TO_FLOAT(temp);
#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180)
#define ANG2RAD(angle) ((float)((angle)*M_PIl)/ANGLE_180)
// p is the texture origin in view space
// Don't add in the offsets at this stage, because doing so can result in

View file

@ -870,16 +870,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
leftheight -= viewz;
rightheight -= viewz;
#define OVERFLOWTEST(height, scale) \
overflow_test = (INT64)centeryfrac - (((INT64)height*scale)>>FRACBITS); \
if (overflow_test < 0) overflow_test = -overflow_test; \
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue;
#define CLAMPMAX INT32_MAX
#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out.
// Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave.
overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS);
if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX;
else if (overflow_test > (INT64)CLAMPMIN) rlight->height = (fixed_t)overflow_test;
else rlight->height = CLAMPMIN;
OVERFLOWTEST(leftheight, ds->scale1)
OVERFLOWTEST(rightheight, ds->scale2)
rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1);
rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
if (overflow_test > (INT64)CLAMPMAX) rlight->heightstep = CLAMPMAX;
else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test;
else rlight->heightstep = CLAMPMIN;
rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
#else
if (light->height < *pfloor->bottomheight)
@ -901,12 +903,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
leftheight -= viewz;
rightheight -= viewz;
OVERFLOWTEST(leftheight, ds->scale1)
OVERFLOWTEST(rightheight, ds->scale2)
#undef OVERFLOWTEST
// Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave.
overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS);
if (overflow_test > (INT64)CLAMPMAX) rlight->botheight = CLAMPMAX;
else if (overflow_test > (INT64)CLAMPMIN) rlight->botheight = (fixed_t)overflow_test;
else rlight->botheight = CLAMPMIN;
rlight->botheight = (centeryfrac) - FixedMul(leftheight, ds->scale1);
rlight->botheightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
if (overflow_test > (INT64)CLAMPMAX) rlight->botheightstep = CLAMPMAX;
else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test;
else rlight->botheightstep = CLAMPMIN;
rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range);
#else
lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight;
@ -1079,9 +1085,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
}
#endif
#define CLAMPMAX INT32_MAX
#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out.
// draw the columns
for (dc_x = x1; dc_x <= x2; dc_x++)
{

View file

@ -1315,6 +1315,7 @@ static void R_ProjectSprite(mobj_t *thing)
return;
scalestep = (yscale2 - yscale)/(x2 - x1);
scalestep = scalestep ? scalestep : 1;
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
// sortscale = max(yscale, yscale2);
@ -1795,7 +1796,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber)
}
}
// Someone seriously wants infinite draw distance for precipitation?
// no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off
if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS))
{
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
@ -1811,13 +1812,6 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber)
R_ProjectPrecipitationSprite(precipthing);
}
}
else
{
// Draw everything in sector, no checks
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
if (!(precipthing->precipflags & PCF_INVISIBLE))
R_ProjectPrecipitationSprite(precipthing);
}
}
//
@ -2536,23 +2530,6 @@ static void Sk_SetDefaultValue(skin_t *skin)
skin->kartweight = 5;
//
skin->normalspeed = 36<<FRACBITS;
skin->runspeed = 28<<FRACBITS;
skin->thrustfactor = 5;
skin->accelstart = 96;
skin->acceleration = 40;
skin->ability = CA_NONE;
skin->ability2 = CA2_SPINDASH;
skin->jumpfactor = FRACUNIT;
skin->actionspd = 30<<FRACBITS;
skin->mindash = 15<<FRACBITS;
skin->maxdash = 90<<FRACBITS;
skin->thokitem = -1;
skin->spinitem = -1;
skin->revitem = -1;
skin->highresscale = FRACUNIT>>1;
for (i = 0; i < sfx_skinsoundslot0; i++)
@ -2586,7 +2563,7 @@ void R_InitSkins(void)
#ifdef SKINVALUES
skin_cons_t[0].strvalue = skins[0].name;
#endif
skin->flags = SF_SUPER|SF_SUPERANIMS|SF_SUPERSPIN;
skin->flags = 0;
strcpy(skin->realname, "Sonic");
strcpy(skin->hudname, "SONIC");
@ -2595,20 +2572,11 @@ void R_InitSkins(void)
strncpy(skin->facemmap, "PLAYMMAP", 9);
skin->prefcolor = SKINCOLOR_BLUE;
skin->ability = CA_THOK;
skin->actionspd = 60<<FRACBITS;
// SRB2kart
skin->kartspeed = 8;
skin->kartweight = 2;
//
skin->normalspeed = 36<<FRACBITS;
skin->runspeed = 28<<FRACBITS;
skin->thrustfactor = 5;
skin->accelstart = 96;
skin->acceleration = 40;
skin->spritedef.numframes = sprites[SPR_PLAY].numframes;
skin->spritedef.spriteframes = sprites[SPR_PLAY].spriteframes;
ST_LoadFaceGraphics(skin->facerank, skin->facewant, skin->facemmap, 0);
@ -2672,31 +2640,12 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
if (player->mo)
player->mo->skin = skin;
player->charability = (UINT8)skin->ability;
player->charability2 = (UINT8)skin->ability2;
player->charflags = (UINT32)skin->flags;
player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem;
player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem;
player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem;
player->actionspd = skin->actionspd;
player->mindash = skin->mindash;
player->maxdash = skin->maxdash;
// SRB2kart
player->kartspeed = skin->kartspeed;
player->kartweight = skin->kartweight;
player->normalspeed = skin->normalspeed;
player->runspeed = skin->runspeed;
player->thrustfactor = skin->thrustfactor;
player->accelstart = skin->accelstart;
player->acceleration = skin->acceleration;
player->jumpfactor = skin->jumpfactor;
/*if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback || modeattacking))
{
if (playernum == consoleplayer)
@ -2895,28 +2844,8 @@ void R_AddSkins(UINT16 wadnum)
#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value);
// character type identification
FULLPROCESS(flags)
//FULLPROCESS(ability)
//FULLPROCESS(ability2)
//FULLPROCESS(thokitem)
//FULLPROCESS(spinitem)
//FULLPROCESS(revitem)
#undef FULLPROCESS
#define GETSPEED(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS;
//GETSPEED(normalspeed)
GETSPEED(runspeed)
//GETSPEED(mindash)
//GETSPEED(maxdash)
//GETSPEED(actionspd)
#undef GETSPEED
/*#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value);
GETINT(thrustfactor)
GETINT(accelstart)
GETINT(acceleration)
#undef GETINT*/
#define GETKARTSTAT(field) \
else if (!stricmp(stoken, #field)) \
{ \
@ -2934,8 +2863,6 @@ void R_AddSkins(UINT16 wadnum)
else if (!stricmp(stoken, "prefcolor"))
skin->prefcolor = K_GetKartColorByName(value);
//else if (!stricmp(stoken, "jumpfactor"))
//skin->jumpfactor = FLOAT_TO_FIXED(atof(value));
else if (!stricmp(stoken, "highresscale"))
skin->highresscale = FLOAT_TO_FIXED(atof(value));
else
@ -3045,9 +2972,6 @@ next_token:
HWR_AddPlayerMD2(numskins);
#endif
if (skin->flags & SF_RUNONWATER) // this is literally the only way a skin can be a major mod... this might be a bit heavy handed
G_SetGameModified(multiplayer, true);
numskins++;
}
return;

View file

@ -83,29 +83,11 @@ typedef struct
char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long)
char facerank[9], facewant[9], facemmap[9]; // Arbitrarily named patch lumps
UINT8 ability; // ability definition
UINT8 ability2; // secondary ability definition
INT32 thokitem;
INT32 spinitem;
INT32 revitem;
fixed_t actionspd;
fixed_t mindash;
fixed_t maxdash;
// SRB2kart
UINT8 kartspeed;
UINT8 kartweight;
//
fixed_t normalspeed; // Normal ground
fixed_t runspeed; // Speed that you break into your run animation
UINT8 thrustfactor; // Thrust = thrustfactor * acceleration
UINT8 accelstart; // Acceleration if speed = 0
UINT8 acceleration; // Acceleration
fixed_t jumpfactor; // multiple of standard jump height
// Definable color translation table
UINT8 starttranscolor;
UINT8 prefcolor;

View file

@ -57,6 +57,9 @@ static void GameMIDIMusic_OnChange(void);
static void GameSounds_OnChange(void);
static void GameDigiMusic_OnChange(void);
static void PlayMusicIfUnfocused_OnChange(void);
static void PlaySoundIfUnfocused_OnChange(void);
// commands for music and sound servers
#ifdef MUSSERV
consvar_t musserver_cmd = {"musserver_cmd", "musserver", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -110,6 +113,9 @@ consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_O
#endif
consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlayMusicIfUnfocused_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_playsoundifunfocused = {"playsoundsifunfocused", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, PlaySoundIfUnfocused_OnChange, 0, NULL, NULL, 0, 0, NULL};
#define S_MAX_VOLUME 127
// when to clip out sounds
@ -270,6 +276,9 @@ void S_RegisterSoundStuff(void)
CV_RegisterVar(&cv_gamemidimusic);
#endif
CV_RegisterVar(&cv_playmusicifunfocused);
CV_RegisterVar(&cv_playsoundifunfocused);
COM_AddCommand("tunes", Command_Tunes_f);
COM_AddCommand("restartaudio", Command_RestartAudio_f);
@ -1897,6 +1906,10 @@ static boolean S_PlayMusic(boolean looping)
}
S_InitMusicVolume(); // switch between digi and sequence volume
if (window_notinfocus && !cv_playmusicifunfocused.value)
I_PauseSong();
return true;
}
@ -1978,6 +1991,24 @@ void S_ResumeAudio(void)
I_ResumeCD();
}
void S_DisableSound(void)
{
if (sound_started && !sound_disabled)
{
sound_disabled = true;
S_StopSounds();
}
}
void S_EnableSound(void)
{
if (sound_started && sound_disabled)
{
sound_disabled = false;
S_InitSfxChannels(cv_soundvolume.value);
}
}
void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
{
if (digvolume < 0)
@ -2156,15 +2187,11 @@ void GameSounds_OnChange(void)
if (sound_disabled)
{
sound_disabled = false;
S_InitSfxChannels(cv_soundvolume.value);
S_StartSound(NULL, sfx_strpst);
if (!( cv_playsoundifunfocused.value && window_notinfocus ))
S_EnableSound();
}
else
{
sound_disabled = true;
S_StopSounds();
}
S_DisableSound();
}
void GameDigiMusic_OnChange(void)
@ -2251,3 +2278,28 @@ void GameMIDIMusic_OnChange(void)
}
}
#endif
static void PlayMusicIfUnfocused_OnChange(void)
{
if (window_notinfocus)
{
if (cv_playmusicifunfocused.value)
I_PauseSong();
else
I_ResumeSong();
}
}
static void PlaySoundIfUnfocused_OnChange(void)
{
if (!cv_gamesounds.value)
return;
if (window_notinfocus)
{
if (cv_playsoundifunfocused.value)
S_DisableSound();
else
S_EnableSound();
}
}

View file

@ -33,6 +33,8 @@ extern consvar_t cv_gamedigimusic;
extern consvar_t cv_gamemidimusic;
#endif
extern consvar_t cv_gamesounds;
extern consvar_t cv_playmusicifunfocused;
extern consvar_t cv_playsoundifunfocused;
#ifdef SNDSERV
extern consvar_t sndserver_cmd, sndserver_arg;
@ -169,6 +171,10 @@ void S_StopMusic(void);
void S_PauseAudio(void);
void S_ResumeAudio(void);
// Enable and disable sound effects
void S_EnableSound(void);
void S_DisableSound(void);
//
// Updates music & sounds
//

View file

@ -403,7 +403,7 @@ void SCR_DisplayTicRate(void)
tic_t i;
tic_t ontic = I_GetTime();
tic_t totaltics = 0;
INT32 ticcntcolor = 0;
const UINT8 *ticcntcolor = NULL;
for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i)
fpsgraph[i % TICRATE] = false;
@ -414,13 +414,36 @@ void SCR_DisplayTicRate(void)
if (fpsgraph[i])
++totaltics;
if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP;
else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP;
if (totaltics <= TICRATE/2) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SALMON, GTC_CACHE);
else if (totaltics == TICRATE) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE);
V_DrawString(vid.width-(24*vid.dupx), vid.height-(16*vid.dupy),
/*V_DrawString(vid.width-(24*vid.dupx), vid.height-(16*vid.dupy),
V_YELLOWMAP|V_NOSCALESTART, "FPS");
V_DrawString(vid.width-(40*vid.dupx), vid.height-( 8*vid.dupy),
ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));
ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));*/
// draw "FPS"
V_DrawFixedPatch(306<<FRACBITS, 183<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, framecounter, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE));
// draw total frame:
V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, TICRATE, ticcntcolor);
// draw "/"
V_DrawFixedPatch(306<<FRACBITS, 190<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, frameslash, ticcntcolor);
// draw our actual framerate
V_DrawPingNum(306, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, totaltics, ticcntcolor);
lasttic = ontic;
}
// SCR_DisplayLocalPing
// Used to draw the user's local ping next to the framerate for a quick check without having to hold TAB for instance. By default, it only shows up if your ping is too high and risks getting you kicked.
void SCR_DisplayLocalPing(void)
{
UINT32 ping = playerpingtable[consoleplayer]; // consoleplayer's ping is everyone's ping in a splitnetgame :P
if (cv_showping.value == 1 || (cv_showping.value == 2 && ping > servermaxping)) // only show 2 (warning) if our ping is at a bad level
{
INT32 dispy = cv_ticrate.value ? 160 : 181;
HU_drawPing(307, dispy, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM);
}
}

View file

@ -180,5 +180,6 @@ FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
// move out to main code for consistency
void SCR_DisplayTicRate(void);
void SCR_DisplayLocalPing(void);
#undef DNWH
#endif //__SCREEN_H__

View file

@ -2974,8 +2974,8 @@ static void I_ShutdownTimer(void)
//
tic_t I_GetTime (void)
{
static Uint32 basetime = 0;
Uint32 ticks = SDL_GetTicks();
static Uint64 basetime = 0;
Uint64 ticks = SDL_GetTicks();
if (!basetime)
basetime = ticks;

View file

@ -64,7 +64,7 @@
#include "../m_menu.h"
#include "../d_main.h"
#include "../s_sound.h"
#include "../i_sound.h" // midi pause/unpause
#include "../i_sound.h" // midi pause/unpause
#include "../i_joy.h"
#include "../st_stuff.h"
#include "../g_game.h"
@ -615,9 +615,13 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
{
// Tell game we got focus back, resume music if necessary
window_notinfocus = false;
if (!paused)
I_ResumeSong(); //resume it
if (cv_gamesounds.value)
S_EnableSound();
if (!firsttimeonmouse)
{
if (cv_usemouse.value) I_StartupMouse();
@ -630,7 +634,10 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
{
// Tell game we lost focus, pause music
window_notinfocus = true;
I_PauseSong();
if (!cv_playmusicifunfocused.value)
I_PauseSong();
if (!cv_playsoundifunfocused.value)
S_DisableSound();
if (!disable_mouse)
{
@ -1327,6 +1334,7 @@ void I_UpdateNoBlit(void)
// from PrBoom's src/SDL/i_video.c
static inline boolean I_SkipFrame(void)
{
#if 0
static boolean skip = false;
if (rendermode != render_soft)
@ -1345,6 +1353,8 @@ static inline boolean I_SkipFrame(void)
default:
return false;
}
#endif
return false;
}
//
@ -1361,6 +1371,9 @@ void I_FinishUpdate(void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
if (rendermode == render_soft && screens[0])
{
SDL_Rect rect;

BIN
src/sdl/srb2icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -1343,6 +1343,9 @@ void I_FinishUpdate(void)
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
if (render_soft == rendermode && screens[0])
{
SDL_Rect *dstrect = NULL;

View file

@ -815,6 +815,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"chain", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Mementos Reaper
{"mkuma", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Trigger Happy Havoc Monokuma
{"toada", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Arid Sands Toad scream
{"bsnipe", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Banana sniping
{"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // :shitsfree:
{"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Debug notification

View file

@ -890,6 +890,7 @@ typedef enum
sfx_chain,
sfx_mkuma,
sfx_toada,
sfx_bsnipe,
sfx_itfree,
sfx_dbgsal,

View file

@ -1342,8 +1342,8 @@ void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed)
V_DrawScaledPatch(x, y, flags, hu_font[c]);
}
// Writes a single character for the chat. (draw WHITE if bit 7 set)
// Essentially the same as the above but it's small or big depending on what resolution you've chosen to huge..
// Writes a single character for the chat (half scaled). (draw WHITE if bit 7 set)
// 16/02/19: Scratch the scaling thing, chat doesn't work anymore under 2x res -Lat'
//
void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap)
{
@ -1359,13 +1359,11 @@ void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UI
if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
return;
w = (vid.width < 640 ) ? (SHORT(hu_font[c]->width)/2) : (SHORT(hu_font[c]->width)); // use normal sized characters if we're using a terribly low resolution.
w = SHORT(hu_font[c]->width)/2;
if (x + w > vid.width)
return;
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, (vid.width < 640) ? (FRACUNIT) : (FRACUNIT/2), flags, hu_font[c], colormap);
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/2, flags, hu_font[c], colormap);
}
// Precompile a wordwrapped string to any given width.
@ -2015,6 +2013,28 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits)
} while (--digits);
}
// Draws a number using the PING font thingy.
// TODO: Merge number drawing functions into one with "font name" selection.
void V_DrawPingNum(INT32 x, INT32 y, INT32 flags, INT32 num, const UINT8 *colormap)
{
INT32 w = SHORT(pingnum[0]->width); // this SHOULD always be 5 but I guess custom graphics exist.
if (flags & V_NOSCALESTART)
w *= vid.dupx;
if (num < 0)
num = -num;
// draw the number
do
{
x -= (w-1); // Oni wanted their outline to intersect.
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, flags, pingnum[num%10], colormap);
num /= 10;
} while (num);
}
// Write a string using the credit font
// NOTE: the text is centered for screens larger than the base width
//

View file

@ -190,6 +190,10 @@ void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string)
void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num);
void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits);
// Draw ping numbers. Used by the scoreboard and that one ping option. :P
// This is a separate function because IMO lua should have access to it as well.
void V_DrawPingNum(INT32 x, INT32 y, INT32 flags, INT32 num, const UINT8 *colormap);
// Find string width from lt_font chars
INT32 V_LevelNameWidth(const char *string);
INT32 V_LevelNameHeight(const char *string);

Some files were not shown because too many files have changed in this diff Show more