mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +00:00
Ball-busting true client-server multiplayer prototype/alpha/whatever
git-svn-id: https://svn.eduke32.com/eduke32@1552 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
0bd458fa42
commit
44575d7e2c
64 changed files with 7858 additions and 2771 deletions
|
@ -51,6 +51,9 @@ endif
|
||||||
JAUDIOLIBDIR=$(SRC)/jaudiolib
|
JAUDIOLIBDIR=$(SRC)/jaudiolib
|
||||||
JAUDIOLIB=libjfaudiolib.a
|
JAUDIOLIB=libjfaudiolib.a
|
||||||
|
|
||||||
|
ENETDIR=$(SRC)/enet
|
||||||
|
ENETLIB=libenet.a
|
||||||
|
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CXX=g++
|
CXX=g++
|
||||||
AS=nasm
|
AS=nasm
|
||||||
|
@ -73,7 +76,7 @@ endif
|
||||||
|
|
||||||
OURCFLAGS=$(debug) -W -Wall -Wimplicit -Werror-implicit-function-declaration \
|
OURCFLAGS=$(debug) -W -Wall -Wimplicit -Werror-implicit-function-declaration \
|
||||||
-funsigned-char -fno-strict-aliasing -DNO_GCC_BUILTINS \
|
-funsigned-char -fno-strict-aliasing -DNO_GCC_BUILTINS \
|
||||||
-I$(INC) -I$(EINC) -I$(SRC)/jmact -I$(JAUDIOLIBDIR)/include -D_FORTIFY_SOURCE=2 \
|
-I$(INC) -I$(EINC) -I$(SRC)/jmact -I$(JAUDIOLIBDIR)/include -I$(ENETDIR)/include -D_FORTIFY_SOURCE=2 \
|
||||||
-fjump-tables -fno-stack-protector
|
-fjump-tables -fno-stack-protector
|
||||||
# -march=pentium3 -mtune=generic -mmmx -m3dnow -msse -mfpmath=sse
|
# -march=pentium3 -mtune=generic -mmmx -m3dnow -msse -mfpmath=sse
|
||||||
OURCXXFLAGS=-fno-exceptions -fno-rtti
|
OURCXXFLAGS=-fno-exceptions -fno-rtti
|
||||||
|
@ -168,6 +171,7 @@ ifeq ($(PLATFORM),WINDOWS)
|
||||||
GAMEOBJS+= $(OBJ)/gameres.$o $(OBJ)/winbits.$o $(OBJ)/startwin.game.$o $(OBJ)/music.$o $(OBJ)/midi.$o $(OBJ)/mpu401.$o
|
GAMEOBJS+= $(OBJ)/gameres.$o $(OBJ)/winbits.$o $(OBJ)/startwin.game.$o $(OBJ)/music.$o $(OBJ)/midi.$o $(OBJ)/mpu401.$o
|
||||||
EDITOROBJS+= $(OBJ)/buildres.$o
|
EDITOROBJS+= $(OBJ)/buildres.$o
|
||||||
JAUDIOLIB=libjfaudiolib_win32.a
|
JAUDIOLIB=libjfaudiolib_win32.a
|
||||||
|
ENETLIB=libenet_win32.a
|
||||||
else
|
else
|
||||||
ifeq ($(RENDERTYPE),SDL)
|
ifeq ($(RENDERTYPE),SDL)
|
||||||
ifeq (0,$(SDL_FRAMEWORK))
|
ifeq (0,$(SDL_FRAMEWORK))
|
||||||
|
@ -198,7 +202,7 @@ OURCXXFLAGS+= $(BUILDCFLAGS)
|
||||||
ifeq ($(PRETTY_OUTPUT),1)
|
ifeq ($(PRETTY_OUTPUT),1)
|
||||||
.SILENT:
|
.SILENT:
|
||||||
endif
|
endif
|
||||||
.PHONY: clean all engine $(EOBJ)/$(ENGINELIB) $(EOBJ)/$(EDITORLIB) $(JAUDIOLIBDIR)/$(JAUDIOLIB)
|
.PHONY: clean all engine $(EOBJ)/$(ENGINELIB) $(EOBJ)/$(EDITORLIB) $(JAUDIOLIBDIR)/$(JAUDIOLIB) $(ENETDIR)/$(ENETLIB)
|
||||||
|
|
||||||
# TARGETS
|
# TARGETS
|
||||||
|
|
||||||
|
@ -212,7 +216,7 @@ all:
|
||||||
notice:
|
notice:
|
||||||
$(BUILD_STARTED)
|
$(BUILD_STARTED)
|
||||||
|
|
||||||
eduke32$(EXESUFFIX): $(GAMEOBJS) $(EOBJ)/$(ENGINELIB) $(JAUDIOLIBDIR)/$(JAUDIOLIB)
|
eduke32$(EXESUFFIX): $(GAMEOBJS) $(EOBJ)/$(ENGINELIB) $(JAUDIOLIBDIR)/$(JAUDIOLIB) $(ENETDIR)/$(ENETLIB)
|
||||||
$(LINK_STATUS)
|
$(LINK_STATUS)
|
||||||
if $(CC) -o $@ $^ $(LIBS) $(STDCPPLIB); then $(LINK_OK); else $(LINK_FAILED); fi
|
if $(CC) -o $@ $^ $(LIBS) $(STDCPPLIB); then $(LINK_OK); else $(LINK_FAILED); fi
|
||||||
ifeq (1,$(RELEASE))
|
ifeq (1,$(RELEASE))
|
||||||
|
@ -221,7 +225,7 @@ ifeq (1,$(RELEASE))
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
mapster32$(EXESUFFIX): $(EDITOROBJS) $(EOBJ)/$(EDITORLIB) $(EOBJ)/$(ENGINELIB) $(JAUDIOLIBDIR)/$(JAUDIOLIB)
|
mapster32$(EXESUFFIX): $(EDITOROBJS) $(EOBJ)/$(EDITORLIB) $(EOBJ)/$(ENGINELIB) $(JAUDIOLIBDIR)/$(JAUDIOLIB) $(ENETDIR)/$(ENETLIB)
|
||||||
$(LINK_STATUS)
|
$(LINK_STATUS)
|
||||||
if $(CC) $(CFLAGS) $(OURCFLAGS) -o $@ $^ $(LIBS) $(STDCPPLIB); then $(LINK_OK); else $(LINK_FAILED); fi
|
if $(CC) $(CFLAGS) $(OURCFLAGS) -o $@ $^ $(LIBS) $(STDCPPLIB); then $(LINK_OK); else $(LINK_FAILED); fi
|
||||||
ifeq (1,$(RELEASE))
|
ifeq (1,$(RELEASE))
|
||||||
|
@ -268,6 +272,16 @@ ifeq ($(PRETTY_OUTPUT),1)
|
||||||
printf "\033[K\033[0;35mChanging dir to \033[1;35m$(CURDIR)\033[0;35m \033[0m\n"
|
printf "\033[K\033[0;35mChanging dir to \033[1;35m$(CURDIR)\033[0;35m \033[0m\n"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
$(ENETDIR)/$(ENETLIB):
|
||||||
|
ifeq ($(PRETTY_OUTPUT),1)
|
||||||
|
printf "\033[K\033[0;35mChanging dir to \033[1;35m$(CURDIR)/$(ENETDIR)\033[0;35m \033[0m\n"
|
||||||
|
endif
|
||||||
|
$(MAKE) -C $(ENETDIR) PRETTY_OUTPUT=$(PRETTY_OUTPUT) EROOT=$(EROOT) RELEASE=$(RELEASE) OPTLEVEL=$(OPTLEVEL)
|
||||||
|
ifeq ($(PRETTY_OUTPUT),1)
|
||||||
|
printf "\033[K\033[0;35mChanging dir to \033[1;35m$(CURDIR)\033[0;35m \033[0m\n"
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
# RULES
|
# RULES
|
||||||
$(OBJ)/%.$o: $(SRC)/%.nasm
|
$(OBJ)/%.$o: $(SRC)/%.nasm
|
||||||
$(COMPILE_STATUS)
|
$(COMPILE_STATUS)
|
||||||
|
@ -309,7 +323,7 @@ $(RSRC)/editor_banner.c: $(RSRC)/build.bmp
|
||||||
# PHONIES
|
# PHONIES
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f $(OBJ)/* eduke32$(EXESUFFIX) mapster32$(EXESUFFIX) core* duke3d_w32$(EXESUFFIX) && $(MAKE) -C $(JAUDIOLIBDIR) clean
|
-rm -f $(OBJ)/* eduke32$(EXESUFFIX) mapster32$(EXESUFFIX) core* duke3d_w32$(EXESUFFIX) && $(MAKE) -C $(JAUDIOLIBDIR) clean && $(MAKE) -C $(ENETDIR) clean
|
||||||
|
|
||||||
veryclean: clean
|
veryclean: clean
|
||||||
-rm -f $(EOBJ)/* $(RSRC)/*banner*
|
-rm -f $(EOBJ)/* $(RSRC)/*banner*
|
||||||
|
|
|
@ -12,6 +12,9 @@ o=obj
|
||||||
JAUDIOLIBDIR=$(SRC)\jaudiolib
|
JAUDIOLIBDIR=$(SRC)\jaudiolib
|
||||||
JAUDIOLIB=libjfaudiolib.lib
|
JAUDIOLIB=libjfaudiolib.lib
|
||||||
|
|
||||||
|
ENETDIR=$(SRC)\enet
|
||||||
|
ENETLIB=libenet.lib
|
||||||
|
|
||||||
ENGINELIB=engine.lib
|
ENGINELIB=engine.lib
|
||||||
EDITORLIB=build.lib
|
EDITORLIB=build.lib
|
||||||
|
|
||||||
|
@ -37,7 +40,7 @@ AS=ml
|
||||||
LINK=link /nologo /opt:ref
|
LINK=link /nologo /opt:ref
|
||||||
MT=mt
|
MT=mt
|
||||||
CFLAGS= /MT /J /nologo $(flags_cl) \
|
CFLAGS= /MT /J /nologo $(flags_cl) \
|
||||||
/I$(INC) /I$(EINC)\msvc /I$(EINC)\ /I$(SRC)\jmact /I$(JAUDIOLIBDIR)\include /I$(MSSDKROOT)\include" /I$(PLATFORMSDK)\include" \
|
/I$(INC) /I$(EINC)\msvc /I$(EINC)\ /I$(SRC)\jmact /I$(JAUDIOLIBDIR)\include /I$(ENETDIR)\include /I$(MSSDKROOT)\include" /I$(PLATFORMSDK)\include" \
|
||||||
/D "_CRT_SECURE_NO_DEPRECATE" /W2 $(ENGINEOPTS) \
|
/D "_CRT_SECURE_NO_DEPRECATE" /W2 $(ENGINEOPTS) \
|
||||||
/I$(DXROOT)\include" /DRENDERTYPEWIN=1
|
/I$(DXROOT)\include" /DRENDERTYPEWIN=1
|
||||||
LIBS=user32.lib gdi32.lib shell32.lib dxguid.lib winmm.lib wsock32.lib comctl32.lib \
|
LIBS=user32.lib gdi32.lib shell32.lib dxguid.lib winmm.lib wsock32.lib comctl32.lib \
|
||||||
|
@ -131,7 +134,7 @@ EDITOROBJS=$(OBJ)\astub.$o \
|
||||||
# TARGETS
|
# TARGETS
|
||||||
all: eduke32$(EXESUFFIX) mapster32$(EXESUFFIX) # duke3d_w32$(EXESUFFIX);
|
all: eduke32$(EXESUFFIX) mapster32$(EXESUFFIX) # duke3d_w32$(EXESUFFIX);
|
||||||
|
|
||||||
eduke32$(EXESUFFIX): $(GAMEOBJS) $(EOBJ)\$(ENGINELIB) $(JAUDIOLIBDIR)\$(JAUDIOLIB)
|
eduke32$(EXESUFFIX): $(GAMEOBJS) $(EOBJ)\$(ENGINELIB) $(JAUDIOLIBDIR)\$(JAUDIOLIB) $(ENETDIR)\$(ENETLIB)
|
||||||
$(LINK) /OUT:$@ /SUBSYSTEM:WINDOWS /LIBPATH:$(DXROOT)\lib\x86" /LIBPATH:$(PLATFORMSDK)\lib" /LIBPATH:$(MSSDKROOT)\lib" $(flags_link) /MAP $** $(LIBS)
|
$(LINK) /OUT:$@ /SUBSYSTEM:WINDOWS /LIBPATH:$(DXROOT)\lib\x86" /LIBPATH:$(PLATFORMSDK)\lib" /LIBPATH:$(MSSDKROOT)\lib" $(flags_link) /MAP $** $(LIBS)
|
||||||
$(MT) -manifest $(RSRC)\manifest.game.xml -hashupdate -outputresource:$@ -out:$@.manifest
|
$(MT) -manifest $(RSRC)\manifest.game.xml -hashupdate -outputresource:$@ -out:$@.manifest
|
||||||
|
|
||||||
|
@ -158,11 +161,16 @@ jaudiolib:
|
||||||
nmake /f Makefile.msvc
|
nmake /f Makefile.msvc
|
||||||
cd $(MAKEDIR)
|
cd $(MAKEDIR)
|
||||||
|
|
||||||
|
enet:
|
||||||
|
cd $(ENETDIR)
|
||||||
|
nmake /f Makefile.msvc
|
||||||
|
cd $(MAKEDIR)
|
||||||
|
|
||||||
AlwaysBuild: ;
|
AlwaysBuild: ;
|
||||||
$(EOBJ)\$(EDITORLIB): editorlib ;
|
$(EOBJ)\$(EDITORLIB): editorlib ;
|
||||||
$(EOBJ)\$(ENGINELIB): enginelib ;
|
$(EOBJ)\$(ENGINELIB): enginelib ;
|
||||||
$(JAUDIOLIBDIR)\$(JAUDIOLIB): jaudiolib ;
|
$(JAUDIOLIBDIR)\$(JAUDIOLIB): jaudiolib ;
|
||||||
|
$(ENETDIR)\$(ENETLIB): enet ;
|
||||||
|
|
||||||
# PHONIES
|
# PHONIES
|
||||||
clean:
|
clean:
|
||||||
|
@ -170,6 +178,8 @@ clean:
|
||||||
*.pdb *.map *.manifest
|
*.pdb *.map *.manifest
|
||||||
cd $(JAUDIOLIBDIR)
|
cd $(JAUDIOLIBDIR)
|
||||||
nmake /f Makefile.msvc clean
|
nmake /f Makefile.msvc clean
|
||||||
|
cd $(MAKEDIR)\$(ENETDIR)
|
||||||
|
nmake /f Makefile.msvc clean
|
||||||
cd $(MAKEDIR)
|
cd $(MAKEDIR)
|
||||||
|
|
||||||
veryclean: clean
|
veryclean: clean
|
||||||
|
|
|
@ -127,7 +127,7 @@ ENGINEOBJS+= \
|
||||||
$(OBJ)/textfont.$o \
|
$(OBJ)/textfont.$o \
|
||||||
$(OBJ)/smalltextfont.$o \
|
$(OBJ)/smalltextfont.$o \
|
||||||
$(OBJ)/kplib.$o \
|
$(OBJ)/kplib.$o \
|
||||||
$(OBJ)/fastlz.$o \
|
$(OBJ)/quicklz.$o \
|
||||||
$(OBJ)/md4.$o \
|
$(OBJ)/md4.$o \
|
||||||
$(OBJ)/osd.$o \
|
$(OBJ)/osd.$o \
|
||||||
$(OBJ)/pragmas.$o \
|
$(OBJ)/pragmas.$o \
|
||||||
|
|
|
@ -10,14 +10,14 @@ $(OBJ)/config.$o: $(SRC)/config.c $(INC)/compat.h $(INC)/osd.h $(INC)/editor.h
|
||||||
$(OBJ)/crc32.$o: $(SRC)/crc32.c $(INC)/crc32.h
|
$(OBJ)/crc32.$o: $(SRC)/crc32.c $(INC)/crc32.h
|
||||||
$(OBJ)/defs.$o: $(SRC)/defs.c $(INC)/build.h $(INC)/baselayer.h $(INC)/scriptfile.h $(INC)/compat.h
|
$(OBJ)/defs.$o: $(SRC)/defs.c $(INC)/build.h $(INC)/baselayer.h $(INC)/scriptfile.h $(INC)/compat.h
|
||||||
$(OBJ)/engine.$o: $(SRC)/engine.c $(INC)/compat.h $(INC)/build.h $(INC)/pragmas.h $(INC)/cache1d.h $(INC)/a.h $(INC)/osd.h $(INC)/baselayer.h $(SRC)/engine_priv.h $(INC)/polymost.h $(INC)/hightile.h $(INC)/mdsprite.h $(INC)/polymer.h
|
$(OBJ)/engine.$o: $(SRC)/engine.c $(INC)/compat.h $(INC)/build.h $(INC)/pragmas.h $(INC)/cache1d.h $(INC)/a.h $(INC)/osd.h $(INC)/baselayer.h $(SRC)/engine_priv.h $(INC)/polymost.h $(INC)/hightile.h $(INC)/mdsprite.h $(INC)/polymer.h
|
||||||
$(OBJ)/polymost.$o: $(SRC)/polymost.c $(INC)/md4.h $(INC)/fastlz.h $(INC)/lzwnew.h $(SRC)/engine_priv.h $(INC)/polymost.h $(INC)/hightile.h $(INC)/mdsprite.h
|
$(OBJ)/polymost.$o: $(SRC)/polymost.c $(INC)/md4.h $(INC)/quicklz.h $(INC)/lzwnew.h $(SRC)/engine_priv.h $(INC)/polymost.h $(INC)/hightile.h $(INC)/mdsprite.h
|
||||||
$(OBJ)/hightile.$o: $(SRC)/hightile.c $(INC)/kplib.h $(INC)/hightile.h
|
$(OBJ)/hightile.$o: $(SRC)/hightile.c $(INC)/kplib.h $(INC)/hightile.h
|
||||||
$(OBJ)/mdsprite.$o: $(SRC)/mdsprite.c $(SRC)/engine_priv.h $(INC)/polymost.h $(INC)/hightile.h $(INC)/mdsprite.h
|
$(OBJ)/mdsprite.$o: $(SRC)/mdsprite.c $(SRC)/engine_priv.h $(INC)/polymost.h $(INC)/hightile.h $(INC)/mdsprite.h
|
||||||
$(OBJ)/textfont.$o: $(SRC)/textfont.c
|
$(OBJ)/textfont.$o: $(SRC)/textfont.c
|
||||||
$(OBJ)/smalltextfont.$o: $(SRC)/smalltextfont.c
|
$(OBJ)/smalltextfont.$o: $(SRC)/smalltextfont.c
|
||||||
$(OBJ)/glbuild.$o: $(SRC)/glbuild.c $(INC)/glbuild.h $(INC)/baselayer.h
|
$(OBJ)/glbuild.$o: $(SRC)/glbuild.c $(INC)/glbuild.h $(INC)/baselayer.h
|
||||||
$(OBJ)/kplib.$o: $(SRC)/kplib.c $(INC)/compat.h
|
$(OBJ)/kplib.$o: $(SRC)/kplib.c $(INC)/compat.h
|
||||||
$(OBJ)/fastlz.$o: $(SRC)/fastlz.c $(INC)/fastlz.h
|
$(OBJ)/quicklz.$o: $(SRC)/quicklz.c $(INC)/quicklz.h
|
||||||
$(OBJ)/lzwnew.$o: $(SRC)/lzwnew.c
|
$(OBJ)/lzwnew.$o: $(SRC)/lzwnew.c
|
||||||
$(OBJ)/md4.$o: $(SRC)/md4.c $(INC)/md4.h $(INC)/compat.h
|
$(OBJ)/md4.$o: $(SRC)/md4.c $(INC)/md4.h $(INC)/compat.h
|
||||||
$(OBJ)/mmulti_unstable.$o: $(SRC)/mmulti_unstable.c $(INC)/mmulti_unstable.h
|
$(OBJ)/mmulti_unstable.$o: $(SRC)/mmulti_unstable.c $(INC)/mmulti_unstable.h
|
||||||
|
|
|
@ -72,7 +72,7 @@ ENGINEOBJS= \
|
||||||
$(OBJ)\smalltextfont.$o \
|
$(OBJ)\smalltextfont.$o \
|
||||||
$(OBJ)\glbuild.$o \
|
$(OBJ)\glbuild.$o \
|
||||||
$(OBJ)\kplib.$o \
|
$(OBJ)\kplib.$o \
|
||||||
$(OBJ)\fastlz.$o \
|
$(OBJ)\quicklz.$o \
|
||||||
$(OBJ)\lzwnew.$o \
|
$(OBJ)\lzwnew.$o \
|
||||||
$(OBJ)\md4.$o \
|
$(OBJ)\md4.$o \
|
||||||
$(OBJ)\mmulti_unstable.$o \
|
$(OBJ)\mmulti_unstable.$o \
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
ENGINELIB=libengine.a
|
ENGINELIB=libengine.a
|
||||||
EDITORLIB=libbuild.a
|
EDITORLIB=libbuild.a
|
||||||
|
|
||||||
SDLCONFIG = /usr/local/bin/sdl-config
|
# SDLCONFIG = /usr/local/bin/sdl-config
|
||||||
# SDLCONFIG = sdl-config
|
SDLCONFIG = sdl-config
|
||||||
|
|
||||||
ifeq ($(wildcard $(SDLCONFIG)),$(SDLCONFIG))
|
ifeq ($(wildcard $(SDLCONFIG)),$(SDLCONFIG))
|
||||||
SDLROOT = /usr/local
|
SDLROOT = /usr/local
|
||||||
|
|
|
@ -40,7 +40,7 @@ extern "C" {
|
||||||
#define MAXSPRITESONSCREEN 4096
|
#define MAXSPRITESONSCREEN 4096
|
||||||
#define MAXUNIQHUDID 256 //Extra slots so HUD models can store animation state without messing game sprites
|
#define MAXUNIQHUDID 256 //Extra slots so HUD models can store animation state without messing game sprites
|
||||||
|
|
||||||
#define RESERVEDPALS 2 // don't forget to increment this when adding reserved pals
|
#define RESERVEDPALS 4 // don't forget to increment this when adding reserved pals
|
||||||
#define DETAILPAL (MAXPALOOKUPS - 1)
|
#define DETAILPAL (MAXPALOOKUPS - 1)
|
||||||
#define GLOWPAL (MAXPALOOKUPS - 2)
|
#define GLOWPAL (MAXPALOOKUPS - 2)
|
||||||
#define SPECULARPAL (MAXPALOOKUPS - 3)
|
#define SPECULARPAL (MAXPALOOKUPS - 3)
|
||||||
|
|
|
@ -36,8 +36,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define USE_ALLOCATOR 1
|
#define USE_ALLOCATOR 1
|
||||||
// #define REPLACE_SYSTEM_ALLOCATOR
|
#define USE_MAGIC_HEADERS 1
|
||||||
#define USE_MAGIC_HEADERS 0
|
#define ENABLE_FAST_HEAP_DETECTION 1
|
||||||
|
|
||||||
#include "nedmalloc.h"
|
#include "nedmalloc.h"
|
||||||
|
|
||||||
#ifndef TRUE
|
#ifndef TRUE
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
/*
|
|
||||||
FastLZ - lightning-fast lossless compression library
|
|
||||||
|
|
||||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
|
||||||
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
|
|
||||||
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FASTLZ_H
|
|
||||||
#define FASTLZ_H
|
|
||||||
|
|
||||||
#define FASTLZ_VERSION 0x000100
|
|
||||||
|
|
||||||
#define FASTLZ_VERSION_MAJOR 0
|
|
||||||
#define FASTLZ_VERSION_MINOR 0
|
|
||||||
#define FASTLZ_VERSION_REVISION 0
|
|
||||||
|
|
||||||
#define FASTLZ_VERSION_STRING "0.1.0"
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compress a block of data in the input buffer and returns the size of
|
|
||||||
compressed block. The size of input buffer is specified by length. The
|
|
||||||
minimum input buffer size is 16.
|
|
||||||
|
|
||||||
The output buffer must be at least 5% larger than the input buffer
|
|
||||||
and can not be smaller than 66 bytes.
|
|
||||||
|
|
||||||
If the input is not compressible, the return value might be larger than
|
|
||||||
length (input buffer size).
|
|
||||||
|
|
||||||
The input buffer and the output buffer can not overlap.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int fastlz_compress(const void* input, int length, void* output);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Decompress a block of compressed data and returns the size of the
|
|
||||||
decompressed block. If error occurs, e.g. the compressed data is
|
|
||||||
corrupted or the output buffer is not large enough, then 0 (zero)
|
|
||||||
will be returned instead.
|
|
||||||
|
|
||||||
The input buffer and the output buffer can not overlap.
|
|
||||||
|
|
||||||
Decompression is memory safe and guaranteed not to write the output buffer
|
|
||||||
more than what is specified in maxout.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Compress a block of data in the input buffer and returns the size of
|
|
||||||
compressed block. The size of input buffer is specified by length. The
|
|
||||||
minimum input buffer size is 16.
|
|
||||||
|
|
||||||
The output buffer must be at least 5% larger than the input buffer
|
|
||||||
and can not be smaller than 66 bytes.
|
|
||||||
|
|
||||||
If the input is not compressible, the return value might be larger than
|
|
||||||
length (input buffer size).
|
|
||||||
|
|
||||||
The input buffer and the output buffer can not overlap.
|
|
||||||
|
|
||||||
Compression level can be specified in parameter level. At the moment,
|
|
||||||
only level 1 and level 2 are supported.
|
|
||||||
Level 1 is the fastest compression and generally useful for short data.
|
|
||||||
Level 2 is slightly slower but it gives better compression ratio.
|
|
||||||
|
|
||||||
Note that the compressed data, regardless of the level, can always be
|
|
||||||
decompressed using the function fastlz_decompress above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* FASTLZ_H */
|
|
|
@ -502,7 +502,6 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Version identifier to allow people to support multiple versions */
|
/* Version identifier to allow people to support multiple versions */
|
||||||
|
|
||||||
#ifndef DLMALLOC_VERSION
|
#ifndef DLMALLOC_VERSION
|
||||||
#define DLMALLOC_VERSION 20804
|
#define DLMALLOC_VERSION 20804
|
||||||
#endif /* DLMALLOC_VERSION */
|
#endif /* DLMALLOC_VERSION */
|
||||||
|
@ -1543,9 +1542,7 @@ unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);
|
||||||
initialized in init_mparams. Note that the non-zeroness of "magic"
|
initialized in init_mparams. Note that the non-zeroness of "magic"
|
||||||
also serves as an initialization flag.
|
also serves as an initialization flag.
|
||||||
*/
|
*/
|
||||||
|
typedef unsigned int flag_t;
|
||||||
typedef unsigned int flag_t; /* The type of various bit flag sets */
|
|
||||||
|
|
||||||
struct malloc_params {
|
struct malloc_params {
|
||||||
volatile size_t magic;
|
volatile size_t magic;
|
||||||
size_t page_size;
|
size_t page_size;
|
||||||
|
@ -1634,16 +1631,14 @@ static void* lastWin32mmap; /* Used as a hint */
|
||||||
#endif /* DEFAULT_GRANULARITY_ALIGNED */
|
#endif /* DEFAULT_GRANULARITY_ALIGNED */
|
||||||
#ifdef ENABLE_LARGE_PAGES
|
#ifdef ENABLE_LARGE_PAGES
|
||||||
int largepagesavailable = 1;
|
int largepagesavailable = 1;
|
||||||
|
#ifndef MEM_LARGE_PAGES
|
||||||
|
#define MEM_LARGE_PAGES 0x20000000
|
||||||
|
#endif
|
||||||
#endif /* ENABLE_LARGE_PAGES */
|
#endif /* ENABLE_LARGE_PAGES */
|
||||||
static FORCEINLINE void* win32mmap(size_t size) {
|
static FORCEINLINE void* win32mmap(size_t size) {
|
||||||
void* baseaddress = 0;
|
void* baseaddress = 0;
|
||||||
void* ptr = 0;
|
void* ptr = 0;
|
||||||
#ifdef ENABLE_LARGE_PAGES
|
#ifdef ENABLE_LARGE_PAGES
|
||||||
|
|
||||||
#ifndef MEM_LARGE_PAGES
|
|
||||||
#define MEM_LARGE_PAGES 0x20000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Note that large pages are *always* allocated on a large page boundary.
|
/* Note that large pages are *always* allocated on a large page boundary.
|
||||||
If however granularity is small then don't waste a kernel call if size
|
If however granularity is small then don't waste a kernel call if size
|
||||||
isn't around the size of a large page */
|
isn't around the size of a large page */
|
||||||
|
@ -1677,7 +1672,11 @@ static FORCEINLINE void* win32mmap(size_t size) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
#ifdef ENABLE_LARGE_PAGES
|
||||||
|
printf("VirtualAlloc returns %p size %u. LargePagesAvailable=%d\n", ptr, size, largepagesavailable);
|
||||||
|
#else
|
||||||
printf("VirtualAlloc returns %p size %u\n", ptr, size);
|
printf("VirtualAlloc returns %p size %u\n", ptr, size);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return (ptr != 0)? ptr: MFAIL;
|
return (ptr != 0)? ptr: MFAIL;
|
||||||
}
|
}
|
||||||
|
@ -1825,6 +1824,7 @@ static FORCEINLINE int win32munmap(void* ptr, size_t size) {
|
||||||
/* Custom pthread-style spin locks on x86 and x64 for gcc */
|
/* Custom pthread-style spin locks on x86 and x64 for gcc */
|
||||||
struct pthread_mlock_t {
|
struct pthread_mlock_t {
|
||||||
volatile unsigned int l;
|
volatile unsigned int l;
|
||||||
|
char cachelinepadding[64];
|
||||||
unsigned int c;
|
unsigned int c;
|
||||||
pthread_t threadid;
|
pthread_t threadid;
|
||||||
};
|
};
|
||||||
|
@ -1836,7 +1836,7 @@ struct pthread_mlock_t {
|
||||||
#define TRY_LOCK(sl) pthread_try_lock(sl)
|
#define TRY_LOCK(sl) pthread_try_lock(sl)
|
||||||
#define SPINS_PER_YIELD 63
|
#define SPINS_PER_YIELD 63
|
||||||
|
|
||||||
static MLOCK_T malloc_global_mutex = { 0, 0, 0};
|
static MLOCK_T malloc_global_mutex = { 0, "", 0, 0};
|
||||||
|
|
||||||
static FORCEINLINE int pthread_acquire_lock (MLOCK_T *sl) {
|
static FORCEINLINE int pthread_acquire_lock (MLOCK_T *sl) {
|
||||||
int spins = 0;
|
int spins = 0;
|
||||||
|
@ -1924,6 +1924,7 @@ static FORCEINLINE int pthread_try_lock (MLOCK_T *sl) {
|
||||||
/* Custom win32-style spin locks on x86 and x64 for MSC */
|
/* Custom win32-style spin locks on x86 and x64 for MSC */
|
||||||
struct win32_mlock_t {
|
struct win32_mlock_t {
|
||||||
volatile long l;
|
volatile long l;
|
||||||
|
char cachelinepadding[64];
|
||||||
unsigned int c;
|
unsigned int c;
|
||||||
long threadid;
|
long threadid;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
#ifndef __MMULTIMSGS_H__
|
|
||||||
#define __MMULTIMSGS_H__
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ok, so this header file defines the message bytes and outlines the basic
|
|
||||||
* message descriptions for out-of-band messages that are common to all games
|
|
||||||
* that utilize my net code. Once a game determines that it is indeed talking
|
|
||||||
* to another peer of the same genus, the rest is up to the game itself to
|
|
||||||
* decide, but for basic stuff, the interfaces will be identical.
|
|
||||||
*
|
|
||||||
* Why am I not choosing to implement all this engine-side? Because all the
|
|
||||||
* games are different and about the only thing they are guaranteed to use in
|
|
||||||
* common that I can be certain of is the services my net code will provide.
|
|
||||||
* So, since I can't code anything in particular with every Build game in mind,
|
|
||||||
* I'm putting handling all the game-visible messages into the game's domain.
|
|
||||||
* The engine will still handle its own internal messages because the game
|
|
||||||
* never sees them. Ever.
|
|
||||||
*
|
|
||||||
* CMDs are messages sent by a peer to another, and RSPs are the replies.
|
|
||||||
*
|
|
||||||
* The master of the network game, regardless if the eventual game is talking
|
|
||||||
* with a peer-to-peer design or not, shall enumerate each peer as it joins
|
|
||||||
* and the master will always assign itself peer number 0. This simplifies
|
|
||||||
* things all-round because each peer that joins automatically knows that
|
|
||||||
* id 0 is its master and it already knows the master's address. Technically
|
|
||||||
* every other peer who joins may get a sequential number for its id so maybe
|
|
||||||
* even transmitting the peer unique ids is unnecessary and we'd be easier
|
|
||||||
* just sending a number of players, but the less craftiness at this point
|
|
||||||
* in time, the better.
|
|
||||||
*
|
|
||||||
* -- Jonathon
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MSGPROTOVER 0x00
|
|
||||||
// 0x00 20031209
|
|
||||||
|
|
||||||
|
|
||||||
#define MSG_CMD_GETGAMEINFO 0x10
|
|
||||||
// char MSG_CMD_GETGAMEINFO
|
|
||||||
// char MSGPROTOVER
|
|
||||||
#define MSG_RSP_BADPROTO 0x11
|
|
||||||
// char MSG_RSP_BADPROTO
|
|
||||||
#define MSG_RSP_NOGAME 0x12
|
|
||||||
// char MSG_RSP_NOGAME
|
|
||||||
// char[8] gamename
|
|
||||||
#define MSG_RSP_GAMEINFO 0x13
|
|
||||||
// char MSG_RSP_GAMEINFO
|
|
||||||
// char[8] gamename eg. DUKE3DSW/DUKE3D\x00\x00/DUKE3DAT
|
|
||||||
// ... other information particular to the game
|
|
||||||
|
|
||||||
|
|
||||||
#define MSG_CMD_JOINGAME 0x20
|
|
||||||
// char MSG_CMD_JOINGAME
|
|
||||||
#define MSG_RSP_GAMEINPROG 0x21
|
|
||||||
// char MSG_RSP_GAMEINPROG
|
|
||||||
#define MSG_RSP_JOINACCEPTED 0x22
|
|
||||||
// char MSG_RSP_JOINACCEPTED
|
|
||||||
// short uniqueid
|
|
||||||
// char numtofollow
|
|
||||||
// short[numtofollow] peeruid
|
|
||||||
// ... other information particular to the game
|
|
||||||
#define MSG_RSP_GAMEFULL 0x23
|
|
||||||
// char MSG_RSP_GAMEFULL
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -32,8 +32,10 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
/* See malloc.c.h for what each function does.
|
/* See malloc.c.h for what each function does.
|
||||||
|
|
||||||
REPLACE_SYSTEM_ALLOCATOR causes nedalloc's functions to be called malloc,
|
REPLACE_SYSTEM_ALLOCATOR on POSIX causes nedalloc's functions to be called
|
||||||
free etc. instead of nedmalloc, nedfree etc. You may or may not want this.
|
malloc, free etc. instead of nedmalloc, nedfree etc. You may or may not want
|
||||||
|
this. On Windows it causes nedmalloc to patch all loaded DLLs and binaries
|
||||||
|
to replace usage of the system allocator.
|
||||||
|
|
||||||
NO_NED_NAMESPACE prevents the functions from being defined in the nedalloc
|
NO_NED_NAMESPACE prevents the functions from being defined in the nedalloc
|
||||||
namespace when in C++ (uses the global namespace instead).
|
namespace when in C++ (uses the global namespace instead).
|
||||||
|
@ -51,25 +53,62 @@ to each block. nedpfree() and nedprealloc() can then automagically know when
|
||||||
to free a system allocated block. Enabling this typically adds 20-50% to
|
to free a system allocated block. Enabling this typically adds 20-50% to
|
||||||
application memory usage.
|
application memory usage.
|
||||||
|
|
||||||
USE_ALLOCATOR can be one of these settings:
|
ENABLE_TOLERANT_NEDMALLOC is automatically turned on if REPLACE_SYSTEM_ALLOCATOR
|
||||||
|
is set or the Windows DLL is being built. This causes nedmalloc to detect when a
|
||||||
|
system allocator block is passed to it and to handle it appropriately. Note that
|
||||||
|
without USE_MAGIC_HEADERS there is a very tiny chance that nedmalloc will segfault
|
||||||
|
on non-Windows builds (it uses Win32 SEH to trap segfaults on Windows and there
|
||||||
|
is no comparable system on POSIX).
|
||||||
|
|
||||||
|
USE_ALLOCATOR can be one of these settings (it defaults to 1):
|
||||||
0: System allocator (nedmalloc now simply acts as a threadcache).
|
0: System allocator (nedmalloc now simply acts as a threadcache).
|
||||||
WARNING: Intended for DEBUG USE ONLY - not all functions work correctly.
|
WARNING: Intended for DEBUG USE ONLY - not all functions work correctly.
|
||||||
1: dlmalloc
|
1: dlmalloc
|
||||||
|
|
||||||
|
ENABLE_LARGE_PAGES enables support for requesting memory from the system in large
|
||||||
|
(typically >=2Mb) pages if the host OS supports this. These occupy just a single
|
||||||
|
TLB entry and can significantly improve performance in large working set applications.
|
||||||
|
|
||||||
|
ENABLE_FAST_HEAP_DETECTION enables special logic to detect blocks allocated
|
||||||
|
by the system heap. This avoids 1.5%-2% overhead when checking for non-nedmalloc
|
||||||
|
blocks, but it assumes that the NT and glibc heaps function in a very specific
|
||||||
|
fashion which may not hold true across OS upgrades.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h> /* for size_t */
|
#include <stddef.h> /* for size_t */
|
||||||
|
|
||||||
#ifndef NEDMALLOCEXTSPEC
|
#ifndef NEDMALLOCEXTSPEC
|
||||||
#ifdef NEDMALLOC_DLL_EXPORTS
|
#ifdef NEDMALLOC_DLL_EXPORTS
|
||||||
#define NEDMALLOCEXTSPEC extern __declspec(dllexport)
|
#ifdef WIN32
|
||||||
|
#define NEDMALLOCEXTSPEC extern __declspec(dllexport)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define NEDMALLOCEXTSPEC extern __attribute__ ((visibility("default")))
|
||||||
|
#endif
|
||||||
|
#ifndef ENABLE_TOLERANT_NEDMALLOC
|
||||||
|
#define ENABLE_TOLERANT_NEDMALLOC 1
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define NEDMALLOCEXTSPEC extern
|
#define NEDMALLOCEXTSPEC extern
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __STDC_VERSION__ >= 199901L /* C99 or better */
|
||||||
|
#define RESTRICT restrict
|
||||||
|
#else
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER>=1400
|
||||||
|
#define RESTRICT __restrict
|
||||||
|
#endif
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define RESTRICT __restrict
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef RESTRICT
|
||||||
|
#define RESTRICT
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER>=1400
|
#if defined(_MSC_VER) && _MSC_VER>=1400
|
||||||
#define NEDMALLOCPTRATTR __declspec(restrict)
|
#define NEDMALLOCPTRATTR __declspec(restrict)
|
||||||
|
#define NEDMALLOCNOALIASATTR __declspec(noalias)
|
||||||
#endif
|
#endif
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define NEDMALLOCPTRATTR __attribute__ ((malloc))
|
#define NEDMALLOCPTRATTR __attribute__ ((malloc))
|
||||||
|
@ -77,6 +116,9 @@ USE_ALLOCATOR can be one of these settings:
|
||||||
#ifndef NEDMALLOCPTRATTR
|
#ifndef NEDMALLOCPTRATTR
|
||||||
#define NEDMALLOCPTRATTR
|
#define NEDMALLOCPTRATTR
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef NEDMALLOCNOALIASATTR
|
||||||
|
#define NEDMALLOCNOALIASATTR
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef USE_MAGIC_HEADERS
|
#ifndef USE_MAGIC_HEADERS
|
||||||
#define USE_MAGIC_HEADERS 0
|
#define USE_MAGIC_HEADERS 0
|
||||||
|
@ -94,7 +136,10 @@ USE_ALLOCATOR can be one of these settings:
|
||||||
#if USE_ALLOCATOR==0
|
#if USE_ALLOCATOR==0
|
||||||
#error Cannot combine using the system allocator with replacing the system allocator
|
#error Cannot combine using the system allocator with replacing the system allocator
|
||||||
#endif
|
#endif
|
||||||
#ifndef _WIN32 /* We have a dedidicated patcher for Windows */
|
#ifndef ENABLE_TOLERANT_NEDMALLOC
|
||||||
|
#define ENABLE_TOLERANT_NEDMALLOC 1
|
||||||
|
#endif
|
||||||
|
#ifndef WIN32 /* We have a dedicated patcher for Windows */
|
||||||
#define nedmalloc malloc
|
#define nedmalloc malloc
|
||||||
#define nedcalloc calloc
|
#define nedcalloc calloc
|
||||||
#define nedrealloc realloc
|
#define nedrealloc realloc
|
||||||
|
@ -107,23 +152,30 @@ USE_ALLOCATOR can be one of these settings:
|
||||||
#define nedmalloc_footprint malloc_footprint
|
#define nedmalloc_footprint malloc_footprint
|
||||||
#define nedindependent_calloc independent_calloc
|
#define nedindependent_calloc independent_calloc
|
||||||
#define nedindependent_comalloc independent_comalloc
|
#define nedindependent_comalloc independent_comalloc
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define nedblksize _msize
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_MALLINFO
|
|
||||||
#define NO_MALLINFO 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !NO_MALLINFO
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
struct mallinfo;
|
struct nedmallinfo {
|
||||||
|
size_t arena; /* non-mmapped space allocated from system */
|
||||||
|
size_t ordblks; /* number of free chunks */
|
||||||
|
size_t smblks; /* always 0 */
|
||||||
|
size_t hblks; /* always 0 */
|
||||||
|
size_t hblkhd; /* space in mmapped regions */
|
||||||
|
size_t usmblks; /* maximum total allocated space */
|
||||||
|
size_t fsmblks; /* always 0 */
|
||||||
|
size_t uordblks; /* total allocated space */
|
||||||
|
size_t fordblks; /* total free space */
|
||||||
|
size_t keepcost; /* releasable (via malloc_trim) space */
|
||||||
|
};
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
#if !defined(NO_NED_NAMESPACE)
|
#if !defined(NO_NED_NAMESPACE)
|
||||||
|
@ -139,11 +191,11 @@ extern "C" {
|
||||||
/* These are the global functions */
|
/* These are the global functions */
|
||||||
|
|
||||||
/* Gets the usable size of an allocated block. Note this will always be bigger than what was
|
/* Gets the usable size of an allocated block. Note this will always be bigger than what was
|
||||||
asked for due to rounding etc. Tries to return zero if this is not a nedmalloc block (though
|
asked for due to rounding etc. Optionally returns 1 in isforeign if the block came from the
|
||||||
one could see a segfault up to 6.25% of the time). On Win32 SEH is used to guarantee that a
|
system allocator - note that there is a small (>0.01%) but real chance of segfault on non-Windows
|
||||||
segfault never happens.
|
systems when passing non-nedmalloc blocks if you don't use USE_MAGIC_HEADERS.
|
||||||
*/
|
*/
|
||||||
NEDMALLOCEXTSPEC size_t nedblksize(void *mem) THROWSPEC;
|
NEDMALLOCEXTSPEC NEDMALLOCNOALIASATTR size_t nedblksize(int *RESTRICT isforeign, void *RESTRICT mem) THROWSPEC;
|
||||||
|
|
||||||
NEDMALLOCEXTSPEC void nedsetvalue(void *v) THROWSPEC;
|
NEDMALLOCEXTSPEC void nedsetvalue(void *v) THROWSPEC;
|
||||||
|
|
||||||
|
@ -152,9 +204,7 @@ NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedcalloc(size_t no, size_t size) THROW
|
||||||
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedrealloc(void *mem, size_t size) THROWSPEC;
|
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedrealloc(void *mem, size_t size) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC void nedfree(void *mem) THROWSPEC;
|
NEDMALLOCEXTSPEC void nedfree(void *mem) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedmemalign(size_t alignment, size_t bytes) THROWSPEC;
|
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedmemalign(size_t alignment, size_t bytes) THROWSPEC;
|
||||||
#if !NO_MALLINFO
|
NEDMALLOCEXTSPEC struct nedmallinfo nedmallinfo(void) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC struct mallinfo nedmallinfo(void) THROWSPEC;
|
|
||||||
#endif
|
|
||||||
NEDMALLOCEXTSPEC int nedmallopt(int parno, int value) THROWSPEC;
|
NEDMALLOCEXTSPEC int nedmallopt(int parno, int value) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC void* nedmalloc_internals(size_t *granularity, size_t *magic) THROWSPEC;
|
NEDMALLOCEXTSPEC void* nedmalloc_internals(size_t *granularity, size_t *magic) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC int nedmalloc_trim(size_t pad) THROWSPEC;
|
NEDMALLOCEXTSPEC int nedmalloc_trim(size_t pad) THROWSPEC;
|
||||||
|
@ -187,12 +237,20 @@ NEDMALLOCEXTSPEC NEDMALLOCPTRATTR nedpool *nedcreatepool(size_t capacity, int th
|
||||||
*/
|
*/
|
||||||
NEDMALLOCEXTSPEC void neddestroypool(nedpool *p) THROWSPEC;
|
NEDMALLOCEXTSPEC void neddestroypool(nedpool *p) THROWSPEC;
|
||||||
|
|
||||||
|
/* Returns a zero terminated snapshot of threadpools existing at the time of call. Call
|
||||||
|
nedfree() on the returned list when you are done. Returns zero if there is only the
|
||||||
|
system pool in existence.
|
||||||
|
*/
|
||||||
|
NEDMALLOCEXTSPEC nedpool **nedpoollist() THROWSPEC;
|
||||||
|
|
||||||
/* Sets a value to be associated with a pool. You can retrieve this value by passing
|
/* Sets a value to be associated with a pool. You can retrieve this value by passing
|
||||||
any memory block allocated from that pool.
|
any memory block allocated from that pool.
|
||||||
*/
|
*/
|
||||||
NEDMALLOCEXTSPEC void nedpsetvalue(nedpool *p, void *v) THROWSPEC;
|
NEDMALLOCEXTSPEC void nedpsetvalue(nedpool *p, void *v) THROWSPEC;
|
||||||
|
|
||||||
/* Gets a previously set value using nedpsetvalue() or zero if memory is unknown.
|
/* Gets a previously set value using nedpsetvalue() or zero if memory is unknown.
|
||||||
Optionally can also retrieve pool.
|
Optionally can also retrieve pool. You can detect an unknown block by the return
|
||||||
|
being zero and *p being unmodifed.
|
||||||
*/
|
*/
|
||||||
NEDMALLOCEXTSPEC void *nedgetvalue(nedpool **p, void *mem) THROWSPEC;
|
NEDMALLOCEXTSPEC void *nedgetvalue(nedpool **p, void *mem) THROWSPEC;
|
||||||
|
|
||||||
|
@ -208,14 +266,13 @@ system pool.
|
||||||
*/
|
*/
|
||||||
NEDMALLOCEXTSPEC void neddisablethreadcache(nedpool *p) THROWSPEC;
|
NEDMALLOCEXTSPEC void neddisablethreadcache(nedpool *p) THROWSPEC;
|
||||||
|
|
||||||
|
|
||||||
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedpmalloc(nedpool *p, size_t size) THROWSPEC;
|
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedpmalloc(nedpool *p, size_t size) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedpcalloc(nedpool *p, size_t no, size_t size) THROWSPEC;
|
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedpcalloc(nedpool *p, size_t no, size_t size) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedprealloc(nedpool *p, void *mem, size_t size) THROWSPEC;
|
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedprealloc(nedpool *p, void *mem, size_t size) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC void nedpfree(nedpool *p, void *mem) THROWSPEC;
|
NEDMALLOCEXTSPEC void nedpfree(nedpool *p, void *mem) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedpmemalign(nedpool *p, size_t alignment, size_t bytes) THROWSPEC;
|
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void * nedpmemalign(nedpool *p, size_t alignment, size_t bytes) THROWSPEC;
|
||||||
#if !NO_MALLINFO
|
NEDMALLOCEXTSPEC struct nedmallinfo nedpmallinfo(nedpool *p) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC struct mallinfo nedpmallinfo(nedpool *p) THROWSPEC;
|
|
||||||
#endif
|
|
||||||
NEDMALLOCEXTSPEC int nedpmallopt(nedpool *p, int parno, int value) THROWSPEC;
|
NEDMALLOCEXTSPEC int nedpmallopt(nedpool *p, int parno, int value) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC int nedpmalloc_trim(nedpool *p, size_t pad) THROWSPEC;
|
NEDMALLOCEXTSPEC int nedpmalloc_trim(nedpool *p, size_t pad) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC void nedpmalloc_stats(nedpool *p) THROWSPEC;
|
NEDMALLOCEXTSPEC void nedpmalloc_stats(nedpool *p) THROWSPEC;
|
||||||
|
@ -223,6 +280,7 @@ NEDMALLOCEXTSPEC size_t nedpmalloc_footprint(nedpool *p) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void **nedpindependent_calloc(nedpool *p, size_t elemsno, size_t elemsize, void **chunks) THROWSPEC;
|
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void **nedpindependent_calloc(nedpool *p, size_t elemsno, size_t elemsize, void **chunks) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void **nedpindependent_comalloc(nedpool *p, size_t elems, size_t *sizes, void **chunks) THROWSPEC;
|
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR void **nedpindependent_comalloc(nedpool *p, size_t elems, size_t *sizes, void **chunks) THROWSPEC;
|
||||||
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR char * nedstrdup(const char *str) THROWSPEC;
|
NEDMALLOCEXTSPEC NEDMALLOCPTRATTR char * nedstrdup(const char *str) THROWSPEC;
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
150
polymer/eduke32/build/include/quicklz.h
Normal file
150
polymer/eduke32/build/include/quicklz.h
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
#ifndef QLZ_HEADER
|
||||||
|
#define QLZ_HEADER
|
||||||
|
|
||||||
|
// Fast data compression library
|
||||||
|
// Copyright (C) 2006-2009 Lasse Mikkel Reinhold
|
||||||
|
// lar@quicklz.com
|
||||||
|
//
|
||||||
|
// QuickLZ can be used for free under the GPL-1 or GPL-2 license (where anything
|
||||||
|
// released into public must be open source) or under a commercial license if such
|
||||||
|
// has been acquired (see http://www.quicklz.com/order.html). The commercial license
|
||||||
|
// does not cover derived or ported versions created by third parties under GPL.
|
||||||
|
|
||||||
|
// You can edit following user settings. Data must be decompressed with the same
|
||||||
|
// setting of QLZ_COMPRESSION_LEVEL and QLZ_STREAMING_BUFFER as it was compressed
|
||||||
|
// (see manual). If QLZ_STREAMING_BUFFER > 0, scratch buffers must be initially
|
||||||
|
// zeroed out (see manual). First #ifndef makes it possible to define settings from
|
||||||
|
// the outside like the compiler command line.
|
||||||
|
|
||||||
|
// BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION
|
||||||
|
// BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION
|
||||||
|
// BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION
|
||||||
|
// BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION
|
||||||
|
// BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION
|
||||||
|
|
||||||
|
// 1.5.0 BETA 2
|
||||||
|
|
||||||
|
#ifndef QLZ_COMPRESSION_LEVEL
|
||||||
|
#define QLZ_COMPRESSION_LEVEL 1
|
||||||
|
//#define QLZ_COMPRESSION_LEVEL 2
|
||||||
|
//#define QLZ_COMPRESSION_LEVEL 3
|
||||||
|
|
||||||
|
#define QLZ_STREAMING_BUFFER 0
|
||||||
|
//#define QLZ_STREAMING_BUFFER 100000
|
||||||
|
//#define QLZ_STREAMING_BUFFER 1000000
|
||||||
|
|
||||||
|
//#define QLZ_MEMORY_SAFE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define QLZ_VERSION_MAJOR 1
|
||||||
|
#define QLZ_VERSION_MINOR 5
|
||||||
|
#define QLZ_VERSION_REVISION 0
|
||||||
|
|
||||||
|
// Using size_t, memset() and memcpy()
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Verify compression level
|
||||||
|
#if QLZ_COMPRESSION_LEVEL != 1 && QLZ_COMPRESSION_LEVEL != 2 && QLZ_COMPRESSION_LEVEL != 3
|
||||||
|
#error QLZ_COMPRESSION_LEVEL must be 1, 2 or 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned int ui32;
|
||||||
|
typedef unsigned short int ui16;
|
||||||
|
|
||||||
|
// Decrease QLZ_POINTERS for level 3 to increase compression speed. Do not touch any other values!
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1
|
||||||
|
#define QLZ_POINTERS 1
|
||||||
|
#define QLZ_HASH_VALUES 4096
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL == 2
|
||||||
|
#define QLZ_POINTERS 4
|
||||||
|
#define QLZ_HASH_VALUES 2048
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL == 3
|
||||||
|
#define QLZ_POINTERS 16
|
||||||
|
#define QLZ_HASH_VALUES 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Detect if pointer size is 64-bit. It's not fatal if some 64-bit target is not detected because this is only for adding an optional 64-bit optimization.
|
||||||
|
#if defined _LP64 || defined __LP64__ || defined __64BIT__ || _ADDR64 || defined _WIN64 || defined __arch64__ || __WORDSIZE == 64 || (defined __sparc && defined __sparcv9) || defined __x86_64 || defined __amd64 || defined __x86_64__ || defined _M_X64 || defined _M_IA64 || defined __ia64 || defined __IA64__
|
||||||
|
#define QLZ_PTR_64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// hash entry
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1
|
||||||
|
ui32 cache;
|
||||||
|
#if defined QLZ_PTR_64 && QLZ_STREAMING_BUFFER == 0
|
||||||
|
unsigned int offset;
|
||||||
|
#else
|
||||||
|
const unsigned char *offset;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
const unsigned char *offset[QLZ_POINTERS];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} qlz_hash_compress;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1
|
||||||
|
const unsigned char *offset;
|
||||||
|
#else
|
||||||
|
const unsigned char *offset[QLZ_POINTERS];
|
||||||
|
#endif
|
||||||
|
} qlz_hash_decompress;
|
||||||
|
|
||||||
|
|
||||||
|
// states
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
#if QLZ_STREAMING_BUFFER > 0
|
||||||
|
unsigned char stream_buffer[QLZ_STREAMING_BUFFER];
|
||||||
|
#endif
|
||||||
|
size_t stream_counter;
|
||||||
|
qlz_hash_compress hash[QLZ_HASH_VALUES];
|
||||||
|
unsigned char hash_counter[QLZ_HASH_VALUES];
|
||||||
|
} qlz_state_compress;
|
||||||
|
|
||||||
|
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1 || QLZ_COMPRESSION_LEVEL == 2
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
#if QLZ_STREAMING_BUFFER > 0
|
||||||
|
unsigned char stream_buffer[QLZ_STREAMING_BUFFER];
|
||||||
|
#endif
|
||||||
|
qlz_hash_decompress hash[QLZ_HASH_VALUES];
|
||||||
|
unsigned char hash_counter[QLZ_HASH_VALUES];
|
||||||
|
size_t stream_counter;
|
||||||
|
} qlz_state_decompress;
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL == 3
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
#if QLZ_STREAMING_BUFFER > 0
|
||||||
|
unsigned char stream_buffer[QLZ_STREAMING_BUFFER];
|
||||||
|
#endif
|
||||||
|
qlz_hash_decompress hash[QLZ_HASH_VALUES];
|
||||||
|
size_t stream_counter;
|
||||||
|
} qlz_state_decompress;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Public functions of QuickLZ
|
||||||
|
size_t qlz_size_decompressed(const char *source);
|
||||||
|
size_t qlz_size_compressed(const char *source);
|
||||||
|
size_t qlz_compress(const void *source, char *destination, size_t size, qlz_state_compress *state);
|
||||||
|
size_t qlz_decompress(const char *source, void *destination, qlz_state_decompress *state);
|
||||||
|
int qlz_get_setting(int setting);
|
||||||
|
|
||||||
|
extern qlz_state_compress *state_compress;
|
||||||
|
extern qlz_state_decompress *state_decompress;
|
||||||
|
|
||||||
|
#if defined (__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "scriptfile.h"
|
#include "scriptfile.h"
|
||||||
#include "cache1d.h"
|
#include "cache1d.h"
|
||||||
#include "kplib.h"
|
#include "kplib.h"
|
||||||
#include "fastlz.h"
|
#include "quicklz.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -677,7 +677,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
tilesizx[tile] = xsiz;
|
tilesizx[tile] = xsiz;
|
||||||
tilesizy[tile] = ysiz;
|
tilesizy[tile] = ysiz;
|
||||||
|
|
||||||
faketilesiz[tile] = fastlz_compress(ftd, xsiz*ysiz, faketiledata[tile]);
|
faketilesiz[tile] = qlz_compress(ftd, faketiledata[tile], xsiz*ysiz, state_compress);
|
||||||
|
|
||||||
xoffset = clamp(xoffset, -128, 127);
|
xoffset = clamp(xoffset, -128, 127);
|
||||||
picanm[tile] = (picanm[tile]&0xffff00ff)+((xoffset&255)<<8);
|
picanm[tile] = (picanm[tile]&0xffff00ff)+((xoffset&255)<<8);
|
||||||
|
@ -728,7 +728,7 @@ static int32_t defsparser(scriptfile *script)
|
||||||
{
|
{
|
||||||
tilesizx[tile] = xsiz;
|
tilesizx[tile] = xsiz;
|
||||||
tilesizy[tile] = ysiz;
|
tilesizy[tile] = ysiz;
|
||||||
faketilesiz[tile] = fastlz_compress(ftd, xsiz*ysiz, faketiledata[tile]);
|
faketilesiz[tile] = qlz_compress(ftd, faketiledata[tile], xsiz*ysiz, state_compress);
|
||||||
picanm[tile] = 0;
|
picanm[tile] = 0;
|
||||||
|
|
||||||
j = 15; while ((j > 1) && (pow2long[j] > xsiz)) j--;
|
j = 15; while ((j > 1) && (pow2long[j] > xsiz)) j--;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "a.h"
|
#include "a.h"
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
#include "fastlz.h"
|
#include "quicklz.h"
|
||||||
|
|
||||||
#include "baselayer.h"
|
#include "baselayer.h"
|
||||||
#include "scriptfile.h"
|
#include "scriptfile.h"
|
||||||
|
@ -132,6 +132,9 @@ int32_t circlewall=-1;
|
||||||
|
|
||||||
char cachedebug = 0;
|
char cachedebug = 0;
|
||||||
|
|
||||||
|
qlz_state_compress *state_compress = NULL;
|
||||||
|
qlz_state_decompress *state_decompress = NULL;
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(NOASM)
|
#if defined(_MSC_VER) && !defined(NOASM)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -5493,6 +5496,9 @@ int32_t preinitengine(void)
|
||||||
|
|
||||||
// this shite is to help get around data segment size limits on some platforms
|
// this shite is to help get around data segment size limits on some platforms
|
||||||
|
|
||||||
|
state_compress = (qlz_state_compress *)Bmalloc(sizeof(qlz_state_compress));
|
||||||
|
state_decompress = (qlz_state_decompress *)Bmalloc(sizeof(qlz_state_decompress));
|
||||||
|
|
||||||
#ifdef DYNALLOC_ARRAYS
|
#ifdef DYNALLOC_ARRAYS
|
||||||
sector = Bcalloc(MAXSECTORS,sizeof(sectortype));
|
sector = Bcalloc(MAXSECTORS,sizeof(sectortype));
|
||||||
wall = Bcalloc(MAXWALLS,sizeof(walltype));
|
wall = Bcalloc(MAXWALLS,sizeof(walltype));
|
||||||
|
@ -5657,6 +5663,9 @@ void uninitengine(void)
|
||||||
if (spritesmooth != NULL)
|
if (spritesmooth != NULL)
|
||||||
Bfree(spritesmooth);
|
Bfree(spritesmooth);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (state_compress) Bfree(state_compress);
|
||||||
|
if (state_decompress) Bfree(state_decompress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7967,7 +7976,7 @@ void loadtile(int16_t tilenume)
|
||||||
if (faketilesiz[tilenume] == -1)
|
if (faketilesiz[tilenume] == -1)
|
||||||
Bmemset((char *)waloff[tilenume],0,dasiz);
|
Bmemset((char *)waloff[tilenume],0,dasiz);
|
||||||
else if (faketiledata[tilenume] != NULL)
|
else if (faketiledata[tilenume] != NULL)
|
||||||
fastlz_decompress(faketiledata[tilenume], faketilesiz[tilenume], (char *)waloff[tilenume], dasiz);
|
qlz_decompress(faketiledata[tilenume], (char *)waloff[tilenume], state_decompress);
|
||||||
faketimerhandler();
|
faketimerhandler();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,551 +0,0 @@
|
||||||
/*
|
|
||||||
FastLZ - lightning-fast lossless compression library
|
|
||||||
|
|
||||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
|
||||||
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
|
|
||||||
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Always check for bound when decompressing.
|
|
||||||
* Generally it is best to leave it defined.
|
|
||||||
*/
|
|
||||||
#define FASTLZ_SAFE
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Give hints to the compiler for branch prediction optimization.
|
|
||||||
*/
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ > 2)
|
|
||||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
|
|
||||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
|
|
||||||
#else
|
|
||||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
|
|
||||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Use inlined functions for supported systems.
|
|
||||||
*/
|
|
||||||
#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
|
|
||||||
#define FASTLZ_INLINE inline
|
|
||||||
#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
|
|
||||||
#define FASTLZ_INLINE __inline
|
|
||||||
#else
|
|
||||||
#define FASTLZ_INLINE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prevent accessing more than 8-bit at once, except on x86 architectures.
|
|
||||||
*/
|
|
||||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
|
||||||
#define FASTLZ_STRICT_ALIGN
|
|
||||||
#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
|
|
||||||
#undef FASTLZ_STRICT_ALIGN
|
|
||||||
#elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */
|
|
||||||
#undef FASTLZ_STRICT_ALIGN
|
|
||||||
#elif defined(_M_IX86) /* Intel, MSVC */
|
|
||||||
#undef FASTLZ_STRICT_ALIGN
|
|
||||||
#elif defined(__386)
|
|
||||||
#undef FASTLZ_STRICT_ALIGN
|
|
||||||
#elif defined(_X86_) /* MinGW */
|
|
||||||
#undef FASTLZ_STRICT_ALIGN
|
|
||||||
#elif defined(__I86__) /* Digital Mars */
|
|
||||||
#undef FASTLZ_STRICT_ALIGN
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: use preprocessor magic to set this on different platforms!
|
|
||||||
*/
|
|
||||||
typedef unsigned char flzuint8;
|
|
||||||
typedef unsigned short flzuint16;
|
|
||||||
typedef unsigned int flzuint32;
|
|
||||||
|
|
||||||
/* prototypes */
|
|
||||||
int fastlz_compress(const void* input, int length, void* output);
|
|
||||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
|
||||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
|
||||||
|
|
||||||
#define MAX_COPY 32
|
|
||||||
#define MAX_LEN 264 /* 256 + 8 */
|
|
||||||
#define MAX_DISTANCE 8192
|
|
||||||
|
|
||||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
|
||||||
#define FASTLZ_READU16(p) *((const flzuint16*)(p))
|
|
||||||
#else
|
|
||||||
#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define HASH_LOG 13
|
|
||||||
#define HASH_SIZE (1<< HASH_LOG)
|
|
||||||
#define HASH_MASK (HASH_SIZE-1)
|
|
||||||
#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
|
|
||||||
|
|
||||||
#undef FASTLZ_LEVEL
|
|
||||||
#define FASTLZ_LEVEL 1
|
|
||||||
|
|
||||||
#undef FASTLZ_COMPRESSOR
|
|
||||||
#undef FASTLZ_DECOMPRESSOR
|
|
||||||
#define FASTLZ_COMPRESSOR fastlz1_compress
|
|
||||||
#define FASTLZ_DECOMPRESSOR fastlz1_decompress
|
|
||||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
|
|
||||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
|
|
||||||
#include "fastlz.c"
|
|
||||||
|
|
||||||
#undef FASTLZ_LEVEL
|
|
||||||
#define FASTLZ_LEVEL 2
|
|
||||||
|
|
||||||
#undef MAX_DISTANCE
|
|
||||||
#define MAX_DISTANCE 8191
|
|
||||||
#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
|
|
||||||
|
|
||||||
#undef FASTLZ_COMPRESSOR
|
|
||||||
#undef FASTLZ_DECOMPRESSOR
|
|
||||||
#define FASTLZ_COMPRESSOR fastlz2_compress
|
|
||||||
#define FASTLZ_DECOMPRESSOR fastlz2_decompress
|
|
||||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
|
|
||||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
|
|
||||||
#include "fastlz.c"
|
|
||||||
|
|
||||||
int fastlz_compress(const void* input, int length, void* output)
|
|
||||||
{
|
|
||||||
/* for short block, choose fastlz1 */
|
|
||||||
if(length < 65536)
|
|
||||||
return fastlz1_compress(input, length, output);
|
|
||||||
|
|
||||||
/* else... */
|
|
||||||
return fastlz2_compress(input, length, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fastlz_decompress(const void* input, int length, void* output, int maxout)
|
|
||||||
{
|
|
||||||
/* magic identifier for compression level */
|
|
||||||
int level = ((*(const flzuint8*)input) >> 5) + 1;
|
|
||||||
|
|
||||||
if(level == 1)
|
|
||||||
return fastlz1_decompress(input, length, output, maxout);
|
|
||||||
if(level == 2)
|
|
||||||
return fastlz2_decompress(input, length, output, maxout);
|
|
||||||
|
|
||||||
/* unknown level, trigger error */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fastlz_compress_level(int level, const void* input, int length, void* output)
|
|
||||||
{
|
|
||||||
if(level == 1)
|
|
||||||
return fastlz1_compress(input, length, output);
|
|
||||||
if(level == 2)
|
|
||||||
return fastlz2_compress(input, length, output);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
|
|
||||||
|
|
||||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
|
|
||||||
{
|
|
||||||
const flzuint8* ip = (const flzuint8*) input;
|
|
||||||
const flzuint8* ip_bound = ip + length - 2;
|
|
||||||
const flzuint8* ip_limit = ip + length - 12;
|
|
||||||
flzuint8* op = (flzuint8*) output;
|
|
||||||
|
|
||||||
const flzuint8* htab[HASH_SIZE];
|
|
||||||
const flzuint8** hslot;
|
|
||||||
flzuint32 hval;
|
|
||||||
|
|
||||||
flzuint32 copy;
|
|
||||||
|
|
||||||
/* sanity check */
|
|
||||||
if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
|
|
||||||
{
|
|
||||||
if(length)
|
|
||||||
{
|
|
||||||
/* create literal copy only */
|
|
||||||
*op++ = length-1;
|
|
||||||
ip_bound++;
|
|
||||||
while(ip <= ip_bound)
|
|
||||||
*op++ = *ip++;
|
|
||||||
return length+1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initializes hash table */
|
|
||||||
for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
|
|
||||||
*hslot = ip;
|
|
||||||
|
|
||||||
/* we start with literal copy */
|
|
||||||
copy = 2;
|
|
||||||
*op++ = MAX_COPY-1;
|
|
||||||
*op++ = *ip++;
|
|
||||||
*op++ = *ip++;
|
|
||||||
|
|
||||||
/* main loop */
|
|
||||||
while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
|
|
||||||
{
|
|
||||||
const flzuint8* ref;
|
|
||||||
flzuint32 distance;
|
|
||||||
|
|
||||||
/* minimum match length */
|
|
||||||
flzuint32 len = 3;
|
|
||||||
|
|
||||||
/* comparison starting-point */
|
|
||||||
const flzuint8* anchor = ip;
|
|
||||||
|
|
||||||
/* check for a run */
|
|
||||||
#if FASTLZ_LEVEL==2
|
|
||||||
if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
|
|
||||||
{
|
|
||||||
distance = 1;
|
|
||||||
ip += 3;
|
|
||||||
ref = anchor - 1 + 3;
|
|
||||||
goto match;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* find potential match */
|
|
||||||
HASH_FUNCTION(hval,ip);
|
|
||||||
hslot = htab + hval;
|
|
||||||
ref = htab[hval];
|
|
||||||
|
|
||||||
/* calculate distance to the match */
|
|
||||||
distance = anchor - ref;
|
|
||||||
|
|
||||||
/* update hash table */
|
|
||||||
*hslot = anchor;
|
|
||||||
|
|
||||||
/* is this a match? check the first 3 bytes */
|
|
||||||
if(distance==0 ||
|
|
||||||
#if FASTLZ_LEVEL==1
|
|
||||||
(distance >= MAX_DISTANCE) ||
|
|
||||||
#else
|
|
||||||
(distance >= MAX_FARDISTANCE) ||
|
|
||||||
#endif
|
|
||||||
*ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
|
|
||||||
goto literal;
|
|
||||||
|
|
||||||
#if FASTLZ_LEVEL==2
|
|
||||||
/* far, needs at least 5-byte match */
|
|
||||||
if(distance >= MAX_DISTANCE)
|
|
||||||
{
|
|
||||||
if(*ip++ != *ref++ || *ip++!= *ref++)
|
|
||||||
goto literal;
|
|
||||||
len += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
match:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* last matched byte */
|
|
||||||
ip = anchor + len;
|
|
||||||
|
|
||||||
/* distance is biased */
|
|
||||||
distance--;
|
|
||||||
|
|
||||||
if(!distance)
|
|
||||||
{
|
|
||||||
/* zero distance means a run */
|
|
||||||
flzuint8 x = ip[-1];
|
|
||||||
while(ip < ip_bound)
|
|
||||||
if(*ref++ != x) break; else ip++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
/* safe because the outer check against ip limit */
|
|
||||||
if(*ref++ != *ip++) break;
|
|
||||||
if(*ref++ != *ip++) break;
|
|
||||||
if(*ref++ != *ip++) break;
|
|
||||||
if(*ref++ != *ip++) break;
|
|
||||||
if(*ref++ != *ip++) break;
|
|
||||||
if(*ref++ != *ip++) break;
|
|
||||||
if(*ref++ != *ip++) break;
|
|
||||||
if(*ref++ != *ip++) break;
|
|
||||||
while(ip < ip_bound)
|
|
||||||
if(*ref++ != *ip++) break;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we have copied something, adjust the copy count */
|
|
||||||
if(copy)
|
|
||||||
/* copy is biased, '0' means 1 byte copy */
|
|
||||||
*(op-copy-1) = copy-1;
|
|
||||||
else
|
|
||||||
/* back, to overwrite the copy count */
|
|
||||||
op--;
|
|
||||||
|
|
||||||
/* reset literal counter */
|
|
||||||
copy = 0;
|
|
||||||
|
|
||||||
/* length is biased, '1' means a match of 3 bytes */
|
|
||||||
ip -= 3;
|
|
||||||
len = ip - anchor;
|
|
||||||
|
|
||||||
/* encode the match */
|
|
||||||
#if FASTLZ_LEVEL==2
|
|
||||||
if(distance < MAX_DISTANCE)
|
|
||||||
{
|
|
||||||
if(len < 7)
|
|
||||||
{
|
|
||||||
*op++ = (len << 5) + (distance >> 8);
|
|
||||||
*op++ = (distance & 255);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*op++ = (7 << 5) + (distance >> 8);
|
|
||||||
for(len-=7; len >= 255; len-= 255)
|
|
||||||
*op++ = 255;
|
|
||||||
*op++ = len;
|
|
||||||
*op++ = (distance & 255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* far away, but not yet in the another galaxy... */
|
|
||||||
if(len < 7)
|
|
||||||
{
|
|
||||||
distance -= MAX_DISTANCE;
|
|
||||||
*op++ = (len << 5) + 31;
|
|
||||||
*op++ = 255;
|
|
||||||
*op++ = distance >> 8;
|
|
||||||
*op++ = distance & 255;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
distance -= MAX_DISTANCE;
|
|
||||||
*op++ = (7 << 5) + 31;
|
|
||||||
for(len-=7; len >= 255; len-= 255)
|
|
||||||
*op++ = 255;
|
|
||||||
*op++ = len;
|
|
||||||
*op++ = 255;
|
|
||||||
*op++ = distance >> 8;
|
|
||||||
*op++ = distance & 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
|
|
||||||
while(len > MAX_LEN-2)
|
|
||||||
{
|
|
||||||
*op++ = (7 << 5) + (distance >> 8);
|
|
||||||
*op++ = MAX_LEN - 2 - 7 -2;
|
|
||||||
*op++ = (distance & 255);
|
|
||||||
len -= MAX_LEN-2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(len < 7)
|
|
||||||
{
|
|
||||||
*op++ = (len << 5) + (distance >> 8);
|
|
||||||
*op++ = (distance & 255);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*op++ = (7 << 5) + (distance >> 8);
|
|
||||||
*op++ = len - 7;
|
|
||||||
*op++ = (distance & 255);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* update the hash at match boundary */
|
|
||||||
HASH_FUNCTION(hval,ip);
|
|
||||||
htab[hval] = ip++;
|
|
||||||
HASH_FUNCTION(hval,ip);
|
|
||||||
htab[hval] = ip++;
|
|
||||||
|
|
||||||
/* assuming literal copy */
|
|
||||||
*op++ = MAX_COPY-1;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
|
|
||||||
literal:
|
|
||||||
*op++ = *anchor++;
|
|
||||||
ip = anchor;
|
|
||||||
copy++;
|
|
||||||
if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
|
|
||||||
{
|
|
||||||
copy = 0;
|
|
||||||
*op++ = MAX_COPY-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* left-over as literal copy */
|
|
||||||
ip_bound++;
|
|
||||||
while(ip <= ip_bound)
|
|
||||||
{
|
|
||||||
*op++ = *ip++;
|
|
||||||
copy++;
|
|
||||||
if(copy == MAX_COPY)
|
|
||||||
{
|
|
||||||
copy = 0;
|
|
||||||
*op++ = MAX_COPY-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we have copied something, adjust the copy length */
|
|
||||||
if(copy)
|
|
||||||
*(op-copy-1) = copy-1;
|
|
||||||
else
|
|
||||||
op--;
|
|
||||||
|
|
||||||
#if FASTLZ_LEVEL==2
|
|
||||||
/* marker for fastlz2 */
|
|
||||||
*(flzuint8*)output |= (1 << 5);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return op - (flzuint8*)output;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
|
|
||||||
{
|
|
||||||
const flzuint8* ip = (const flzuint8*) input;
|
|
||||||
const flzuint8* ip_limit = ip + length;
|
|
||||||
flzuint8* op = (flzuint8*) output;
|
|
||||||
flzuint8* op_limit = op + maxout;
|
|
||||||
flzuint32 ctrl = (*ip++) & 31;
|
|
||||||
int loop = 1;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
const flzuint8* ref = op;
|
|
||||||
flzuint32 len = ctrl >> 5;
|
|
||||||
flzuint32 ofs = (ctrl & 31) << 8;
|
|
||||||
|
|
||||||
if(ctrl >= 32)
|
|
||||||
{
|
|
||||||
#if FASTLZ_LEVEL==2
|
|
||||||
flzuint8 code;
|
|
||||||
#endif
|
|
||||||
len--;
|
|
||||||
ref -= ofs;
|
|
||||||
if (len == 7-1)
|
|
||||||
#if FASTLZ_LEVEL==1
|
|
||||||
len += *ip++;
|
|
||||||
ref -= *ip++;
|
|
||||||
#else
|
|
||||||
do
|
|
||||||
{
|
|
||||||
code = *ip++;
|
|
||||||
len += code;
|
|
||||||
} while (code==255);
|
|
||||||
code = *ip++;
|
|
||||||
ref -= code;
|
|
||||||
|
|
||||||
/* match from 16-bit distance */
|
|
||||||
if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
|
|
||||||
if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
|
|
||||||
{
|
|
||||||
ofs = (*ip++) << 8;
|
|
||||||
ofs += *ip++;
|
|
||||||
ref = op - ofs - MAX_DISTANCE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef FASTLZ_SAFE
|
|
||||||
if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
|
|
||||||
ctrl = *ip++;
|
|
||||||
else
|
|
||||||
loop = 0;
|
|
||||||
|
|
||||||
if(ref == op)
|
|
||||||
{
|
|
||||||
/* optimize copy for a run */
|
|
||||||
flzuint8 b = ref[-1];
|
|
||||||
*op++ = b;
|
|
||||||
*op++ = b;
|
|
||||||
*op++ = b;
|
|
||||||
for(; len; --len)
|
|
||||||
*op++ = b;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
|
||||||
const flzuint16* p;
|
|
||||||
flzuint16* q;
|
|
||||||
#endif
|
|
||||||
/* copy from reference */
|
|
||||||
ref--;
|
|
||||||
*op++ = *ref++;
|
|
||||||
*op++ = *ref++;
|
|
||||||
*op++ = *ref++;
|
|
||||||
|
|
||||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
|
||||||
/* copy a byte, so that now it's word aligned */
|
|
||||||
if(len & 1)
|
|
||||||
{
|
|
||||||
*op++ = *ref++;
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy 16-bit at once */
|
|
||||||
q = (flzuint16*) op;
|
|
||||||
op += len;
|
|
||||||
p = (const flzuint16*) ref;
|
|
||||||
for(len>>=1; len > 4; len-=4)
|
|
||||||
{
|
|
||||||
*q++ = *p++;
|
|
||||||
*q++ = *p++;
|
|
||||||
*q++ = *p++;
|
|
||||||
*q++ = *p++;
|
|
||||||
}
|
|
||||||
for(; len; --len)
|
|
||||||
*q++ = *p++;
|
|
||||||
#else
|
|
||||||
for(; len; --len)
|
|
||||||
*op++ = *ref++;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ctrl++;
|
|
||||||
#ifdef FASTLZ_SAFE
|
|
||||||
if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
|
|
||||||
return 0;
|
|
||||||
if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*op++ = *ip++;
|
|
||||||
for(--ctrl; ctrl; ctrl--)
|
|
||||||
*op++ = *ip++;
|
|
||||||
|
|
||||||
loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
|
|
||||||
if(loop)
|
|
||||||
ctrl = *ip++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(FASTLZ_EXPECT_CONDITIONAL(loop));
|
|
||||||
|
|
||||||
return op - (flzuint8*)output;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
|
|
|
@ -22,26 +22,23 @@ char hicfirstinit = 0;
|
||||||
//
|
//
|
||||||
hicreplctyp * hicfindsubst(int32_t picnum, int32_t palnum, int32_t skybox)
|
hicreplctyp * hicfindsubst(int32_t picnum, int32_t palnum, int32_t skybox)
|
||||||
{
|
{
|
||||||
hicreplctyp *hr;
|
if (!hicfirstinit || (uint32_t)picnum >= (uint32_t)MAXTILES) return NULL;
|
||||||
|
|
||||||
if (!hicfirstinit) return NULL;
|
|
||||||
if ((uint32_t)picnum >= (uint32_t)MAXTILES) return NULL;
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
for (hr = hicreplc[picnum]; hr; hr = hr->next)
|
if (skybox)
|
||||||
{
|
{
|
||||||
if (hr->palnum == palnum)
|
hicreplctyp *hr = hicreplc[picnum];
|
||||||
{
|
for (; hr; hr = hr->next)
|
||||||
if (skybox)
|
if (hr->palnum == palnum && hr->skybox && !hr->skybox->ignore)
|
||||||
{
|
return hr;
|
||||||
if (hr->skybox && !hr->skybox->ignore) return hr;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
hicreplctyp *hr = hicreplc[picnum];
|
||||||
if (!hr->ignore) return hr;
|
for (; hr; hr = hr->next)
|
||||||
}
|
if (hr->palnum == palnum && !hr->ignore)
|
||||||
}
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!palnum || palnum >= (MAXPALOOKUPS - RESERVEDPALS)) break;
|
if (!palnum || palnum >= (MAXPALOOKUPS - RESERVEDPALS)) break;
|
||||||
|
|
|
@ -35,20 +35,25 @@ DEALINGS IN THE SOFTWARE.
|
||||||
#pragma warning(disable:4706) /* assignment within conditional expression */
|
#pragma warning(disable:4706) /* assignment within conditional expression */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*#define FULLSANITYCHECKS*/
|
|
||||||
#define USE_ALLOCATOR 1
|
#define USE_ALLOCATOR 1
|
||||||
// #define REPLACE_SYSTEM_ALLOCATOR
|
#define USE_MAGIC_HEADERS 1
|
||||||
#define USE_MAGIC_HEADERS 0
|
|
||||||
#define MAXTHREADSINPOOL 1
|
#define MAXTHREADSINPOOL 1
|
||||||
#define FINEGRAINEDBINS 1
|
#define FINEGRAINEDBINS 1
|
||||||
#define ENABLE_LARGE_PAGES
|
#define ENABLE_LARGE_PAGES 1
|
||||||
|
#define ENABLE_FAST_HEAP_DETECTION 1
|
||||||
|
|
||||||
#ifndef UNREFERENCED_PARAMETER
|
/*#define ENABLE_TOLERANT_NEDMALLOC 1*/
|
||||||
#define UNREFERENCED_PARAMETER(x) x=x
|
/*#define ENABLE_FAST_HEAP_DETECTION 1*/
|
||||||
|
|
||||||
|
/*#define FULLSANITYCHECKS*/
|
||||||
|
/* If link time code generation is on, don't force or prevent inlining */
|
||||||
|
#if defined(_MSC_VER) && defined(NEDMALLOC_DLL_EXPORTS)
|
||||||
|
#define FORCEINLINE
|
||||||
|
#define NOINLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "nedmalloc.h"
|
#include "nedmalloc.h"
|
||||||
#ifdef _WIN32
|
#ifdef WIN32
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,7 +90,6 @@ DEALINGS IN THE SOFTWARE.
|
||||||
/*#define USE_SPIN_LOCKS 0*/
|
/*#define USE_SPIN_LOCKS 0*/
|
||||||
|
|
||||||
|
|
||||||
/*#define FORCEINLINE*/
|
|
||||||
#include "malloc.c.h"
|
#include "malloc.c.h"
|
||||||
#ifdef NDEBUG /* Disable assert checking on release builds */
|
#ifdef NDEBUG /* Disable assert checking on release builds */
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
@ -118,7 +122,8 @@ DEALINGS IN THE SOFTWARE.
|
||||||
#define THREADCACHEMAXFREESPACE (512*1024*4)
|
#define THREADCACHEMAXFREESPACE (512*1024*4)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
#ifdef WIN32
|
||||||
#define TLSVAR DWORD
|
#define TLSVAR DWORD
|
||||||
#define TLSALLOC(k) (*(k)=TlsAlloc(), TLS_OUT_OF_INDEXES==*(k))
|
#define TLSALLOC(k) (*(k)=TlsAlloc(), TLS_OUT_OF_INDEXES==*(k))
|
||||||
#define TLSFREE(k) (!TlsFree(k))
|
#define TLSFREE(k) (!TlsFree(k))
|
||||||
|
@ -159,11 +164,14 @@ static void *unsupported_operation(const char *opname) THROWSPEC
|
||||||
}
|
}
|
||||||
static size_t mspacecounter=(size_t) 0xdeadbeef;
|
static size_t mspacecounter=(size_t) 0xdeadbeef;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef ENABLE_FAST_HEAP_DETECTION
|
||||||
|
static void *RESTRICT leastusedaddress;
|
||||||
|
static size_t largestusedblock;
|
||||||
|
#endif
|
||||||
|
|
||||||
static FORCEINLINE void *CallMalloc(void *mspace, size_t size, size_t alignment) THROWSPEC
|
static FORCEINLINE void *CallMalloc(void *RESTRICT mspace, size_t size, size_t alignment) THROWSPEC
|
||||||
{
|
{
|
||||||
void *ret=0;
|
void *RESTRICT ret=0;
|
||||||
UNREFERENCED_PARAMETER(alignment);
|
|
||||||
#if USE_MAGIC_HEADERS
|
#if USE_MAGIC_HEADERS
|
||||||
size_t *_ret=0;
|
size_t *_ret=0;
|
||||||
size+=alignment+3*sizeof(size_t);
|
size+=alignment+3*sizeof(size_t);
|
||||||
|
@ -172,6 +180,14 @@ static FORCEINLINE void *CallMalloc(void *mspace, size_t size, size_t alignment)
|
||||||
ret=malloc(size);
|
ret=malloc(size);
|
||||||
#elif USE_ALLOCATOR==1
|
#elif USE_ALLOCATOR==1
|
||||||
ret=mspace_malloc((mstate) mspace, size);
|
ret=mspace_malloc((mstate) mspace, size);
|
||||||
|
#ifndef ENABLE_FAST_HEAP_DETECTION
|
||||||
|
if(ret)
|
||||||
|
{
|
||||||
|
size_t truesize=chunksize(mem2chunk(ret));
|
||||||
|
if(!leastusedaddress || (void *)((mstate) mspace)->least_addr<leastusedaddress) leastusedaddress=(void *)((mstate) mspace)->least_addr;
|
||||||
|
if(!largestusedblock || truesize>largestusedblock) largestusedblock=(truesize+mparams.page_size) & ~(mparams.page_size-1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
if(!ret) return 0;
|
if(!ret) return 0;
|
||||||
#if USE_MAGIC_HEADERS
|
#if USE_MAGIC_HEADERS
|
||||||
|
@ -180,23 +196,30 @@ static FORCEINLINE void *CallMalloc(void *mspace, size_t size, size_t alignment)
|
||||||
if(alignment) ret=(void *)(((size_t) ret+alignment-1)&~(alignment-1));
|
if(alignment) ret=(void *)(((size_t) ret+alignment-1)&~(alignment-1));
|
||||||
for(; _ret<(size_t *)ret-2; _ret++) *_ret=*(size_t *)"NEDMALOC";
|
for(; _ret<(size_t *)ret-2; _ret++) *_ret=*(size_t *)"NEDMALOC";
|
||||||
_ret[0]=(size_t) mspace;
|
_ret[0]=(size_t) mspace;
|
||||||
_ret[1]=size;
|
_ret[1]=size-3*sizeof(size_t);
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCEINLINE void *CallCalloc(void *mspace, size_t no, size_t size, size_t alignment) THROWSPEC
|
static FORCEINLINE void *CallCalloc(void *RESTRICT mspace, size_t size, size_t alignment) THROWSPEC
|
||||||
{
|
{
|
||||||
void *ret=0;
|
void *RESTRICT ret=0;
|
||||||
UNREFERENCED_PARAMETER(alignment);
|
|
||||||
#if USE_MAGIC_HEADERS
|
#if USE_MAGIC_HEADERS
|
||||||
size_t *_ret=0;
|
size_t *_ret=0;
|
||||||
size+=alignment+3*sizeof(size_t);
|
size+=alignment+3*sizeof(size_t);
|
||||||
#endif
|
#endif
|
||||||
#if USE_ALLOCATOR==0
|
#if USE_ALLOCATOR==0
|
||||||
ret=calloc(no, size);
|
ret=calloc(1, size);
|
||||||
#elif USE_ALLOCATOR==1
|
#elif USE_ALLOCATOR==1
|
||||||
ret=mspace_calloc((mstate) mspace, no, size);
|
ret=mspace_calloc((mstate) mspace, 1, size);
|
||||||
|
#ifndef ENABLE_FAST_HEAP_DETECTION
|
||||||
|
if(ret)
|
||||||
|
{
|
||||||
|
size_t truesize=chunksize(mem2chunk(ret));
|
||||||
|
if(!leastusedaddress || (void *)((mstate) mspace)->least_addr<leastusedaddress) leastusedaddress=(void *)((mstate) mspace)->least_addr;
|
||||||
|
if(!largestusedblock || truesize>largestusedblock) largestusedblock=(truesize+mparams.page_size) & ~(mparams.page_size-1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
if(!ret) return 0;
|
if(!ret) return 0;
|
||||||
#if USE_MAGIC_HEADERS
|
#if USE_MAGIC_HEADERS
|
||||||
|
@ -205,39 +228,52 @@ static FORCEINLINE void *CallCalloc(void *mspace, size_t no, size_t size, size_t
|
||||||
if(alignment) ret=(void *)(((size_t) ret+alignment-1)&~(alignment-1));
|
if(alignment) ret=(void *)(((size_t) ret+alignment-1)&~(alignment-1));
|
||||||
for(; _ret<(size_t *)ret-2; _ret++) *_ret=*(size_t *) "NEDMALOC";
|
for(; _ret<(size_t *)ret-2; _ret++) *_ret=*(size_t *) "NEDMALOC";
|
||||||
_ret[0]=(size_t) mspace;
|
_ret[0]=(size_t) mspace;
|
||||||
_ret[1]=size;
|
_ret[1]=size-3*sizeof(size_t);
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCEINLINE void *CallRealloc(void *mspace, void *mem, size_t size) THROWSPEC
|
static FORCEINLINE void *CallRealloc(void *RESTRICT mspace, void *RESTRICT mem, int isforeign, size_t oldsize, size_t newsize) THROWSPEC
|
||||||
{
|
{
|
||||||
void *ret=0;
|
void *RESTRICT ret=0;
|
||||||
#if USE_MAGIC_HEADERS
|
#if USE_MAGIC_HEADERS
|
||||||
mstate oldmspace=0;
|
mstate oldmspace=0;
|
||||||
size_t *_ret=0, *_mem=(size_t *) mem-3, oldsize=0;
|
size_t *_ret=0, *_mem=(size_t *) mem-3;
|
||||||
if(_mem[0]!=*(size_t *) "NEDMALOC")
|
#endif
|
||||||
|
if(isforeign)
|
||||||
{ /* Transfer */
|
{ /* Transfer */
|
||||||
if((ret=CallMalloc(mspace, size, 0)))
|
#if USE_MAGIC_HEADERS
|
||||||
{ /* It's probably safe to copy size bytes from mem - can't do much different */
|
assert(_mem[0]!=*(size_t *) "NEDMALOC");
|
||||||
|
#endif
|
||||||
|
if((ret=CallMalloc(mspace, newsize, 0)))
|
||||||
|
{
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("*** nedmalloc frees system allocated block %p\n", mem);
|
printf("*** nedmalloc frees system allocated block %p\n", mem);
|
||||||
#endif
|
#endif
|
||||||
memcpy(ret, mem, size);
|
memcpy(ret, mem, oldsize<newsize ? oldsize : newsize);
|
||||||
free(mem);
|
free(mem);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
size+=3*sizeof(size_t);
|
#if USE_MAGIC_HEADERS
|
||||||
|
assert(_mem[0]==*(size_t *) "NEDMALOC");
|
||||||
|
newsize+=3*sizeof(size_t);
|
||||||
oldmspace=(mstate) _mem[1];
|
oldmspace=(mstate) _mem[1];
|
||||||
oldsize=_mem[2];
|
assert(oldsize>=_mem[2]);
|
||||||
for(; *_mem==*(size_t *) "NEDMALOC"; *_mem--=0);
|
for(; *_mem==*(size_t *) "NEDMALOC"; *_mem--=*(size_t *) "nedmaloc");
|
||||||
mem=(void *)(++_mem);
|
mem=(void *)(++_mem);
|
||||||
#endif
|
#endif
|
||||||
#if USE_ALLOCATOR==0
|
#if USE_ALLOCATOR==0
|
||||||
ret=realloc(mem, size);
|
ret=realloc(mem, newsize);
|
||||||
#elif USE_ALLOCATOR==1
|
#elif USE_ALLOCATOR==1
|
||||||
ret=mspace_realloc((mstate) mspace, mem, size);
|
ret=mspace_realloc((mstate) mspace, mem, newsize);
|
||||||
|
#ifndef ENABLE_FAST_HEAP_DETECTION
|
||||||
|
if(ret)
|
||||||
|
{
|
||||||
|
size_t truesize=chunksize(mem2chunk(ret));
|
||||||
|
if(!largestusedblock || truesize>largestusedblock) largestusedblock=(truesize+mparams.page_size) & ~(mparams.page_size-1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
if(!ret)
|
if(!ret)
|
||||||
{ /* Put it back the way it was */
|
{ /* Put it back the way it was */
|
||||||
|
@ -251,27 +287,33 @@ static FORCEINLINE void *CallRealloc(void *mspace, void *mem, size_t size) THROW
|
||||||
ret=(void *)(_ret+3);
|
ret=(void *)(_ret+3);
|
||||||
for(; _ret<(size_t *)ret-2; _ret++) *_ret=*(size_t *) "NEDMALOC";
|
for(; _ret<(size_t *)ret-2; _ret++) *_ret=*(size_t *) "NEDMALOC";
|
||||||
_ret[0]=(size_t) mspace;
|
_ret[0]=(size_t) mspace;
|
||||||
_ret[1]=size;
|
_ret[1]=newsize-3*sizeof(size_t);
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCEINLINE void CallFree(void *mspace, void *mem) THROWSPEC
|
static FORCEINLINE void CallFree(void *RESTRICT mspace, void *RESTRICT mem, int isforeign) THROWSPEC
|
||||||
{
|
{
|
||||||
#if USE_MAGIC_HEADERS
|
#if USE_MAGIC_HEADERS
|
||||||
mstate oldmspace=0;
|
mstate oldmspace=0;
|
||||||
size_t *_mem=(size_t *) mem-3, oldsize=0;
|
size_t *_mem=(size_t *) mem-3, oldsize=0;
|
||||||
if(_mem[0]!=*(size_t *) "NEDMALOC")
|
#endif
|
||||||
|
if(isforeign)
|
||||||
{
|
{
|
||||||
|
#if USE_MAGIC_HEADERS
|
||||||
|
assert(_mem[0]!=*(size_t *) "NEDMALOC");
|
||||||
|
#endif
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("*** nedmalloc frees system allocated block %p\n", mem);
|
printf("*** nedmalloc frees system allocated block %p\n", mem);
|
||||||
#endif
|
#endif
|
||||||
free(mem);
|
free(mem);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#if USE_MAGIC_HEADERS
|
||||||
|
assert(_mem[0]==*(size_t *) "NEDMALOC");
|
||||||
oldmspace=(mstate) _mem[1];
|
oldmspace=(mstate) _mem[1];
|
||||||
oldsize=_mem[2];
|
oldsize=_mem[2];
|
||||||
for(; *_mem==*(size_t *) "NEDMALOC"; *_mem--=0);
|
for(; *_mem==*(size_t *) "NEDMALOC"; *_mem--=*(size_t *) "nedmaloc");
|
||||||
mem=(void *)(++_mem);
|
mem=(void *)(++_mem);
|
||||||
#endif
|
#endif
|
||||||
#if USE_ALLOCATOR==0
|
#if USE_ALLOCATOR==0
|
||||||
|
@ -281,7 +323,7 @@ static FORCEINLINE void CallFree(void *mspace, void *mem) THROWSPEC
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nedblksize(void *mem) THROWSPEC
|
static NEDMALLOCNOALIASATTR mstate nedblkmstate(void *RESTRICT mem) THROWSPEC
|
||||||
{
|
{
|
||||||
if(mem)
|
if(mem)
|
||||||
{
|
{
|
||||||
|
@ -289,9 +331,7 @@ size_t nedblksize(void *mem) THROWSPEC
|
||||||
size_t *_mem=(size_t *) mem-3;
|
size_t *_mem=(size_t *) mem-3;
|
||||||
if(_mem[0]==*(size_t *) "NEDMALOC")
|
if(_mem[0]==*(size_t *) "NEDMALOC")
|
||||||
{
|
{
|
||||||
// mstate mspace=(mstate) _mem[1];
|
return (mstate) _mem[1];
|
||||||
size_t size=_mem[2];
|
|
||||||
return size-3*sizeof(size_t);
|
|
||||||
}
|
}
|
||||||
else return 0;
|
else return 0;
|
||||||
#else
|
#else
|
||||||
|
@ -299,6 +339,58 @@ size_t nedblksize(void *mem) THROWSPEC
|
||||||
/* Fail everything */
|
/* Fail everything */
|
||||||
return 0;
|
return 0;
|
||||||
#elif USE_ALLOCATOR==1
|
#elif USE_ALLOCATOR==1
|
||||||
|
#ifdef ENABLE_FAST_HEAP_DETECTION
|
||||||
|
#ifdef WIN32
|
||||||
|
/* On Windows for RELEASE both x86 and x64 the NT heap precedes each block with an eight byte header
|
||||||
|
which looks like:
|
||||||
|
normal: 4 bytes of size, 4 bytes of [char < 64, char < 64, char < 64 bit 0 always set, char random ]
|
||||||
|
mmaped: 4 bytes of size 4 bytes of [zero, zero, 0xb, zero ]
|
||||||
|
|
||||||
|
On Windows for DEBUG both x86 and x64 the preceding four bytes is always 0xfdfdfdfd (no man's land).
|
||||||
|
*/
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct _HEAP_ENTRY
|
||||||
|
{
|
||||||
|
USHORT Size;
|
||||||
|
USHORT PreviousSize;
|
||||||
|
UCHAR Cookie; /* SegmentIndex */
|
||||||
|
UCHAR Flags; /* always bit 0 (HEAP_ENTRY_BUSY). bit 1=(HEAP_ENTRY_EXTRA_PRESENT), bit 2=normal block (HEAP_ENTRY_FILL_PATTERN), bit 3=mmap block (HEAP_ENTRY_VIRTUAL_ALLOC). Bit 4 (HEAP_ENTRY_LAST_ENTRY) could be set */
|
||||||
|
UCHAR UnusedBytes;
|
||||||
|
UCHAR SmallTagIndex; /* fastbin index. Always one of 0x02, 0x03, 0x04 < 0x80 */
|
||||||
|
} *RESTRICT he=((struct _HEAP_ENTRY *) mem)-1;
|
||||||
|
#pragma pack(pop)
|
||||||
|
unsigned int header=((unsigned int *)mem)[-1], mask1=0x8080E100, result1, mask2=0xFFFFFF06, result2;
|
||||||
|
result1=header & mask1; /* Positive testing for NT heap */
|
||||||
|
result2=header & mask2; /* Positive testing for dlmalloc */
|
||||||
|
if(result1==0x00000100 && result2!=0x00000102)
|
||||||
|
{ /* This is likely a NT heap block */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __linux__
|
||||||
|
/* On Linux glibc uses ptmalloc2 (really dlmalloc) just as we do, but prev_foot contains rubbish
|
||||||
|
when the preceding block is allocated because ptmalloc2 finds the local mstate by rounding the ptr
|
||||||
|
down to the nearest megabyte. It's like dlmalloc with FOOTERS disabled. */
|
||||||
|
mchunkptr p=mem2chunk(mem);
|
||||||
|
mstate fm=get_mstate_for(p);
|
||||||
|
/* If it's a ptmalloc2 block, fm is likely to be some crazy value */
|
||||||
|
if(!is_aligned(fm)) return 0;
|
||||||
|
if((size_t)mem-(size_t)fm>=(size_t)1<<(SIZE_T_BITSIZE-1)) return 0;
|
||||||
|
if(ok_magic(fm))
|
||||||
|
return fm;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
if(1) { }
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mchunkptr p=mem2chunk(mem);
|
||||||
|
mstate fm=get_mstate_for(p);
|
||||||
|
assert(ok_magic(fm)); /* If this fails, someone tried to free a block twice */
|
||||||
|
if(ok_magic(fm))
|
||||||
|
return fm;
|
||||||
|
}
|
||||||
|
#else
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__try
|
__try
|
||||||
#endif
|
#endif
|
||||||
|
@ -309,44 +401,109 @@ size_t nedblksize(void *mem) THROWSPEC
|
||||||
|
|
||||||
mchunkptr->prev_foot = mem-(2*size_t) = mstate ^ mparams.magic for PRECEDING block;
|
mchunkptr->prev_foot = mem-(2*size_t) = mstate ^ mparams.magic for PRECEDING block;
|
||||||
mchunkptr->head = mem-(1*size_t) = 8 multiple size of this block with bottom three bits = FLAG_BITS
|
mchunkptr->head = mem-(1*size_t) = 8 multiple size of this block with bottom three bits = FLAG_BITS
|
||||||
|
FLAG_BITS = bit 0 is CINUSE (currently in use unless is mmap), bit 1 is PINUSE (previous block currently
|
||||||
|
in use unless mmap), bit 2 is UNUSED and currently is always zero.
|
||||||
*/
|
*/
|
||||||
mchunkptr p=mem2chunk(mem);
|
register void *RESTRICT leastusedaddress_=leastusedaddress; /* Cache these to avoid register reloading */
|
||||||
mstate fm=0;
|
register size_t largestusedblock_=largestusedblock;
|
||||||
if(!is_inuse(p)) return 0;
|
if(!is_aligned(mem)) return 0; /* Would fail very rarely as all allocators return aligned blocks */
|
||||||
/* The following isn't safe but is probably true: unlikely to allocate
|
if(mem<leastusedaddress_) return 0; /* Simple but effective */
|
||||||
a 2Gb block on a 32bit system or a 8Eb block on a 64 bit system */
|
{
|
||||||
if(p->head & ((size_t)1)<<(SIZE_T_BITSIZE-SIZE_T_ONE)) return 0;
|
mchunkptr p=mem2chunk(mem);
|
||||||
/* We have now reduced our chances of being wrong to 0.5^4 = 6.25%.
|
mstate fm=0;
|
||||||
We could start comparing prev_foot's for similarity but it starts getting slow. */
|
int ismmapped=is_mmapped(p);
|
||||||
fm = get_mstate_for(p);
|
if((!ismmapped && !is_inuse(p)) || (p->head & FLAG4_BIT)) return 0;
|
||||||
assert(ok_magic(fm)); /* If this fails, someone tried to free a block twice */
|
/* Reduced uncertainty by 0.5^2 = 25.0% */
|
||||||
if(ok_magic(fm))
|
/* size should never exceed largestusedblock */
|
||||||
return chunksize(p)-overhead_for(p);
|
if(chunksize(p)>largestusedblock_) return 0;
|
||||||
|
/* Reduced uncertainty by a minimum of 0.5^3 = 12.5%, maximum 0.5^16 = 0.0015% */
|
||||||
|
/* Having sanity checked prev_foot and head, check next block */
|
||||||
|
if(!ismmapped && (!next_pinuse(p) || (next_chunk(p)->head & FLAG4_BIT))) return 0;
|
||||||
|
/* Reduced uncertainty by 0.5^5 = 3.13% or 0.5^18 = 0.00038% */
|
||||||
|
#if 0
|
||||||
|
/* If previous block is free, check that its next block pointer equals us */
|
||||||
|
if(!ismmapped && !pinuse(p))
|
||||||
|
if(next_chunk(prev_chunk(p))!=p) return 0;
|
||||||
|
/* We could start comparing prev_foot's for similarity but it starts getting slow. */
|
||||||
|
#endif
|
||||||
|
fm = get_mstate_for(p);
|
||||||
|
if(!is_aligned(fm) || (void *)fm<leastusedaddress_) return 0;
|
||||||
|
if((size_t)mem-(size_t)fm>=(size_t)1<<(SIZE_T_BITSIZE-1)) return 0;
|
||||||
|
assert(ok_magic(fm)); /* If this fails, someone tried to free a block twice */
|
||||||
|
if(ok_magic(fm))
|
||||||
|
return fm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__except(1) { }
|
__except(1) { }
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
NEDMALLOCNOALIASATTR size_t nedblksize(int *RESTRICT isforeign, void *RESTRICT mem) THROWSPEC
|
||||||
|
{
|
||||||
|
if(mem)
|
||||||
|
{
|
||||||
|
if(isforeign) *isforeign=1;
|
||||||
|
#if USE_MAGIC_HEADERS
|
||||||
|
{
|
||||||
|
size_t *_mem=(size_t *) mem-3;
|
||||||
|
if(_mem[0]==*(size_t *) "NEDMALOC")
|
||||||
|
{
|
||||||
|
mstate mspace=(mstate) _mem[1];
|
||||||
|
size_t size=_mem[2];
|
||||||
|
if(isforeign) *isforeign=0;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif USE_ALLOCATOR==1
|
||||||
|
if(nedblkmstate(mem))
|
||||||
|
{
|
||||||
|
mchunkptr p=mem2chunk(mem);
|
||||||
|
if(isforeign) *isforeign=0;
|
||||||
|
return chunksize(p)-overhead_for(p);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int a=1; /* Set breakpoints here if needed */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_TOLERANT_NEDMALLOC) || USE_ALLOCATOR==0
|
||||||
|
#ifdef WIN32
|
||||||
|
/* This is the MSVCRT equivalent */
|
||||||
|
return _msize(mem);
|
||||||
|
#elif defined(__linux__)
|
||||||
|
/* This is the glibc/ptmalloc2/dlmalloc equivalent. */
|
||||||
|
return malloc_usable_size(mem);
|
||||||
|
#elif defined(__FreeBSD__) || defined(__APPLE__)
|
||||||
|
/* This is the BSD libc equivalent. */
|
||||||
|
return malloc_size(mem);
|
||||||
|
#else
|
||||||
|
#error Cannot tolerate the memory allocator of an unknown system!
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nedsetvalue(void *v) THROWSPEC { nedpsetvalue((nedpool *) 0, v); }
|
void nedsetvalue(void *v) THROWSPEC { nedpsetvalue((nedpool *) 0, v); }
|
||||||
NEDMALLOCPTRATTR void * nedmalloc(size_t size) THROWSPEC { return nedpmalloc((nedpool *) 0, size); }
|
NEDMALLOCPTRATTR void * nedmalloc(size_t size) THROWSPEC { return nedpmalloc((nedpool *) 0, size); }
|
||||||
NEDMALLOCPTRATTR void * nedcalloc(size_t no, size_t size) THROWSPEC { return nedpcalloc((nedpool *) 0, no, size); }
|
NEDMALLOCPTRATTR void * nedcalloc(size_t no, size_t size) THROWSPEC { return nedpcalloc((nedpool *) 0, no, size); }
|
||||||
NEDMALLOCPTRATTR void * nedrealloc(void *mem, size_t size) THROWSPEC { return nedprealloc((nedpool *) 0, mem, size); }
|
NEDMALLOCPTRATTR void * nedrealloc(void *mem, size_t size) THROWSPEC { return nedprealloc((nedpool *) 0, mem, size); }
|
||||||
void nedfree(void *mem) THROWSPEC { nedpfree((nedpool *) 0, mem); }
|
void nedfree(void *mem) THROWSPEC { nedpfree((nedpool *) 0, mem); }
|
||||||
NEDMALLOCPTRATTR void * nedmemalign(size_t alignment, size_t bytes) THROWSPEC { return nedpmemalign((nedpool *) 0, alignment, bytes); }
|
NEDMALLOCPTRATTR void * nedmemalign(size_t alignment, size_t bytes) THROWSPEC { return nedpmemalign((nedpool *) 0, alignment, bytes); }
|
||||||
#if !NO_MALLINFO
|
struct nedmallinfo nedmallinfo(void) THROWSPEC { return nedpmallinfo((nedpool *) 0); }
|
||||||
struct mallinfo nedmallinfo(void) THROWSPEC { return nedpmallinfo((nedpool *) 0); }
|
int nedmallopt(int parno, int value) THROWSPEC { return nedpmallopt((nedpool *) 0, parno, value); }
|
||||||
#endif
|
int nedmalloc_trim(size_t pad) THROWSPEC { return nedpmalloc_trim((nedpool *) 0, pad); }
|
||||||
int nedmallopt(int parno, int value) THROWSPEC { return nedpmallopt((nedpool *) 0, parno, value); }
|
void nedmalloc_stats() THROWSPEC { nedpmalloc_stats((nedpool *) 0); }
|
||||||
int nedmalloc_trim(size_t pad) THROWSPEC { return nedpmalloc_trim((nedpool *) 0, pad); }
|
size_t nedmalloc_footprint() THROWSPEC { return nedpmalloc_footprint((nedpool *) 0); }
|
||||||
void nedmalloc_stats() THROWSPEC { nedpmalloc_stats((nedpool *) 0); }
|
|
||||||
size_t nedmalloc_footprint() THROWSPEC { return nedpmalloc_footprint((nedpool *) 0); }
|
|
||||||
NEDMALLOCPTRATTR void **nedindependent_calloc(size_t elemsno, size_t elemsize, void **chunks) THROWSPEC { return nedpindependent_calloc((nedpool *) 0, elemsno, elemsize, chunks); }
|
NEDMALLOCPTRATTR void **nedindependent_calloc(size_t elemsno, size_t elemsize, void **chunks) THROWSPEC { return nedpindependent_calloc((nedpool *) 0, elemsno, elemsize, chunks); }
|
||||||
NEDMALLOCPTRATTR void **nedindependent_comalloc(size_t elems, size_t *sizes, void **chunks) THROWSPEC { return nedpindependent_comalloc((nedpool *) 0, elems, sizes, chunks); }
|
// NEDMALLOCPTRATTR void **nedindependent_comalloc(size_t elems, size_t *sizes, void **chunks) THROWSPEC { return nedpindependent_comalloc((nedpool *) 0, elems, sizes, chunks); }
|
||||||
|
|
||||||
struct threadcacheblk_t;
|
struct threadcacheblk_t;
|
||||||
typedef struct threadcacheblk_t threadcacheblk;
|
typedef struct threadcacheblk_t threadcacheblk;
|
||||||
|
@ -383,7 +540,7 @@ struct nedpool_t
|
||||||
};
|
};
|
||||||
static nedpool syspool;
|
static nedpool syspool;
|
||||||
|
|
||||||
static FORCEINLINE unsigned int size2binidx(size_t _size) THROWSPEC
|
static FORCEINLINE NEDMALLOCNOALIASATTR unsigned int size2binidx(size_t _size) THROWSPEC
|
||||||
{ /* 8=1000 16=10000 20=10100 24=11000 32=100000 48=110000 4096=1000000000000 */
|
{ /* 8=1000 16=10000 20=10100 24=11000 32=100000 48=110000 4096=1000000000000 */
|
||||||
unsigned int topbit, size=(unsigned int)(_size>>4);
|
unsigned int topbit, size=(unsigned int)(_size>>4);
|
||||||
/* 16=1 20=1 24=1 32=10 48=11 64=100 96=110 128=1000 4096=100000000 */
|
/* 16=1 20=1 24=1 32=10 48=11 64=100 96=110 128=1000 4096=100000000 */
|
||||||
|
@ -467,9 +624,8 @@ static void tcfullsanitycheck(threadcache *tc) THROWSPEC
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned int age) THROWSPEC
|
static NOINLINE void RemoveCacheEntries(nedpool *RESTRICT p, threadcache *RESTRICT tc, unsigned int age) THROWSPEC
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(p);
|
|
||||||
#ifdef FULLSANITYCHECKS
|
#ifdef FULLSANITYCHECKS
|
||||||
tcfullsanitycheck(tc);
|
tcfullsanitycheck(tc);
|
||||||
#endif
|
#endif
|
||||||
|
@ -485,7 +641,7 @@ static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned in
|
||||||
{
|
{
|
||||||
threadcacheblk *f=*tcb;
|
threadcacheblk *f=*tcb;
|
||||||
size_t blksize=f->size; /*nedblksize(f);*/
|
size_t blksize=f->size; /*nedblksize(f);*/
|
||||||
assert(blksize<=nedblksize(f));
|
assert(blksize<=nedblksize(0, f));
|
||||||
assert(blksize);
|
assert(blksize);
|
||||||
#ifdef FULLSANITYCHECKS
|
#ifdef FULLSANITYCHECKS
|
||||||
assert(*(unsigned int *) "NEDN"==(*tcb)->magic);
|
assert(*(unsigned int *) "NEDN"==(*tcb)->magic);
|
||||||
|
@ -497,7 +653,7 @@ static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned in
|
||||||
*tcbptr=0;
|
*tcbptr=0;
|
||||||
tc->freeInCache-=blksize;
|
tc->freeInCache-=blksize;
|
||||||
assert((long) tc->freeInCache>=0);
|
assert((long) tc->freeInCache>=0);
|
||||||
CallFree(0, f);
|
CallFree(0, f, 0);
|
||||||
/*tcsanitycheck(tcbptr);*/
|
/*tcsanitycheck(tcbptr);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -506,7 +662,7 @@ static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned in
|
||||||
tcfullsanitycheck(tc);
|
tcfullsanitycheck(tc);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
static void DestroyCaches(nedpool *p) THROWSPEC
|
static void DestroyCaches(nedpool *RESTRICT p) THROWSPEC
|
||||||
{
|
{
|
||||||
if(p->caches)
|
if(p->caches)
|
||||||
{
|
{
|
||||||
|
@ -521,14 +677,14 @@ static void DestroyCaches(nedpool *p) THROWSPEC
|
||||||
assert(!tc->freeInCache);
|
assert(!tc->freeInCache);
|
||||||
tc->mymspace=-1;
|
tc->mymspace=-1;
|
||||||
tc->threadid=0;
|
tc->threadid=0;
|
||||||
CallFree(0, tc);
|
CallFree(0, tc, 0);
|
||||||
p->caches[n]=0;
|
p->caches[n]=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static NOINLINE threadcache *AllocCache(nedpool *p) THROWSPEC
|
static NOINLINE threadcache *AllocCache(nedpool *RESTRICT p) THROWSPEC
|
||||||
{
|
{
|
||||||
threadcache *tc=0;
|
threadcache *tc=0;
|
||||||
int n, end;
|
int n, end;
|
||||||
|
@ -539,7 +695,7 @@ static NOINLINE threadcache *AllocCache(nedpool *p) THROWSPEC
|
||||||
RELEASE_LOCK(&p->mutex);
|
RELEASE_LOCK(&p->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
tc=p->caches[n]=(threadcache *) CallCalloc(p->m[0], 1, sizeof(threadcache), 0);
|
tc=p->caches[n]=(threadcache *) CallCalloc(p->m[0], sizeof(threadcache), 0);
|
||||||
if(!tc)
|
if(!tc)
|
||||||
{
|
{
|
||||||
RELEASE_LOCK(&p->mutex);
|
RELEASE_LOCK(&p->mutex);
|
||||||
|
@ -557,14 +713,13 @@ static NOINLINE threadcache *AllocCache(nedpool *p) THROWSPEC
|
||||||
return tc;
|
return tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *threadcache_malloc(nedpool *p, threadcache *tc, size_t *size) THROWSPEC
|
static void *threadcache_malloc(nedpool *RESTRICT p, threadcache *RESTRICT tc, size_t *RESTRICT _size) THROWSPEC
|
||||||
{
|
{
|
||||||
void *ret=0;
|
void *RESTRICT ret=0;
|
||||||
|
size_t size=*_size, blksize=0;
|
||||||
unsigned int bestsize;
|
unsigned int bestsize;
|
||||||
unsigned int idx=size2binidx(*size);
|
unsigned int idx=size2binidx(size);
|
||||||
size_t blksize=0;
|
threadcacheblk *RESTRICT blk, **RESTRICT binsptr;
|
||||||
threadcacheblk *blk, **binsptr;
|
|
||||||
UNREFERENCED_PARAMETER(p);
|
|
||||||
#ifdef FULLSANITYCHECKS
|
#ifdef FULLSANITYCHECKS
|
||||||
tcfullsanitycheck(tc);
|
tcfullsanitycheck(tc);
|
||||||
#endif
|
#endif
|
||||||
|
@ -573,31 +728,31 @@ static void *threadcache_malloc(nedpool *p, threadcache *tc, size_t *size) THROW
|
||||||
#ifdef FINEGRAINEDBINS
|
#ifdef FINEGRAINEDBINS
|
||||||
/* Finer grained bin fit */
|
/* Finer grained bin fit */
|
||||||
idx<<=1;
|
idx<<=1;
|
||||||
if(*size>bestsize)
|
if(size>bestsize)
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
bestsize+=bestsize>>1;
|
bestsize+=bestsize>>1;
|
||||||
}
|
}
|
||||||
if(*size>bestsize)
|
if(size>bestsize)
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
bestsize=1<<(4+(idx>>1));
|
bestsize=1<<(4+(idx>>1));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if(*size>bestsize)
|
if(size>bestsize)
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
bestsize<<=1;
|
bestsize<<=1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
assert(bestsize>=*size);
|
assert(bestsize>=size);
|
||||||
if(*size<bestsize) *size=bestsize;
|
if(size<bestsize) size=bestsize;
|
||||||
assert(*size<=THREADCACHEMAX);
|
assert(size<=THREADCACHEMAX);
|
||||||
assert(idx<=THREADCACHEMAXBINS);
|
assert(idx<=THREADCACHEMAXBINS);
|
||||||
binsptr=&tc->bins[idx*2];
|
binsptr=&tc->bins[idx*2];
|
||||||
/* Try to match close, but move up a bin if necessary */
|
/* Try to match close, but move up a bin if necessary */
|
||||||
blk=*binsptr;
|
blk=*binsptr;
|
||||||
if(!blk || blk->size<*size)
|
if(!blk || blk->size<size)
|
||||||
{ /* Bump it up a bin */
|
{ /* Bump it up a bin */
|
||||||
if(idx<THREADCACHEMAXBINS)
|
if(idx<THREADCACHEMAXBINS)
|
||||||
{
|
{
|
||||||
|
@ -609,8 +764,8 @@ static void *threadcache_malloc(nedpool *p, threadcache *tc, size_t *size) THROW
|
||||||
if(blk)
|
if(blk)
|
||||||
{
|
{
|
||||||
blksize=blk->size; /*nedblksize(blk);*/
|
blksize=blk->size; /*nedblksize(blk);*/
|
||||||
assert(nedblksize(blk)>=blksize);
|
assert(nedblksize(0, blk)>=blksize);
|
||||||
assert(blksize>=*size);
|
assert(blksize>=size);
|
||||||
if(blk->next)
|
if(blk->next)
|
||||||
blk->next->prev=0;
|
blk->next->prev=0;
|
||||||
*binsptr=blk->next;
|
*binsptr=blk->next;
|
||||||
|
@ -620,14 +775,14 @@ static void *threadcache_malloc(nedpool *p, threadcache *tc, size_t *size) THROW
|
||||||
blk->magic=0;
|
blk->magic=0;
|
||||||
#endif
|
#endif
|
||||||
assert(binsptr[0]!=blk && binsptr[1]!=blk);
|
assert(binsptr[0]!=blk && binsptr[1]!=blk);
|
||||||
assert(nedblksize(blk)>=sizeof(threadcacheblk) && nedblksize(blk)<=THREADCACHEMAX+CHUNK_OVERHEAD);
|
assert(nedblksize(0, blk)>=sizeof(threadcacheblk) && nedblksize(0, blk)<=THREADCACHEMAX+CHUNK_OVERHEAD);
|
||||||
/*printf("malloc: %p, %p, %p, %lu\n", p, tc, blk, (long) size);*/
|
/*printf("malloc: %p, %p, %p, %lu\n", p, tc, blk, (long) _size);*/
|
||||||
ret=(void *) blk;
|
ret=(void *) blk;
|
||||||
}
|
}
|
||||||
++tc->mallocs;
|
++tc->mallocs;
|
||||||
if(ret)
|
if(ret)
|
||||||
{
|
{
|
||||||
assert(blksize>=*size);
|
assert(blksize>=size);
|
||||||
++tc->successes;
|
++tc->successes;
|
||||||
tc->freeInCache-=blksize;
|
tc->freeInCache-=blksize;
|
||||||
assert((long) tc->freeInCache>=0);
|
assert((long) tc->freeInCache>=0);
|
||||||
|
@ -642,13 +797,13 @@ static void *threadcache_malloc(nedpool *p, threadcache *tc, size_t *size) THROW
|
||||||
#ifdef FULLSANITYCHECKS
|
#ifdef FULLSANITYCHECKS
|
||||||
tcfullsanitycheck(tc);
|
tcfullsanitycheck(tc);
|
||||||
#endif
|
#endif
|
||||||
|
*_size=size;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
static NOINLINE void ReleaseFreeInCache(nedpool *p, threadcache *tc, int mymspace) THROWSPEC
|
static NOINLINE void ReleaseFreeInCache(nedpool *RESTRICT p, threadcache *RESTRICT tc, int mymspace) THROWSPEC
|
||||||
{
|
{
|
||||||
unsigned int age=THREADCACHEMAXFREESPACE/8192;
|
unsigned int age=THREADCACHEMAXFREESPACE/8192;
|
||||||
/*ACQUIRE_LOCK(&p->m[mymspace]->mutex);*/
|
/*ACQUIRE_LOCK(&p->m[mymspace]->mutex);*/
|
||||||
UNREFERENCED_PARAMETER(mymspace);
|
|
||||||
while(age && tc->freeInCache>=THREADCACHEMAXFREESPACE)
|
while(age && tc->freeInCache>=THREADCACHEMAXFREESPACE)
|
||||||
{
|
{
|
||||||
RemoveCacheEntries(p, tc, age);
|
RemoveCacheEntries(p, tc, age);
|
||||||
|
@ -657,15 +812,15 @@ static NOINLINE void ReleaseFreeInCache(nedpool *p, threadcache *tc, int mymspac
|
||||||
}
|
}
|
||||||
/*RELEASE_LOCK(&p->m[mymspace]->mutex);*/
|
/*RELEASE_LOCK(&p->m[mymspace]->mutex);*/
|
||||||
}
|
}
|
||||||
static void threadcache_free(nedpool *p, threadcache *tc, int mymspace, void *mem, size_t size) THROWSPEC
|
static void threadcache_free(nedpool *RESTRICT p, threadcache *RESTRICT tc, int mymspace, void *RESTRICT mem, size_t size) THROWSPEC
|
||||||
{
|
{
|
||||||
unsigned int bestsize;
|
unsigned int bestsize;
|
||||||
unsigned int idx=size2binidx(size);
|
unsigned int idx=size2binidx(size);
|
||||||
threadcacheblk **binsptr, *tck=(threadcacheblk *) mem;
|
threadcacheblk **RESTRICT binsptr, *RESTRICT tck=(threadcacheblk *) mem;
|
||||||
assert(size>=sizeof(threadcacheblk) && size<=THREADCACHEMAX+CHUNK_OVERHEAD);
|
assert(size>=sizeof(threadcacheblk) && size<=THREADCACHEMAX+CHUNK_OVERHEAD);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* Make sure this is a valid memory block */
|
/* Make sure this is a valid memory block */
|
||||||
assert(nedblksize(mem));
|
assert(nedblksize(0, mem));
|
||||||
#endif
|
#endif
|
||||||
#ifdef FULLSANITYCHECKS
|
#ifdef FULLSANITYCHECKS
|
||||||
tcfullsanitycheck(tc);
|
tcfullsanitycheck(tc);
|
||||||
|
@ -677,7 +832,7 @@ static void threadcache_free(nedpool *p, threadcache *tc, int mymspace, void *me
|
||||||
idx<<=1;
|
idx<<=1;
|
||||||
if(size>bestsize)
|
if(size>bestsize)
|
||||||
{
|
{
|
||||||
unsigned int biggerbestsize=bestsize+(bestsize<<1);
|
unsigned int biggerbestsize=bestsize+bestsize<<1;
|
||||||
if(size>=biggerbestsize)
|
if(size>=biggerbestsize)
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
|
@ -723,7 +878,7 @@ static void threadcache_free(nedpool *p, threadcache *tc, int mymspace, void *me
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static NOINLINE int InitPool(nedpool *p, size_t capacity, int threads) THROWSPEC
|
static NOINLINE int InitPool(nedpool *RESTRICT p, size_t capacity, int threads) THROWSPEC
|
||||||
{ /* threads is -1 for system pool */
|
{ /* threads is -1 for system pool */
|
||||||
ensure_initialization();
|
ensure_initialization();
|
||||||
ACQUIRE_MALLOC_GLOBAL_LOCK();
|
ACQUIRE_MALLOC_GLOBAL_LOCK();
|
||||||
|
@ -759,7 +914,7 @@ err:
|
||||||
RELEASE_MALLOC_GLOBAL_LOCK();
|
RELEASE_MALLOC_GLOBAL_LOCK();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static NOINLINE mstate FindMSpace(nedpool *p, threadcache *tc, int *lastUsed, size_t size) THROWSPEC
|
static NOINLINE mstate FindMSpace(nedpool *RESTRICT p, threadcache *RESTRICT tc, int *RESTRICT lastUsed, size_t size) THROWSPEC
|
||||||
{ /* Gets called when thread's last used mspace is in use. The strategy
|
{ /* Gets called when thread's last used mspace is in use. The strategy
|
||||||
is to run through the list of all available mspaces looking for an
|
is to run through the list of all available mspaces looking for an
|
||||||
unlocked one and if we fail, we create a new one so long as we don't
|
unlocked one and if we fail, we create a new one so long as we don't
|
||||||
|
@ -818,20 +973,57 @@ found:
|
||||||
return p->m[n];
|
return p->m[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct PoolList_t
|
||||||
|
{
|
||||||
|
size_t size; /* Size of list */
|
||||||
|
size_t length; /* Actual entries in list */
|
||||||
|
#ifdef DEBUG
|
||||||
|
nedpool *list[1]; /* Force testing of list expansion */
|
||||||
|
#else
|
||||||
|
nedpool *list[16];
|
||||||
|
#endif
|
||||||
|
} PoolList;
|
||||||
|
static MLOCK_T poollistlock;
|
||||||
|
static PoolList *poollist;
|
||||||
NEDMALLOCPTRATTR nedpool *nedcreatepool(size_t capacity, int threads) THROWSPEC
|
NEDMALLOCPTRATTR nedpool *nedcreatepool(size_t capacity, int threads) THROWSPEC
|
||||||
{
|
{
|
||||||
nedpool *ret;
|
nedpool *ret=0;
|
||||||
if(!(ret=(nedpool *) nedpcalloc(0, 1, sizeof(nedpool)))) return 0;
|
if(!poollist)
|
||||||
|
{
|
||||||
|
PoolList *newpoollist=0;
|
||||||
|
if(!(newpoollist=(PoolList *) nedpcalloc(0, 1, sizeof(PoolList)+sizeof(nedpool *)))) return 0;
|
||||||
|
INITIAL_LOCK(&poollistlock);
|
||||||
|
ACQUIRE_LOCK(&poollistlock);
|
||||||
|
poollist=newpoollist;
|
||||||
|
poollist->size=sizeof(poollist->list)/sizeof(nedpool *);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ACQUIRE_LOCK(&poollistlock);
|
||||||
|
if(poollist->length==poollist->size)
|
||||||
|
{
|
||||||
|
PoolList *newpoollist=0;
|
||||||
|
size_t newsize=0;
|
||||||
|
newsize=sizeof(PoolList)+(poollist->size+1)*sizeof(nedpool *);
|
||||||
|
if(!(newpoollist=(PoolList *) nedprealloc(0, poollist, newsize))) goto badexit;
|
||||||
|
poollist=newpoollist;
|
||||||
|
memset(&poollist->list[poollist->size], 0, newsize-((size_t)&poollist->list[poollist->size]-(size_t)&poollist->list[0]));
|
||||||
|
poollist->size=((newsize-((char *)&poollist->list[0]-(char *)poollist))/sizeof(nedpool *))-1;
|
||||||
|
assert(poollist->size>poollist->length);
|
||||||
|
}
|
||||||
|
if(!(ret=(nedpool *) nedpcalloc(0, 1, sizeof(nedpool)))) goto badexit;
|
||||||
if(!InitPool(ret, capacity, threads))
|
if(!InitPool(ret, capacity, threads))
|
||||||
{
|
{
|
||||||
nedpfree(0, ret);
|
nedpfree(0, ret);
|
||||||
return 0;
|
goto badexit;
|
||||||
}
|
}
|
||||||
|
poollist->list[poollist->length++]=ret;
|
||||||
|
badexit:
|
||||||
|
RELEASE_LOCK(&poollistlock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
void neddestroypool(nedpool *p) THROWSPEC
|
void neddestroypool(nedpool *p) THROWSPEC
|
||||||
{
|
{
|
||||||
int n;
|
unsigned int n;
|
||||||
ACQUIRE_LOCK(&p->mutex);
|
ACQUIRE_LOCK(&p->mutex);
|
||||||
DestroyCaches(p);
|
DestroyCaches(p);
|
||||||
for(n=0; p->m[n]; n++)
|
for(n=0; p->m[n]; n++)
|
||||||
|
@ -844,6 +1036,18 @@ void neddestroypool(nedpool *p) THROWSPEC
|
||||||
RELEASE_LOCK(&p->mutex);
|
RELEASE_LOCK(&p->mutex);
|
||||||
if(TLSFREE(p->mycache)) abort();
|
if(TLSFREE(p->mycache)) abort();
|
||||||
nedpfree(0, p);
|
nedpfree(0, p);
|
||||||
|
ACQUIRE_LOCK(&poollistlock);
|
||||||
|
assert(poollist);
|
||||||
|
for(n=0; n<poollist->length && poollist->list[n]!=p; n++);
|
||||||
|
assert(n!=poollist->length);
|
||||||
|
memmove(&poollist->list[n], &poollist->list[n+1], (size_t)&poollist->list[poollist->length]-(size_t)&poollist->list[n]);
|
||||||
|
if(!--poollist->length)
|
||||||
|
{
|
||||||
|
assert(!poollist->list[0]);
|
||||||
|
nedpfree(0, poollist);
|
||||||
|
poollist=0;
|
||||||
|
}
|
||||||
|
RELEASE_LOCK(&poollistlock);
|
||||||
}
|
}
|
||||||
void neddestroysyspool() THROWSPEC
|
void neddestroysyspool() THROWSPEC
|
||||||
{
|
{
|
||||||
|
@ -860,35 +1064,36 @@ void neddestroysyspool() THROWSPEC
|
||||||
}
|
}
|
||||||
/* Render syspool unusable */
|
/* Render syspool unusable */
|
||||||
for(n=0; n<THREADCACHEMAXCACHES; n++)
|
for(n=0; n<THREADCACHEMAXCACHES; n++)
|
||||||
p->caches[n]=(threadcache *)0xdeadbeef;
|
p->caches[n]=(threadcache *)(size_t)(sizeof(size_t)>4 ? 0xdeadbeefdeadbeefULL : 0xdeadbeefUL);
|
||||||
for(n=0; n<MAXTHREADSINPOOL+1; n++)
|
for(n=0; n<MAXTHREADSINPOOL+1; n++)
|
||||||
p->m[n]=(mstate)0xdeadbeef;
|
p->m[n]=(mstate)(size_t)(sizeof(size_t)>4 ? 0xdeadbeefdeadbeefULL : 0xdeadbeefUL);
|
||||||
if(TLSFREE(p->mycache)) abort();
|
if(TLSFREE(p->mycache)) abort();
|
||||||
RELEASE_LOCK(&p->mutex);
|
RELEASE_LOCK(&p->mutex);
|
||||||
}
|
}
|
||||||
|
nedpool **nedpoollist() THROWSPEC
|
||||||
|
{
|
||||||
|
nedpool **ret=0;
|
||||||
|
if(poollist)
|
||||||
|
{
|
||||||
|
ACQUIRE_LOCK(&poollistlock);
|
||||||
|
if(!(ret=(nedpool **) nedmalloc((poollist->length+1)*sizeof(nedpool *)))) goto badexit;
|
||||||
|
memcpy(ret, poollist->list, (poollist->length+1)*sizeof(nedpool *));
|
||||||
|
badexit:
|
||||||
|
RELEASE_LOCK(&poollistlock);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void nedpsetvalue(nedpool *p, void *v) THROWSPEC
|
void nedpsetvalue(nedpool *p, void *v) THROWSPEC
|
||||||
{
|
{
|
||||||
if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); }
|
if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); }
|
||||||
p->uservalue=v;
|
p->uservalue=v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *nedgetvalue(nedpool **p, void *mem) THROWSPEC
|
void *nedgetvalue(nedpool **p, void *mem) THROWSPEC
|
||||||
{
|
{
|
||||||
nedpool *np=0;
|
nedpool *np=0;
|
||||||
mchunkptr mcp=mem2chunk(mem);
|
mstate fm=nedblkmstate(mem);
|
||||||
mstate fm;
|
if(!fm || !fm->extp) return 0;
|
||||||
if(!(is_aligned(chunk2mem(mcp))) && mcp->head != FENCEPOST_HEAD) return 0;
|
|
||||||
if(!cinuse(mcp)) return 0;
|
|
||||||
if(!next_pinuse(mcp)) return 0;
|
|
||||||
if(!is_mmapped(mcp) && !pinuse(mcp))
|
|
||||||
{
|
|
||||||
if(next_chunk(prev_chunk(mcp))!=mcp) return 0;
|
|
||||||
}
|
|
||||||
fm=get_mstate_for(mcp);
|
|
||||||
if(!ok_magic(fm)) return 0;
|
|
||||||
if(!ok_address(fm, mcp)) return 0;
|
|
||||||
if(!fm->extp) return 0;
|
|
||||||
np=(nedpool *) fm->extp;
|
np=(nedpool *) fm->extp;
|
||||||
if(p) *p=np;
|
if(p) *p=np;
|
||||||
return np->uservalue;
|
return np->uservalue;
|
||||||
|
@ -922,7 +1127,7 @@ void nedtrimthreadcache(nedpool *p, int disable) THROWSPEC
|
||||||
{
|
{
|
||||||
tc->mymspace=-1;
|
tc->mymspace=-1;
|
||||||
tc->threadid=0;
|
tc->threadid=0;
|
||||||
CallFree(0, p->caches[mycache-1]);
|
CallFree(0, p->caches[mycache-1], 0);
|
||||||
p->caches[mycache-1]=0;
|
p->caches[mycache-1]=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -940,7 +1145,7 @@ void neddisablethreadcache(nedpool *p) THROWSPEC
|
||||||
if(USE_ALLOCATOR==1) { RELEASE_LOCK(&m->mutex); } \
|
if(USE_ALLOCATOR==1) { RELEASE_LOCK(&m->mutex); } \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static FORCEINLINE mstate GetMSpace(nedpool *p, threadcache *tc, int mymspace, size_t size) THROWSPEC
|
static FORCEINLINE mstate GetMSpace(nedpool *RESTRICT p, threadcache *RESTRICT tc, int mymspace, size_t size) THROWSPEC
|
||||||
{ /* Returns a locked and ready for use mspace */
|
{ /* Returns a locked and ready for use mspace */
|
||||||
mstate m=p->m[mymspace];
|
mstate m=p->m[mymspace];
|
||||||
assert(m);
|
assert(m);
|
||||||
|
@ -950,22 +1155,14 @@ static FORCEINLINE mstate GetMSpace(nedpool *p, threadcache *tc, int mymspace, s
|
||||||
#endif
|
#endif
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
static FORCEINLINE void GetThreadCache(nedpool **p, threadcache **tc, int *mymspace, size_t *size) THROWSPEC
|
static NOINLINE void GetThreadCache_cold1(nedpool *RESTRICT *RESTRICT p) THROWSPEC
|
||||||
{
|
{
|
||||||
int mycache;
|
*p=&syspool;
|
||||||
if(size && *size<sizeof(threadcacheblk)) *size=sizeof(threadcacheblk);
|
if(!syspool.threads) InitPool(&syspool, 0, -1);
|
||||||
if(!*p)
|
}
|
||||||
{
|
static NOINLINE void GetThreadCache_cold2(nedpool *RESTRICT *RESTRICT p, threadcache *RESTRICT *RESTRICT tc, int *RESTRICT mymspace, int mycache) THROWSPEC
|
||||||
*p=&syspool;
|
{
|
||||||
if(!syspool.threads) InitPool(&syspool, 0, -1);
|
if(!mycache)
|
||||||
}
|
|
||||||
mycache=(int)(size_t) TLSGET((*p)->mycache);
|
|
||||||
if(mycache>0)
|
|
||||||
{ /* Already have a cache */
|
|
||||||
*tc=(*p)->caches[mycache-1];
|
|
||||||
*mymspace=(*tc)->mymspace;
|
|
||||||
}
|
|
||||||
else if(!mycache)
|
|
||||||
{ /* Need to allocate a new cache */
|
{ /* Need to allocate a new cache */
|
||||||
*tc=AllocCache(*p);
|
*tc=AllocCache(*p);
|
||||||
if(!*tc)
|
if(!*tc)
|
||||||
|
@ -981,6 +1178,20 @@ static FORCEINLINE void GetThreadCache(nedpool **p, threadcache **tc, int *mymsp
|
||||||
*tc=0;
|
*tc=0;
|
||||||
*mymspace=-mycache-1;
|
*mymspace=-mycache-1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
static FORCEINLINE void GetThreadCache(nedpool *RESTRICT *RESTRICT p, threadcache *RESTRICT *RESTRICT tc, int *RESTRICT mymspace, size_t *RESTRICT size) THROWSPEC
|
||||||
|
{
|
||||||
|
int mycache;
|
||||||
|
if(size && *size<sizeof(threadcacheblk)) *size=sizeof(threadcacheblk);
|
||||||
|
if(!*p)
|
||||||
|
GetThreadCache_cold1(p);
|
||||||
|
mycache=(int)(size_t) TLSGET((*p)->mycache);
|
||||||
|
if(mycache>0)
|
||||||
|
{ /* Already have a cache */
|
||||||
|
*tc=(*p)->caches[mycache-1];
|
||||||
|
*mymspace=(*tc)->mymspace;
|
||||||
|
}
|
||||||
|
else GetThreadCache_cold2(p, tc, mymspace, mycache);
|
||||||
assert(*mymspace>=0);
|
assert(*mymspace>=0);
|
||||||
assert(!(*tc) || (long)(size_t)CURRENT_THREAD==(*tc)->threadid);
|
assert(!(*tc) || (long)(size_t)CURRENT_THREAD==(*tc)->threadid);
|
||||||
#ifdef FULLSANITYCHECKS
|
#ifdef FULLSANITYCHECKS
|
||||||
|
@ -1030,7 +1241,7 @@ NEDMALLOCPTRATTR void * nedpcalloc(nedpool *p, size_t no, size_t size) THROWSPEC
|
||||||
if(!ret)
|
if(!ret)
|
||||||
{ /* Use this thread's mspace */
|
{ /* Use this thread's mspace */
|
||||||
GETMSPACE(m, p, tc, mymspace, rsize,
|
GETMSPACE(m, p, tc, mymspace, rsize,
|
||||||
ret=CallCalloc(m, 1, rsize, 0));
|
ret=CallCalloc(m, rsize, 0));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1038,35 +1249,42 @@ NEDMALLOCPTRATTR void * nedprealloc(nedpool *p, void *mem, size_t size) THROWSPE
|
||||||
{
|
{
|
||||||
void *ret=0;
|
void *ret=0;
|
||||||
threadcache *tc;
|
threadcache *tc;
|
||||||
int mymspace;
|
int mymspace, isforeign=1;
|
||||||
|
size_t memsize;
|
||||||
if(!mem) return nedpmalloc(p, size);
|
if(!mem) return nedpmalloc(p, size);
|
||||||
|
memsize=nedblksize(&isforeign, mem);
|
||||||
|
assert(memsize);
|
||||||
|
if(!memsize)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "nedmalloc: nedprealloc() called with a block not created by nedmalloc!\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
else if(size<=memsize && memsize-size<
|
||||||
|
#ifdef DEBUG
|
||||||
|
32
|
||||||
|
#else
|
||||||
|
1024
|
||||||
|
#endif
|
||||||
|
) /* If realloc size is within 1Kb smaller than existing, noop it */
|
||||||
|
return mem;
|
||||||
GetThreadCache(&p, &tc, &mymspace, &size);
|
GetThreadCache(&p, &tc, &mymspace, &size);
|
||||||
#if THREADCACHEMAX
|
#if THREADCACHEMAX
|
||||||
if(tc && size && size<=THREADCACHEMAX)
|
if(tc && size && size<=THREADCACHEMAX)
|
||||||
{ /* Use the thread cache */
|
{ /* Use the thread cache */
|
||||||
size_t memsize=nedblksize(mem);
|
|
||||||
#if !USE_MAGIC_HEADERS
|
|
||||||
assert(memsize);
|
|
||||||
if(!memsize)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "nedmalloc: nedprealloc() called with a block not created by nedmalloc!\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if((ret=threadcache_malloc(p, tc, &size)))
|
if((ret=threadcache_malloc(p, tc, &size)))
|
||||||
{
|
{
|
||||||
memcpy(ret, mem, memsize<size ? memsize : size);
|
memcpy(ret, mem, memsize<size ? memsize : size);
|
||||||
if(memsize && memsize<=THREADCACHEMAX)
|
if(memsize>=sizeof(threadcacheblk) && memsize<=(THREADCACHEMAX+CHUNK_OVERHEAD))
|
||||||
threadcache_free(p, tc, mymspace, mem, memsize);
|
threadcache_free(p, tc, mymspace, mem, memsize);
|
||||||
else
|
else
|
||||||
CallFree(0, mem);
|
CallFree(0, mem, isforeign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(!ret)
|
if(!ret)
|
||||||
{ /* Reallocs always happen in the mspace they happened in, so skip
|
{ /* Reallocs always happen in the mspace they happened in, so skip
|
||||||
locking the preferred mspace for this thread */
|
locking the preferred mspace for this thread */
|
||||||
ret=CallRealloc(0, mem, size);
|
ret=CallRealloc(p->m[mymspace], mem, isforeign, memsize, size);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1074,30 +1292,29 @@ void nedpfree(nedpool *p, void *mem) THROWSPEC
|
||||||
{ /* Frees always happen in the mspace they happened in, so skip
|
{ /* Frees always happen in the mspace they happened in, so skip
|
||||||
locking the preferred mspace for this thread */
|
locking the preferred mspace for this thread */
|
||||||
threadcache *tc;
|
threadcache *tc;
|
||||||
int mymspace;
|
int mymspace, isforeign=1;
|
||||||
size_t memsize;
|
size_t memsize;
|
||||||
if(!mem)
|
if(!mem)
|
||||||
{ /* You'd be surprised the number of times this happens as so many
|
{ /* If you tried this on FreeBSD you'd be sorry! */
|
||||||
allocators are non-conformant here */
|
#ifdef DEBUG
|
||||||
// fprintf(stderr, "nedmalloc: WARNING nedpfree() called with zero. This is not portable behaviour!\n");
|
fprintf(stderr, "nedmalloc: WARNING nedpfree() called with zero. This is not portable behaviour!\n");
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GetThreadCache(&p, &tc, &mymspace, 0);
|
memsize=nedblksize(&isforeign, mem);
|
||||||
#if THREADCACHEMAX
|
|
||||||
memsize=nedblksize(mem);
|
|
||||||
#if !USE_MAGIC_HEADERS
|
|
||||||
assert(memsize);
|
assert(memsize);
|
||||||
if(!memsize)
|
if(!memsize)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "nedmalloc: nedpfree() called with a block not created by nedmalloc!\n");
|
fprintf(stderr, "nedmalloc: nedpfree() called with a block not created by nedmalloc!\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
#endif
|
GetThreadCache(&p, &tc, &mymspace, 0);
|
||||||
if(mem && tc && memsize && memsize<=(THREADCACHEMAX+CHUNK_OVERHEAD))
|
#if THREADCACHEMAX
|
||||||
|
if(mem && tc && memsize>=sizeof(threadcacheblk) && memsize<=(THREADCACHEMAX+CHUNK_OVERHEAD))
|
||||||
threadcache_free(p, tc, mymspace, mem, memsize);
|
threadcache_free(p, tc, mymspace, mem, memsize);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
CallFree(0, mem);
|
CallFree(0, mem, isforeign);
|
||||||
}
|
}
|
||||||
NEDMALLOCPTRATTR void * nedpmemalign(nedpool *p, size_t alignment, size_t bytes) THROWSPEC
|
NEDMALLOCPTRATTR void * nedpmemalign(nedpool *p, size_t alignment, size_t bytes) THROWSPEC
|
||||||
{
|
{
|
||||||
|
@ -1111,15 +1328,14 @@ NEDMALLOCPTRATTR void * nedpmemalign(nedpool *p, size_t alignment, size_t bytes)
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#if !NO_MALLINFO
|
struct nedmallinfo nedpmallinfo(nedpool *p) THROWSPEC
|
||||||
struct mallinfo nedpmallinfo(nedpool *p) THROWSPEC
|
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
struct mallinfo ret={0,0,0,0,0,0,0,0,0,0};
|
struct nedmallinfo ret={0};
|
||||||
if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); }
|
if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); }
|
||||||
for(n=0; p->m[n]; n++)
|
for(n=0; p->m[n]; n++)
|
||||||
{
|
{
|
||||||
#if USE_ALLOCATOR==1
|
#if USE_ALLOCATOR==1 && !NO_MALLINFO
|
||||||
struct mallinfo t=mspace_mallinfo(p->m[n]);
|
struct mallinfo t=mspace_mallinfo(p->m[n]);
|
||||||
ret.arena+=t.arena;
|
ret.arena+=t.arena;
|
||||||
ret.ordblks+=t.ordblks;
|
ret.ordblks+=t.ordblks;
|
||||||
|
@ -1132,10 +1348,8 @@ struct mallinfo nedpmallinfo(nedpool *p) THROWSPEC
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
int nedpmallopt(nedpool *p, int parno, int value) THROWSPEC
|
int nedpmallopt(nedpool *p, int parno, int value) THROWSPEC
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(p);
|
|
||||||
#if USE_ALLOCATOR==1
|
#if USE_ALLOCATOR==1
|
||||||
return mspace_mallopt(parno, value);
|
return mspace_mallopt(parno, value);
|
||||||
#else
|
#else
|
||||||
|
@ -1205,6 +1419,8 @@ NEDMALLOCPTRATTR void **nedpindependent_calloc(nedpool *p, size_t elemsno, size_
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
NEDMALLOCPTRATTR void **nedpindependent_comalloc(nedpool *p, size_t elems, size_t *sizes, void **chunks) THROWSPEC
|
NEDMALLOCPTRATTR void **nedpindependent_comalloc(nedpool *p, size_t elems, size_t *sizes, void **chunks) THROWSPEC
|
||||||
{
|
{
|
||||||
void **ret;
|
void **ret;
|
||||||
|
@ -1224,6 +1440,7 @@ NEDMALLOCPTRATTR void **nedpindependent_comalloc(nedpool *p, size_t elems, size_
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
// cheap replacement for strdup so we aren't feeding system allocated blocks into nedmalloc
|
// cheap replacement for strdup so we aren't feeding system allocated blocks into nedmalloc
|
||||||
|
|
||||||
|
|
|
@ -4290,109 +4290,84 @@ static void polymer_getscratchmaterial(_prmaterial* material)
|
||||||
static void polymer_getbuildmaterial(_prmaterial* material, int16_t tilenum, char pal, int8_t shade)
|
static void polymer_getbuildmaterial(_prmaterial* material, int16_t tilenum, char pal, int8_t shade)
|
||||||
{
|
{
|
||||||
pthtyp* pth;
|
pthtyp* pth;
|
||||||
pthtyp* detailpth;
|
|
||||||
pthtyp* glowpth;
|
|
||||||
|
|
||||||
polymer_getscratchmaterial(material);
|
polymer_getscratchmaterial(material);
|
||||||
|
|
||||||
// PR_BIT_NORMAL_MAP
|
|
||||||
if (hicfindsubst(tilenum, NORMALPAL, 0))
|
|
||||||
{
|
|
||||||
glowpth = NULL;
|
|
||||||
glowpth = gltexcache(tilenum, NORMALPAL, 0);
|
|
||||||
|
|
||||||
if (glowpth && glowpth->hicr && (glowpth->hicr->palnum == NORMALPAL)) {
|
|
||||||
material->normalmap = glowpth->glpic;
|
|
||||||
material->normalbias[0] = glowpth->hicr->specpower;
|
|
||||||
material->normalbias[1] = glowpth->hicr->specfactor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PR_BIT_DIFFUSE_MAP
|
// PR_BIT_DIFFUSE_MAP
|
||||||
if (!waloff[tilenum])
|
if (!waloff[tilenum])
|
||||||
loadtile(tilenum);
|
loadtile(tilenum);
|
||||||
|
|
||||||
pth = NULL;
|
if ((pth = gltexcache(tilenum, pal, (material == &spriteplane.material) ? 4 : 0)))
|
||||||
pth = gltexcache(tilenum, pal, (material == &spriteplane.material) ? 4 : 0);
|
{
|
||||||
|
|
||||||
if (pth)
|
|
||||||
material->diffusemap = pth->glpic;
|
material->diffusemap = pth->glpic;
|
||||||
|
|
||||||
if (pth->hicr)
|
if (pth->hicr)
|
||||||
{
|
|
||||||
material->diffusescale[0] = pth->hicr->xscale;
|
|
||||||
material->diffusescale[1] = pth->hicr->yscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PR_BIT_DIFFUSE_DETAIL_MAP
|
|
||||||
if (hicfindsubst(tilenum, DETAILPAL, 0))
|
|
||||||
{
|
|
||||||
detailpth = NULL;
|
|
||||||
detailpth = gltexcache(tilenum, DETAILPAL, 0);
|
|
||||||
|
|
||||||
if (detailpth && detailpth->hicr && (detailpth->hicr->palnum == DETAILPAL))
|
|
||||||
{
|
{
|
||||||
material->detailmap = detailpth->glpic;
|
material->diffusescale[0] = pth->hicr->xscale;
|
||||||
|
material->diffusescale[1] = pth->hicr->yscale;
|
||||||
|
|
||||||
material->detailscale[0] = detailpth->hicr->xscale;
|
// PR_BIT_SPECULAR_MATERIAL
|
||||||
material->detailscale[1] = detailpth->hicr->yscale;
|
if (pth->hicr->specpower != 1.0f)
|
||||||
|
material->specmaterial[0] = pth->hicr->specpower;
|
||||||
|
material->specmaterial[1] = pth->hicr->specfactor;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// PR_BIT_DIFFUSE_MODULATION
|
// PR_BIT_DIFFUSE_MODULATION
|
||||||
material->diffusemodulation[0] =
|
material->diffusemodulation[0] =
|
||||||
material->diffusemodulation[1] =
|
material->diffusemodulation[1] =
|
||||||
material->diffusemodulation[2] =
|
material->diffusemodulation[2] =
|
||||||
((float)(numpalookups-min(max(shade*shadescale,0),numpalookups)))/((float)numpalookups);
|
((float)(numpalookups-min(max(shade*shadescale,0),numpalookups)))/((float)numpalookups);
|
||||||
|
|
||||||
if (pth && (pth->flags & 2))
|
if (pth->flags & 2)
|
||||||
{
|
|
||||||
if (pth->palnum != pal)
|
|
||||||
{
|
{
|
||||||
material->diffusemodulation[0] *= (float)hictinting[pal].r / 255.0;
|
if (pth->palnum != pal)
|
||||||
material->diffusemodulation[1] *= (float)hictinting[pal].g / 255.0;
|
{
|
||||||
material->diffusemodulation[2] *= (float)hictinting[pal].b / 255.0;
|
material->diffusemodulation[0] *= (float)hictinting[pal].r / 255.0;
|
||||||
}
|
material->diffusemodulation[1] *= (float)hictinting[pal].g / 255.0;
|
||||||
// fullscreen tint on global palette change
|
material->diffusemodulation[2] *= (float)hictinting[pal].b / 255.0;
|
||||||
if (hictinting[MAXPALOOKUPS-1].r != 255 ||
|
}
|
||||||
hictinting[MAXPALOOKUPS-1].g != 255 ||
|
|
||||||
hictinting[MAXPALOOKUPS-1].b != 255)
|
// fullscreen tint on global palette change... this is used for nightvision and underwater tinting
|
||||||
{
|
// if ((hictinting[MAXPALOOKUPS-1].r + hictinting[MAXPALOOKUPS-1].g + hictinting[MAXPALOOKUPS-1].b) != 0x2FD)
|
||||||
material->diffusemodulation[0] *= hictinting[MAXPALOOKUPS-1].r / 255.0;
|
if (((uint32_t)hictinting[MAXPALOOKUPS-1].r & 0xFFFFFF00) != 0xFFFFFF00)
|
||||||
material->diffusemodulation[1] *= hictinting[MAXPALOOKUPS-1].g / 255.0;
|
{
|
||||||
material->diffusemodulation[2] *= hictinting[MAXPALOOKUPS-1].b / 255.0;
|
material->diffusemodulation[0] *= hictinting[MAXPALOOKUPS-1].r / 255.0;
|
||||||
|
material->diffusemodulation[1] *= hictinting[MAXPALOOKUPS-1].g / 255.0;
|
||||||
|
material->diffusemodulation[2] *= hictinting[MAXPALOOKUPS-1].b / 255.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PR_BIT_GLOW_MAP
|
||||||
|
if (r_fullbrights && pth->flags & 16)
|
||||||
|
material->glowmap = pth->ofb->glpic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PR_BIT_DIFFUSE_DETAIL_MAP
|
||||||
|
if (hicfindsubst(tilenum, DETAILPAL, 0) && (pth = gltexcache(tilenum, DETAILPAL, 0)) &&
|
||||||
|
pth->hicr && (pth->hicr->palnum == DETAILPAL))
|
||||||
|
{
|
||||||
|
material->detailmap = pth->glpic;
|
||||||
|
material->detailscale[0] = pth->hicr->xscale;
|
||||||
|
material->detailscale[1] = pth->hicr->yscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PR_BIT_GLOW_MAP
|
||||||
|
if (hicfindsubst(tilenum, GLOWPAL, 0) && (pth = gltexcache(tilenum, GLOWPAL, 0)) &&
|
||||||
|
pth->hicr && (pth->hicr->palnum == GLOWPAL))
|
||||||
|
material->glowmap = pth->glpic;
|
||||||
|
|
||||||
// PR_BIT_SPECULAR_MAP
|
// PR_BIT_SPECULAR_MAP
|
||||||
if (hicfindsubst(tilenum, SPECULARPAL, 0))
|
if (hicfindsubst(tilenum, SPECULARPAL, 0) && (pth = gltexcache(tilenum, SPECULARPAL, 0)) &&
|
||||||
|
pth->hicr && (pth->hicr->palnum == SPECULARPAL))
|
||||||
|
material->specmap = pth->glpic;
|
||||||
|
|
||||||
|
// PR_BIT_NORMAL_MAP
|
||||||
|
if (hicfindsubst(tilenum, NORMALPAL, 0) && (pth = gltexcache(tilenum, NORMALPAL, 0)) &&
|
||||||
|
pth->hicr && (pth->hicr->palnum == NORMALPAL))
|
||||||
{
|
{
|
||||||
glowpth = NULL;
|
material->normalmap = pth->glpic;
|
||||||
glowpth = gltexcache(tilenum, SPECULARPAL, 0);
|
material->normalbias[0] = pth->hicr->specpower;
|
||||||
|
material->normalbias[1] = pth->hicr->specfactor;
|
||||||
if (glowpth && glowpth->hicr && (glowpth->hicr->palnum == SPECULARPAL))
|
|
||||||
material->specmap = glowpth->glpic;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PR_BIT_SPECULAR_MATERIAL
|
|
||||||
if (pth->hicr)
|
|
||||||
{
|
|
||||||
if (pth->hicr->specpower != 1.0f)
|
|
||||||
material->specmaterial[0] = pth->hicr->specpower;
|
|
||||||
material->specmaterial[1] = pth->hicr->specfactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PR_BIT_GLOW_MAP
|
|
||||||
if (r_fullbrights && pth && pth->flags & 16)
|
|
||||||
material->glowmap = pth->ofb->glpic;
|
|
||||||
|
|
||||||
if (hicfindsubst(tilenum, GLOWPAL, 0))
|
|
||||||
{
|
|
||||||
glowpth = NULL;
|
|
||||||
glowpth = gltexcache(tilenum, GLOWPAL, 0);
|
|
||||||
|
|
||||||
if (glowpth && glowpth->hicr && (glowpth->hicr->palnum == GLOWPAL))
|
|
||||||
material->glowmap = glowpth->glpic;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -247,7 +247,7 @@ void drawline2d(float x0, float y0, float x1, float y1, char col)
|
||||||
#define USEKENFILTER 1
|
#define USEKENFILTER 1
|
||||||
|
|
||||||
#ifdef USELZF
|
#ifdef USELZF
|
||||||
# include "fastlz.h"
|
# include "quicklz.h"
|
||||||
#else
|
#else
|
||||||
# include "lzwnew.h"
|
# include "lzwnew.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -4283,8 +4283,8 @@ void polymost_drawrooms()
|
||||||
w2d = -w2d;
|
w2d = -w2d;
|
||||||
if ((w1d==0 && w2d==0) || (w1d<0 || w2d<0))
|
if ((w1d==0 && w2d==0) || (w1d<0 || w2d<0))
|
||||||
continue;
|
continue;
|
||||||
ptonline[0] = w2[0]+(w2d/(w1d+w2d))*w21[0];
|
ptonline[0] = (int32_t)(w2[0]+(w2d/(w1d+w2d))*w21[0]);
|
||||||
ptonline[1] = w2[1]+(w2d/(w1d+w2d))*w21[1];
|
ptonline[1] = (int32_t)(w2[1]+(w2d/(w1d+w2d))*w21[1]);
|
||||||
scrp[0] = ptonline[0]-vect.x;
|
scrp[0] = ptonline[0]-vect.x;
|
||||||
scrp[1] = ptonline[1]-vect.y;
|
scrp[1] = ptonline[1]-vect.y;
|
||||||
if (scrv[0]*scrp[0] + scrv[1]*scrp[1] <= 0)
|
if (scrv[0]*scrp[0] + scrv[1]*scrp[1] <= 0)
|
||||||
|
@ -6096,7 +6096,7 @@ int32_t dxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf, c
|
||||||
if (glusetexcache == 2)
|
if (glusetexcache == 2)
|
||||||
{
|
{
|
||||||
#ifdef USELZF
|
#ifdef USELZF
|
||||||
cleng = fastlz_compress(pic, miplen, packbuf/*, miplen-1*/);
|
cleng = qlz_compress(pic, packbuf, miplen, state_compress);
|
||||||
if (cleng == 0 || cleng > j-1)
|
if (cleng == 0 || cleng > j-1)
|
||||||
{
|
{
|
||||||
// failed to compress
|
// failed to compress
|
||||||
|
@ -6138,7 +6138,7 @@ int32_t dxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf, c
|
||||||
{
|
{
|
||||||
#ifdef USELZF
|
#ifdef USELZF
|
||||||
j = (miplen/stride)<<3;
|
j = (miplen/stride)<<3;
|
||||||
cleng = fastlz_compress(midbuf,j,packbuf/*,j-1*/);
|
cleng = qlz_compress(midbuf,packbuf,j,state_compress);
|
||||||
if (cleng == 0 || cleng > j-1)
|
if (cleng == 0 || cleng > j-1)
|
||||||
{
|
{
|
||||||
cleng = j;
|
cleng = j;
|
||||||
|
@ -6169,7 +6169,7 @@ int32_t dxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf, c
|
||||||
{
|
{
|
||||||
#ifdef USELZF
|
#ifdef USELZF
|
||||||
j = (miplen/stride)<<2;
|
j = (miplen/stride)<<2;
|
||||||
cleng = fastlz_compress(midbuf,j,packbuf/*,j-1*/);
|
cleng = qlz_compress(midbuf,packbuf,j,state_compress);
|
||||||
if (cleng == 0 || cleng > j-1)
|
if (cleng == 0 || cleng > j-1)
|
||||||
{
|
{
|
||||||
cleng = j;
|
cleng = j;
|
||||||
|
@ -6205,7 +6205,7 @@ int32_t dxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf, c
|
||||||
{
|
{
|
||||||
#ifdef USELZF
|
#ifdef USELZF
|
||||||
j = (miplen/stride)<<2;
|
j = (miplen/stride)<<2;
|
||||||
cleng = fastlz_compress(midbuf,j,packbuf/*,j-1*/);
|
cleng = qlz_compress(midbuf,packbuf,j,state_compress);
|
||||||
if (cleng == 0 || cleng > j-1)
|
if (cleng == 0 || cleng > j-1)
|
||||||
{
|
{
|
||||||
cleng = j;
|
cleng = j;
|
||||||
|
@ -6239,7 +6239,7 @@ int32_t dedxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf,
|
||||||
if (ispacked && cleng < pict->size) inbuf = packbuf; else inbuf = pic;
|
if (ispacked && cleng < pict->size) inbuf = packbuf; else inbuf = pic;
|
||||||
if (kread(fil, inbuf, cleng) != cleng) return -1;
|
if (kread(fil, inbuf, cleng) != cleng) return -1;
|
||||||
if (ispacked && cleng < pict->size)
|
if (ispacked && cleng < pict->size)
|
||||||
if (fastlz_decompress(packbuf, cleng, pic, pict->size) == 0) return -1;
|
if (qlz_decompress(packbuf, pic, state_decompress) == 0) return -1;
|
||||||
#else
|
#else
|
||||||
if (ispacked) inbuf = packbuf; else inbuf = pic;
|
if (ispacked) inbuf = packbuf; else inbuf = pic;
|
||||||
if (kread(fil, inbuf, cleng) != cleng) return -1;
|
if (kread(fil, inbuf, cleng) != cleng) return -1;
|
||||||
|
@ -6266,7 +6266,7 @@ int32_t dedxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf,
|
||||||
if (ispacked && cleng < j) inbuf = packbuf; else inbuf = midbuf;
|
if (ispacked && cleng < j) inbuf = packbuf; else inbuf = midbuf;
|
||||||
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
||||||
if (ispacked && cleng < j)
|
if (ispacked && cleng < j)
|
||||||
if (fastlz_decompress(packbuf,cleng,midbuf,j) == 0) return -1;
|
if (qlz_decompress(packbuf,midbuf,state_decompress) == 0) return -1;
|
||||||
#else
|
#else
|
||||||
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
||||||
if (ispacked && lzwuncompress(packbuf,cleng,midbuf,j) != j) return -1;
|
if (ispacked && lzwuncompress(packbuf,cleng,midbuf,j) != j) return -1;
|
||||||
|
@ -6284,7 +6284,7 @@ int32_t dedxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf,
|
||||||
if (ispacked && cleng < j) inbuf = packbuf; else inbuf = midbuf;
|
if (ispacked && cleng < j) inbuf = packbuf; else inbuf = midbuf;
|
||||||
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
||||||
if (ispacked && cleng < j)
|
if (ispacked && cleng < j)
|
||||||
if (fastlz_decompress(packbuf,cleng,midbuf,j) == 0) return -1;
|
if (qlz_decompress(packbuf,midbuf,state_decompress) == 0) return -1;
|
||||||
#else
|
#else
|
||||||
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
||||||
if (ispacked && lzwuncompress(packbuf,cleng,midbuf,j) != j) return -1;
|
if (ispacked && lzwuncompress(packbuf,cleng,midbuf,j) != j) return -1;
|
||||||
|
@ -6304,7 +6304,7 @@ int32_t dedxtfilter(int32_t fil, texcachepicture *pict, char *pic, void *midbuf,
|
||||||
if (ispacked && cleng < j) inbuf = packbuf; else inbuf = midbuf;
|
if (ispacked && cleng < j) inbuf = packbuf; else inbuf = midbuf;
|
||||||
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
||||||
if (ispacked && cleng < j)
|
if (ispacked && cleng < j)
|
||||||
if (fastlz_decompress(packbuf,cleng,midbuf,j) == 0) return -1;
|
if (qlz_decompress(packbuf,midbuf,state_decompress) == 0) return -1;
|
||||||
#else
|
#else
|
||||||
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
if (Bread(fil,inbuf,cleng) < cleng) return -1;
|
||||||
if (ispacked && lzwuncompress(packbuf,cleng,midbuf,j) != j) return -1;
|
if (ispacked && lzwuncompress(packbuf,cleng,midbuf,j) != j) return -1;
|
||||||
|
|
854
polymer/eduke32/build/src/quicklz.c
Normal file
854
polymer/eduke32/build/src/quicklz.c
Normal file
|
@ -0,0 +1,854 @@
|
||||||
|
// Fast data compression library
|
||||||
|
// Copyright (C) 2006-2009 Lasse Mikkel Reinhold
|
||||||
|
// lar@quicklz.com
|
||||||
|
//
|
||||||
|
// QuickLZ can be used for free under the GPL-1 or GPL-2 license (where anything
|
||||||
|
// released into public must be open source) or under a commercial license if such
|
||||||
|
// has been acquired (see http://www.quicklz.com/order.html). The commercial license
|
||||||
|
// does not cover derived or ported versions created by third parties under GPL.
|
||||||
|
|
||||||
|
// BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION
|
||||||
|
// BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION
|
||||||
|
// BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION
|
||||||
|
// BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION
|
||||||
|
// BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION BETA VERSION
|
||||||
|
|
||||||
|
// 1.5.0 BETA 2
|
||||||
|
|
||||||
|
#include "quicklz.h"
|
||||||
|
|
||||||
|
#if QLZ_VERSION_MAJOR != 1 || QLZ_VERSION_MINOR != 5 || QLZ_VERSION_REVISION != 0
|
||||||
|
#error quicklz.c and quicklz.h have different versions
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(__X86__) || defined(__i386__) || defined(i386) || defined(_M_IX86) || defined(__386__) || defined(__x86_64__) || defined(_M_X64))
|
||||||
|
#define X86X64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MINOFFSET 2
|
||||||
|
#define UNCONDITIONAL_MATCHLEN 6
|
||||||
|
#define UNCOMPRESSED_END 4
|
||||||
|
#define CWORD_LEN 4
|
||||||
|
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1 && defined QLZ_PTR_64 && QLZ_STREAMING_BUFFER == 0
|
||||||
|
#define OFFSET_BASE source
|
||||||
|
#define CAST (ui32)(size_t)
|
||||||
|
#else
|
||||||
|
#define OFFSET_BASE 0
|
||||||
|
#define CAST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int qlz_get_setting(int setting)
|
||||||
|
{
|
||||||
|
switch (setting)
|
||||||
|
{
|
||||||
|
case 0: return QLZ_COMPRESSION_LEVEL;
|
||||||
|
case 1: return sizeof(qlz_state_compress);
|
||||||
|
case 2: return sizeof(qlz_state_decompress);
|
||||||
|
case 3: return QLZ_STREAMING_BUFFER;
|
||||||
|
#ifdef QLZ_MEMORY_SAFE
|
||||||
|
case 6: return 1;
|
||||||
|
#else
|
||||||
|
case 6: return 0;
|
||||||
|
#endif
|
||||||
|
case 7: return QLZ_VERSION_MAJOR;
|
||||||
|
case 8: return QLZ_VERSION_MINOR;
|
||||||
|
case 9: return QLZ_VERSION_REVISION;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1
|
||||||
|
static int same(const unsigned char *src, size_t n)
|
||||||
|
{
|
||||||
|
while(n > 0 && *(src + n) == *src)
|
||||||
|
n--;
|
||||||
|
return n == 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void reset_table_compress(qlz_state_compress *state)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < QLZ_HASH_VALUES; i++)
|
||||||
|
{
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1
|
||||||
|
state->hash[i].offset = 0;
|
||||||
|
#else
|
||||||
|
state->hash_counter[i] = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reset_table_decompress(qlz_state_decompress *state)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
(void)state;
|
||||||
|
(void)i;
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 2
|
||||||
|
for(i = 0; i < QLZ_HASH_VALUES; i++)
|
||||||
|
{
|
||||||
|
state->hash_counter[i] = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline ui32 hash_func(ui32 i)
|
||||||
|
{
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 2
|
||||||
|
return ((i >> 9) ^ (i >> 13) ^ i) & (QLZ_HASH_VALUES - 1);
|
||||||
|
#else
|
||||||
|
return ((i >> 12) ^ i) & (QLZ_HASH_VALUES - 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline ui32 fast_read(void const *src, ui32 bytes)
|
||||||
|
{
|
||||||
|
#ifndef X86X64
|
||||||
|
unsigned char *p = (unsigned char*)src;
|
||||||
|
switch (bytes)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
return(*p | *(p + 1) << 8 | *(p + 2) << 16 | *(p + 3) << 24);
|
||||||
|
case 3:
|
||||||
|
return(*p | *(p + 1) << 8 | *(p + 2) << 16);
|
||||||
|
case 2:
|
||||||
|
return(*p | *(p + 1) << 8);
|
||||||
|
case 1:
|
||||||
|
return(*p);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
if (bytes >= 1 && bytes <= 4)
|
||||||
|
return *((ui32*)src);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline ui32 hashat(const unsigned char *src)
|
||||||
|
{
|
||||||
|
ui32 fetch, hash;
|
||||||
|
fetch = fast_read(src, 3);
|
||||||
|
hash = hash_func(fetch);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void fast_write(ui32 f, void *dst, size_t bytes)
|
||||||
|
{
|
||||||
|
#ifndef X86X64
|
||||||
|
unsigned char *p = (unsigned char*)dst;
|
||||||
|
|
||||||
|
switch (bytes)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
*p = (unsigned char)f;
|
||||||
|
*(p + 1) = (unsigned char)(f >> 8);
|
||||||
|
*(p + 2) = (unsigned char)(f >> 16);
|
||||||
|
*(p + 3) = (unsigned char)(f >> 24);
|
||||||
|
return;
|
||||||
|
case 3:
|
||||||
|
*p = (unsigned char)f;
|
||||||
|
*(p + 1) = (unsigned char)(f >> 8);
|
||||||
|
*(p + 2) = (unsigned char)(f >> 16);
|
||||||
|
return;
|
||||||
|
case 2:
|
||||||
|
*p = (unsigned char)f;
|
||||||
|
*(p + 1) = (unsigned char)(f >> 8);
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
*p = (unsigned char)f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
switch (bytes)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
*((ui32*)dst) = f;
|
||||||
|
return;
|
||||||
|
case 3:
|
||||||
|
*((ui32*)dst) = f;
|
||||||
|
return;
|
||||||
|
case 2:
|
||||||
|
*((ui16 *)dst) = (ui16)f;
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
*((unsigned char*)dst) = (unsigned char)f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t qlz_size_decompressed(const char *source)
|
||||||
|
{
|
||||||
|
ui32 n, r;
|
||||||
|
n = (((*source) & 2) == 2) ? 4 : 1;
|
||||||
|
r = fast_read(source + 1 + n, n);
|
||||||
|
r = r & (0xffffffff >> ((4 - n)*8));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t qlz_size_compressed(const char *source)
|
||||||
|
{
|
||||||
|
ui32 n, r;
|
||||||
|
n = (((*source) & 2) == 2) ? 4 : 1;
|
||||||
|
r = fast_read(source + 1, n);
|
||||||
|
r = r & (0xffffffff >> ((4 - n)*8));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t qlz_size_header(const char *source)
|
||||||
|
{
|
||||||
|
size_t n = 2*((((*source) & 2) == 2) ? 4 : 1) + 1;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static __inline void memcpy_up(unsigned char *dst, const unsigned char *src, ui32 n)
|
||||||
|
{
|
||||||
|
// Caution if modifying memcpy_up! Overlap of dst and src must be special handled.
|
||||||
|
#ifndef X86X64
|
||||||
|
unsigned char *end = dst + n;
|
||||||
|
while(dst < end)
|
||||||
|
{
|
||||||
|
*dst = *src;
|
||||||
|
dst++;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ui32 f = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*(ui32 *)(dst + f) = *(ui32 *)(src + f);
|
||||||
|
f += MINOFFSET + 1;
|
||||||
|
}
|
||||||
|
while (f < n);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void update_hash(qlz_state_decompress *state, const unsigned char *s)
|
||||||
|
{
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1
|
||||||
|
ui32 hash;
|
||||||
|
hash = hashat(s);
|
||||||
|
state->hash[hash].offset = s;
|
||||||
|
state->hash_counter[hash] = 1;
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL == 2
|
||||||
|
ui32 hash;
|
||||||
|
unsigned char c;
|
||||||
|
hash = hashat(s);
|
||||||
|
c = state->hash_counter[hash];
|
||||||
|
state->hash[hash].offset[c & (QLZ_POINTERS - 1)] = s;
|
||||||
|
c++;
|
||||||
|
state->hash_counter[hash] = c;
|
||||||
|
#endif
|
||||||
|
(void)state;
|
||||||
|
(void)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QLZ_COMPRESSION_LEVEL <= 2
|
||||||
|
static void update_hash_upto(qlz_state_decompress *state, unsigned char **lh, const unsigned char *max)
|
||||||
|
{
|
||||||
|
while(*lh < max)
|
||||||
|
{
|
||||||
|
(*lh)++;
|
||||||
|
update_hash(state, *lh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static size_t qlz_compress_core(const unsigned char *source, unsigned char *destination, size_t size, qlz_state_compress *state)
|
||||||
|
{
|
||||||
|
const unsigned char *last_byte = source + size - 1;
|
||||||
|
const unsigned char *src = source;
|
||||||
|
unsigned char *cword_ptr = destination;
|
||||||
|
unsigned char *dst = destination + CWORD_LEN;
|
||||||
|
ui32 cword_val = 1U << 31;
|
||||||
|
const unsigned char *last_matchstart = last_byte - UNCONDITIONAL_MATCHLEN - UNCOMPRESSED_END;
|
||||||
|
ui32 fetch = 0;
|
||||||
|
unsigned int lits = 0;
|
||||||
|
|
||||||
|
(void) lits;
|
||||||
|
|
||||||
|
if(src <= last_matchstart)
|
||||||
|
fetch = fast_read(src, 3);
|
||||||
|
|
||||||
|
while(src <= last_matchstart)
|
||||||
|
{
|
||||||
|
if ((cword_val & 1) == 1)
|
||||||
|
{
|
||||||
|
// store uncompressed if compression ratio is too low
|
||||||
|
if (src > source + (size >> 1) && dst - destination > src - source - ((src - source) >> 5))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fast_write((cword_val >> 1) | (1U << 31), cword_ptr, CWORD_LEN);
|
||||||
|
|
||||||
|
cword_ptr = dst;
|
||||||
|
dst += CWORD_LEN;
|
||||||
|
cword_val = 1U << 31;
|
||||||
|
fetch = fast_read(src, 3);
|
||||||
|
}
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1
|
||||||
|
{
|
||||||
|
const unsigned char *o;
|
||||||
|
ui32 hash, cached;
|
||||||
|
|
||||||
|
hash = hash_func(fetch);
|
||||||
|
cached = fetch ^ state->hash[hash].cache;
|
||||||
|
state->hash[hash].cache = fetch;
|
||||||
|
|
||||||
|
o = state->hash[hash].offset + OFFSET_BASE;
|
||||||
|
state->hash[hash].offset = CAST(src - OFFSET_BASE);
|
||||||
|
|
||||||
|
#ifdef X86X64
|
||||||
|
if ((cached & 0xffffff) == 0 && o != OFFSET_BASE && (src - o > MINOFFSET || (src == o + 1 && lits >= 3 && src > source + 3 && same(src - 3, 6))))
|
||||||
|
{
|
||||||
|
if(cached != 0)
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
if (cached == 0 && o != OFFSET_BASE && (src - o > MINOFFSET || (src == o + 1 && lits >= 3 && src > source + 3 && same(src - 3, 6))))
|
||||||
|
{
|
||||||
|
if (*(o + 3) != *(src + 3))
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
hash <<= 4;
|
||||||
|
cword_val = (cword_val >> 1) | (1U << 31);
|
||||||
|
fast_write((3 - 2) | hash, dst, 2);
|
||||||
|
src += 3;
|
||||||
|
dst += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const unsigned char *old_src = src;
|
||||||
|
size_t matchlen;
|
||||||
|
hash <<= 4;
|
||||||
|
|
||||||
|
cword_val = (cword_val >> 1) | (1U << 31);
|
||||||
|
src += 4;
|
||||||
|
|
||||||
|
if(*(o + (src - old_src)) == *src)
|
||||||
|
{
|
||||||
|
src++;
|
||||||
|
if(*(o + (src - old_src)) == *src)
|
||||||
|
{
|
||||||
|
size_t q = last_byte - UNCOMPRESSED_END - (src - 5) + 1;
|
||||||
|
size_t remaining = q > 255 ? 255 : q;
|
||||||
|
src++;
|
||||||
|
while(*(o + (src - old_src)) == *src && (size_t)(src - old_src) < remaining)
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
matchlen = src - old_src;
|
||||||
|
if (matchlen < 18)
|
||||||
|
{
|
||||||
|
fast_write((ui32)(matchlen - 2) | hash, dst, 2);
|
||||||
|
dst += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fast_write((ui32)(matchlen << 16) | hash, dst, 3);
|
||||||
|
dst += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fetch = fast_read(src, 3);
|
||||||
|
lits = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lits++;
|
||||||
|
*dst = *src;
|
||||||
|
src++;
|
||||||
|
dst++;
|
||||||
|
cword_val = (cword_val >> 1);
|
||||||
|
#ifdef X86X64
|
||||||
|
fetch = fast_read(src, 3);
|
||||||
|
#else
|
||||||
|
fetch = (fetch >> 8 & 0xffff) | (*(src + 2) << 16);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL >= 2
|
||||||
|
{
|
||||||
|
const unsigned char *o, *offset2;
|
||||||
|
ui32 hash, matchlen, k, m, best_k = 0;
|
||||||
|
unsigned char c;
|
||||||
|
size_t remaining = (last_byte - UNCOMPRESSED_END - src + 1) > 255 ? 255 : (last_byte - UNCOMPRESSED_END - src + 1);
|
||||||
|
(void)best_k;
|
||||||
|
|
||||||
|
|
||||||
|
//hash = hashat(src);
|
||||||
|
fetch = fast_read(src, 3);
|
||||||
|
hash = hash_func(fetch);
|
||||||
|
|
||||||
|
c = state->hash_counter[hash];
|
||||||
|
|
||||||
|
offset2 = state->hash[hash].offset[0];
|
||||||
|
if(offset2 < src - MINOFFSET && c > 0 && ((fast_read(offset2, 3) ^ fetch) & 0xffffff) == 0)
|
||||||
|
{
|
||||||
|
matchlen = 3;
|
||||||
|
if(*(offset2 + matchlen) == *(src + matchlen))
|
||||||
|
{
|
||||||
|
matchlen = 4;
|
||||||
|
while(*(offset2 + matchlen) == *(src + matchlen) && matchlen < remaining)
|
||||||
|
matchlen++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
matchlen = 0;
|
||||||
|
for(k = 1; k < QLZ_POINTERS && c > k; k++)
|
||||||
|
{
|
||||||
|
o = state->hash[hash].offset[k];
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 3
|
||||||
|
if(((fast_read(o, 3) ^ fetch) & 0xffffff) == 0 && o < src - MINOFFSET)
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL == 2
|
||||||
|
if(*(src + matchlen) == *(o + matchlen) && ((fast_read(o, 3) ^ fetch) & 0xffffff) == 0 && o < src - MINOFFSET)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
m = 3;
|
||||||
|
while(*(o + m) == *(src + m) && m < remaining)
|
||||||
|
m++;
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 3
|
||||||
|
if ((m > matchlen) || (m == matchlen && o > offset2))
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL == 2
|
||||||
|
if (m > matchlen)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
offset2 = o;
|
||||||
|
matchlen = m;
|
||||||
|
best_k = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
o = offset2;
|
||||||
|
state->hash[hash].offset[c & (QLZ_POINTERS - 1)] = src;
|
||||||
|
c++;
|
||||||
|
state->hash_counter[hash] = c;
|
||||||
|
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 3
|
||||||
|
if(matchlen > 2 && src - o < 131071)
|
||||||
|
{
|
||||||
|
ui32 u;
|
||||||
|
size_t offset = src - o;
|
||||||
|
|
||||||
|
for(u = 1; u < matchlen; u++)
|
||||||
|
{
|
||||||
|
hash = hashat(src + u);
|
||||||
|
c = state->hash_counter[hash]++;
|
||||||
|
state->hash[hash].offset[c & (QLZ_POINTERS - 1)] = src + u;
|
||||||
|
}
|
||||||
|
|
||||||
|
cword_val = (cword_val >> 1) | (1U << 31);
|
||||||
|
src += matchlen;
|
||||||
|
|
||||||
|
if(matchlen == 3 && offset <= 63)
|
||||||
|
{
|
||||||
|
*dst = (unsigned char)(offset << 2);
|
||||||
|
dst++;
|
||||||
|
}
|
||||||
|
else if (matchlen == 3 && offset <= 16383)
|
||||||
|
{
|
||||||
|
ui32 f = (ui32)((offset << 2) | 1);
|
||||||
|
fast_write(f, dst, 2);
|
||||||
|
dst += 2;
|
||||||
|
}
|
||||||
|
else if (matchlen <= 18 && offset <= 1023)
|
||||||
|
{
|
||||||
|
ui32 f = ((matchlen - 3) << 2) | ((ui32)offset << 6) | 2;
|
||||||
|
fast_write(f, dst, 2);
|
||||||
|
dst += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(matchlen <= 33)
|
||||||
|
{
|
||||||
|
ui32 f = ((matchlen - 2) << 2) | ((ui32)offset << 7) | 3;
|
||||||
|
fast_write(f, dst, 3);
|
||||||
|
dst += 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui32 f = ((matchlen - 3) << 7) | ((ui32)offset << 15) | 3;
|
||||||
|
fast_write(f, dst, 4);
|
||||||
|
dst += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*dst = *src;
|
||||||
|
src++;
|
||||||
|
dst++;
|
||||||
|
cword_val = (cword_val >> 1);
|
||||||
|
}
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL == 2
|
||||||
|
|
||||||
|
if(matchlen > 2)
|
||||||
|
{
|
||||||
|
cword_val = (cword_val >> 1) | (1U << 31);
|
||||||
|
src += matchlen;
|
||||||
|
|
||||||
|
if (matchlen < 10)
|
||||||
|
{
|
||||||
|
ui32 f = best_k | ((matchlen - 2) << 2) | (hash << 5);
|
||||||
|
fast_write(f, dst, 2);
|
||||||
|
dst += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui32 f = best_k | (matchlen << 16) | (hash << 5);
|
||||||
|
fast_write(f, dst, 3);
|
||||||
|
dst += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*dst = *src;
|
||||||
|
src++;
|
||||||
|
dst++;
|
||||||
|
cword_val = (cword_val >> 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
while (src <= last_byte)
|
||||||
|
{
|
||||||
|
if ((cword_val & 1) == 1)
|
||||||
|
{
|
||||||
|
fast_write((cword_val >> 1) | (1U << 31), cword_ptr, CWORD_LEN);
|
||||||
|
cword_ptr = dst;
|
||||||
|
dst += CWORD_LEN;
|
||||||
|
cword_val = 1U << 31;
|
||||||
|
}
|
||||||
|
#if QLZ_COMPRESSION_LEVEL < 3
|
||||||
|
if (src <= last_byte - 3)
|
||||||
|
{
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1
|
||||||
|
ui32 hash, fetch;
|
||||||
|
fetch = fast_read(src, 3);
|
||||||
|
hash = hash_func(fetch);
|
||||||
|
state->hash[hash].offset = CAST(src - OFFSET_BASE);
|
||||||
|
state->hash[hash].cache = fetch;
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL == 2
|
||||||
|
ui32 hash;
|
||||||
|
unsigned char c;
|
||||||
|
hash = hashat(src);
|
||||||
|
c = state->hash_counter[hash];
|
||||||
|
state->hash[hash].offset[c & (QLZ_POINTERS - 1)] = src;
|
||||||
|
c++;
|
||||||
|
state->hash_counter[hash] = c;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
*dst = *src;
|
||||||
|
src++;
|
||||||
|
dst++;
|
||||||
|
cword_val = (cword_val >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while((cword_val & 1) != 1)
|
||||||
|
cword_val = (cword_val >> 1);
|
||||||
|
|
||||||
|
fast_write((cword_val >> 1) | (1U << 31), cword_ptr, CWORD_LEN);
|
||||||
|
|
||||||
|
// min. size must be 9 bytes so that the qlz_size functions can take 9 bytes as argument
|
||||||
|
return dst - destination < 9 ? 9 : dst - destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t qlz_decompress_core(const unsigned char *source, unsigned char *destination, size_t size, qlz_state_decompress *state, const unsigned char *history)
|
||||||
|
{
|
||||||
|
const unsigned char *src = source + qlz_size_header((const char *)source);
|
||||||
|
unsigned char *dst = destination;
|
||||||
|
const unsigned char *last_destination_byte = destination + size - 1;
|
||||||
|
ui32 cword_val = 1;
|
||||||
|
const unsigned char *last_matchstart = last_destination_byte - UNCONDITIONAL_MATCHLEN - UNCOMPRESSED_END;
|
||||||
|
unsigned char *last_hashed = destination - 1;
|
||||||
|
const unsigned char *last_source_byte = source + qlz_size_compressed((const char *)source) - 1;
|
||||||
|
static const ui32 bitlut[16] = {4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
|
||||||
|
|
||||||
|
(void) last_source_byte;
|
||||||
|
(void) last_hashed;
|
||||||
|
(void) state;
|
||||||
|
(void) history;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
ui32 fetch;
|
||||||
|
|
||||||
|
if (cword_val == 1)
|
||||||
|
{
|
||||||
|
#ifdef QLZ_MEMORY_SAFE
|
||||||
|
if(src + CWORD_LEN - 1 > last_source_byte)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
cword_val = fast_read(src, CWORD_LEN);
|
||||||
|
src += CWORD_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef QLZ_MEMORY_SAFE
|
||||||
|
if(src + 4 - 1 > last_source_byte)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fetch = fast_read(src, 4);
|
||||||
|
|
||||||
|
if ((cword_val & 1) == 1)
|
||||||
|
{
|
||||||
|
ui32 matchlen;
|
||||||
|
const unsigned char *offset2;
|
||||||
|
|
||||||
|
#if QLZ_COMPRESSION_LEVEL == 1
|
||||||
|
ui32 hash;
|
||||||
|
cword_val = cword_val >> 1;
|
||||||
|
hash = (fetch >> 4) & 0xfff;
|
||||||
|
offset2 = (const unsigned char *)(size_t)state->hash[hash].offset;
|
||||||
|
|
||||||
|
if((fetch & 0xf) != 0)
|
||||||
|
{
|
||||||
|
matchlen = (fetch & 0xf) + 2;
|
||||||
|
src += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
matchlen = *(src + 2);
|
||||||
|
src += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL == 2
|
||||||
|
ui32 hash;
|
||||||
|
unsigned char c;
|
||||||
|
cword_val = cword_val >> 1;
|
||||||
|
hash = (fetch >> 5) & 0x7ff;
|
||||||
|
c = (unsigned char)(fetch & 0x3);
|
||||||
|
offset2 = state->hash[hash].offset[c];
|
||||||
|
|
||||||
|
if((fetch & (28)) != 0)
|
||||||
|
{
|
||||||
|
matchlen = ((fetch >> 2) & 0x7) + 2;
|
||||||
|
src += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
matchlen = *(src + 2);
|
||||||
|
src += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif QLZ_COMPRESSION_LEVEL == 3
|
||||||
|
ui32 offset;
|
||||||
|
cword_val = cword_val >> 1;
|
||||||
|
if ((fetch & 3) == 0)
|
||||||
|
{
|
||||||
|
offset = (fetch & 0xff) >> 2;
|
||||||
|
matchlen = 3;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
else if ((fetch & 2) == 0)
|
||||||
|
{
|
||||||
|
offset = (fetch & 0xffff) >> 2;
|
||||||
|
matchlen = 3;
|
||||||
|
src += 2;
|
||||||
|
}
|
||||||
|
else if ((fetch & 1) == 0)
|
||||||
|
{
|
||||||
|
offset = (fetch & 0xffff) >> 6;
|
||||||
|
matchlen = ((fetch >> 2) & 15) + 3;
|
||||||
|
src += 2;
|
||||||
|
}
|
||||||
|
else if ((fetch & 127) != 3)
|
||||||
|
{
|
||||||
|
offset = (fetch >> 7) & 0x1ffff;
|
||||||
|
matchlen = ((fetch >> 2) & 0x1f) + 2;
|
||||||
|
src += 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset = (fetch >> 15);
|
||||||
|
matchlen = ((fetch >> 7) & 255) + 3;
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset2 = dst - offset;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef QLZ_MEMORY_SAFE
|
||||||
|
if(offset2 < history || offset2 > dst - MINOFFSET - 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(matchlen > (ui32)(last_destination_byte - dst - UNCOMPRESSED_END + 1))
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memcpy_up(dst, offset2, matchlen);
|
||||||
|
dst += matchlen;
|
||||||
|
|
||||||
|
#if QLZ_COMPRESSION_LEVEL <= 2
|
||||||
|
update_hash_upto(state, &last_hashed, dst - matchlen);
|
||||||
|
last_hashed = dst - 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dst < last_matchstart)
|
||||||
|
{
|
||||||
|
unsigned int n = bitlut[cword_val & 0xf];
|
||||||
|
#ifdef X86X64
|
||||||
|
*(ui32 *)dst = *(ui32 *)src;
|
||||||
|
#else
|
||||||
|
memcpy_up(dst, src, 4);
|
||||||
|
#endif
|
||||||
|
cword_val = cword_val >> n;
|
||||||
|
dst += n;
|
||||||
|
src += n;
|
||||||
|
#if QLZ_COMPRESSION_LEVEL <= 2
|
||||||
|
update_hash_upto(state, &last_hashed, dst - 3);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(dst <= last_destination_byte)
|
||||||
|
{
|
||||||
|
if (cword_val == 1)
|
||||||
|
{
|
||||||
|
src += CWORD_LEN;
|
||||||
|
cword_val = 1U << 31;
|
||||||
|
}
|
||||||
|
#ifdef QLZ_MEMORY_SAFE
|
||||||
|
if(src >= last_source_byte + 1)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
*dst = *src;
|
||||||
|
dst++;
|
||||||
|
src++;
|
||||||
|
cword_val = cword_val >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QLZ_COMPRESSION_LEVEL <= 2
|
||||||
|
update_hash_upto(state, &last_hashed, last_destination_byte - 3); // todo, use constant
|
||||||
|
#endif
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t qlz_compress(const void *source, char *destination, size_t size, qlz_state_compress *state)
|
||||||
|
{
|
||||||
|
size_t r;
|
||||||
|
ui32 compressed;
|
||||||
|
size_t base;
|
||||||
|
|
||||||
|
if(size == 0 || size > 0xffffffff - 400)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(size < 216)
|
||||||
|
base = 3;
|
||||||
|
else
|
||||||
|
base = 9;
|
||||||
|
|
||||||
|
#if QLZ_STREAMING_BUFFER > 0
|
||||||
|
if (state->stream_counter + size - 1 >= QLZ_STREAMING_BUFFER)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
reset_table_compress(state);
|
||||||
|
r = base + qlz_compress_core((const unsigned char *)source, (unsigned char*)destination + base, size, state);
|
||||||
|
#if QLZ_STREAMING_BUFFER > 0
|
||||||
|
reset_table_compress(state);
|
||||||
|
#endif
|
||||||
|
if(r == base)
|
||||||
|
{
|
||||||
|
memcpy(destination + base, source, size);
|
||||||
|
r = size + base;
|
||||||
|
compressed = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
compressed = 1;
|
||||||
|
}
|
||||||
|
state->stream_counter = 0;
|
||||||
|
}
|
||||||
|
#if QLZ_STREAMING_BUFFER > 0
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char *src = state->stream_buffer + state->stream_counter;
|
||||||
|
|
||||||
|
memcpy(src, source, size);
|
||||||
|
r = base + qlz_compress_core(src, (unsigned char*)destination + base, size, state);
|
||||||
|
|
||||||
|
if(r == base)
|
||||||
|
{
|
||||||
|
memcpy(destination + base, src, size);
|
||||||
|
r = size + base;
|
||||||
|
compressed = 0;
|
||||||
|
reset_table_compress(state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
compressed = 1;
|
||||||
|
}
|
||||||
|
state->stream_counter += size;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(base == 3)
|
||||||
|
{
|
||||||
|
*destination = (unsigned char)(0 | compressed);
|
||||||
|
*(destination + 1) = (unsigned char)r;
|
||||||
|
*(destination + 2) = (unsigned char)size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*destination = (unsigned char)(2 | compressed);
|
||||||
|
fast_write((ui32)r, destination + 1, 4);
|
||||||
|
fast_write((ui32)size, destination + 5, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
*destination |= (QLZ_COMPRESSION_LEVEL << 2);
|
||||||
|
*destination |= (1 << 6);
|
||||||
|
*destination |= ((QLZ_STREAMING_BUFFER == 0 ? 0 : (QLZ_STREAMING_BUFFER == 100000 ? 1 : (QLZ_STREAMING_BUFFER == 1000000 ? 2 : 3))) << 4);
|
||||||
|
|
||||||
|
// 76543210
|
||||||
|
// 01SSLLHC
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t qlz_decompress(const char *source, void *destination, qlz_state_decompress *state)
|
||||||
|
{
|
||||||
|
size_t dsiz = qlz_size_decompressed(source);
|
||||||
|
|
||||||
|
#if QLZ_STREAMING_BUFFER > 0
|
||||||
|
if (state->stream_counter + qlz_size_decompressed(source) - 1 >= QLZ_STREAMING_BUFFER)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if((*source & 1) == 1)
|
||||||
|
{
|
||||||
|
reset_table_decompress(state);
|
||||||
|
dsiz = qlz_decompress_core((const unsigned char *)source, (unsigned char *)destination, dsiz, state, (const unsigned char *)destination);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(destination, source + qlz_size_header(source), dsiz);
|
||||||
|
}
|
||||||
|
state->stream_counter = 0;
|
||||||
|
reset_table_decompress(state);
|
||||||
|
}
|
||||||
|
#if QLZ_STREAMING_BUFFER > 0
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char *dst = state->stream_buffer + state->stream_counter;
|
||||||
|
if((*source & 1) == 1)
|
||||||
|
{
|
||||||
|
dsiz = qlz_decompress_core((const unsigned char *)source, dst, dsiz, state, (const unsigned char *)state->stream_buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(dst, source + qlz_size_header(source), dsiz);
|
||||||
|
reset_table_decompress(state);
|
||||||
|
}
|
||||||
|
memcpy(destination, dst, dsiz);
|
||||||
|
state->stream_counter += dsiz;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return dsiz;
|
||||||
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ static char keytranslation[SDL_NUM_SCANCODES];
|
||||||
static int32_t buildkeytranslationtable(void);
|
static int32_t buildkeytranslationtable(void);
|
||||||
|
|
||||||
//static SDL_Surface * loadtarga(const char *fn); // for loading the icon
|
//static SDL_Surface * loadtarga(const char *fn); // for loading the icon
|
||||||
static SDL_Surface * appicon;
|
static SDL_Surface * appicon = NULL;
|
||||||
static SDL_Surface * loadappicon(void);
|
static SDL_Surface * loadappicon(void);
|
||||||
|
|
||||||
int32_t wm_msgbox(char *name, char *fmt, ...)
|
int32_t wm_msgbox(char *name, char *fmt, ...)
|
||||||
|
@ -337,7 +337,10 @@ void uninitsystem(void)
|
||||||
uninittimer();
|
uninittimer();
|
||||||
|
|
||||||
if (appicon)
|
if (appicon)
|
||||||
|
{
|
||||||
SDL_FreeSurface(appicon);
|
SDL_FreeSurface(appicon);
|
||||||
|
appicon = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
|
|
|
@ -3405,6 +3405,8 @@ static int32_t SetupOpenGL(int32_t width, int32_t height, int32_t bitspp)
|
||||||
{
|
{
|
||||||
if (!Bstrcmp(glinfo.renderer,"Intel 865G"))
|
if (!Bstrcmp(glinfo.renderer,"Intel 865G"))
|
||||||
err = 0;
|
err = 0;
|
||||||
|
else if (!Bstrcmp(glinfo.renderer,"Intel 915G"))
|
||||||
|
err = 0;
|
||||||
else if (!Bstrcmp(glinfo.renderer,"Intel 945GM"))
|
else if (!Bstrcmp(glinfo.renderer,"Intel 945GM"))
|
||||||
err = 0;
|
err = 0;
|
||||||
else if (!Bstrcmp(glinfo.renderer,"Intel 965/963 Graphics Media Accelerator"))
|
else if (!Bstrcmp(glinfo.renderer,"Intel 965/963 Graphics Media Accelerator"))
|
||||||
|
|
|
@ -108,10 +108,6 @@
|
||||||
RelativePath=".\build\include\enet_mmulti.h"
|
RelativePath=".\build\include\enet_mmulti.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\build\include\fastlz.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\build\include\glbuild.h"
|
RelativePath=".\build\include\glbuild.h"
|
||||||
>
|
>
|
||||||
|
@ -152,10 +148,6 @@
|
||||||
RelativePath=".\build\include\mmulti_unstable.h"
|
RelativePath=".\build\include\mmulti_unstable.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\build\include\mmultimsgs.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\build\include\nedmalloc.h"
|
RelativePath=".\build\include\nedmalloc.h"
|
||||||
>
|
>
|
||||||
|
@ -184,6 +176,10 @@
|
||||||
RelativePath=".\build\include\pragmas.h"
|
RelativePath=".\build\include\pragmas.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\build\include\quicklz.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\build\include\scriptfile.h"
|
RelativePath=".\build\include\scriptfile.h"
|
||||||
>
|
>
|
||||||
|
@ -260,10 +256,6 @@
|
||||||
RelativePath=".\build\src\engine_priv.h"
|
RelativePath=".\build\src\engine_priv.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\build\src\fastlz.c"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\build\src\glbuild.c"
|
RelativePath=".\build\src\glbuild.c"
|
||||||
>
|
>
|
||||||
|
@ -316,6 +308,10 @@
|
||||||
RelativePath=".\build\src\pragmas.c"
|
RelativePath=".\build\src\pragmas.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\build\src\quicklz.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\build\src\scriptfile.c"
|
RelativePath=".\build\src\scriptfile.c"
|
||||||
>
|
>
|
||||||
|
@ -778,6 +774,86 @@
|
||||||
Name="Misc"
|
Name="Misc"
|
||||||
>
|
>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="enet"
|
||||||
|
>
|
||||||
|
<Filter
|
||||||
|
Name="source"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\src\callbacks.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\src\host.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\src\list.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\src\packet.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\src\peer.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\src\protocol.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\src\unix.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\src\win32.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="headers"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\include\enet\callbacks.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\include\enet\enet.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\include\enet\list.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\include\enet\protocol.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\include\enet\time.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\include\enet\types.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\include\enet\unix.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\include\enet\utility.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\source\enet\include\enet\win32.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Filter>
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
</Globals>
|
</Globals>
|
||||||
|
|
|
@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
extern int32_t g_numEnvSoundsPlaying;
|
extern int32_t g_numEnvSoundsPlaying;
|
||||||
extern int32_t g_noEnemies;
|
extern int32_t g_noEnemies;
|
||||||
|
extern int32_t ticrandomseed;
|
||||||
|
|
||||||
inline void G_UpdateInterpolations(void) //Stick at beginning of G_DoMoveThings
|
inline void G_UpdateInterpolations(void) //Stick at beginning of G_DoMoveThings
|
||||||
{
|
{
|
||||||
|
@ -4832,6 +4833,9 @@ static void G_MoveMisc(void) // STATNUM 5
|
||||||
ActorExtra[i].floorz = s->z = getflorzofslope(s->sectnum,s->x,s->y);
|
ActorExtra[i].floorz = s->z = getflorzofslope(s->sectnum,s->x,s->y);
|
||||||
else switch (DynamicTileMap[switchpicnum])
|
else switch (DynamicTileMap[switchpicnum])
|
||||||
{
|
{
|
||||||
|
case APLAYER__STATIC:
|
||||||
|
s->cstat = 32768;
|
||||||
|
goto BOLT;
|
||||||
case NEON1__STATIC:
|
case NEON1__STATIC:
|
||||||
case NEON2__STATIC:
|
case NEON2__STATIC:
|
||||||
case NEON3__STATIC:
|
case NEON3__STATIC:
|
||||||
|
@ -5670,7 +5674,7 @@ static void G_MoveEffectors(void) //STATNUM 3
|
||||||
m = (s->xvel*sintable[(s->ang+512)&2047])>>14;
|
m = (s->xvel*sintable[(s->ang+512)&2047])>>14;
|
||||||
x = (s->xvel*sintable[s->ang&2047])>>14;
|
x = (s->xvel*sintable[s->ang&2047])>>14;
|
||||||
|
|
||||||
for (p = connecthead; p >= 0; p=connectpoint2[p])
|
TRAVERSE_CONNECT(p)
|
||||||
if (sector[g_player[p].ps->cursectnum].lotag != 2)
|
if (sector[g_player[p].ps->cursectnum].lotag != 2)
|
||||||
{
|
{
|
||||||
if (g_playerSpawnPoints[p].os == s->sectnum)
|
if (g_playerSpawnPoints[p].os == s->sectnum)
|
||||||
|
@ -5849,7 +5853,7 @@ static void G_MoveEffectors(void) //STATNUM 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (p = connecthead; p >= 0; p = connectpoint2[p])
|
TRAVERSE_CONNECT(p)
|
||||||
{
|
{
|
||||||
if (sprite[g_player[p].ps->i].sectnum == s->sectnum)
|
if (sprite[g_player[p].ps->i].sectnum == s->sectnum)
|
||||||
{
|
{
|
||||||
|
@ -7135,7 +7139,7 @@ static void G_MoveEffectors(void) //STATNUM 3
|
||||||
fricyv += x<<5;
|
fricyv += x<<5;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (p = connecthead; p >= 0; p = connectpoint2[p])
|
TRAVERSE_CONNECT(p)
|
||||||
if (sprite[g_player[p].ps->i].sectnum == s->sectnum && g_player[p].ps->on_ground)
|
if (sprite[g_player[p].ps->i].sectnum == s->sectnum && g_player[p].ps->on_ground)
|
||||||
g_player[p].ps->posz += s->zvel;
|
g_player[p].ps->posz += s->zvel;
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "fx_man.h"
|
#include "fx_man.h"
|
||||||
|
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "fastlz.h"
|
#include "quicklz.h"
|
||||||
|
|
||||||
#include "m32script.h"
|
#include "m32script.h"
|
||||||
#include "m32def.h"
|
#include "m32def.h"
|
||||||
|
@ -244,8 +244,8 @@ void create_map_snapshot(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mapstate->sectors = (sectortype *)Bcalloc(1, sizeof(sectortype) * numsectors);
|
mapstate->sectors = (sectortype *)Bcalloc(1, sizeof(sectortype) * numsectors);
|
||||||
mapstate->sectsiz = j = fastlz_compress(§or[0], sizeof(sectortype) * numsectors,
|
mapstate->sectsiz = j = qlz_compress(§or[0], (char *)&mapstate->sectors[0],
|
||||||
&mapstate->sectors[0]/*, sizeof(sectortype) * numsectors*/);
|
sizeof(sectortype) * numsectors, state_compress);
|
||||||
mapstate->sectors = (sectortype *)Brealloc(mapstate->sectors, j);
|
mapstate->sectors = (sectortype *)Brealloc(mapstate->sectors, j);
|
||||||
mapstate->sectcrc = tempcrc;
|
mapstate->sectcrc = tempcrc;
|
||||||
}
|
}
|
||||||
|
@ -265,8 +265,8 @@ void create_map_snapshot(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mapstate->walls = (walltype *)Bcalloc(1, sizeof(walltype) * numwalls);
|
mapstate->walls = (walltype *)Bcalloc(1, sizeof(walltype) * numwalls);
|
||||||
mapstate->wallsiz = j = fastlz_compress(&wall[0], sizeof(walltype) * numwalls,
|
mapstate->wallsiz = j = qlz_compress(&wall[0], (char *)&mapstate->walls[0],
|
||||||
&mapstate->walls[0]/*, sizeof(walltype) * numwalls*/);
|
sizeof(walltype) * numwalls, state_compress);
|
||||||
mapstate->walls = (walltype *)Brealloc(mapstate->walls, j);
|
mapstate->walls = (walltype *)Brealloc(mapstate->walls, j);
|
||||||
mapstate->wallcrc = tempcrc;
|
mapstate->wallcrc = tempcrc;
|
||||||
}
|
}
|
||||||
|
@ -298,8 +298,8 @@ void create_map_snapshot(void)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mapstate->spritesiz = j = fastlz_compress(&tspri[0], sizeof(spritetype) * numsprites,
|
mapstate->spritesiz = j = qlz_compress(&tspri[0], (char *)&mapstate->sprites[0],
|
||||||
&mapstate->sprites[0]/*, sizeof(spritetype) * numsprites*/);
|
sizeof(spritetype) * numsprites, state_compress);
|
||||||
mapstate->sprites = (spritetype *)Brealloc(mapstate->sprites, j);
|
mapstate->sprites = (spritetype *)Brealloc(mapstate->sprites, j);
|
||||||
mapstate->spritecrc = tempcrc;
|
mapstate->spritecrc = tempcrc;
|
||||||
Bfree(tspri);
|
Bfree(tspri);
|
||||||
|
@ -370,13 +370,13 @@ int32_t map_undoredo(int32_t dir)
|
||||||
|
|
||||||
if (mapstate->numsectors)
|
if (mapstate->numsectors)
|
||||||
{
|
{
|
||||||
fastlz_decompress(&mapstate->sectors[0], mapstate->sectsiz, §or[0], sizeof(sectortype) * numsectors);
|
qlz_decompress((const char *)&mapstate->sectors[0], §or[0], state_decompress);
|
||||||
|
|
||||||
if (mapstate->numwalls)
|
if (mapstate->numwalls)
|
||||||
fastlz_decompress(&mapstate->walls[0], mapstate->wallsiz, &wall[0], sizeof(walltype) * numwalls);
|
qlz_decompress((const char *)&mapstate->walls[0], &wall[0], state_decompress);
|
||||||
|
|
||||||
if (mapstate->numsprites)
|
if (mapstate->numsprites)
|
||||||
fastlz_decompress(&mapstate->sprites[0], mapstate->spritesiz, &sprite[0], sizeof(spritetype) * numsprites);
|
qlz_decompress((const char *)&mapstate->sprites[0], &sprite[0], state_decompress);
|
||||||
}
|
}
|
||||||
|
|
||||||
updatenumsprites();
|
updatenumsprites();
|
||||||
|
|
|
@ -47,6 +47,12 @@ extern "C" {
|
||||||
|
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
|
||||||
|
#include "enet/enet.h"
|
||||||
|
|
||||||
|
extern ENetHost * net_server;
|
||||||
|
extern ENetHost * net_client;
|
||||||
|
extern ENetPeer * net_peer;
|
||||||
|
|
||||||
#define APPNAME "EDuke32"
|
#define APPNAME "EDuke32"
|
||||||
#define VERSION " 2.0.0devel"
|
#define VERSION " 2.0.0devel"
|
||||||
// this is checked against http://eduke32.com/VERSION
|
// this is checked against http://eduke32.com/VERSION
|
||||||
|
@ -83,7 +89,7 @@ extern int32_t g_scriptVersion, g_Shareware, g_gameType;
|
||||||
|
|
||||||
#define AUTO_AIM_ANGLE 48
|
#define AUTO_AIM_ANGLE 48
|
||||||
#define RECSYNCBUFSIZ 2520 //2520 is the (LCM of 1-8)*3
|
#define RECSYNCBUFSIZ 2520 //2520 is the (LCM of 1-8)*3
|
||||||
#define MOVEFIFOSIZ 256
|
#define MOVEFIFOSIZ 2
|
||||||
|
|
||||||
#define FOURSLEIGHT (1<<8)
|
#define FOURSLEIGHT (1<<8)
|
||||||
|
|
||||||
|
@ -422,9 +428,9 @@ extern int32_t fricxv,fricyv;
|
||||||
// mywhatever type globals
|
// mywhatever type globals
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t posx, posy, posz, horiz, ohoriz, ohorizoff, invdisptime;
|
int32_t posx, posy, posz, oposx, oposy, oposz, posxv, posyv, poszv;
|
||||||
int32_t bobposx, bobposy, oposx, oposy, oposz, pyoff, opyoff;
|
int32_t bobposx, bobposy, pyoff, opyoff, horiz, ohoriz, ohorizoff, invdisptime;
|
||||||
int32_t posxv, posyv, poszv, last_pissed_time, truefz, truecz;
|
int32_t last_pissed_time, truefz, truecz;
|
||||||
int32_t player_par, visibility;
|
int32_t player_par, visibility;
|
||||||
int32_t bobcounter, weapon_sway;
|
int32_t bobcounter, weapon_sway;
|
||||||
int32_t pals_time, randomflamex, crack_time;
|
int32_t pals_time, randomflamex, crack_time;
|
||||||
|
@ -485,7 +491,7 @@ typedef struct {
|
||||||
char name[32];
|
char name[32];
|
||||||
} DukePlayer_t;
|
} DukePlayer_t;
|
||||||
|
|
||||||
extern char tempbuf[2048], packbuf[576], menutextbuf[128];
|
extern char tempbuf[2048], packbuf[4096], menutextbuf[128];
|
||||||
|
|
||||||
extern int32_t g_spriteGravity;
|
extern int32_t g_spriteGravity;
|
||||||
|
|
||||||
|
@ -559,9 +565,9 @@ typedef struct {
|
||||||
void *lightptr;
|
void *lightptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int8_t filler[16]; // pad struct to 128 bytes
|
|
||||||
|
|
||||||
projectile_t *projectile; //4b/8b
|
projectile_t *projectile; //4b/8b
|
||||||
|
|
||||||
|
int8_t filler[16]; // pad struct to 128 bytes
|
||||||
} ActorData_t;
|
} ActorData_t;
|
||||||
|
|
||||||
extern ActorData_t ActorExtra[MAXSPRITES];
|
extern ActorData_t ActorExtra[MAXSPRITES];
|
||||||
|
@ -638,8 +644,6 @@ extern char boardfilename[BMAX_PATH];
|
||||||
extern uint8_t waterpal[768],slimepal[768],titlepal[768],drealms[768],endingpal[768],animpal[768];
|
extern uint8_t waterpal[768],slimepal[768],titlepal[768],drealms[768],endingpal[768],animpal[768];
|
||||||
extern char currentboardfilename[BMAX_PATH];
|
extern char currentboardfilename[BMAX_PATH];
|
||||||
extern char cachedebug,g_earthquakeTime;
|
extern char cachedebug,g_earthquakeTime;
|
||||||
// 0: master/slave, 1: peer-to-peer
|
|
||||||
extern int32_t g_networkBroadcastMode;
|
|
||||||
extern char lumplockbyte[11];
|
extern char lumplockbyte[11];
|
||||||
|
|
||||||
//DUKE3D.H - replace the end "my's" with this
|
//DUKE3D.H - replace the end "my's" with this
|
||||||
|
@ -670,7 +674,6 @@ typedef struct {
|
||||||
|
|
||||||
extern DukeStatus_t sbar;
|
extern DukeStatus_t sbar;
|
||||||
extern int32_t g_cameraDistance, g_cameraClock, g_playerFriction,g_showShareware;
|
extern int32_t g_cameraDistance, g_cameraClock, g_playerFriction,g_showShareware;
|
||||||
extern int32_t g_networkBroadcastMode, g_movesPerPacket;
|
|
||||||
extern int32_t g_gameQuit;
|
extern int32_t g_gameQuit;
|
||||||
|
|
||||||
extern int32_t playerswhenstarted;
|
extern int32_t playerswhenstarted;
|
||||||
|
@ -1042,6 +1045,9 @@ typedef struct {
|
||||||
walltype wall[MAXWALLS];
|
walltype wall[MAXWALLS];
|
||||||
} mapstate_t;
|
} mapstate_t;
|
||||||
|
|
||||||
|
extern void G_SaveMapState(mapstate_t *save);
|
||||||
|
extern void G_RestoreMapState(mapstate_t *save);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t partime, designertime;
|
int32_t partime, designertime;
|
||||||
char *name, *filename, *musicfn, *alt_musicfn;
|
char *name, *filename, *musicfn, *alt_musicfn;
|
||||||
|
@ -1088,12 +1094,13 @@ enum DukePacket_t
|
||||||
{
|
{
|
||||||
PACKET_MASTER_TO_SLAVE,
|
PACKET_MASTER_TO_SLAVE,
|
||||||
PACKET_SLAVE_TO_MASTER,
|
PACKET_SLAVE_TO_MASTER,
|
||||||
PACKET_BROADCAST,
|
|
||||||
SERVER_GENERATED_BROADCAST,
|
|
||||||
PACKET_VERSION,
|
PACKET_VERSION,
|
||||||
|
|
||||||
/* don't change anything above this line */
|
/* don't change anything above this line */
|
||||||
|
|
||||||
|
PACKET_NUM_PLAYERS,
|
||||||
|
PACKET_PLAYER_INDEX,
|
||||||
|
PACKET_PLAYER_DISCONNECTED,
|
||||||
PACKET_MESSAGE,
|
PACKET_MESSAGE,
|
||||||
|
|
||||||
PACKET_NEW_GAME,
|
PACKET_NEW_GAME,
|
||||||
|
@ -1103,6 +1110,7 @@ enum DukePacket_t
|
||||||
PACKET_PLAYER_OPTIONS,
|
PACKET_PLAYER_OPTIONS,
|
||||||
PACKET_PLAYER_NAME,
|
PACKET_PLAYER_NAME,
|
||||||
|
|
||||||
|
PACKET_REQUEST_GAMESTATE,
|
||||||
PACKET_USER_MAP,
|
PACKET_USER_MAP,
|
||||||
|
|
||||||
PACKET_MAP_VOTE,
|
PACKET_MAP_VOTE,
|
||||||
|
|
60
polymer/eduke32/source/enet/Makefile
Normal file
60
polymer/eduke32/source/enet/Makefile
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
CC=gcc
|
||||||
|
OBJ=obj
|
||||||
|
OBJNAME?=libenet.a
|
||||||
|
PRETTY_OUTPUT?=1
|
||||||
|
EROOT?=build
|
||||||
|
RELEASE?=1
|
||||||
|
OPTLEVEL?=2
|
||||||
|
SRC=src
|
||||||
|
|
||||||
|
include ../../$(EROOT)/Makefile.shared
|
||||||
|
|
||||||
|
ifneq (0,$(RELEASE))
|
||||||
|
# Debugging disabled
|
||||||
|
debug=-fomit-frame-pointer -funswitch-loops -O$(OPTLEVEL)
|
||||||
|
else
|
||||||
|
# Debugging enabled
|
||||||
|
debug=-ggdb -O0 -DDEBUGGINGAIDS
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq (0,$(DEBUGANYWAY))
|
||||||
|
debug+=-ggdb
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS=$(debug) -W -Wall -Wimplicit -Werror-implicit-function-declaration \
|
||||||
|
-funsigned-char -fno-strict-aliasing -DNO_GCC_BUILTINS -D_FORTIFY_SOURCE=2 \
|
||||||
|
-fjump-tables -fno-stack-protector
|
||||||
|
|
||||||
|
CPPFLAGS=-Iinclude -Isrc -DHAVE_VORBIS
|
||||||
|
|
||||||
|
OBJECTS=$(OBJ)/callbacks.o \
|
||||||
|
$(OBJ)/host.o \
|
||||||
|
$(OBJ)/list.o \
|
||||||
|
$(OBJ)/packet.o \
|
||||||
|
$(OBJ)/peer.o \
|
||||||
|
$(OBJ)/protocol.o
|
||||||
|
|
||||||
|
ifeq ($(PLATFORM),WINDOWS)
|
||||||
|
OBJECTS+= $(OBJ)/win32.o
|
||||||
|
OBJNAME=libenet_win32.a
|
||||||
|
OBJ=obj_win
|
||||||
|
else
|
||||||
|
OBJECTS+= $(OBJ)/unix.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
# OBJECTS=$(SOURCES:%.c=$(OBJ)/%.o)
|
||||||
|
|
||||||
|
$(OBJNAME): $(OBJECTS)
|
||||||
|
$(AR) cr $@ $^
|
||||||
|
|
||||||
|
$(OBJECTS): $(OBJ)/%.o: $(SRC)/%.c
|
||||||
|
-mkdir -p $(OBJ)
|
||||||
|
$(COMPILE_STATUS)
|
||||||
|
if $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@; then $(COMPILE_OK); else $(COMPILE_FAILED); fi
|
||||||
|
|
||||||
|
ifeq ($(PRETTY_OUTPUT),1)
|
||||||
|
.SILENT:
|
||||||
|
endif
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
-rm -f $(OBJECTS) $(OBJNAME)
|
45
polymer/eduke32/source/enet/Makefile.msvc
Normal file
45
polymer/eduke32/source/enet/Makefile.msvc
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
OBJ=obj.msc
|
||||||
|
INC=include
|
||||||
|
SRC=src
|
||||||
|
ENETLIB=libenet.lib
|
||||||
|
|
||||||
|
!ifdef DEBUG
|
||||||
|
# debugging options
|
||||||
|
flags_cl=/Od /Zi
|
||||||
|
flags_link=/DEBUG
|
||||||
|
flags_lib=
|
||||||
|
!else
|
||||||
|
# release options
|
||||||
|
flags_cl=/Ox /GL /arch:SSE
|
||||||
|
flags_link=/RELEASE /LTCG
|
||||||
|
flags_lib=/LTCG
|
||||||
|
!endif
|
||||||
|
|
||||||
|
CC=cl
|
||||||
|
LINK=link /opt:ref /nologo
|
||||||
|
|
||||||
|
CFLAGS=$(CFLAGS) /nologo /MT /J $(flags_cl) $(TARGETOPTS) /I$(INC) /I$(SRC)
|
||||||
|
!ifdef DEBUG
|
||||||
|
CFLAGS=$(CFLAGS) /DDEBUGGINGAIDS
|
||||||
|
!endif
|
||||||
|
|
||||||
|
CFLAGS=$(CFLAGS) /DRENDERTYPE$(RENDERTYPE)=1 /D "_CRT_SECURE_NO_DEPRECATE" /W2 /DHAVE_VORBIS /Iinclude/msvc /DWIN32
|
||||||
|
|
||||||
|
OBJECTS=$(OBJ)\callbacks.o \
|
||||||
|
$(OBJ)\host.o \
|
||||||
|
$(OBJ)\list.o \
|
||||||
|
$(OBJ)\packet.o \
|
||||||
|
$(OBJ)\peer.o \
|
||||||
|
$(OBJ)\protocol.o \
|
||||||
|
$(OBJ)\win32.o
|
||||||
|
|
||||||
|
{$(SRC)}.c{$(OBJ)}.o:
|
||||||
|
$(CC) /c $(CFLAGS) /Fo$@ $<
|
||||||
|
|
||||||
|
enet: $(ENETLIB)
|
||||||
|
$(ENETLIB): $(OBJECTS)
|
||||||
|
lib $(flags_lib) /out:$@ /nologo $**
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-del /Q $(OBJ)\* $(ENETLIB)
|
||||||
|
|
28
polymer/eduke32/source/enet/include/enet/callbacks.h
Normal file
28
polymer/eduke32/source/enet/include/enet/callbacks.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
@file callbacks.h
|
||||||
|
@brief ENet callbacks
|
||||||
|
*/
|
||||||
|
#ifndef __ENET_CALLBACKS_H__
|
||||||
|
#define __ENET_CALLBACKS_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void * (ENET_CALLBACK * malloc) (size_t size);
|
||||||
|
void (ENET_CALLBACK * free) (void * memory);
|
||||||
|
int (ENET_CALLBACK * rand) (void);
|
||||||
|
} ENetCallbacks;
|
||||||
|
|
||||||
|
/** @defgroup callbacks ENet internal callbacks
|
||||||
|
@{
|
||||||
|
@ingroup private
|
||||||
|
*/
|
||||||
|
extern void * enet_malloc (size_t);
|
||||||
|
extern void enet_free (void *);
|
||||||
|
extern int enet_rand (void);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* __ENET_CALLBACKS_H__ */
|
||||||
|
|
492
polymer/eduke32/source/enet/include/enet/enet.h
Normal file
492
polymer/eduke32/source/enet/include/enet/enet.h
Normal file
|
@ -0,0 +1,492 @@
|
||||||
|
/**
|
||||||
|
@file enet.h
|
||||||
|
@brief ENet public header file
|
||||||
|
*/
|
||||||
|
#ifndef __ENET_ENET_H__
|
||||||
|
#define __ENET_ENET_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "enet/win32.h"
|
||||||
|
#else
|
||||||
|
#include "enet/unix.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "enet/types.h"
|
||||||
|
#include "enet/protocol.h"
|
||||||
|
#include "enet/list.h"
|
||||||
|
#include "enet/callbacks.h"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ENET_VERSION = 1
|
||||||
|
} ENetVersion;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ENET_SOCKET_TYPE_STREAM = 1,
|
||||||
|
ENET_SOCKET_TYPE_DATAGRAM = 2
|
||||||
|
} ENetSocketType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ENET_SOCKET_WAIT_NONE = 0,
|
||||||
|
ENET_SOCKET_WAIT_SEND = (1 << 0),
|
||||||
|
ENET_SOCKET_WAIT_RECEIVE = (1 << 1)
|
||||||
|
} ENetSocketWait;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ENET_SOCKOPT_NONBLOCK = 1,
|
||||||
|
ENET_SOCKOPT_BROADCAST = 2,
|
||||||
|
ENET_SOCKOPT_RCVBUF = 3,
|
||||||
|
ENET_SOCKOPT_SNDBUF = 4,
|
||||||
|
ENET_SOCKOPT_REUSEADDR = 5
|
||||||
|
} ENetSocketOption;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ENET_HOST_ANY = 0, /**< specifies the default server host */
|
||||||
|
ENET_HOST_BROADCAST = 0xFFFFFFFF, /**< specifies a subnet-wide broadcast */
|
||||||
|
|
||||||
|
ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Portable internet address structure.
|
||||||
|
*
|
||||||
|
* The host must be specified in network byte-order, and the port must be in host
|
||||||
|
* byte-order. The constant ENET_HOST_ANY may be used to specify the default
|
||||||
|
* server host. The constant ENET_HOST_BROADCAST may be used to specify the
|
||||||
|
* broadcast address (255.255.255.255). This makes sense for enet_host_connect,
|
||||||
|
* but not for enet_host_create. Once a server responds to a broadcast, the
|
||||||
|
* address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
|
||||||
|
*/
|
||||||
|
typedef struct _ENetAddress
|
||||||
|
{
|
||||||
|
enet_uint32 host;
|
||||||
|
enet_uint16 port;
|
||||||
|
} ENetAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet flag bit constants.
|
||||||
|
*
|
||||||
|
* The host must be specified in network byte-order, and the port must be in
|
||||||
|
* host byte-order. The constant ENET_HOST_ANY may be used to specify the
|
||||||
|
* default server host.
|
||||||
|
|
||||||
|
@sa ENetPacket
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/** packet must be received by the target peer and resend attempts should be
|
||||||
|
* made until the packet is delivered */
|
||||||
|
ENET_PACKET_FLAG_RELIABLE = (1 << 0),
|
||||||
|
/** packet will not be sequenced with other packets
|
||||||
|
* not supported for reliable packets
|
||||||
|
*/
|
||||||
|
ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
|
||||||
|
/** packet will not allocate data, and user must supply it instead */
|
||||||
|
ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2)
|
||||||
|
} ENetPacketFlag;
|
||||||
|
|
||||||
|
struct _ENetPacket;
|
||||||
|
typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ENet packet structure.
|
||||||
|
*
|
||||||
|
* An ENet data packet that may be sent to or received from a peer. The shown
|
||||||
|
* fields should only be read and never modified. The data field contains the
|
||||||
|
* allocated data for the packet. The dataLength fields specifies the length
|
||||||
|
* of the allocated data. The flags field is either 0 (specifying no flags),
|
||||||
|
* or a bitwise-or of any combination of the following flags:
|
||||||
|
*
|
||||||
|
* ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer
|
||||||
|
* and resend attempts should be made until the packet is delivered
|
||||||
|
*
|
||||||
|
* ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets
|
||||||
|
* (not supported for reliable packets)
|
||||||
|
*
|
||||||
|
* ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
|
||||||
|
|
||||||
|
@sa ENetPacketFlag
|
||||||
|
*/
|
||||||
|
typedef struct _ENetPacket
|
||||||
|
{
|
||||||
|
size_t referenceCount; /**< internal use only */
|
||||||
|
enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */
|
||||||
|
enet_uint8 * data; /**< allocated data for packet */
|
||||||
|
size_t dataLength; /**< length of data */
|
||||||
|
ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */
|
||||||
|
} ENetPacket;
|
||||||
|
|
||||||
|
typedef struct _ENetAcknowledgement
|
||||||
|
{
|
||||||
|
ENetListNode acknowledgementList;
|
||||||
|
enet_uint32 sentTime;
|
||||||
|
ENetProtocol command;
|
||||||
|
} ENetAcknowledgement;
|
||||||
|
|
||||||
|
typedef struct _ENetOutgoingCommand
|
||||||
|
{
|
||||||
|
ENetListNode outgoingCommandList;
|
||||||
|
enet_uint16 reliableSequenceNumber;
|
||||||
|
enet_uint16 unreliableSequenceNumber;
|
||||||
|
enet_uint32 sentTime;
|
||||||
|
enet_uint32 roundTripTimeout;
|
||||||
|
enet_uint32 roundTripTimeoutLimit;
|
||||||
|
enet_uint32 fragmentOffset;
|
||||||
|
enet_uint16 fragmentLength;
|
||||||
|
enet_uint16 sendAttempts;
|
||||||
|
ENetProtocol command;
|
||||||
|
ENetPacket * packet;
|
||||||
|
} ENetOutgoingCommand;
|
||||||
|
|
||||||
|
typedef struct _ENetIncomingCommand
|
||||||
|
{
|
||||||
|
ENetListNode incomingCommandList;
|
||||||
|
enet_uint16 reliableSequenceNumber;
|
||||||
|
enet_uint16 unreliableSequenceNumber;
|
||||||
|
ENetProtocol command;
|
||||||
|
enet_uint32 fragmentCount;
|
||||||
|
enet_uint32 fragmentsRemaining;
|
||||||
|
enet_uint32 * fragments;
|
||||||
|
ENetPacket * packet;
|
||||||
|
} ENetIncomingCommand;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ENET_PEER_STATE_DISCONNECTED = 0,
|
||||||
|
ENET_PEER_STATE_CONNECTING = 1,
|
||||||
|
ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2,
|
||||||
|
ENET_PEER_STATE_CONNECTION_PENDING = 3,
|
||||||
|
ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4,
|
||||||
|
ENET_PEER_STATE_CONNECTED = 5,
|
||||||
|
ENET_PEER_STATE_DISCONNECT_LATER = 6,
|
||||||
|
ENET_PEER_STATE_DISCONNECTING = 7,
|
||||||
|
ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8,
|
||||||
|
ENET_PEER_STATE_ZOMBIE = 9
|
||||||
|
} ENetPeerState;
|
||||||
|
|
||||||
|
#ifndef ENET_BUFFER_MAXIMUM
|
||||||
|
#define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
|
||||||
|
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
|
||||||
|
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
|
||||||
|
ENET_HOST_DEFAULT_MTU = 1400,
|
||||||
|
|
||||||
|
ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500,
|
||||||
|
ENET_PEER_DEFAULT_PACKET_THROTTLE = 32,
|
||||||
|
ENET_PEER_PACKET_THROTTLE_SCALE = 32,
|
||||||
|
ENET_PEER_PACKET_THROTTLE_COUNTER = 7,
|
||||||
|
ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2,
|
||||||
|
ENET_PEER_PACKET_THROTTLE_DECELERATION = 2,
|
||||||
|
ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000,
|
||||||
|
ENET_PEER_PACKET_LOSS_SCALE = (1 << 16),
|
||||||
|
ENET_PEER_PACKET_LOSS_INTERVAL = 10000,
|
||||||
|
ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024,
|
||||||
|
ENET_PEER_TIMEOUT_LIMIT = 32,
|
||||||
|
ENET_PEER_TIMEOUT_MINIMUM = 5000,
|
||||||
|
ENET_PEER_TIMEOUT_MAXIMUM = 30000,
|
||||||
|
ENET_PEER_PING_INTERVAL = 500,
|
||||||
|
ENET_PEER_UNSEQUENCED_WINDOWS = 64,
|
||||||
|
ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 1024,
|
||||||
|
ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32,
|
||||||
|
ENET_PEER_RELIABLE_WINDOWS = 16,
|
||||||
|
ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000,
|
||||||
|
ENET_PEER_FREE_RELIABLE_WINDOWS = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _ENetChannel
|
||||||
|
{
|
||||||
|
enet_uint16 outgoingReliableSequenceNumber;
|
||||||
|
enet_uint16 outgoingUnreliableSequenceNumber;
|
||||||
|
enet_uint16 usedReliableWindows;
|
||||||
|
enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS];
|
||||||
|
enet_uint16 incomingReliableSequenceNumber;
|
||||||
|
ENetList incomingReliableCommands;
|
||||||
|
ENetList incomingUnreliableCommands;
|
||||||
|
} ENetChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ENet peer which data packets may be sent or received from.
|
||||||
|
*
|
||||||
|
* No fields should be modified unless otherwise specified.
|
||||||
|
*/
|
||||||
|
typedef struct _ENetPeer
|
||||||
|
{
|
||||||
|
struct _ENetHost * host;
|
||||||
|
enet_uint16 outgoingPeerID;
|
||||||
|
enet_uint16 incomingPeerID;
|
||||||
|
enet_uint32 sessionID;
|
||||||
|
ENetAddress address; /**< Internet address of the peer */
|
||||||
|
void * data; /**< Application private data, may be freely modified */
|
||||||
|
ENetPeerState state;
|
||||||
|
ENetChannel * channels;
|
||||||
|
size_t channelCount; /**< Number of channels allocated for communication with peer */
|
||||||
|
enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */
|
||||||
|
enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */
|
||||||
|
enet_uint32 incomingBandwidthThrottleEpoch;
|
||||||
|
enet_uint32 outgoingBandwidthThrottleEpoch;
|
||||||
|
enet_uint32 incomingDataTotal;
|
||||||
|
enet_uint32 outgoingDataTotal;
|
||||||
|
enet_uint32 lastSendTime;
|
||||||
|
enet_uint32 lastReceiveTime;
|
||||||
|
enet_uint32 nextTimeout;
|
||||||
|
enet_uint32 earliestTimeout;
|
||||||
|
enet_uint32 packetLossEpoch;
|
||||||
|
enet_uint32 packetsSent;
|
||||||
|
enet_uint32 packetsLost;
|
||||||
|
enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
|
||||||
|
enet_uint32 packetLossVariance;
|
||||||
|
enet_uint32 packetThrottle;
|
||||||
|
enet_uint32 packetThrottleLimit;
|
||||||
|
enet_uint32 packetThrottleCounter;
|
||||||
|
enet_uint32 packetThrottleEpoch;
|
||||||
|
enet_uint32 packetThrottleAcceleration;
|
||||||
|
enet_uint32 packetThrottleDeceleration;
|
||||||
|
enet_uint32 packetThrottleInterval;
|
||||||
|
enet_uint32 lastRoundTripTime;
|
||||||
|
enet_uint32 lowestRoundTripTime;
|
||||||
|
enet_uint32 lastRoundTripTimeVariance;
|
||||||
|
enet_uint32 highestRoundTripTimeVariance;
|
||||||
|
enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */
|
||||||
|
enet_uint32 roundTripTimeVariance;
|
||||||
|
enet_uint16 mtu;
|
||||||
|
enet_uint32 windowSize;
|
||||||
|
enet_uint32 reliableDataInTransit;
|
||||||
|
enet_uint16 outgoingReliableSequenceNumber;
|
||||||
|
ENetList acknowledgements;
|
||||||
|
ENetList sentReliableCommands;
|
||||||
|
ENetList sentUnreliableCommands;
|
||||||
|
ENetList outgoingReliableCommands;
|
||||||
|
ENetList outgoingUnreliableCommands;
|
||||||
|
enet_uint16 incomingUnsequencedGroup;
|
||||||
|
enet_uint16 outgoingUnsequencedGroup;
|
||||||
|
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
|
||||||
|
enet_uint32 disconnectData;
|
||||||
|
} ENetPeer;
|
||||||
|
|
||||||
|
/** An ENet host for communicating with peers.
|
||||||
|
*
|
||||||
|
* No fields should be modified.
|
||||||
|
|
||||||
|
@sa enet_host_create()
|
||||||
|
@sa enet_host_destroy()
|
||||||
|
@sa enet_host_connect()
|
||||||
|
@sa enet_host_service()
|
||||||
|
@sa enet_host_flush()
|
||||||
|
@sa enet_host_broadcast()
|
||||||
|
@sa enet_host_bandwidth_limit()
|
||||||
|
@sa enet_host_bandwidth_throttle()
|
||||||
|
*/
|
||||||
|
typedef struct _ENetHost
|
||||||
|
{
|
||||||
|
ENetSocket socket;
|
||||||
|
ENetAddress address; /**< Internet address of the host */
|
||||||
|
enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */
|
||||||
|
enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */
|
||||||
|
enet_uint32 bandwidthThrottleEpoch;
|
||||||
|
enet_uint32 mtu;
|
||||||
|
int recalculateBandwidthLimits;
|
||||||
|
ENetPeer * peers; /**< array of peers allocated for this host */
|
||||||
|
size_t peerCount; /**< number of peers allocated for this host */
|
||||||
|
enet_uint32 serviceTime;
|
||||||
|
ENetPeer * lastServicedPeer;
|
||||||
|
int continueSending;
|
||||||
|
size_t packetSize;
|
||||||
|
enet_uint16 headerFlags;
|
||||||
|
ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
|
||||||
|
size_t commandCount;
|
||||||
|
ENetBuffer buffers [ENET_BUFFER_MAXIMUM];
|
||||||
|
size_t bufferCount;
|
||||||
|
ENetAddress receivedAddress;
|
||||||
|
enet_uint8 receivedData [ENET_PROTOCOL_MAXIMUM_MTU];
|
||||||
|
size_t receivedDataLength;
|
||||||
|
} ENetHost;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ENet event type, as specified in @ref ENetEvent.
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/** no event occurred within the specified time limit */
|
||||||
|
ENET_EVENT_TYPE_NONE = 0,
|
||||||
|
|
||||||
|
/** a connection request initiated by enet_host_connect has completed.
|
||||||
|
* The peer field contains the peer which successfully connected.
|
||||||
|
*/
|
||||||
|
ENET_EVENT_TYPE_CONNECT = 1,
|
||||||
|
|
||||||
|
/** a peer has disconnected. This event is generated on a successful
|
||||||
|
* completion of a disconnect initiated by enet_pper_disconnect, if
|
||||||
|
* a peer has timed out, or if a connection request intialized by
|
||||||
|
* enet_host_connect has timed out. The peer field contains the peer
|
||||||
|
* which disconnected. The data field contains user supplied data
|
||||||
|
* describing the disconnection, or 0, if none is available.
|
||||||
|
*/
|
||||||
|
ENET_EVENT_TYPE_DISCONNECT = 2,
|
||||||
|
|
||||||
|
/** a packet has been received from a peer. The peer field specifies the
|
||||||
|
* peer which sent the packet. The channelID field specifies the channel
|
||||||
|
* number upon which the packet was received. The packet field contains
|
||||||
|
* the packet that was received; this packet must be destroyed with
|
||||||
|
* enet_packet_destroy after use.
|
||||||
|
*/
|
||||||
|
ENET_EVENT_TYPE_RECEIVE = 3
|
||||||
|
} ENetEventType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ENet event as returned by enet_host_service().
|
||||||
|
|
||||||
|
@sa enet_host_service
|
||||||
|
*/
|
||||||
|
typedef struct _ENetEvent
|
||||||
|
{
|
||||||
|
ENetEventType type; /**< type of the event */
|
||||||
|
ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */
|
||||||
|
enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */
|
||||||
|
enet_uint32 data; /**< data associated with the event, if appropriate */
|
||||||
|
ENetPacket * packet; /**< packet associated with the event, if appropriate */
|
||||||
|
} ENetEvent;
|
||||||
|
|
||||||
|
/** @defgroup global ENet global functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes ENet globally. Must be called prior to using any functions in
|
||||||
|
ENet.
|
||||||
|
@returns 0 on success, < 0 on failure
|
||||||
|
*/
|
||||||
|
ENET_API int enet_initialize (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant.
|
||||||
|
|
||||||
|
@param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use
|
||||||
|
@param inits user-overriden callbacks where any NULL callbacks will use ENet's defaults
|
||||||
|
@returns 0 on success, < 0 on failure
|
||||||
|
*/
|
||||||
|
ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Shuts down ENet globally. Should be called when a program that has
|
||||||
|
initialized ENet exits.
|
||||||
|
*/
|
||||||
|
ENET_API void enet_deinitialize (void);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/** @defgroup private ENet private implementation functions */
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the wall-time in milliseconds. Its initial value is unspecified
|
||||||
|
unless otherwise set.
|
||||||
|
*/
|
||||||
|
ENET_API enet_uint32 enet_time_get (void);
|
||||||
|
/**
|
||||||
|
Sets the current wall-time in milliseconds.
|
||||||
|
*/
|
||||||
|
ENET_API void enet_time_set (enet_uint32);
|
||||||
|
|
||||||
|
/** @defgroup socket ENet socket functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
ENET_API ENetSocket enet_socket_create (ENetSocketType);
|
||||||
|
ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *);
|
||||||
|
ENET_API int enet_socket_listen (ENetSocket, int);
|
||||||
|
ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
|
||||||
|
ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
|
||||||
|
ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
|
||||||
|
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
|
||||||
|
ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
|
||||||
|
ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
|
||||||
|
ENET_API void enet_socket_destroy (ENetSocket);
|
||||||
|
ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/** @defgroup Address ENet address functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
/** Attempts to resolve the host named by the parameter hostName and sets
|
||||||
|
the host field in the address parameter if successful.
|
||||||
|
@param address destination to store resolved address
|
||||||
|
@param hostName host name to lookup
|
||||||
|
@retval 0 on success
|
||||||
|
@retval < 0 on failure
|
||||||
|
@returns the address of the given hostName in address on success
|
||||||
|
*/
|
||||||
|
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
|
||||||
|
|
||||||
|
/** Gives the printable form of the ip address specified in the address parameter.
|
||||||
|
@param address address printed
|
||||||
|
@param hostName destination for name, must not be NULL
|
||||||
|
@param nameLength maximum length of hostName.
|
||||||
|
@returns the null-terminated name of the host in hostName on success
|
||||||
|
@retval 0 on success
|
||||||
|
@retval < 0 on failure
|
||||||
|
*/
|
||||||
|
ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
|
||||||
|
|
||||||
|
/** Attempts to do a reverse lookup of the host field in the address parameter.
|
||||||
|
@param address address used for reverse lookup
|
||||||
|
@param hostName destination for name, must not be NULL
|
||||||
|
@param nameLength maximum length of hostName.
|
||||||
|
@returns the null-terminated name of the host in hostName on success
|
||||||
|
@retval 0 on success
|
||||||
|
@retval < 0 on failure
|
||||||
|
*/
|
||||||
|
ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
|
||||||
|
ENET_API void enet_packet_destroy (ENetPacket *);
|
||||||
|
ENET_API int enet_packet_resize (ENetPacket *, size_t);
|
||||||
|
extern enet_uint32 enet_crc32 (const ENetBuffer *, size_t);
|
||||||
|
|
||||||
|
ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, enet_uint32, enet_uint32);
|
||||||
|
ENET_API void enet_host_destroy (ENetHost *);
|
||||||
|
ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t);
|
||||||
|
ENET_API int enet_host_check_events (ENetHost *, ENetEvent *);
|
||||||
|
ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
|
||||||
|
ENET_API void enet_host_flush (ENetHost *);
|
||||||
|
ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
|
||||||
|
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
|
||||||
|
extern void enet_host_bandwidth_throttle (ENetHost *);
|
||||||
|
|
||||||
|
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
|
||||||
|
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8);
|
||||||
|
ENET_API void enet_peer_ping (ENetPeer *);
|
||||||
|
ENET_API void enet_peer_reset (ENetPeer *);
|
||||||
|
ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32);
|
||||||
|
ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32);
|
||||||
|
ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32);
|
||||||
|
ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
|
||||||
|
extern int enet_peer_throttle (ENetPeer *, enet_uint32);
|
||||||
|
extern void enet_peer_reset_queues (ENetPeer *);
|
||||||
|
extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
|
||||||
|
extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32);
|
||||||
|
extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
|
||||||
|
|
||||||
|
extern size_t enet_protocol_command_size (enet_uint8);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __ENET_ENET_H__ */
|
||||||
|
|
42
polymer/eduke32/source/enet/include/enet/list.h
Normal file
42
polymer/eduke32/source/enet/include/enet/list.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
@file list.h
|
||||||
|
@brief ENet list management
|
||||||
|
*/
|
||||||
|
#ifndef __ENET_LIST_H__
|
||||||
|
#define __ENET_LIST_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct _ENetListNode
|
||||||
|
{
|
||||||
|
struct _ENetListNode * next;
|
||||||
|
struct _ENetListNode * previous;
|
||||||
|
} ENetListNode;
|
||||||
|
|
||||||
|
typedef ENetListNode * ENetListIterator;
|
||||||
|
|
||||||
|
typedef struct _ENetList
|
||||||
|
{
|
||||||
|
ENetListNode sentinel;
|
||||||
|
} ENetList;
|
||||||
|
|
||||||
|
extern void enet_list_clear (ENetList *);
|
||||||
|
|
||||||
|
extern ENetListIterator enet_list_insert (ENetListIterator, void *);
|
||||||
|
extern void * enet_list_remove (ENetListIterator);
|
||||||
|
|
||||||
|
extern size_t enet_list_size (ENetList *);
|
||||||
|
|
||||||
|
#define enet_list_begin(list) ((list) -> sentinel.next)
|
||||||
|
#define enet_list_end(list) (& (list) -> sentinel)
|
||||||
|
|
||||||
|
#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
|
||||||
|
|
||||||
|
#define enet_list_next(iterator) ((iterator) -> next)
|
||||||
|
#define enet_list_previous(iterator) ((iterator) -> previous)
|
||||||
|
|
||||||
|
#define enet_list_front(list) ((void *) (list) -> sentinel.next)
|
||||||
|
#define enet_list_back(list) ((void *) (list) -> sentinel.previous)
|
||||||
|
|
||||||
|
#endif /* __ENET_LIST_H__ */
|
||||||
|
|
174
polymer/eduke32/source/enet/include/enet/protocol.h
Normal file
174
polymer/eduke32/source/enet/include/enet/protocol.h
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
/**
|
||||||
|
@file protocol.h
|
||||||
|
@brief ENet protocol
|
||||||
|
*/
|
||||||
|
#ifndef __ENET_PROTOCOL_H__
|
||||||
|
#define __ENET_PROTOCOL_H__
|
||||||
|
|
||||||
|
#include "enet/types.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ENET_PROTOCOL_MINIMUM_MTU = 576,
|
||||||
|
ENET_PROTOCOL_MAXIMUM_MTU = 4096,
|
||||||
|
ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
|
||||||
|
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
|
||||||
|
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768,
|
||||||
|
ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1,
|
||||||
|
ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255,
|
||||||
|
ENET_PROTOCOL_MAXIMUM_PEER_ID = 0x7FFF
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ENET_PROTOCOL_COMMAND_NONE = 0,
|
||||||
|
ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1,
|
||||||
|
ENET_PROTOCOL_COMMAND_CONNECT = 2,
|
||||||
|
ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3,
|
||||||
|
ENET_PROTOCOL_COMMAND_DISCONNECT = 4,
|
||||||
|
ENET_PROTOCOL_COMMAND_PING = 5,
|
||||||
|
ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6,
|
||||||
|
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7,
|
||||||
|
ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8,
|
||||||
|
ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
|
||||||
|
ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
|
||||||
|
ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
|
||||||
|
ENET_PROTOCOL_COMMAND_COUNT = 12,
|
||||||
|
|
||||||
|
ENET_PROTOCOL_COMMAND_MASK = 0x0F
|
||||||
|
} ENetProtocolCommand;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
|
||||||
|
ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
|
||||||
|
|
||||||
|
ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15),
|
||||||
|
ENET_PROTOCOL_HEADER_FLAG_MASK = 0x8000
|
||||||
|
} ENetProtocolFlag;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
enet_uint32 checksum;
|
||||||
|
enet_uint16 peerID;
|
||||||
|
enet_uint16 sentTime;
|
||||||
|
} ENetProtocolHeader;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
enet_uint8 command;
|
||||||
|
enet_uint8 channelID;
|
||||||
|
enet_uint16 reliableSequenceNumber;
|
||||||
|
} ENetProtocolCommandHeader;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
enet_uint16 receivedReliableSequenceNumber;
|
||||||
|
enet_uint16 receivedSentTime;
|
||||||
|
} ENetProtocolAcknowledge;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
enet_uint16 outgoingPeerID;
|
||||||
|
enet_uint16 mtu;
|
||||||
|
enet_uint32 windowSize;
|
||||||
|
enet_uint32 channelCount;
|
||||||
|
enet_uint32 incomingBandwidth;
|
||||||
|
enet_uint32 outgoingBandwidth;
|
||||||
|
enet_uint32 packetThrottleInterval;
|
||||||
|
enet_uint32 packetThrottleAcceleration;
|
||||||
|
enet_uint32 packetThrottleDeceleration;
|
||||||
|
enet_uint32 sessionID;
|
||||||
|
} ENetProtocolConnect;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
enet_uint16 outgoingPeerID;
|
||||||
|
enet_uint16 mtu;
|
||||||
|
enet_uint32 windowSize;
|
||||||
|
enet_uint32 channelCount;
|
||||||
|
enet_uint32 incomingBandwidth;
|
||||||
|
enet_uint32 outgoingBandwidth;
|
||||||
|
enet_uint32 packetThrottleInterval;
|
||||||
|
enet_uint32 packetThrottleAcceleration;
|
||||||
|
enet_uint32 packetThrottleDeceleration;
|
||||||
|
} ENetProtocolVerifyConnect;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
enet_uint32 incomingBandwidth;
|
||||||
|
enet_uint32 outgoingBandwidth;
|
||||||
|
} ENetProtocolBandwidthLimit;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
enet_uint32 packetThrottleInterval;
|
||||||
|
enet_uint32 packetThrottleAcceleration;
|
||||||
|
enet_uint32 packetThrottleDeceleration;
|
||||||
|
} ENetProtocolThrottleConfigure;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
enet_uint32 data;
|
||||||
|
} ENetProtocolDisconnect;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
} ENetProtocolPing;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
enet_uint16 dataLength;
|
||||||
|
} ENetProtocolSendReliable;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
enet_uint16 unreliableSequenceNumber;
|
||||||
|
enet_uint16 dataLength;
|
||||||
|
} ENetProtocolSendUnreliable;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
enet_uint16 unsequencedGroup;
|
||||||
|
enet_uint16 dataLength;
|
||||||
|
} ENetProtocolSendUnsequenced;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
enet_uint16 startSequenceNumber;
|
||||||
|
enet_uint16 dataLength;
|
||||||
|
enet_uint32 fragmentCount;
|
||||||
|
enet_uint32 fragmentNumber;
|
||||||
|
enet_uint32 totalLength;
|
||||||
|
enet_uint32 fragmentOffset;
|
||||||
|
} ENetProtocolSendFragment;
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
ENetProtocolCommandHeader header;
|
||||||
|
ENetProtocolAcknowledge acknowledge;
|
||||||
|
ENetProtocolConnect connect;
|
||||||
|
ENetProtocolVerifyConnect verifyConnect;
|
||||||
|
ENetProtocolDisconnect disconnect;
|
||||||
|
ENetProtocolPing ping;
|
||||||
|
ENetProtocolSendReliable sendReliable;
|
||||||
|
ENetProtocolSendUnreliable sendUnreliable;
|
||||||
|
ENetProtocolSendUnsequenced sendUnsequenced;
|
||||||
|
ENetProtocolSendFragment sendFragment;
|
||||||
|
ENetProtocolBandwidthLimit bandwidthLimit;
|
||||||
|
ENetProtocolThrottleConfigure throttleConfigure;
|
||||||
|
} ENetProtocol;
|
||||||
|
|
||||||
|
#endif /* __ENET_PROTOCOL_H__ */
|
||||||
|
|
18
polymer/eduke32/source/enet/include/enet/time.h
Normal file
18
polymer/eduke32/source/enet/include/enet/time.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
@file time.h
|
||||||
|
@brief ENet time constants and macros
|
||||||
|
*/
|
||||||
|
#ifndef __ENET_TIME_H__
|
||||||
|
#define __ENET_TIME_H__
|
||||||
|
|
||||||
|
#define ENET_TIME_OVERFLOW 86400000
|
||||||
|
|
||||||
|
#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW)
|
||||||
|
#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW)
|
||||||
|
#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b))
|
||||||
|
#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b))
|
||||||
|
|
||||||
|
#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b))
|
||||||
|
|
||||||
|
#endif /* __ENET_TIME_H__ */
|
||||||
|
|
13
polymer/eduke32/source/enet/include/enet/types.h
Normal file
13
polymer/eduke32/source/enet/include/enet/types.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
@file types.h
|
||||||
|
@brief type definitions for ENet
|
||||||
|
*/
|
||||||
|
#ifndef __ENET_TYPES_H__
|
||||||
|
#define __ENET_TYPES_H__
|
||||||
|
|
||||||
|
typedef unsigned char enet_uint8; /**< unsigned 8-bit type */
|
||||||
|
typedef unsigned short enet_uint16; /**< unsigned 16-bit type */
|
||||||
|
typedef unsigned int enet_uint32; /**< unsigned 32-bit type */
|
||||||
|
|
||||||
|
#endif /* __ENET_TYPES_H__ */
|
||||||
|
|
45
polymer/eduke32/source/enet/include/enet/unix.h
Normal file
45
polymer/eduke32/source/enet/include/enet/unix.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
@file unix.h
|
||||||
|
@brief ENet Unix header
|
||||||
|
*/
|
||||||
|
#ifndef __ENET_UNIX_H__
|
||||||
|
#define __ENET_UNIX_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
typedef int ENetSocket;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ENET_SOCKET_NULL = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
|
||||||
|
#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
|
||||||
|
|
||||||
|
#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */
|
||||||
|
#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void * data;
|
||||||
|
size_t dataLength;
|
||||||
|
} ENetBuffer;
|
||||||
|
|
||||||
|
#define ENET_CALLBACK
|
||||||
|
|
||||||
|
#define ENET_API extern
|
||||||
|
|
||||||
|
typedef fd_set ENetSocketSet;
|
||||||
|
|
||||||
|
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
|
||||||
|
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
|
||||||
|
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
|
||||||
|
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
|
||||||
|
|
||||||
|
#endif /* __ENET_UNIX_H__ */
|
||||||
|
|
12
polymer/eduke32/source/enet/include/enet/utility.h
Normal file
12
polymer/eduke32/source/enet/include/enet/utility.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
@file utility.h
|
||||||
|
@brief ENet utility header
|
||||||
|
*/
|
||||||
|
#ifndef __ENET_UTILITY_H__
|
||||||
|
#define __ENET_UTILITY_H__
|
||||||
|
|
||||||
|
#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||||
|
#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||||
|
|
||||||
|
#endif /* __ENET_UTILITY_H__ */
|
||||||
|
|
58
polymer/eduke32/source/enet/include/enet/win32.h
Normal file
58
polymer/eduke32/source/enet/include/enet/win32.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
@file win32.h
|
||||||
|
@brief ENet Win32 header
|
||||||
|
*/
|
||||||
|
#ifndef __ENET_WIN32_H__
|
||||||
|
#define __ENET_WIN32_H__
|
||||||
|
|
||||||
|
#ifdef ENET_BUILDING_LIB
|
||||||
|
#pragma warning (disable: 4996) // 'strncpy' was declared deprecated
|
||||||
|
#pragma warning (disable: 4267) // size_t to int conversion
|
||||||
|
#pragma warning (disable: 4244) // 64bit to 32bit int
|
||||||
|
#pragma warning (disable: 4018) // signed/unsigned mismatch
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
|
||||||
|
typedef SOCKET ENetSocket;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ENET_SOCKET_NULL = INVALID_SOCKET
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ENET_HOST_TO_NET_16(value) (htons (value))
|
||||||
|
#define ENET_HOST_TO_NET_32(value) (htonl (value))
|
||||||
|
|
||||||
|
#define ENET_NET_TO_HOST_16(value) (ntohs (value))
|
||||||
|
#define ENET_NET_TO_HOST_32(value) (ntohl (value))
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
size_t dataLength;
|
||||||
|
void * data;
|
||||||
|
} ENetBuffer;
|
||||||
|
|
||||||
|
#define ENET_CALLBACK __cdecl
|
||||||
|
|
||||||
|
#if defined ENET_DLL
|
||||||
|
#if defined ENET_BUILDING_LIB
|
||||||
|
#define ENET_API __declspec( dllexport )
|
||||||
|
#else
|
||||||
|
#define ENET_API __declspec( dllimport )
|
||||||
|
#endif /* ENET_BUILDING_LIB */
|
||||||
|
#else /* !ENET_DLL */
|
||||||
|
#define ENET_API extern
|
||||||
|
#endif /* ENET_DLL */
|
||||||
|
|
||||||
|
typedef fd_set ENetSocketSet;
|
||||||
|
|
||||||
|
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
|
||||||
|
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
|
||||||
|
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
|
||||||
|
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
|
||||||
|
|
||||||
|
#endif /* __ENET_WIN32_H__ */
|
||||||
|
|
||||||
|
|
53
polymer/eduke32/source/enet/src/callbacks.c
Normal file
53
polymer/eduke32/source/enet/src/callbacks.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
@file callbacks.c
|
||||||
|
@brief ENet callback functions
|
||||||
|
*/
|
||||||
|
#define ENET_BUILDING_LIB 1
|
||||||
|
#include "enet/enet.h"
|
||||||
|
|
||||||
|
static ENetCallbacks callbacks = { malloc, free, rand };
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits)
|
||||||
|
{
|
||||||
|
if (version != ENET_VERSION)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (inits -> malloc != NULL || inits -> free != NULL)
|
||||||
|
{
|
||||||
|
if (inits -> malloc == NULL || inits -> free == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
callbacks.malloc = inits -> malloc;
|
||||||
|
callbacks.free = inits -> free;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inits -> rand != NULL)
|
||||||
|
callbacks.rand = inits -> rand;
|
||||||
|
|
||||||
|
return enet_initialize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
enet_malloc (size_t size)
|
||||||
|
{
|
||||||
|
void * memory = callbacks.malloc (size);
|
||||||
|
|
||||||
|
if (memory == NULL)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
return memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_free (void * memory)
|
||||||
|
{
|
||||||
|
callbacks.free (memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_rand (void)
|
||||||
|
{
|
||||||
|
return callbacks.rand ();
|
||||||
|
}
|
||||||
|
|
401
polymer/eduke32/source/enet/src/host.c
Normal file
401
polymer/eduke32/source/enet/src/host.c
Normal file
|
@ -0,0 +1,401 @@
|
||||||
|
/**
|
||||||
|
@file host.c
|
||||||
|
@brief ENet host management functions
|
||||||
|
*/
|
||||||
|
#define ENET_BUILDING_LIB 1
|
||||||
|
#include <string.h>
|
||||||
|
#include "enet/enet.h"
|
||||||
|
|
||||||
|
/** @defgroup host ENet host functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Creates a host for communicating to peers.
|
||||||
|
|
||||||
|
@param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host.
|
||||||
|
@param peerCount the maximum number of peers that should be allocated for the host.
|
||||||
|
@param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
|
||||||
|
@param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
|
||||||
|
|
||||||
|
@returns the host on success and NULL on failure
|
||||||
|
|
||||||
|
@remarks ENet will strategically drop packets on specific sides of a connection between hosts
|
||||||
|
to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine
|
||||||
|
the window size of a connection which limits the amount of reliable packets that may be in transit
|
||||||
|
at any given time.
|
||||||
|
*/
|
||||||
|
ENetHost *
|
||||||
|
enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
|
||||||
|
{
|
||||||
|
ENetHost * host = (ENetHost *) enet_malloc (sizeof (ENetHost));
|
||||||
|
ENetPeer * currentPeer;
|
||||||
|
|
||||||
|
if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
|
||||||
|
memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
|
||||||
|
|
||||||
|
host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
|
||||||
|
if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
|
||||||
|
{
|
||||||
|
if (host -> socket != ENET_SOCKET_NULL)
|
||||||
|
enet_socket_destroy (host -> socket);
|
||||||
|
|
||||||
|
enet_free (host -> peers);
|
||||||
|
enet_free (host);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
|
||||||
|
enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
|
||||||
|
enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
|
||||||
|
enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
|
||||||
|
|
||||||
|
if (address != NULL)
|
||||||
|
host -> address = * address;
|
||||||
|
|
||||||
|
host -> incomingBandwidth = incomingBandwidth;
|
||||||
|
host -> outgoingBandwidth = outgoingBandwidth;
|
||||||
|
host -> bandwidthThrottleEpoch = 0;
|
||||||
|
host -> recalculateBandwidthLimits = 0;
|
||||||
|
host -> mtu = ENET_HOST_DEFAULT_MTU;
|
||||||
|
host -> peerCount = peerCount;
|
||||||
|
host -> lastServicedPeer = host -> peers;
|
||||||
|
host -> commandCount = 0;
|
||||||
|
host -> bufferCount = 0;
|
||||||
|
host -> receivedAddress.host = ENET_HOST_ANY;
|
||||||
|
host -> receivedAddress.port = 0;
|
||||||
|
host -> receivedDataLength = 0;
|
||||||
|
|
||||||
|
for (currentPeer = host -> peers;
|
||||||
|
currentPeer < & host -> peers [host -> peerCount];
|
||||||
|
++ currentPeer)
|
||||||
|
{
|
||||||
|
currentPeer -> host = host;
|
||||||
|
currentPeer -> incomingPeerID = currentPeer - host -> peers;
|
||||||
|
currentPeer -> data = NULL;
|
||||||
|
|
||||||
|
enet_list_clear (& currentPeer -> acknowledgements);
|
||||||
|
enet_list_clear (& currentPeer -> sentReliableCommands);
|
||||||
|
enet_list_clear (& currentPeer -> sentUnreliableCommands);
|
||||||
|
enet_list_clear (& currentPeer -> outgoingReliableCommands);
|
||||||
|
enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
|
||||||
|
|
||||||
|
enet_peer_reset (currentPeer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Destroys the host and all resources associated with it.
|
||||||
|
@param host pointer to the host to destroy
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_host_destroy (ENetHost * host)
|
||||||
|
{
|
||||||
|
ENetPeer * currentPeer;
|
||||||
|
|
||||||
|
enet_socket_destroy (host -> socket);
|
||||||
|
|
||||||
|
for (currentPeer = host -> peers;
|
||||||
|
currentPeer < & host -> peers [host -> peerCount];
|
||||||
|
++ currentPeer)
|
||||||
|
{
|
||||||
|
enet_peer_reset (currentPeer);
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_free (host -> peers);
|
||||||
|
enet_free (host);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Initiates a connection to a foreign host.
|
||||||
|
@param host host seeking the connection
|
||||||
|
@param address destination for the connection
|
||||||
|
@param channelCount number of channels to allocate
|
||||||
|
@returns a peer representing the foreign host on success, NULL on failure
|
||||||
|
@remarks The peer returned will have not completed the connection until enet_host_service()
|
||||||
|
notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
|
||||||
|
*/
|
||||||
|
ENetPeer *
|
||||||
|
enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount)
|
||||||
|
{
|
||||||
|
ENetPeer * currentPeer;
|
||||||
|
ENetChannel * channel;
|
||||||
|
ENetProtocol command;
|
||||||
|
|
||||||
|
if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
|
||||||
|
channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
|
||||||
|
else
|
||||||
|
if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
|
||||||
|
channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
|
||||||
|
|
||||||
|
for (currentPeer = host -> peers;
|
||||||
|
currentPeer < & host -> peers [host -> peerCount];
|
||||||
|
++ currentPeer)
|
||||||
|
{
|
||||||
|
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPeer >= & host -> peers [host -> peerCount])
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
currentPeer -> state = ENET_PEER_STATE_CONNECTING;
|
||||||
|
currentPeer -> address = * address;
|
||||||
|
currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
|
||||||
|
currentPeer -> channelCount = channelCount;
|
||||||
|
currentPeer -> sessionID = (enet_uint32) enet_rand ();
|
||||||
|
|
||||||
|
if (host -> outgoingBandwidth == 0)
|
||||||
|
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||||
|
else
|
||||||
|
currentPeer -> windowSize = (host -> outgoingBandwidth /
|
||||||
|
ENET_PEER_WINDOW_SIZE_SCALE) *
|
||||||
|
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
|
||||||
|
|
||||||
|
if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
|
||||||
|
currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
|
||||||
|
else
|
||||||
|
if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
|
||||||
|
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||||
|
|
||||||
|
for (channel = currentPeer -> channels;
|
||||||
|
channel < & currentPeer -> channels [channelCount];
|
||||||
|
++ channel)
|
||||||
|
{
|
||||||
|
channel -> outgoingReliableSequenceNumber = 0;
|
||||||
|
channel -> outgoingUnreliableSequenceNumber = 0;
|
||||||
|
channel -> incomingReliableSequenceNumber = 0;
|
||||||
|
|
||||||
|
enet_list_clear (& channel -> incomingReliableCommands);
|
||||||
|
enet_list_clear (& channel -> incomingUnreliableCommands);
|
||||||
|
|
||||||
|
channel -> usedReliableWindows = 0;
|
||||||
|
memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
|
||||||
|
}
|
||||||
|
|
||||||
|
command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
|
||||||
|
command.header.channelID = 0xFF;
|
||||||
|
command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
|
||||||
|
command.connect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu);
|
||||||
|
command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
|
||||||
|
command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
|
||||||
|
command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
|
||||||
|
command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
|
||||||
|
command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
|
||||||
|
command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
|
||||||
|
command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
|
||||||
|
command.connect.sessionID = currentPeer -> sessionID;
|
||||||
|
|
||||||
|
enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
|
||||||
|
|
||||||
|
return currentPeer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Queues a packet to be sent to all peers associated with the host.
|
||||||
|
@param host host on which to broadcast the packet
|
||||||
|
@param channelID channel on which to broadcast
|
||||||
|
@param packet packet to broadcast
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
|
||||||
|
{
|
||||||
|
ENetPeer * currentPeer;
|
||||||
|
|
||||||
|
for (currentPeer = host -> peers;
|
||||||
|
currentPeer < & host -> peers [host -> peerCount];
|
||||||
|
++ currentPeer)
|
||||||
|
{
|
||||||
|
if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
enet_peer_send (currentPeer, channelID, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet -> referenceCount == 0)
|
||||||
|
enet_packet_destroy (packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adjusts the bandwidth limits of a host.
|
||||||
|
@param host host to adjust
|
||||||
|
@param incomingBandwidth new incoming bandwidth
|
||||||
|
@param outgoingBandwidth new outgoing bandwidth
|
||||||
|
@remarks the incoming and outgoing bandwidth parameters are identical in function to those
|
||||||
|
specified in enet_host_create().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
|
||||||
|
{
|
||||||
|
host -> incomingBandwidth = incomingBandwidth;
|
||||||
|
host -> outgoingBandwidth = outgoingBandwidth;
|
||||||
|
host -> recalculateBandwidthLimits = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_host_bandwidth_throttle (ENetHost * host)
|
||||||
|
{
|
||||||
|
enet_uint32 timeCurrent = enet_time_get (),
|
||||||
|
elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
|
||||||
|
peersTotal = 0,
|
||||||
|
dataTotal = 0,
|
||||||
|
peersRemaining,
|
||||||
|
bandwidth,
|
||||||
|
throttle = 0,
|
||||||
|
bandwidthLimit = 0;
|
||||||
|
int needsAdjustment;
|
||||||
|
ENetPeer * peer;
|
||||||
|
ENetProtocol command;
|
||||||
|
|
||||||
|
if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (peer = host -> peers;
|
||||||
|
peer < & host -> peers [host -> peerCount];
|
||||||
|
++ peer)
|
||||||
|
{
|
||||||
|
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
++ peersTotal;
|
||||||
|
dataTotal += peer -> outgoingDataTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peersTotal == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
peersRemaining = peersTotal;
|
||||||
|
needsAdjustment = 1;
|
||||||
|
|
||||||
|
if (host -> outgoingBandwidth == 0)
|
||||||
|
bandwidth = ~0;
|
||||||
|
else
|
||||||
|
bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
|
||||||
|
|
||||||
|
while (peersRemaining > 0 && needsAdjustment != 0)
|
||||||
|
{
|
||||||
|
needsAdjustment = 0;
|
||||||
|
|
||||||
|
if (dataTotal < bandwidth)
|
||||||
|
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||||
|
else
|
||||||
|
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
|
||||||
|
|
||||||
|
for (peer = host -> peers;
|
||||||
|
peer < & host -> peers [host -> peerCount];
|
||||||
|
++ peer)
|
||||||
|
{
|
||||||
|
enet_uint32 peerBandwidth;
|
||||||
|
|
||||||
|
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
|
||||||
|
peer -> incomingBandwidth == 0 ||
|
||||||
|
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
|
||||||
|
if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
peer -> packetThrottleLimit = (peerBandwidth *
|
||||||
|
ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
|
||||||
|
|
||||||
|
if (peer -> packetThrottleLimit == 0)
|
||||||
|
peer -> packetThrottleLimit = 1;
|
||||||
|
|
||||||
|
if (peer -> packetThrottle > peer -> packetThrottleLimit)
|
||||||
|
peer -> packetThrottle = peer -> packetThrottleLimit;
|
||||||
|
|
||||||
|
peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
|
||||||
|
|
||||||
|
|
||||||
|
needsAdjustment = 1;
|
||||||
|
-- peersRemaining;
|
||||||
|
bandwidth -= peerBandwidth;
|
||||||
|
dataTotal -= peerBandwidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peersRemaining > 0)
|
||||||
|
for (peer = host -> peers;
|
||||||
|
peer < & host -> peers [host -> peerCount];
|
||||||
|
++ peer)
|
||||||
|
{
|
||||||
|
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
|
||||||
|
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
peer -> packetThrottleLimit = throttle;
|
||||||
|
|
||||||
|
if (peer -> packetThrottle > peer -> packetThrottleLimit)
|
||||||
|
peer -> packetThrottle = peer -> packetThrottleLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (host -> recalculateBandwidthLimits)
|
||||||
|
{
|
||||||
|
host -> recalculateBandwidthLimits = 0;
|
||||||
|
|
||||||
|
peersRemaining = peersTotal;
|
||||||
|
bandwidth = host -> incomingBandwidth;
|
||||||
|
needsAdjustment = 1;
|
||||||
|
|
||||||
|
if (bandwidth == 0)
|
||||||
|
bandwidthLimit = 0;
|
||||||
|
else
|
||||||
|
while (peersRemaining > 0 && needsAdjustment != 0)
|
||||||
|
{
|
||||||
|
needsAdjustment = 0;
|
||||||
|
bandwidthLimit = bandwidth / peersRemaining;
|
||||||
|
|
||||||
|
for (peer = host -> peers;
|
||||||
|
peer < & host -> peers [host -> peerCount];
|
||||||
|
++ peer)
|
||||||
|
{
|
||||||
|
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
|
||||||
|
peer -> incomingBandwidthThrottleEpoch == timeCurrent)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (peer -> outgoingBandwidth > 0 &&
|
||||||
|
peer -> outgoingBandwidth >= bandwidthLimit)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
peer -> incomingBandwidthThrottleEpoch = timeCurrent;
|
||||||
|
|
||||||
|
needsAdjustment = 1;
|
||||||
|
-- peersRemaining;
|
||||||
|
bandwidth -= peer -> outgoingBandwidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (peer = host -> peers;
|
||||||
|
peer < & host -> peers [host -> peerCount];
|
||||||
|
++ peer)
|
||||||
|
{
|
||||||
|
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
|
||||||
|
command.header.channelID = 0xFF;
|
||||||
|
command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
|
||||||
|
|
||||||
|
if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
|
||||||
|
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
|
||||||
|
else
|
||||||
|
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
|
||||||
|
|
||||||
|
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
host -> bandwidthThrottleEpoch = timeCurrent;
|
||||||
|
|
||||||
|
for (peer = host -> peers;
|
||||||
|
peer < & host -> peers [host -> peerCount];
|
||||||
|
++ peer)
|
||||||
|
{
|
||||||
|
peer -> incomingDataTotal = 0;
|
||||||
|
peer -> outgoingDataTotal = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
57
polymer/eduke32/source/enet/src/list.c
Normal file
57
polymer/eduke32/source/enet/src/list.c
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
@file list.c
|
||||||
|
@brief ENet linked list functions
|
||||||
|
*/
|
||||||
|
#define ENET_BUILDING_LIB 1
|
||||||
|
#include "enet/list.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
@defgroup list ENet linked list utility functions
|
||||||
|
@ingroup private
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_list_clear (ENetList * list)
|
||||||
|
{
|
||||||
|
list -> sentinel.next = & list -> sentinel;
|
||||||
|
list -> sentinel.previous = & list -> sentinel;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetListIterator
|
||||||
|
enet_list_insert (ENetListIterator position, void * data)
|
||||||
|
{
|
||||||
|
ENetListIterator result = (ENetListIterator) data;
|
||||||
|
|
||||||
|
result -> previous = position -> previous;
|
||||||
|
result -> next = position;
|
||||||
|
|
||||||
|
result -> previous -> next = result;
|
||||||
|
position -> previous = result;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
enet_list_remove (ENetListIterator position)
|
||||||
|
{
|
||||||
|
position -> previous -> next = position -> next;
|
||||||
|
position -> next -> previous = position -> previous;
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
enet_list_size (ENetList * list)
|
||||||
|
{
|
||||||
|
size_t size = 0;
|
||||||
|
ENetListIterator position;
|
||||||
|
|
||||||
|
for (position = enet_list_begin (list);
|
||||||
|
position != enet_list_end (list);
|
||||||
|
position = enet_list_next (position))
|
||||||
|
++ size;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
155
polymer/eduke32/source/enet/src/packet.c
Normal file
155
polymer/eduke32/source/enet/src/packet.c
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/**
|
||||||
|
@file packet.c
|
||||||
|
@brief ENet packet management functions
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#define ENET_BUILDING_LIB 1
|
||||||
|
#include "enet/enet.h"
|
||||||
|
|
||||||
|
/** @defgroup Packet ENet packet functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Creates a packet that may be sent to a peer.
|
||||||
|
@param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
|
||||||
|
@param dataLength size of the data allocated for this packet
|
||||||
|
@param flags flags for this packet as described for the ENetPacket structure.
|
||||||
|
@returns the packet on success, NULL on failure
|
||||||
|
*/
|
||||||
|
ENetPacket *
|
||||||
|
enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
|
||||||
|
{
|
||||||
|
ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
|
||||||
|
|
||||||
|
if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
|
||||||
|
packet -> data = (enet_uint8 *) data;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet -> data = (enet_uint8 *) enet_malloc (dataLength);
|
||||||
|
if (packet -> data == NULL)
|
||||||
|
{
|
||||||
|
enet_free (packet);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data != NULL)
|
||||||
|
memcpy (packet -> data, data, dataLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
packet -> referenceCount = 0;
|
||||||
|
packet -> flags = flags;
|
||||||
|
packet -> dataLength = dataLength;
|
||||||
|
packet -> freeCallback = NULL;
|
||||||
|
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Destroys the packet and deallocates its data.
|
||||||
|
@param packet packet to be destroyed
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_packet_destroy (ENetPacket * packet)
|
||||||
|
{
|
||||||
|
if (packet -> freeCallback != NULL)
|
||||||
|
(* packet -> freeCallback) (packet);
|
||||||
|
if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
|
||||||
|
enet_free (packet -> data);
|
||||||
|
enet_free (packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Attempts to resize the data in the packet to length specified in the
|
||||||
|
dataLength parameter
|
||||||
|
@param packet packet to resize
|
||||||
|
@param dataLength new size for the packet data
|
||||||
|
@returns 0 on success, < 0 on failure
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
enet_packet_resize (ENetPacket * packet, size_t dataLength)
|
||||||
|
{
|
||||||
|
enet_uint8 * newData;
|
||||||
|
|
||||||
|
if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
|
||||||
|
{
|
||||||
|
packet -> dataLength = dataLength;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
newData = (enet_uint8 *) enet_malloc (dataLength);
|
||||||
|
if (newData == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy (newData, packet -> data, packet -> dataLength);
|
||||||
|
enet_free (packet -> data);
|
||||||
|
|
||||||
|
packet -> data = newData;
|
||||||
|
packet -> dataLength = dataLength;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int initializedCRC32 = 0;
|
||||||
|
static enet_uint32 crcTable [256];
|
||||||
|
|
||||||
|
static enet_uint32
|
||||||
|
reflect_crc (int val, int bits)
|
||||||
|
{
|
||||||
|
int result = 0, bit;
|
||||||
|
|
||||||
|
for (bit = 0; bit < bits; bit ++)
|
||||||
|
{
|
||||||
|
if(val & 1) result |= 1 << (bits - 1 - bit);
|
||||||
|
val >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initialize_crc32 ()
|
||||||
|
{
|
||||||
|
int byte;
|
||||||
|
|
||||||
|
for (byte = 0; byte < 256; ++ byte)
|
||||||
|
{
|
||||||
|
enet_uint32 crc = reflect_crc (byte, 8) << 24;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
for(offset = 0; offset < 8; ++ offset)
|
||||||
|
{
|
||||||
|
if (crc & 0x80000000)
|
||||||
|
crc = (crc << 1) ^ 0x04c11db7;
|
||||||
|
else
|
||||||
|
crc <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
crcTable [byte] = reflect_crc (crc, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
initializedCRC32 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_uint32
|
||||||
|
enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
|
||||||
|
{
|
||||||
|
enet_uint32 crc = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
if (! initializedCRC32) initialize_crc32 ();
|
||||||
|
|
||||||
|
while (bufferCount -- > 0)
|
||||||
|
{
|
||||||
|
const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
|
||||||
|
* dataEnd = & data [buffers -> dataLength];
|
||||||
|
|
||||||
|
while (data < dataEnd)
|
||||||
|
{
|
||||||
|
crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];
|
||||||
|
}
|
||||||
|
|
||||||
|
++ buffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ENET_HOST_TO_NET_32 (~ crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
700
polymer/eduke32/source/enet/src/peer.c
Normal file
700
polymer/eduke32/source/enet/src/peer.c
Normal file
|
@ -0,0 +1,700 @@
|
||||||
|
/**
|
||||||
|
@file peer.c
|
||||||
|
@brief ENet peer management functions
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#define ENET_BUILDING_LIB 1
|
||||||
|
#include "enet/enet.h"
|
||||||
|
|
||||||
|
/** @defgroup peer ENet peer functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Configures throttle parameter for a peer.
|
||||||
|
|
||||||
|
Unreliable packets are dropped by ENet in response to the varying conditions
|
||||||
|
of the Internet connection to the peer. The throttle represents a probability
|
||||||
|
that an unreliable packet should not be dropped and thus sent by ENet to the peer.
|
||||||
|
The lowest mean round trip time from the sending of a reliable packet to the
|
||||||
|
receipt of its acknowledgement is measured over an amount of time specified by
|
||||||
|
the interval parameter in milliseconds. If a measured round trip time happens to
|
||||||
|
be significantly less than the mean round trip time measured over the interval,
|
||||||
|
then the throttle probability is increased to allow more traffic by an amount
|
||||||
|
specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE
|
||||||
|
constant. If a measured round trip time happens to be significantly greater than
|
||||||
|
the mean round trip time measured over the interval, then the throttle probability
|
||||||
|
is decreased to limit traffic by an amount specified in the deceleration parameter, which
|
||||||
|
is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant. When the throttle has
|
||||||
|
a value of ENET_PEER_PACKET_THROTTLE_SCALE, on unreliable packets are dropped by
|
||||||
|
ENet, and so 100% of all unreliable packets will be sent. When the throttle has a
|
||||||
|
value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable
|
||||||
|
packets will be sent. Intermediate values for the throttle represent intermediate
|
||||||
|
probabilities between 0% and 100% of unreliable packets being sent. The bandwidth
|
||||||
|
limits of the local and foreign hosts are taken into account to determine a
|
||||||
|
sensible limit for the throttle probability above which it should not raise even in
|
||||||
|
the best of conditions.
|
||||||
|
|
||||||
|
@param peer peer to configure
|
||||||
|
@param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL.
|
||||||
|
@param acceleration rate at which to increase the throttle probability as mean RTT declines
|
||||||
|
@param deceleration rate at which to decrease the throttle probability as mean RTT increases
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration)
|
||||||
|
{
|
||||||
|
ENetProtocol command;
|
||||||
|
|
||||||
|
peer -> packetThrottleInterval = interval;
|
||||||
|
peer -> packetThrottleAcceleration = acceleration;
|
||||||
|
peer -> packetThrottleDeceleration = deceleration;
|
||||||
|
|
||||||
|
command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
|
||||||
|
command.header.channelID = 0xFF;
|
||||||
|
|
||||||
|
command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval);
|
||||||
|
command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration);
|
||||||
|
command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration);
|
||||||
|
|
||||||
|
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
|
||||||
|
{
|
||||||
|
if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance)
|
||||||
|
{
|
||||||
|
peer -> packetThrottle = peer -> packetThrottleLimit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (rtt < peer -> lastRoundTripTime)
|
||||||
|
{
|
||||||
|
peer -> packetThrottle += peer -> packetThrottleAcceleration;
|
||||||
|
|
||||||
|
if (peer -> packetThrottle > peer -> packetThrottleLimit)
|
||||||
|
peer -> packetThrottle = peer -> packetThrottleLimit;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
|
||||||
|
{
|
||||||
|
if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
|
||||||
|
peer -> packetThrottle -= peer -> packetThrottleDeceleration;
|
||||||
|
else
|
||||||
|
peer -> packetThrottle = 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Queues a packet to be sent.
|
||||||
|
@param peer destination for the packet
|
||||||
|
@param channelID channel on which to send
|
||||||
|
@param packet packet to send
|
||||||
|
@retval 0 on success
|
||||||
|
@retval < 0 on failure
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
|
||||||
|
{
|
||||||
|
ENetChannel * channel = & peer -> channels [channelID];
|
||||||
|
ENetProtocol command;
|
||||||
|
size_t fragmentLength;
|
||||||
|
|
||||||
|
if (peer -> state != ENET_PEER_STATE_CONNECTED ||
|
||||||
|
channelID >= peer -> channelCount)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
|
||||||
|
|
||||||
|
if (packet -> dataLength > fragmentLength)
|
||||||
|
{
|
||||||
|
enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
|
||||||
|
enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
|
||||||
|
fragmentNumber,
|
||||||
|
fragmentOffset;
|
||||||
|
|
||||||
|
packet -> flags |= ENET_PACKET_FLAG_RELIABLE;
|
||||||
|
packet -> flags &= ~ENET_PACKET_FLAG_UNSEQUENCED;
|
||||||
|
|
||||||
|
for (fragmentNumber = 0,
|
||||||
|
fragmentOffset = 0;
|
||||||
|
fragmentOffset < packet -> dataLength;
|
||||||
|
++ fragmentNumber,
|
||||||
|
fragmentOffset += fragmentLength)
|
||||||
|
{
|
||||||
|
if (packet -> dataLength - fragmentOffset < fragmentLength)
|
||||||
|
fragmentLength = packet -> dataLength - fragmentOffset;
|
||||||
|
|
||||||
|
command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
|
||||||
|
command.header.channelID = channelID;
|
||||||
|
command.sendFragment.startSequenceNumber = startSequenceNumber;
|
||||||
|
command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
|
||||||
|
command.sendFragment.fragmentCount = fragmentCount;
|
||||||
|
command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
|
||||||
|
command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
|
||||||
|
command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
|
||||||
|
|
||||||
|
enet_peer_queue_outgoing_command (peer, & command, packet, fragmentOffset, fragmentLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
command.header.channelID = channelID;
|
||||||
|
|
||||||
|
if (! (packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNSEQUENCED)) && channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
|
||||||
|
packet -> flags |= ENET_PACKET_FLAG_RELIABLE;
|
||||||
|
|
||||||
|
if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
|
||||||
|
{
|
||||||
|
command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
|
||||||
|
command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
|
||||||
|
{
|
||||||
|
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
|
||||||
|
command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
|
||||||
|
command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
|
||||||
|
command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
|
||||||
|
command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Attempts to dequeue any incoming queued packet.
|
||||||
|
@param peer peer to dequeue packets from
|
||||||
|
@param channelID channel on which to receive
|
||||||
|
@returns a pointer to the packet, or NULL if there are no available incoming queued packets
|
||||||
|
*/
|
||||||
|
ENetPacket *
|
||||||
|
enet_peer_receive (ENetPeer * peer, enet_uint8 channelID)
|
||||||
|
{
|
||||||
|
ENetChannel * channel = & peer -> channels [channelID];
|
||||||
|
ENetIncomingCommand * incomingCommand = NULL;
|
||||||
|
ENetPacket * packet;
|
||||||
|
|
||||||
|
if (! enet_list_empty (& channel -> incomingUnreliableCommands))
|
||||||
|
{
|
||||||
|
incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingUnreliableCommands);
|
||||||
|
|
||||||
|
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
|
||||||
|
{
|
||||||
|
if (incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber)
|
||||||
|
incomingCommand = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (incomingCommand == NULL &&
|
||||||
|
! enet_list_empty (& channel -> incomingReliableCommands))
|
||||||
|
{
|
||||||
|
incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingReliableCommands);
|
||||||
|
|
||||||
|
if (incomingCommand -> fragmentsRemaining > 0 ||
|
||||||
|
incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
|
||||||
|
|
||||||
|
if (incomingCommand -> fragmentCount > 0)
|
||||||
|
channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (incomingCommand == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
enet_list_remove (& incomingCommand -> incomingCommandList);
|
||||||
|
|
||||||
|
packet = incomingCommand -> packet;
|
||||||
|
|
||||||
|
-- packet -> referenceCount;
|
||||||
|
|
||||||
|
if (incomingCommand -> fragments != NULL)
|
||||||
|
enet_free (incomingCommand -> fragments);
|
||||||
|
|
||||||
|
enet_free (incomingCommand);
|
||||||
|
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
enet_peer_reset_outgoing_commands (ENetList * queue)
|
||||||
|
{
|
||||||
|
ENetOutgoingCommand * outgoingCommand;
|
||||||
|
|
||||||
|
while (! enet_list_empty (queue))
|
||||||
|
{
|
||||||
|
outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue));
|
||||||
|
|
||||||
|
if (outgoingCommand -> packet != NULL)
|
||||||
|
{
|
||||||
|
-- outgoingCommand -> packet -> referenceCount;
|
||||||
|
|
||||||
|
if (outgoingCommand -> packet -> referenceCount == 0)
|
||||||
|
enet_packet_destroy (outgoingCommand -> packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_free (outgoingCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
enet_peer_reset_incoming_commands (ENetList * queue)
|
||||||
|
{
|
||||||
|
ENetIncomingCommand * incomingCommand;
|
||||||
|
|
||||||
|
while (! enet_list_empty (queue))
|
||||||
|
{
|
||||||
|
incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
|
||||||
|
|
||||||
|
if (incomingCommand -> packet != NULL)
|
||||||
|
{
|
||||||
|
-- incomingCommand -> packet -> referenceCount;
|
||||||
|
|
||||||
|
if (incomingCommand -> packet -> referenceCount == 0)
|
||||||
|
enet_packet_destroy (incomingCommand -> packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (incomingCommand -> fragments != NULL)
|
||||||
|
enet_free (incomingCommand -> fragments);
|
||||||
|
|
||||||
|
enet_free (incomingCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_peer_reset_queues (ENetPeer * peer)
|
||||||
|
{
|
||||||
|
ENetChannel * channel;
|
||||||
|
|
||||||
|
while (! enet_list_empty (& peer -> acknowledgements))
|
||||||
|
enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
|
||||||
|
|
||||||
|
enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
|
||||||
|
enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
|
||||||
|
enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
|
||||||
|
enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
|
||||||
|
|
||||||
|
if (peer -> channels != NULL && peer -> channelCount > 0)
|
||||||
|
{
|
||||||
|
for (channel = peer -> channels;
|
||||||
|
channel < & peer -> channels [peer -> channelCount];
|
||||||
|
++ channel)
|
||||||
|
{
|
||||||
|
enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands);
|
||||||
|
enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands);
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_free (peer -> channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
peer -> channels = NULL;
|
||||||
|
peer -> channelCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Forcefully disconnects a peer.
|
||||||
|
@param peer peer to forcefully disconnect
|
||||||
|
@remarks The foreign host represented by the peer is not notified of the disconnection and will timeout
|
||||||
|
on its connection to the local host.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_peer_reset (ENetPeer * peer)
|
||||||
|
{
|
||||||
|
peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
|
||||||
|
peer -> sessionID = 0;
|
||||||
|
|
||||||
|
peer -> state = ENET_PEER_STATE_DISCONNECTED;
|
||||||
|
|
||||||
|
peer -> incomingBandwidth = 0;
|
||||||
|
peer -> outgoingBandwidth = 0;
|
||||||
|
peer -> incomingBandwidthThrottleEpoch = 0;
|
||||||
|
peer -> outgoingBandwidthThrottleEpoch = 0;
|
||||||
|
peer -> incomingDataTotal = 0;
|
||||||
|
peer -> outgoingDataTotal = 0;
|
||||||
|
peer -> lastSendTime = 0;
|
||||||
|
peer -> lastReceiveTime = 0;
|
||||||
|
peer -> nextTimeout = 0;
|
||||||
|
peer -> earliestTimeout = 0;
|
||||||
|
peer -> packetLossEpoch = 0;
|
||||||
|
peer -> packetsSent = 0;
|
||||||
|
peer -> packetsLost = 0;
|
||||||
|
peer -> packetLoss = 0;
|
||||||
|
peer -> packetLossVariance = 0;
|
||||||
|
peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE;
|
||||||
|
peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||||
|
peer -> packetThrottleCounter = 0;
|
||||||
|
peer -> packetThrottleEpoch = 0;
|
||||||
|
peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION;
|
||||||
|
peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION;
|
||||||
|
peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL;
|
||||||
|
peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
|
||||||
|
peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
|
||||||
|
peer -> lastRoundTripTimeVariance = 0;
|
||||||
|
peer -> highestRoundTripTimeVariance = 0;
|
||||||
|
peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
|
||||||
|
peer -> roundTripTimeVariance = 0;
|
||||||
|
peer -> mtu = peer -> host -> mtu;
|
||||||
|
peer -> reliableDataInTransit = 0;
|
||||||
|
peer -> outgoingReliableSequenceNumber = 0;
|
||||||
|
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||||
|
peer -> incomingUnsequencedGroup = 0;
|
||||||
|
peer -> outgoingUnsequencedGroup = 0;
|
||||||
|
peer -> disconnectData = 0;
|
||||||
|
|
||||||
|
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
|
||||||
|
|
||||||
|
enet_peer_reset_queues (peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sends a ping request to a peer.
|
||||||
|
@param peer destination for the ping request
|
||||||
|
@remarks ping requests factor into the mean round trip time as designated by the
|
||||||
|
roundTripTime field in the ENetPeer structure. Enet automatically pings all connected
|
||||||
|
peers at regular intervals, however, this function may be called to ensure more
|
||||||
|
frequent ping requests.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_peer_ping (ENetPeer * peer)
|
||||||
|
{
|
||||||
|
ENetProtocol command;
|
||||||
|
|
||||||
|
if (peer -> state != ENET_PEER_STATE_CONNECTED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
|
||||||
|
command.header.channelID = 0xFF;
|
||||||
|
|
||||||
|
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Force an immediate disconnection from a peer.
|
||||||
|
@param peer peer to disconnect
|
||||||
|
@param data data describing the disconnection
|
||||||
|
@remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not
|
||||||
|
guarenteed to receive the disconnect notification, and is reset immediately upon
|
||||||
|
return from this function.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data)
|
||||||
|
{
|
||||||
|
ENetProtocol command;
|
||||||
|
|
||||||
|
if (peer -> state == ENET_PEER_STATE_DISCONNECTED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (peer -> state != ENET_PEER_STATE_ZOMBIE &&
|
||||||
|
peer -> state != ENET_PEER_STATE_DISCONNECTING)
|
||||||
|
{
|
||||||
|
enet_peer_reset_queues (peer);
|
||||||
|
|
||||||
|
command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
|
||||||
|
command.header.channelID = 0xFF;
|
||||||
|
command.disconnect.data = ENET_HOST_TO_NET_32 (data);
|
||||||
|
|
||||||
|
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
|
||||||
|
|
||||||
|
enet_host_flush (peer -> host);
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_peer_reset (peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Request a disconnection from a peer.
|
||||||
|
@param peer peer to request a disconnection
|
||||||
|
@param data data describing the disconnection
|
||||||
|
@remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
|
||||||
|
once the disconnection is complete.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
|
||||||
|
{
|
||||||
|
ENetProtocol command;
|
||||||
|
|
||||||
|
if (peer -> state == ENET_PEER_STATE_DISCONNECTING ||
|
||||||
|
peer -> state == ENET_PEER_STATE_DISCONNECTED ||
|
||||||
|
peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT ||
|
||||||
|
peer -> state == ENET_PEER_STATE_ZOMBIE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
enet_peer_reset_queues (peer);
|
||||||
|
|
||||||
|
command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT;
|
||||||
|
command.header.channelID = 0xFF;
|
||||||
|
command.disconnect.data = ENET_HOST_TO_NET_32 (data);
|
||||||
|
|
||||||
|
if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
|
||||||
|
command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
|
||||||
|
else
|
||||||
|
command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
|
||||||
|
|
||||||
|
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
|
||||||
|
|
||||||
|
if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
|
||||||
|
peer -> state = ENET_PEER_STATE_DISCONNECTING;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enet_host_flush (peer -> host);
|
||||||
|
enet_peer_reset (peer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
|
||||||
|
@param peer peer to request a disconnection
|
||||||
|
@param data data describing the disconnection
|
||||||
|
@remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
|
||||||
|
once the disconnection is complete.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
|
||||||
|
{
|
||||||
|
if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) &&
|
||||||
|
! (enet_list_empty (& peer -> outgoingReliableCommands) &&
|
||||||
|
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
|
||||||
|
enet_list_empty (& peer -> sentReliableCommands)))
|
||||||
|
{
|
||||||
|
peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
|
||||||
|
peer -> disconnectData = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
enet_peer_disconnect (peer, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetAcknowledgement *
|
||||||
|
enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime)
|
||||||
|
{
|
||||||
|
ENetAcknowledgement * acknowledgement;
|
||||||
|
|
||||||
|
if (command -> header.channelID < peer -> channelCount)
|
||||||
|
{
|
||||||
|
ENetChannel * channel = & peer -> channels [command -> header.channelID];
|
||||||
|
enet_uint16 reliableWindow = command -> header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE,
|
||||||
|
currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
|
||||||
|
|
||||||
|
if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
|
||||||
|
reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
|
||||||
|
|
||||||
|
if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge);
|
||||||
|
|
||||||
|
acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement));
|
||||||
|
|
||||||
|
acknowledgement -> sentTime = sentTime;
|
||||||
|
acknowledgement -> command = * command;
|
||||||
|
|
||||||
|
enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement);
|
||||||
|
|
||||||
|
return acknowledgement;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetOutgoingCommand *
|
||||||
|
enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length)
|
||||||
|
{
|
||||||
|
ENetChannel * channel = & peer -> channels [command -> header.channelID];
|
||||||
|
ENetOutgoingCommand * outgoingCommand;
|
||||||
|
|
||||||
|
peer -> outgoingDataTotal += enet_protocol_command_size (command -> header.command) + length;
|
||||||
|
|
||||||
|
outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
|
||||||
|
|
||||||
|
if (command -> header.channelID == 0xFF)
|
||||||
|
{
|
||||||
|
++ peer -> outgoingReliableSequenceNumber;
|
||||||
|
|
||||||
|
outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
|
||||||
|
outgoingCommand -> unreliableSequenceNumber = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||||
|
{
|
||||||
|
++ channel -> outgoingReliableSequenceNumber;
|
||||||
|
channel -> outgoingUnreliableSequenceNumber = 0;
|
||||||
|
|
||||||
|
outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
|
||||||
|
outgoingCommand -> unreliableSequenceNumber = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
|
||||||
|
{
|
||||||
|
++ peer -> outgoingUnsequencedGroup;
|
||||||
|
|
||||||
|
outgoingCommand -> reliableSequenceNumber = 0;
|
||||||
|
outgoingCommand -> unreliableSequenceNumber = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++ channel -> outgoingUnreliableSequenceNumber;
|
||||||
|
|
||||||
|
outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
|
||||||
|
outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
outgoingCommand -> sendAttempts = 0;
|
||||||
|
outgoingCommand -> sentTime = 0;
|
||||||
|
outgoingCommand -> roundTripTimeout = 0;
|
||||||
|
outgoingCommand -> roundTripTimeoutLimit = 0;
|
||||||
|
outgoingCommand -> fragmentOffset = offset;
|
||||||
|
outgoingCommand -> fragmentLength = length;
|
||||||
|
outgoingCommand -> packet = packet;
|
||||||
|
outgoingCommand -> command = * command;
|
||||||
|
outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
|
||||||
|
|
||||||
|
if (packet != NULL)
|
||||||
|
++ packet -> referenceCount;
|
||||||
|
|
||||||
|
if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||||
|
enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
|
||||||
|
else
|
||||||
|
enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
|
||||||
|
|
||||||
|
return outgoingCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetIncomingCommand *
|
||||||
|
enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount)
|
||||||
|
{
|
||||||
|
ENetChannel * channel = & peer -> channels [command -> header.channelID];
|
||||||
|
enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber;
|
||||||
|
enet_uint16 reliableWindow, currentWindow;
|
||||||
|
ENetIncomingCommand * incomingCommand;
|
||||||
|
ENetListIterator currentCommand;
|
||||||
|
|
||||||
|
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
|
||||||
|
goto freePacket;
|
||||||
|
|
||||||
|
if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
|
||||||
|
{
|
||||||
|
reliableSequenceNumber = command -> header.reliableSequenceNumber;
|
||||||
|
reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
|
||||||
|
currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
|
||||||
|
|
||||||
|
if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
|
||||||
|
reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
|
||||||
|
|
||||||
|
if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
|
||||||
|
goto freePacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
|
||||||
|
{
|
||||||
|
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
|
||||||
|
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
|
||||||
|
if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
|
||||||
|
goto freePacket;
|
||||||
|
|
||||||
|
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
|
||||||
|
currentCommand != enet_list_end (& channel -> incomingReliableCommands);
|
||||||
|
currentCommand = enet_list_previous (currentCommand))
|
||||||
|
{
|
||||||
|
incomingCommand = (ENetIncomingCommand *) currentCommand;
|
||||||
|
|
||||||
|
if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
|
||||||
|
{
|
||||||
|
if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber)
|
||||||
|
{
|
||||||
|
if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
|
||||||
|
break;
|
||||||
|
|
||||||
|
goto freePacket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
|
||||||
|
unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber);
|
||||||
|
|
||||||
|
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
|
||||||
|
currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
|
||||||
|
currentCommand = enet_list_previous (currentCommand))
|
||||||
|
{
|
||||||
|
incomingCommand = (ENetIncomingCommand *) currentCommand;
|
||||||
|
|
||||||
|
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
|
||||||
|
{
|
||||||
|
if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber)
|
||||||
|
{
|
||||||
|
if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
|
||||||
|
break;
|
||||||
|
|
||||||
|
goto freePacket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
|
||||||
|
currentCommand = enet_list_end (& channel -> incomingUnreliableCommands);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto freePacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
|
||||||
|
|
||||||
|
incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
|
||||||
|
incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF;
|
||||||
|
incomingCommand -> command = * command;
|
||||||
|
incomingCommand -> fragmentCount = fragmentCount;
|
||||||
|
incomingCommand -> fragmentsRemaining = fragmentCount;
|
||||||
|
incomingCommand -> packet = packet;
|
||||||
|
incomingCommand -> fragments = NULL;
|
||||||
|
|
||||||
|
if (fragmentCount > 0)
|
||||||
|
{
|
||||||
|
incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
|
||||||
|
memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet != NULL)
|
||||||
|
++ packet -> referenceCount;
|
||||||
|
|
||||||
|
enet_list_insert (enet_list_next (currentCommand), incomingCommand);
|
||||||
|
|
||||||
|
return incomingCommand;
|
||||||
|
|
||||||
|
freePacket:
|
||||||
|
if (packet != NULL)
|
||||||
|
{
|
||||||
|
if (packet -> referenceCount == 0)
|
||||||
|
enet_packet_destroy (packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
1577
polymer/eduke32/source/enet/src/protocol.c
Normal file
1577
polymer/eduke32/source/enet/src/protocol.c
Normal file
File diff suppressed because it is too large
Load diff
438
polymer/eduke32/source/enet/src/unix.c
Normal file
438
polymer/eduke32/source/enet/src/unix.c
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
/**
|
||||||
|
@file unix.c
|
||||||
|
@brief ENet Unix system specific functions
|
||||||
|
*/
|
||||||
|
#ifndef WIN32
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define ENET_BUILDING_LIB 1
|
||||||
|
#include "enet/enet.h"
|
||||||
|
|
||||||
|
#ifdef HAS_FCNTL
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#undef HAS_POLL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_POLL
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAS_SOCKLEN_T
|
||||||
|
// typedef int socklen_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MSG_NOSIGNAL
|
||||||
|
#define MSG_NOSIGNAL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static enet_uint32 timeBase = 0;
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_initialize (void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_deinitialize (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_uint32
|
||||||
|
enet_time_get (void)
|
||||||
|
{
|
||||||
|
struct timeval timeVal;
|
||||||
|
|
||||||
|
gettimeofday (& timeVal, NULL);
|
||||||
|
|
||||||
|
return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_time_set (enet_uint32 newTimeBase)
|
||||||
|
{
|
||||||
|
struct timeval timeVal;
|
||||||
|
|
||||||
|
gettimeofday (& timeVal, NULL);
|
||||||
|
|
||||||
|
timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_address_set_host (ENetAddress * address, const char * name)
|
||||||
|
{
|
||||||
|
struct hostent * hostEntry = NULL;
|
||||||
|
#ifdef HAS_GETHOSTBYNAME_R
|
||||||
|
struct hostent hostData;
|
||||||
|
char buffer [2048];
|
||||||
|
int errnum;
|
||||||
|
|
||||||
|
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__)
|
||||||
|
gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
|
||||||
|
#else
|
||||||
|
hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
hostEntry = gethostbyname (name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (hostEntry == NULL ||
|
||||||
|
hostEntry -> h_addrtype != AF_INET)
|
||||||
|
{
|
||||||
|
#ifdef HAS_INET_PTON
|
||||||
|
if (! inet_pton (AF_INET, name, & address -> host))
|
||||||
|
#else
|
||||||
|
if (! inet_aton (name, (struct in_addr *) & address -> host))
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
|
||||||
|
{
|
||||||
|
#ifdef HAS_INET_NTOP
|
||||||
|
if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
|
||||||
|
#else
|
||||||
|
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
|
||||||
|
if (addr != NULL)
|
||||||
|
strncpy (name, addr, nameLength);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
|
||||||
|
{
|
||||||
|
struct in_addr in;
|
||||||
|
struct hostent * hostEntry = NULL;
|
||||||
|
#ifdef HAS_GETHOSTBYADDR_R
|
||||||
|
struct hostent hostData;
|
||||||
|
char buffer [2048];
|
||||||
|
int errnum;
|
||||||
|
|
||||||
|
in.s_addr = address -> host;
|
||||||
|
|
||||||
|
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__)
|
||||||
|
gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
|
||||||
|
#else
|
||||||
|
hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
in.s_addr = address -> host;
|
||||||
|
|
||||||
|
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (hostEntry == NULL)
|
||||||
|
return enet_address_get_host_ip (address, name, nameLength);
|
||||||
|
|
||||||
|
strncpy (name, hostEntry -> h_name, nameLength);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||||
|
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
|
||||||
|
if (address != NULL)
|
||||||
|
{
|
||||||
|
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||||
|
sin.sin_addr.s_addr = address -> host;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sin.sin_port = 0;
|
||||||
|
sin.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bind (socket,
|
||||||
|
(struct sockaddr *) & sin,
|
||||||
|
sizeof (struct sockaddr_in));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_listen (ENetSocket socket, int backlog)
|
||||||
|
{
|
||||||
|
return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetSocket
|
||||||
|
enet_socket_create (ENetSocketType type)
|
||||||
|
{
|
||||||
|
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
switch (option)
|
||||||
|
{
|
||||||
|
case ENET_SOCKOPT_NONBLOCK:
|
||||||
|
#ifdef HAS_FCNTL
|
||||||
|
result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
|
||||||
|
#else
|
||||||
|
result = ioctl (socket, FIONBIO, & value);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_BROADCAST:
|
||||||
|
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_REUSEADDR:
|
||||||
|
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_RCVBUF:
|
||||||
|
result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_SNDBUF:
|
||||||
|
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result == -1 ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||||
|
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||||
|
sin.sin_addr.s_addr = address -> host;
|
||||||
|
|
||||||
|
return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetSocket
|
||||||
|
enet_socket_accept (ENetSocket socket, ENetAddress * address)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
socklen_t sinLength = sizeof (struct sockaddr_in);
|
||||||
|
|
||||||
|
result = accept (socket,
|
||||||
|
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||||
|
address != NULL ? & sinLength : NULL);
|
||||||
|
|
||||||
|
if (result == -1)
|
||||||
|
return ENET_SOCKET_NULL;
|
||||||
|
|
||||||
|
if (address != NULL)
|
||||||
|
{
|
||||||
|
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||||
|
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_socket_destroy (ENetSocket socket)
|
||||||
|
{
|
||||||
|
close (socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_send (ENetSocket socket,
|
||||||
|
const ENetAddress * address,
|
||||||
|
const ENetBuffer * buffers,
|
||||||
|
size_t bufferCount)
|
||||||
|
{
|
||||||
|
struct msghdr msgHdr;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
int sentLength;
|
||||||
|
|
||||||
|
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||||
|
|
||||||
|
if (address != NULL)
|
||||||
|
{
|
||||||
|
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||||
|
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||||
|
sin.sin_addr.s_addr = address -> host;
|
||||||
|
|
||||||
|
msgHdr.msg_name = & sin;
|
||||||
|
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
msgHdr.msg_iov = (struct iovec *) buffers;
|
||||||
|
msgHdr.msg_iovlen = bufferCount;
|
||||||
|
|
||||||
|
sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
||||||
|
|
||||||
|
if (sentLength == -1)
|
||||||
|
{
|
||||||
|
if (errno == EWOULDBLOCK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_receive (ENetSocket socket,
|
||||||
|
ENetAddress * address,
|
||||||
|
ENetBuffer * buffers,
|
||||||
|
size_t bufferCount)
|
||||||
|
{
|
||||||
|
struct msghdr msgHdr;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
int recvLength;
|
||||||
|
|
||||||
|
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||||
|
|
||||||
|
if (address != NULL)
|
||||||
|
{
|
||||||
|
msgHdr.msg_name = & sin;
|
||||||
|
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
msgHdr.msg_iov = (struct iovec *) buffers;
|
||||||
|
msgHdr.msg_iovlen = bufferCount;
|
||||||
|
|
||||||
|
recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
||||||
|
|
||||||
|
if (recvLength == -1)
|
||||||
|
{
|
||||||
|
if (errno == EWOULDBLOCK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAS_MSGHDR_FLAGS
|
||||||
|
if (msgHdr.msg_flags & MSG_TRUNC)
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (address != NULL)
|
||||||
|
{
|
||||||
|
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||||
|
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
return recvLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
|
||||||
|
{
|
||||||
|
struct timeval timeVal;
|
||||||
|
|
||||||
|
timeVal.tv_sec = timeout / 1000;
|
||||||
|
timeVal.tv_usec = (timeout % 1000) * 1000;
|
||||||
|
|
||||||
|
return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
|
||||||
|
{
|
||||||
|
#ifdef HAS_POLL
|
||||||
|
struct pollfd pollSocket;
|
||||||
|
int pollCount;
|
||||||
|
|
||||||
|
pollSocket.fd = socket;
|
||||||
|
pollSocket.events = 0;
|
||||||
|
|
||||||
|
if (* condition & ENET_SOCKET_WAIT_SEND)
|
||||||
|
pollSocket.events |= POLLOUT;
|
||||||
|
|
||||||
|
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
|
||||||
|
pollSocket.events |= POLLIN;
|
||||||
|
|
||||||
|
pollCount = poll (& pollSocket, 1, timeout);
|
||||||
|
|
||||||
|
if (pollCount < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
* condition = ENET_SOCKET_WAIT_NONE;
|
||||||
|
|
||||||
|
if (pollCount == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (pollSocket.revents & POLLOUT)
|
||||||
|
* condition |= ENET_SOCKET_WAIT_SEND;
|
||||||
|
|
||||||
|
if (pollSocket.revents & POLLIN)
|
||||||
|
* condition |= ENET_SOCKET_WAIT_RECEIVE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
fd_set readSet, writeSet;
|
||||||
|
struct timeval timeVal;
|
||||||
|
int selectCount;
|
||||||
|
|
||||||
|
timeVal.tv_sec = timeout / 1000;
|
||||||
|
timeVal.tv_usec = (timeout % 1000) * 1000;
|
||||||
|
|
||||||
|
FD_ZERO (& readSet);
|
||||||
|
FD_ZERO (& writeSet);
|
||||||
|
|
||||||
|
if (* condition & ENET_SOCKET_WAIT_SEND)
|
||||||
|
FD_SET (socket, & writeSet);
|
||||||
|
|
||||||
|
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
|
||||||
|
FD_SET (socket, & readSet);
|
||||||
|
|
||||||
|
selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
|
||||||
|
|
||||||
|
if (selectCount < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
* condition = ENET_SOCKET_WAIT_NONE;
|
||||||
|
|
||||||
|
if (selectCount == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (FD_ISSET (socket, & writeSet))
|
||||||
|
* condition |= ENET_SOCKET_WAIT_SEND;
|
||||||
|
|
||||||
|
if (FD_ISSET (socket, & readSet))
|
||||||
|
* condition |= ENET_SOCKET_WAIT_RECEIVE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
348
polymer/eduke32/source/enet/src/win32.c
Normal file
348
polymer/eduke32/source/enet/src/win32.c
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
/**
|
||||||
|
@file win32.c
|
||||||
|
@brief ENet Win32 system specific functions
|
||||||
|
*/
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#define ENET_BUILDING_LIB 1
|
||||||
|
#include "enet/enet.h"
|
||||||
|
|
||||||
|
static enet_uint32 timeBase = 0;
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_initialize (void)
|
||||||
|
{
|
||||||
|
WORD versionRequested = MAKEWORD (1, 1);
|
||||||
|
WSADATA wsaData;
|
||||||
|
|
||||||
|
if (WSAStartup (versionRequested, & wsaData))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (LOBYTE (wsaData.wVersion) != 1||
|
||||||
|
HIBYTE (wsaData.wVersion) != 1)
|
||||||
|
{
|
||||||
|
WSACleanup ();
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeBeginPeriod (1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_deinitialize (void)
|
||||||
|
{
|
||||||
|
timeEndPeriod (1);
|
||||||
|
|
||||||
|
WSACleanup ();
|
||||||
|
}
|
||||||
|
|
||||||
|
enet_uint32
|
||||||
|
enet_time_get (void)
|
||||||
|
{
|
||||||
|
return (enet_uint32) timeGetTime () - timeBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_time_set (enet_uint32 newTimeBase)
|
||||||
|
{
|
||||||
|
timeBase = (enet_uint32) timeGetTime () - newTimeBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_address_set_host (ENetAddress * address, const char * name)
|
||||||
|
{
|
||||||
|
struct hostent * hostEntry;
|
||||||
|
|
||||||
|
hostEntry = gethostbyname (name);
|
||||||
|
if (hostEntry == NULL ||
|
||||||
|
hostEntry -> h_addrtype != AF_INET)
|
||||||
|
{
|
||||||
|
unsigned long host = inet_addr (name);
|
||||||
|
if (host == INADDR_NONE)
|
||||||
|
return -1;
|
||||||
|
address -> host = host;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
|
||||||
|
{
|
||||||
|
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
|
||||||
|
if (addr == NULL)
|
||||||
|
return -1;
|
||||||
|
strncpy (name, addr, nameLength);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
|
||||||
|
{
|
||||||
|
struct in_addr in;
|
||||||
|
struct hostent * hostEntry;
|
||||||
|
|
||||||
|
in.s_addr = address -> host;
|
||||||
|
|
||||||
|
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
|
||||||
|
if (hostEntry == NULL)
|
||||||
|
return enet_address_get_host_ip (address, name, nameLength);
|
||||||
|
|
||||||
|
strncpy (name, hostEntry -> h_name, nameLength);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||||
|
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
|
||||||
|
if (address != NULL)
|
||||||
|
{
|
||||||
|
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||||
|
sin.sin_addr.s_addr = address -> host;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sin.sin_port = 0;
|
||||||
|
sin.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bind (socket,
|
||||||
|
(struct sockaddr *) & sin,
|
||||||
|
sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_listen (ENetSocket socket, int backlog)
|
||||||
|
{
|
||||||
|
return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetSocket
|
||||||
|
enet_socket_create (ENetSocketType type)
|
||||||
|
{
|
||||||
|
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||||
|
{
|
||||||
|
int result = SOCKET_ERROR;
|
||||||
|
switch (option)
|
||||||
|
{
|
||||||
|
case ENET_SOCKOPT_NONBLOCK:
|
||||||
|
{
|
||||||
|
u_long nonBlocking = (u_long) value;
|
||||||
|
result = ioctlsocket (socket, FIONBIO, & nonBlocking);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_BROADCAST:
|
||||||
|
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_REUSEADDR:
|
||||||
|
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_RCVBUF:
|
||||||
|
result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_SNDBUF:
|
||||||
|
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result == SOCKET_ERROR ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||||
|
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||||
|
sin.sin_addr.s_addr = address -> host;
|
||||||
|
|
||||||
|
return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetSocket
|
||||||
|
enet_socket_accept (ENetSocket socket, ENetAddress * address)
|
||||||
|
{
|
||||||
|
SOCKET result;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
int sinLength = sizeof (struct sockaddr_in);
|
||||||
|
|
||||||
|
result = accept (socket,
|
||||||
|
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||||
|
address != NULL ? & sinLength : NULL);
|
||||||
|
|
||||||
|
if (result == INVALID_SOCKET)
|
||||||
|
return ENET_SOCKET_NULL;
|
||||||
|
|
||||||
|
if (address != NULL)
|
||||||
|
{
|
||||||
|
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||||
|
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_socket_destroy (ENetSocket socket)
|
||||||
|
{
|
||||||
|
closesocket (socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_send (ENetSocket socket,
|
||||||
|
const ENetAddress * address,
|
||||||
|
const ENetBuffer * buffers,
|
||||||
|
size_t bufferCount)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
DWORD sentLength;
|
||||||
|
|
||||||
|
if (address != NULL)
|
||||||
|
{
|
||||||
|
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||||
|
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||||
|
sin.sin_addr.s_addr = address -> host;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WSASendTo (socket,
|
||||||
|
(LPWSABUF) buffers,
|
||||||
|
(DWORD) bufferCount,
|
||||||
|
& sentLength,
|
||||||
|
0,
|
||||||
|
address != NULL ? (struct sockaddr *) & sin : 0,
|
||||||
|
address != NULL ? sizeof (struct sockaddr_in) : 0,
|
||||||
|
NULL,
|
||||||
|
NULL) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
if (WSAGetLastError () == WSAEWOULDBLOCK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) sentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_receive (ENetSocket socket,
|
||||||
|
ENetAddress * address,
|
||||||
|
ENetBuffer * buffers,
|
||||||
|
size_t bufferCount)
|
||||||
|
{
|
||||||
|
INT sinLength = sizeof (struct sockaddr_in);
|
||||||
|
DWORD flags = 0,
|
||||||
|
recvLength;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
if (WSARecvFrom (socket,
|
||||||
|
(LPWSABUF) buffers,
|
||||||
|
(DWORD) bufferCount,
|
||||||
|
& recvLength,
|
||||||
|
& flags,
|
||||||
|
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||||
|
address != NULL ? & sinLength : NULL,
|
||||||
|
NULL,
|
||||||
|
NULL) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
switch (WSAGetLastError ())
|
||||||
|
{
|
||||||
|
case WSAEWOULDBLOCK:
|
||||||
|
case WSAECONNRESET:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & MSG_PARTIAL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (address != NULL)
|
||||||
|
{
|
||||||
|
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||||
|
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) recvLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
|
||||||
|
{
|
||||||
|
struct timeval timeVal;
|
||||||
|
|
||||||
|
timeVal.tv_sec = timeout / 1000;
|
||||||
|
timeVal.tv_usec = (timeout % 1000) * 1000;
|
||||||
|
|
||||||
|
return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
|
||||||
|
{
|
||||||
|
fd_set readSet, writeSet;
|
||||||
|
struct timeval timeVal;
|
||||||
|
int selectCount;
|
||||||
|
|
||||||
|
timeVal.tv_sec = timeout / 1000;
|
||||||
|
timeVal.tv_usec = (timeout % 1000) * 1000;
|
||||||
|
|
||||||
|
FD_ZERO (& readSet);
|
||||||
|
FD_ZERO (& writeSet);
|
||||||
|
|
||||||
|
if (* condition & ENET_SOCKET_WAIT_SEND)
|
||||||
|
FD_SET (socket, & writeSet);
|
||||||
|
|
||||||
|
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
|
||||||
|
FD_SET (socket, & readSet);
|
||||||
|
|
||||||
|
selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
|
||||||
|
|
||||||
|
if (selectCount < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
* condition = ENET_SOCKET_WAIT_NONE;
|
||||||
|
|
||||||
|
if (selectCount == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (FD_ISSET (socket, & writeSet))
|
||||||
|
* condition |= ENET_SOCKET_WAIT_SEND;
|
||||||
|
|
||||||
|
if (FD_ISSET (socket, & readSet))
|
||||||
|
* condition |= ENET_SOCKET_WAIT_RECEIVE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -183,6 +183,7 @@ extern int32_t A_IncurDamage(int32_t sn);
|
||||||
extern void G_MoveWorld(void);
|
extern void G_MoveWorld(void);
|
||||||
extern void A_MoveCyclers(void);
|
extern void A_MoveCyclers(void);
|
||||||
extern void A_MoveDummyPlayers(void);
|
extern void A_MoveDummyPlayers(void);
|
||||||
|
extern void P_ResetStatus(int32_t snum);
|
||||||
|
|
||||||
// game.c
|
// game.c
|
||||||
extern inline void G_SetStatusBarScale(int32_t sc);
|
extern inline void G_SetStatusBarScale(int32_t sc);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5358,8 +5358,6 @@ repeatcase:
|
||||||
else if ((Bstrlen(tempbuf)+1) > sizeof(MapInfo[j*MAXLEVELS+k].filename))
|
else if ((Bstrlen(tempbuf)+1) > sizeof(MapInfo[j*MAXLEVELS+k].filename))
|
||||||
MapInfo[j*MAXLEVELS+k].filename = Brealloc(MapInfo[j*MAXLEVELS+k].filename,(Bstrlen(tempbuf)+1));
|
MapInfo[j*MAXLEVELS+k].filename = Brealloc(MapInfo[j*MAXLEVELS+k].filename,(Bstrlen(tempbuf)+1));
|
||||||
|
|
||||||
/* initprintf("level file name string len: %d\n",Bstrlen(tempbuf)); */
|
|
||||||
|
|
||||||
Bstrcpy(MapInfo[j*MAXLEVELS+k].filename,tempbuf);
|
Bstrcpy(MapInfo[j*MAXLEVELS+k].filename,tempbuf);
|
||||||
|
|
||||||
C_SkipComments();
|
C_SkipComments();
|
||||||
|
@ -5581,19 +5579,15 @@ repeatcase:
|
||||||
|
|
||||||
C_GetNextValue(LABEL_DEFINE);
|
C_GetNextValue(LABEL_DEFINE);
|
||||||
g_sounds[k].ps = *(g_scriptPtr-1);
|
g_sounds[k].ps = *(g_scriptPtr-1);
|
||||||
g_scriptPtr--;
|
|
||||||
C_GetNextValue(LABEL_DEFINE);
|
C_GetNextValue(LABEL_DEFINE);
|
||||||
g_sounds[k].pe = *(g_scriptPtr-1);
|
g_sounds[k].pe = *(g_scriptPtr-1);
|
||||||
g_scriptPtr--;
|
|
||||||
C_GetNextValue(LABEL_DEFINE);
|
C_GetNextValue(LABEL_DEFINE);
|
||||||
g_sounds[k].pr = *(g_scriptPtr-1);
|
g_sounds[k].pr = *(g_scriptPtr-1);
|
||||||
g_scriptPtr--;
|
|
||||||
C_GetNextValue(LABEL_DEFINE);
|
C_GetNextValue(LABEL_DEFINE);
|
||||||
g_sounds[k].m = *(g_scriptPtr-1);
|
g_sounds[k].m = *(g_scriptPtr-1);
|
||||||
g_scriptPtr--;
|
|
||||||
C_GetNextValue(LABEL_DEFINE);
|
C_GetNextValue(LABEL_DEFINE);
|
||||||
g_sounds[k].vo = *(g_scriptPtr-1);
|
g_sounds[k].vo = *(g_scriptPtr-1);
|
||||||
g_scriptPtr--;
|
g_scriptPtr -= 5;
|
||||||
|
|
||||||
if (k > g_maxSoundPos)
|
if (k > g_maxSoundPos)
|
||||||
g_maxSoundPos = k;
|
g_maxSoundPos = k;
|
||||||
|
@ -5627,8 +5621,7 @@ repeatcase:
|
||||||
*(g_scriptPtr++) = CON_ENDEVENT;
|
*(g_scriptPtr++) = CON_ENDEVENT;
|
||||||
previous_event = NULL;
|
previous_event = NULL;
|
||||||
}
|
}
|
||||||
g_parsingEventPtr = 0;
|
g_parsingEventPtr = g_parsingActorPtr = 0;
|
||||||
g_parsingActorPtr = 0;
|
|
||||||
g_currentEvent = -1;
|
g_currentEvent = -1;
|
||||||
Bsprintf(g_szCurrentBlockName,"(none)");
|
Bsprintf(g_szCurrentBlockName,"(none)");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -105,10 +105,6 @@ extern "C" {
|
||||||
|
|
||||||
#define MAXJOYAXES 8
|
#define MAXJOYAXES 8
|
||||||
|
|
||||||
// Number of GAMEPAD axes
|
|
||||||
|
|
||||||
#define MAXGAMEPADAXES 2
|
|
||||||
|
|
||||||
// MIN/MAX scale value for controller scales
|
// MIN/MAX scale value for controller scales
|
||||||
|
|
||||||
#define MAXCONTROLSCALEVALUE (1<<19)
|
#define MAXCONTROLSCALEVALUE (1<<19)
|
||||||
|
|
|
@ -39,6 +39,7 @@ vmstate_t vm;
|
||||||
|
|
||||||
int32_t g_errorLineNum;
|
int32_t g_errorLineNum;
|
||||||
int32_t g_tw;
|
int32_t g_tw;
|
||||||
|
extern int32_t ticrandomseed;
|
||||||
|
|
||||||
static int32_t X_DoExecute(int32_t once);
|
static int32_t X_DoExecute(int32_t once);
|
||||||
|
|
||||||
|
@ -1824,7 +1825,7 @@ nullquote:
|
||||||
|
|
||||||
ud.m_volume_number = ud.volume_number = volnume;
|
ud.m_volume_number = ud.volume_number = volnume;
|
||||||
ud.m_level_number = ud.level_number = levnume;
|
ud.m_level_number = ud.level_number = levnume;
|
||||||
if (numplayers > 1 && myconnectindex == connecthead)
|
if (numplayers > 1 && net_server)
|
||||||
Net_NewGame(volnume,levnume);
|
Net_NewGame(volnume,levnume);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2712,7 +2713,7 @@ nullquote:
|
||||||
|
|
||||||
g_lastSaveSlot = *insptr++;
|
g_lastSaveSlot = *insptr++;
|
||||||
|
|
||||||
if ((g_movesPerPacket == 4 && connecthead != myconnectindex) || g_lastSaveSlot > 9)
|
if (g_lastSaveSlot > 9)
|
||||||
continue;
|
continue;
|
||||||
if ((tw == CON_SAVE) || !(ud.savegame[g_lastSaveSlot][0]))
|
if ((tw == CON_SAVE) || !(ud.savegame[g_lastSaveSlot][0]))
|
||||||
{
|
{
|
||||||
|
@ -4703,6 +4704,9 @@ void A_Execute(int32_t iActor,int32_t iPlayer,int32_t lDist)
|
||||||
|
|
||||||
// if (actorscrptr[sprite[iActor].picnum] == 0) return;
|
// if (actorscrptr[sprite[iActor].picnum] == 0) return;
|
||||||
|
|
||||||
|
if (net_server || net_client)
|
||||||
|
randomseed = ticrandomseed;
|
||||||
|
|
||||||
vm.g_i = iActor; // Sprite ID
|
vm.g_i = iActor; // Sprite ID
|
||||||
vm.g_p = iPlayer; // Player ID
|
vm.g_p = iPlayer; // Player ID
|
||||||
vm.g_x = lDist; // ?
|
vm.g_x = lDist; // ?
|
||||||
|
@ -4996,9 +5000,15 @@ void G_RestoreMapState(mapstate_t *save)
|
||||||
{
|
{
|
||||||
if (aGameVars[i].dwFlags & GAMEVAR_NORESET) continue;
|
if (aGameVars[i].dwFlags & GAMEVAR_NORESET) continue;
|
||||||
if (aGameVars[i].dwFlags & GAMEVAR_PERPLAYER)
|
if (aGameVars[i].dwFlags & GAMEVAR_PERPLAYER)
|
||||||
|
{
|
||||||
|
if (!save->vars[i]) continue;
|
||||||
Bmemcpy(&aGameVars[i].val.plValues[0],&save->vars[i][0],sizeof(intptr_t) * MAXPLAYERS);
|
Bmemcpy(&aGameVars[i].val.plValues[0],&save->vars[i][0],sizeof(intptr_t) * MAXPLAYERS);
|
||||||
|
}
|
||||||
else if (aGameVars[i].dwFlags & GAMEVAR_PERACTOR)
|
else if (aGameVars[i].dwFlags & GAMEVAR_PERACTOR)
|
||||||
|
{
|
||||||
|
if (!save->vars[i]) continue;
|
||||||
Bmemcpy(&aGameVars[i].val.plValues[0],&save->vars[i][0],sizeof(intptr_t) * MAXSPRITES);
|
Bmemcpy(&aGameVars[i].val.plValues[0],&save->vars[i][0],sizeof(intptr_t) * MAXSPRITES);
|
||||||
|
}
|
||||||
else aGameVars[i].val.lValue = (intptr_t)save->vars[i];
|
else aGameVars[i].val.lValue = (intptr_t)save->vars[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5082,7 +5092,6 @@ void G_RestoreMapState(mapstate_t *save)
|
||||||
Net_ResetPrediction();
|
Net_ResetPrediction();
|
||||||
|
|
||||||
Net_WaitForEverybody();
|
Net_WaitForEverybody();
|
||||||
mmulti_flushpackets();
|
|
||||||
clearfifo();
|
clearfifo();
|
||||||
G_ResetTimers();
|
G_ResetTimers();
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ int16_t cyclers[MAXCYCLERS][6],g_numCyclers;
|
||||||
|
|
||||||
char *ScriptQuotes[MAXQUOTES], *ScriptQuoteRedefinitions[MAXQUOTES];
|
char *ScriptQuotes[MAXQUOTES], *ScriptQuoteRedefinitions[MAXQUOTES];
|
||||||
|
|
||||||
char tempbuf[2048], packbuf[576], menutextbuf[128], buf[1024];
|
char tempbuf[2048], packbuf[4096], menutextbuf[128], buf[1024];
|
||||||
|
|
||||||
int16_t camsprite;
|
int16_t camsprite;
|
||||||
int16_t g_mirrorWall[64], g_mirrorSector[64], g_mirrorCount;
|
int16_t g_mirrorWall[64], g_mirrorSector[64], g_mirrorCount;
|
||||||
|
@ -163,7 +163,7 @@ int32_t myhorizbak[MOVEFIFOSIZ],g_playerFriction = 0xcc00, g_showShareware;
|
||||||
int16_t myangbak[MOVEFIFOSIZ];
|
int16_t myangbak[MOVEFIFOSIZ];
|
||||||
char szPlayerName[32];
|
char szPlayerName[32];
|
||||||
int32_t g_damageCameras,g_freezerSelfDamage=0,g_tripbombLaserMode=0;
|
int32_t g_damageCameras,g_freezerSelfDamage=0,g_tripbombLaserMode=0;
|
||||||
int32_t g_networkBroadcastMode = 255, g_movesPerPacket = 1,g_gameQuit = 0,everyothertime;
|
int32_t g_gameQuit = 0,everyothertime;
|
||||||
int32_t g_numFreezeBounces=3,g_rpgBlastRadius,g_pipebombBlastRadius,g_tripbombBlastRadius,
|
int32_t g_numFreezeBounces=3,g_rpgBlastRadius,g_pipebombBlastRadius,g_tripbombBlastRadius,
|
||||||
g_shrinkerBlastRadius,g_morterBlastRadius,g_bouncemineBlastRadius,g_seenineBlastRadius;
|
g_shrinkerBlastRadius,g_morterBlastRadius,g_bouncemineBlastRadius,g_seenineBlastRadius;
|
||||||
DukeStatus_t sbar;
|
DukeStatus_t sbar;
|
||||||
|
@ -185,7 +185,6 @@ projectile_t ProjectileData[MAXTILES], DefaultProjectileData[MAXTILES], SpritePr
|
||||||
|
|
||||||
char CheatKeys[2] = { sc_D, sc_N };
|
char CheatKeys[2] = { sc_D, sc_N };
|
||||||
char setupfilename[BMAX_PATH]= SETUPFILENAME;
|
char setupfilename[BMAX_PATH]= SETUPFILENAME;
|
||||||
// char datetimestring[] = ""__DATE__" "__TIME__"";
|
|
||||||
|
|
||||||
int32_t g_doQuickSave = 0;
|
int32_t g_doQuickSave = 0;
|
||||||
uint32_t g_moveThingsCount = 0;
|
uint32_t g_moveThingsCount = 0;
|
||||||
|
|
|
@ -318,7 +318,10 @@ int32_t DirectSoundDrv_PCM_Init(int32_t *mixrate, int32_t *numchannels, int32_t
|
||||||
|
|
||||||
memset(&bufdesc, 0, sizeof(DSBUFFERDESC));
|
memset(&bufdesc, 0, sizeof(DSBUFFERDESC));
|
||||||
bufdesc.dwSize = sizeof(DSBUFFERDESC);
|
bufdesc.dwSize = sizeof(DSBUFFERDESC);
|
||||||
bufdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
bufdesc.dwFlags = DSBCAPS_LOCSOFTWARE |
|
||||||
|
DSBCAPS_PRIMARYBUFFER |
|
||||||
|
DSBCAPS_GETCURRENTPOSITION2 |
|
||||||
|
DSBCAPS_STICKYFOCUS ;
|
||||||
|
|
||||||
err = IDirectSound_CreateSoundBuffer(lpds, &bufdesc, &lpdsbprimary, 0);
|
err = IDirectSound_CreateSoundBuffer(lpds, &bufdesc, &lpdsbprimary, 0);
|
||||||
if (FAILED( err )) {
|
if (FAILED( err )) {
|
||||||
|
@ -344,8 +347,9 @@ int32_t DirectSoundDrv_PCM_Init(int32_t *mixrate, int32_t *numchannels, int32_t
|
||||||
|
|
||||||
bufdesc.dwFlags = DSBCAPS_LOCSOFTWARE |
|
bufdesc.dwFlags = DSBCAPS_LOCSOFTWARE |
|
||||||
DSBCAPS_CTRLPOSITIONNOTIFY |
|
DSBCAPS_CTRLPOSITIONNOTIFY |
|
||||||
DSBCAPS_GETCURRENTPOSITION2;
|
DSBCAPS_GETCURRENTPOSITION2 |
|
||||||
bufdesc.dwBufferBytes = wfex.nBlockAlign * 2048 * 2;
|
DSBCAPS_STICKYFOCUS ;
|
||||||
|
bufdesc.dwBufferBytes = wfex.nBlockAlign * 2560 * 2;
|
||||||
bufdesc.lpwfxFormat = &wfex;
|
bufdesc.lpwfxFormat = &wfex;
|
||||||
|
|
||||||
err = IDirectSound_CreateSoundBuffer(lpds, &bufdesc, &lpdsbsec, 0);
|
err = IDirectSound_CreateSoundBuffer(lpds, &bufdesc, &lpdsbsec, 0);
|
||||||
|
|
|
@ -159,22 +159,18 @@ uint32_t MV_MixPosition;
|
||||||
int32_t MV_ErrorCode = MV_Ok;
|
int32_t MV_ErrorCode = MV_Ok;
|
||||||
|
|
||||||
static int32_t lockdepth = 0;
|
static int32_t lockdepth = 0;
|
||||||
static int32_t DisableInterrupts(void)
|
static void DisableInterrupts(void)
|
||||||
{
|
{
|
||||||
if (lockdepth++ > 0)
|
if (lockdepth++ > 0)
|
||||||
{
|
return;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
SoundDriver_Lock();
|
SoundDriver_Lock();
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RestoreInterrupts(int32_t a)
|
static void RestoreInterrupts(void)
|
||||||
{
|
{
|
||||||
if (--lockdepth > 0)
|
if (--lockdepth > 0)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
SoundDriver_Unlock();
|
SoundDriver_Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,12 +357,11 @@ void MV_PlayVoice
|
||||||
)
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
int32_t flags;
|
|
||||||
|
|
||||||
flags = DisableInterrupts();
|
DisableInterrupts();
|
||||||
LL_SortedInsertion(&VoiceList, voice, prev, next, VoiceNode, priority);
|
LL_SortedInsertion(&VoiceList, voice, prev, next, VoiceNode, priority);
|
||||||
|
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -382,15 +377,13 @@ void MV_StopVoice
|
||||||
)
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
int32_t flags;
|
DisableInterrupts();
|
||||||
|
|
||||||
flags = DisableInterrupts();
|
|
||||||
|
|
||||||
// move the voice from the play list to the free list
|
// move the voice from the play list to the free list
|
||||||
LL_Remove(voice, next, prev);
|
LL_Remove(voice, next, prev);
|
||||||
LL_Add((VoiceNode*) &VoicePool, voice, next, prev);
|
LL_Add((VoiceNode*) &VoicePool, voice, next, prev);
|
||||||
|
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
|
|
||||||
if (voice->wavetype == Vorbis)
|
if (voice->wavetype == Vorbis)
|
||||||
{
|
{
|
||||||
|
@ -501,49 +494,47 @@ void MV_ServiceVoc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Play any waiting voices
|
// Play any waiting voices
|
||||||
//flags = DisableInterrupts();
|
//DisableInterrupts();
|
||||||
|
|
||||||
if (!VoiceList.next)
|
if (!VoiceList.next || (voice = VoiceList.next) == &VoiceList)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (voice = VoiceList.next; voice != &VoiceList; voice = next)
|
do
|
||||||
{
|
{
|
||||||
if ( voice->Paused )
|
next = voice->next;
|
||||||
{
|
|
||||||
next = voice->next;
|
if (voice->Paused)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
MV_BufferEmpty[ MV_MixPage ] = FALSE;
|
MV_BufferEmpty[ MV_MixPage ] = FALSE;
|
||||||
|
|
||||||
// if (!voice->Paused)
|
MV_MixFunction(voice, MV_MixPage);
|
||||||
MV_MixFunction(voice, MV_MixPage);
|
|
||||||
|
|
||||||
next = voice->next;
|
|
||||||
|
|
||||||
// Is this voice done?
|
// Is this voice done?
|
||||||
if (!voice->Playing/* && !voice->Paused*/)
|
if (!voice->Playing)
|
||||||
{
|
{
|
||||||
//JBF: prevent a deadlock caused by MV_StopVoice grabbing the mutex again
|
//JBF: prevent a deadlock caused by MV_StopVoice grabbing the mutex again
|
||||||
//MV_StopVoice( voice );
|
//MV_StopVoice( voice );
|
||||||
LL_Remove(voice, next, prev);
|
LL_Remove(voice, next, prev);
|
||||||
LL_Add((VoiceNode*) &VoicePool, voice, next, prev);
|
LL_Add((VoiceNode*) &VoicePool, voice, next, prev);
|
||||||
|
|
||||||
|
if (voice->wavetype == Vorbis)
|
||||||
|
MV_ReleaseVorbisVoice(voice);
|
||||||
|
|
||||||
if (MV_CallBackFunc)
|
if (MV_CallBackFunc)
|
||||||
{
|
|
||||||
MV_CallBackFunc(voice->callbackval);
|
MV_CallBackFunc(voice->callbackval);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while ((voice = next) != &VoiceList);
|
||||||
|
|
||||||
//RestoreInterrupts(flags);
|
//RestoreInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------
|
/*---------------------------------------------------------------------
|
||||||
Function: MV_GetNextVOCBlock
|
Function: MV_GetNextVOCBlock
|
||||||
|
|
||||||
Interperate the information of a VOC format sound file.
|
Interpret the information of a VOC format sound file.
|
||||||
---------------------------------------------------------------------*/
|
---------------------------------------------------------------------*/
|
||||||
|
|
||||||
playbackstatus MV_GetNextVOCBlock
|
playbackstatus MV_GetNextVOCBlock
|
||||||
|
@ -585,7 +576,8 @@ playbackstatus MV_GetNextVOCBlock
|
||||||
packtype = 0;
|
packtype = 0;
|
||||||
|
|
||||||
done = FALSE;
|
done = FALSE;
|
||||||
while (!done)
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
// Stop playing if we get a NULL pointer
|
// Stop playing if we get a NULL pointer
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
|
@ -753,6 +745,7 @@ playbackstatus MV_GetNextVOCBlock
|
||||||
|
|
||||||
lastblocktype = blocktype;
|
lastblocktype = blocktype;
|
||||||
}
|
}
|
||||||
|
while (!done);
|
||||||
|
|
||||||
if (voice->Playing)
|
if (voice->Playing)
|
||||||
{
|
{
|
||||||
|
@ -963,9 +956,8 @@ VoiceNode *MV_GetVoice
|
||||||
|
|
||||||
{
|
{
|
||||||
VoiceNode *voice;
|
VoiceNode *voice;
|
||||||
int32_t flags;
|
|
||||||
|
|
||||||
flags = DisableInterrupts();
|
DisableInterrupts();
|
||||||
|
|
||||||
for (voice = VoiceList.next; voice != &VoiceList; voice = voice->next)
|
for (voice = VoiceList.next; voice != &VoiceList; voice = voice->next)
|
||||||
{
|
{
|
||||||
|
@ -975,7 +967,7 @@ VoiceNode *MV_GetVoice
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
|
|
||||||
if (voice == &VoiceList)
|
if (voice == &VoiceList)
|
||||||
{
|
{
|
||||||
|
@ -1031,8 +1023,7 @@ int32_t MV_KillAllVoices
|
||||||
)
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
VoiceNode * voice, * next;
|
VoiceNode * voice = VoiceList.prev;
|
||||||
int32_t flags;
|
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
{
|
||||||
|
@ -1040,19 +1031,25 @@ int32_t MV_KillAllVoices
|
||||||
return(MV_Error);
|
return(MV_Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = DisableInterrupts();
|
if (&VoiceList == VoiceList.next)
|
||||||
|
return(MV_Ok);
|
||||||
|
|
||||||
|
DisableInterrupts();
|
||||||
|
|
||||||
// Remove all the voices from the list
|
// Remove all the voices from the list
|
||||||
for (voice = VoiceList.next; voice != &VoiceList; voice = next)
|
while (voice != &VoiceList)
|
||||||
{
|
{
|
||||||
next = voice->next;
|
if (voice->priority == MV_MUSIC_PRIORITY)
|
||||||
if (voice->priority < MV_MUSIC_PRIORITY)
|
|
||||||
{
|
{
|
||||||
MV_Kill(voice->handle);
|
voice = voice->prev;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MV_Kill(voice->handle);
|
||||||
|
voice = VoiceList.prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
|
|
||||||
return(MV_Ok);
|
return(MV_Ok);
|
||||||
}
|
}
|
||||||
|
@ -1071,7 +1068,6 @@ int32_t MV_Kill
|
||||||
|
|
||||||
{
|
{
|
||||||
VoiceNode *voice;
|
VoiceNode *voice;
|
||||||
int32_t flags;
|
|
||||||
uint32_t callbackval;
|
uint32_t callbackval;
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
|
@ -1080,12 +1076,12 @@ int32_t MV_Kill
|
||||||
return(MV_Error);
|
return(MV_Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = DisableInterrupts();
|
DisableInterrupts();
|
||||||
|
|
||||||
voice = MV_GetVoice(handle);
|
voice = MV_GetVoice(handle);
|
||||||
if (voice == NULL)
|
if (voice == NULL)
|
||||||
{
|
{
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
MV_SetErrorCode(MV_VoiceNotFound);
|
MV_SetErrorCode(MV_VoiceNotFound);
|
||||||
return(MV_Error);
|
return(MV_Error);
|
||||||
}
|
}
|
||||||
|
@ -1094,7 +1090,7 @@ int32_t MV_Kill
|
||||||
|
|
||||||
MV_StopVoice(voice);
|
MV_StopVoice(voice);
|
||||||
|
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
|
|
||||||
if (MV_CallBackFunc)
|
if (MV_CallBackFunc)
|
||||||
{
|
{
|
||||||
|
@ -1119,7 +1115,6 @@ int32_t MV_VoicesPlaying
|
||||||
{
|
{
|
||||||
VoiceNode *voice;
|
VoiceNode *voice;
|
||||||
int32_t NumVoices = 0;
|
int32_t NumVoices = 0;
|
||||||
int32_t flags;
|
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
{
|
||||||
|
@ -1127,14 +1122,14 @@ int32_t MV_VoicesPlaying
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = DisableInterrupts();
|
DisableInterrupts();
|
||||||
|
|
||||||
for (voice = VoiceList.next; voice != &VoiceList; voice = voice->next)
|
for (voice = VoiceList.next; voice != &VoiceList; voice = voice->next)
|
||||||
{
|
{
|
||||||
NumVoices++;
|
NumVoices++;
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
|
|
||||||
return(NumVoices);
|
return(NumVoices);
|
||||||
}
|
}
|
||||||
|
@ -1154,15 +1149,13 @@ VoiceNode *MV_AllocVoice
|
||||||
{
|
{
|
||||||
VoiceNode *voice;
|
VoiceNode *voice;
|
||||||
VoiceNode *node;
|
VoiceNode *node;
|
||||||
int32_t flags;
|
|
||||||
|
|
||||||
//return( NULL );
|
|
||||||
if (MV_Recording)
|
if (MV_Recording)
|
||||||
{
|
{
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = DisableInterrupts();
|
DisableInterrupts();
|
||||||
|
|
||||||
// Check if we have any free voices
|
// Check if we have any free voices
|
||||||
if (LL_Empty(&VoicePool, next, prev))
|
if (LL_Empty(&VoicePool, next, prev))
|
||||||
|
@ -1187,13 +1180,13 @@ VoiceNode *MV_AllocVoice
|
||||||
if (LL_Empty(&VoicePool, next, prev))
|
if (LL_Empty(&VoicePool, next, prev))
|
||||||
{
|
{
|
||||||
// No free voices
|
// No free voices
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
voice = VoicePool.next;
|
voice = VoicePool.next;
|
||||||
LL_Remove(voice, next, prev);
|
LL_Remove(voice, next, prev);
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
|
|
||||||
// Find a free voice handle
|
// Find a free voice handle
|
||||||
do
|
do
|
||||||
|
@ -1226,7 +1219,6 @@ int32_t MV_VoiceAvailable
|
||||||
{
|
{
|
||||||
VoiceNode *voice;
|
VoiceNode *voice;
|
||||||
VoiceNode *node;
|
VoiceNode *node;
|
||||||
int32_t flags;
|
|
||||||
|
|
||||||
// Check if we have any free voices
|
// Check if we have any free voices
|
||||||
if (!LL_Empty(&VoicePool, next, prev))
|
if (!LL_Empty(&VoicePool, next, prev))
|
||||||
|
@ -1234,7 +1226,7 @@ int32_t MV_VoiceAvailable
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = DisableInterrupts();
|
DisableInterrupts();
|
||||||
|
|
||||||
// check if we have a higher priority than a voice that is playing.
|
// check if we have a higher priority than a voice that is playing.
|
||||||
voice = VoiceList.next;
|
voice = VoiceList.next;
|
||||||
|
@ -1246,7 +1238,7 @@ int32_t MV_VoiceAvailable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
|
|
||||||
if ((voice != &VoiceList) && (priority >= voice->priority))
|
if ((voice != &VoiceList) && (priority >= voice->priority))
|
||||||
{
|
{
|
||||||
|
@ -1411,7 +1403,7 @@ void MV_SetVoiceMixMode
|
||||||
//int32_t flags;
|
//int32_t flags;
|
||||||
int32_t test;
|
int32_t test;
|
||||||
|
|
||||||
//flags = DisableInterrupts();
|
//DisableInterrupts();
|
||||||
|
|
||||||
test = T_DEFAULT;
|
test = T_DEFAULT;
|
||||||
if (MV_Bits == 8)
|
if (MV_Bits == 8)
|
||||||
|
@ -1608,7 +1600,6 @@ int32_t MV_PauseVoice
|
||||||
|
|
||||||
{
|
{
|
||||||
VoiceNode *voice;
|
VoiceNode *voice;
|
||||||
int32_t flags;
|
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
{
|
||||||
|
@ -1616,19 +1607,19 @@ int32_t MV_PauseVoice
|
||||||
return(MV_Error);
|
return(MV_Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = DisableInterrupts();
|
DisableInterrupts();
|
||||||
|
|
||||||
voice = MV_GetVoice(handle);
|
voice = MV_GetVoice(handle);
|
||||||
if (voice == NULL)
|
if (voice == NULL)
|
||||||
{
|
{
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
MV_SetErrorCode(MV_VoiceNotFound);
|
MV_SetErrorCode(MV_VoiceNotFound);
|
||||||
return(MV_Warning);
|
return(MV_Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
voice->Paused = pause;
|
voice->Paused = pause;
|
||||||
|
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
|
|
||||||
return(MV_Ok);
|
return(MV_Ok);
|
||||||
}
|
}
|
||||||
|
@ -1648,7 +1639,6 @@ int32_t MV_EndLooping
|
||||||
|
|
||||||
{
|
{
|
||||||
VoiceNode *voice;
|
VoiceNode *voice;
|
||||||
int32_t flags;
|
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
{
|
||||||
|
@ -1656,12 +1646,12 @@ int32_t MV_EndLooping
|
||||||
return(MV_Error);
|
return(MV_Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = DisableInterrupts();
|
DisableInterrupts();
|
||||||
|
|
||||||
voice = MV_GetVoice(handle);
|
voice = MV_GetVoice(handle);
|
||||||
if (voice == NULL)
|
if (voice == NULL)
|
||||||
{
|
{
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
MV_SetErrorCode(MV_VoiceNotFound);
|
MV_SetErrorCode(MV_VoiceNotFound);
|
||||||
return(MV_Warning);
|
return(MV_Warning);
|
||||||
}
|
}
|
||||||
|
@ -1670,7 +1660,7 @@ int32_t MV_EndLooping
|
||||||
voice->LoopStart = NULL;
|
voice->LoopStart = NULL;
|
||||||
voice->LoopEnd = NULL;
|
voice->LoopEnd = NULL;
|
||||||
|
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
|
|
||||||
return(MV_Ok);
|
return(MV_Ok);
|
||||||
}
|
}
|
||||||
|
@ -1974,13 +1964,12 @@ void MV_StopPlayback
|
||||||
{
|
{
|
||||||
VoiceNode *voice;
|
VoiceNode *voice;
|
||||||
VoiceNode *next;
|
VoiceNode *next;
|
||||||
int32_t flags;
|
|
||||||
|
|
||||||
// Stop sound playback
|
// Stop sound playback
|
||||||
SoundDriver_StopPlayback();
|
SoundDriver_StopPlayback();
|
||||||
|
|
||||||
// Make sure all callbacks are done.
|
// Make sure all callbacks are done.
|
||||||
flags = DisableInterrupts();
|
DisableInterrupts();
|
||||||
|
|
||||||
for (voice = VoiceList.next; voice != &VoiceList; voice = next)
|
for (voice = VoiceList.next; voice != &VoiceList; voice = next)
|
||||||
{
|
{
|
||||||
|
@ -1994,7 +1983,7 @@ void MV_StopPlayback
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreInterrupts(flags);
|
RestoreInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -94,15 +94,7 @@ extern "C" {
|
||||||
|
|
||||||
// Number of JOY axes
|
// Number of JOY axes
|
||||||
|
|
||||||
#define MAXJOYAXES 6
|
#define MAXJOYAXES 8
|
||||||
|
|
||||||
// Number of GamePad axes
|
|
||||||
|
|
||||||
#define MAXGAMEPADAXES 2
|
|
||||||
|
|
||||||
// Number of axes
|
|
||||||
|
|
||||||
#define MAXAXES 6
|
|
||||||
|
|
||||||
// NORMAL axis scale
|
// NORMAL axis scale
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ static int32_t CONTROL_MouseButtonClicked[MAXMOUSEBUTTONS], CONTROL_JoyButt
|
||||||
static uint8_t CONTROL_MouseButtonClickedCount[MAXMOUSEBUTTONS], CONTROL_JoyButtonClickedCount[MAXJOYBUTTONS];
|
static uint8_t CONTROL_MouseButtonClickedCount[MAXMOUSEBUTTONS], CONTROL_JoyButtonClickedCount[MAXJOYBUTTONS];
|
||||||
static int32_t CONTROL_UserInputCleared[3];
|
static int32_t CONTROL_UserInputCleared[3];
|
||||||
static int32_t(*GetTime)(void);
|
static int32_t(*GetTime)(void);
|
||||||
static int32_t CONTROL_Started = FALSE;
|
int32_t CONTROL_Started = FALSE;
|
||||||
static int32_t ticrate;
|
static int32_t ticrate;
|
||||||
static int32_t CONTROL_DoubleClickSpeed;
|
static int32_t CONTROL_DoubleClickSpeed;
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,7 @@ typedef enum
|
||||||
//
|
//
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
|
|
||||||
|
extern int32_t CONTROL_Started;
|
||||||
extern int32_t CONTROL_MousePresent;
|
extern int32_t CONTROL_MousePresent;
|
||||||
extern int32_t CONTROL_JoyPresent;
|
extern int32_t CONTROL_JoyPresent;
|
||||||
extern int32_t CONTROL_MouseEnabled;
|
extern int32_t CONTROL_MouseEnabled;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#define TRAVERSE_SPRITE_SECT(l, o, n) for ((o) = (l); (n) = nextspritesect[o], (o) != -1; (o) = (n))
|
#define TRAVERSE_SPRITE_SECT(l, o, n) for ((o) = (l); (n) = nextspritesect[o], (o) != -1; (o) = (n))
|
||||||
#define TRAVERSE_SPRITE_STAT(l, o, n) for ((o) = (l); (n) = nextspritestat[o], (o) != -1; (o) = (n))
|
#define TRAVERSE_SPRITE_STAT(l, o, n) for ((o) = (l); (n) = nextspritestat[o], (o) != -1; (o) = (n))
|
||||||
#define TRAVERSE_CONNECT(i) for (i = connecthead; i != -1; i = connectpoint2[i])
|
#define TRAVERSE_CONNECT(i) for (i = 0; i != -1; i = connectpoint2[i])
|
||||||
|
|
||||||
#define TEST(flags,mask) ((flags) & (mask))
|
#define TEST(flags,mask) ((flags) & (mask))
|
||||||
#define SET(flags,mask) ((flags) |= (mask))
|
#define SET(flags,mask) ((flags) |= (mask))
|
||||||
|
|
|
@ -1460,11 +1460,12 @@ void M_DisplayMenus(void)
|
||||||
tempbuf[0] = PACKET_LOAD_GAME;
|
tempbuf[0] = PACKET_LOAD_GAME;
|
||||||
tempbuf[1] = g_lastSaveSlot;
|
tempbuf[1] = g_lastSaveSlot;
|
||||||
tempbuf[2] = myconnectindex;
|
tempbuf[2] = myconnectindex;
|
||||||
TRAVERSE_CONNECT(x)
|
|
||||||
{
|
if (net_client)
|
||||||
if (x != myconnectindex) mmulti_sendpacket(x,tempbuf,3);
|
enet_peer_send(net_peer, 0, enet_packet_create(tempbuf, 3, ENET_PACKET_FLAG_RELIABLE));
|
||||||
if ((!g_networkBroadcastMode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master
|
else if (net_server)
|
||||||
}
|
enet_host_broadcast(net_server, 0, enet_packet_create(tempbuf, 3, ENET_PACKET_FLAG_RELIABLE));
|
||||||
|
|
||||||
Net_GetPackets();
|
Net_GetPackets();
|
||||||
|
|
||||||
G_LoadPlayer(g_lastSaveSlot);
|
G_LoadPlayer(g_lastSaveSlot);
|
||||||
|
@ -1789,26 +1790,25 @@ void M_DisplayMenus(void)
|
||||||
|
|
||||||
cheat_for_port_credits:
|
cheat_for_port_credits:
|
||||||
if (g_scriptVersion == 13) l = (-2);
|
if (g_scriptVersion == 13) l = (-2);
|
||||||
mgametext(160,38-l,"GAME PROGRAMMING",0,2+8+16);
|
mgametext(160,38-l,"PROGRAMMING AND PROJECT MANAGEMENT",0,2+8+16);
|
||||||
p = "Richard \"TerminX\" Gobeille";
|
p = "Richard \"TerminX\" Gobeille";
|
||||||
minitext(161-(Bstrlen(p)<<1), 39+10-l, p, 4, 10+16+128);
|
minitext(161-(Bstrlen(p)<<1), 39+10-l, p, 4, 10+16+128);
|
||||||
minitext(160-(Bstrlen(p)<<1), 38+10-l, p, 8, 10+16+128);
|
minitext(160-(Bstrlen(p)<<1), 38+10-l, p, 8, 10+16+128);
|
||||||
|
|
||||||
mgametext(160,57-l,"\"JFDUKE3D\" AND \"JFBUILD\" CODE",0,2+8+16);
|
mgametext(160,57-l,"POLYMER RENDERING SYSTEM",0,2+8+16);
|
||||||
p = "Jonathon \"JonoF\" Fowler";
|
p = "Pierre-Loup \"Plagman\" Griffais";
|
||||||
minitext(161-(Bstrlen(p)<<1), 58+10-l, p, 4, 10+16+128);
|
minitext(161-(Bstrlen(p)<<1), 58+10-l, p, 4, 10+16+128);
|
||||||
minitext(160-(Bstrlen(p)<<1), 57+10-l, p, 8, 10+16+128);
|
minitext(160-(Bstrlen(p)<<1), 57+10-l, p, 8, 10+16+128);
|
||||||
|
|
||||||
mgametext(160,76-l,"BUILD ENGINE, \"POLYMOST\" RENDERER",0,2+8+16);
|
mgametext(160,76-l,"ENGINE AND GAME PORTING WORK",0,2+8+16);
|
||||||
mgametext(160,76+8-l,"NETWORKING, OTHER CODE",0,2+8+16);
|
p = "Jonathon \"JonoF\" Fowler";
|
||||||
p = "Ken \"Awesoken\" Silverman";
|
minitext(161-(Bstrlen(p)<<1), 77+10-l, p, 4, 10+16+128);
|
||||||
minitext(161-(Bstrlen(p)<<1), 77+8+10-l, p, 4, 10+16+128);
|
minitext(160-(Bstrlen(p)<<1), 76+10-l, p, 8, 10+16+128);
|
||||||
minitext(160-(Bstrlen(p)<<1), 76+8+10-l, p, 8, 10+16+128);
|
|
||||||
|
|
||||||
mgametext(160,103-l,"ADDITIONAL RENDERING FEATURES",0,2+8+16);
|
mgametext(160,95-l,"BUILD ENGINE AND POLYMOST RENDERER",0,2+8+16);
|
||||||
p = "Pierre-Loup \"Plagman\" Griffais";
|
p = "Ken \"Awesoken\" Silverman";
|
||||||
minitext(161-(Bstrlen(p)<<1), 104+10-l, p, 4, 10+16+128);
|
minitext(161-(Bstrlen(p)<<1), 96+10-l, p, 4, 10+16+128);
|
||||||
minitext(160-(Bstrlen(p)<<1), 103+10-l, p, 8, 10+16+128);
|
minitext(160-(Bstrlen(p)<<1), 95+10-l, p, 8, 10+16+128);
|
||||||
|
|
||||||
mgametext(160,122-l,"LICENSE AND OTHER CONTRIBUTORS",0,2+8+16);
|
mgametext(160,122-l,"LICENSE AND OTHER CONTRIBUTORS",0,2+8+16);
|
||||||
{
|
{
|
||||||
|
@ -1836,11 +1836,15 @@ cheat_for_port_credits:
|
||||||
"Ozkan Sezer", // SDL/GTK version checking improvements
|
"Ozkan Sezer", // SDL/GTK version checking improvements
|
||||||
"Peter Green", // dynamic remapping, custom gametypes
|
"Peter Green", // dynamic remapping, custom gametypes
|
||||||
"Peter Veenstra", // port to 64-bit
|
"Peter Veenstra", // port to 64-bit
|
||||||
|
"Randy Heit", // random snippets of ZDoom here and there
|
||||||
|
"Robin Green", // CON array support
|
||||||
"Philipp Kutin", // Mapster32 improvements
|
"Philipp Kutin", // Mapster32 improvements
|
||||||
"Ryan Gordon", // icculus.org Duke3D port sound code
|
"Ryan Gordon", // icculus.org Duke3D port sound code
|
||||||
"Stephen Anthony", // early 64-bit porting work
|
"Stephen Anthony", // early 64-bit porting work
|
||||||
" ",
|
" ",
|
||||||
"EDuke originally by Matt Saettler",
|
"EDuke originally by Matt Saettler.",
|
||||||
|
" ",
|
||||||
|
"BUILD engine technology available under BUILDLIC.",
|
||||||
" ",
|
" ",
|
||||||
"--x--",
|
"--x--",
|
||||||
" ",
|
" ",
|
||||||
|
@ -1862,9 +1866,6 @@ cheat_for_port_credits:
|
||||||
p = "Visit www.eduke32.com for news and updates";
|
p = "Visit www.eduke32.com for news and updates";
|
||||||
minitext(161-(Bstrlen(p)<<1), 136+10+10+10+10+4-l, p, 4, 10+16+128);
|
minitext(161-(Bstrlen(p)<<1), 136+10+10+10+10+4-l, p, 4, 10+16+128);
|
||||||
minitext(160-(Bstrlen(p)<<1), 135+10+10+10+10+4-l, p, 8, 10+16+128);
|
minitext(160-(Bstrlen(p)<<1), 135+10+10+10+10+4-l, p, 8, 10+16+128);
|
||||||
p = "See wiki.eduke32.com/stuff for new releases";
|
|
||||||
minitext(161-(Bstrlen(p)<<1), 143+10+10+10+10+4-l, p, 4, 10+16+128);
|
|
||||||
minitext(160-(Bstrlen(p)<<1), 142+10+10+10+10+4-l, p, 8, 10+16+128);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1878,9 +1879,6 @@ cheat_for_port_credits:
|
||||||
{
|
{
|
||||||
if (ud.multimode > 1 && x == 0 && ud.recstat != 2)
|
if (ud.multimode > 1 && x == 0 && ud.recstat != 2)
|
||||||
{
|
{
|
||||||
if (g_movesPerPacket == 4 && myconnectindex != connecthead)
|
|
||||||
break;
|
|
||||||
|
|
||||||
last_zero = 0;
|
last_zero = 0;
|
||||||
ChangeToMenu(600);
|
ChangeToMenu(600);
|
||||||
}
|
}
|
||||||
|
@ -1897,8 +1895,6 @@ cheat_for_port_credits:
|
||||||
ChangeToMenu(202);
|
ChangeToMenu(202);
|
||||||
break; // JBF 20031205: was 200
|
break; // JBF 20031205: was 200
|
||||||
case 2:
|
case 2:
|
||||||
if (g_movesPerPacket == 4 && connecthead != myconnectindex)
|
|
||||||
break;
|
|
||||||
ChangeToMenu(300);
|
ChangeToMenu(300);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -1927,23 +1923,13 @@ cheat_for_port_credits:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_movesPerPacket == 4)
|
menutext(c,67,MENUHIGHLIGHT(0),PHX(-2),"NEW GAME");
|
||||||
{
|
|
||||||
if (myconnectindex == connecthead)
|
|
||||||
menutext(c,67,MENUHIGHLIGHT(0),PHX(-2),"NEW GAME");
|
|
||||||
else
|
|
||||||
menutext(c,67,MENUHIGHLIGHT(0),1,"NEW GAME");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
menutext(c,67,MENUHIGHLIGHT(0),PHX(-2),"NEW GAME");
|
|
||||||
|
|
||||||
// menutext(c,67+16,0,1,"NETWORK GAME");
|
// menutext(c,67+16,0,1,"NETWORK GAME");
|
||||||
|
|
||||||
menutext(c,67+16/*+16*/,MENUHIGHLIGHT(1),PHX(-3),"OPTIONS");
|
menutext(c,67+16/*+16*/,MENUHIGHLIGHT(1),PHX(-3),"OPTIONS");
|
||||||
|
|
||||||
if (g_movesPerPacket == 4 && connecthead != myconnectindex)
|
menutext(c,67+16+16/*+16*/,MENUHIGHLIGHT(2),PHX(-4),"LOAD GAME");
|
||||||
menutext(c,67+16+16/*+16*/,MENUHIGHLIGHT(2),1,"LOAD GAME");
|
|
||||||
else menutext(c,67+16+16/*+16*/,MENUHIGHLIGHT(2),PHX(-4),"LOAD GAME");
|
|
||||||
|
|
||||||
if (!VOLUMEALL)
|
if (!VOLUMEALL)
|
||||||
{
|
{
|
||||||
|
@ -1971,8 +1957,6 @@ cheat_for_port_credits:
|
||||||
switch (x)
|
switch (x)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
if (g_movesPerPacket == 4 && myconnectindex != connecthead)
|
|
||||||
break;
|
|
||||||
if (ud.multimode < 2 || ud.recstat == 2)
|
if (ud.multimode < 2 || ud.recstat == 2)
|
||||||
ChangeToMenu(1500);
|
ChangeToMenu(1500);
|
||||||
else
|
else
|
||||||
|
@ -1982,8 +1966,6 @@ cheat_for_port_credits:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (g_movesPerPacket == 4 && connecthead != myconnectindex)
|
|
||||||
break;
|
|
||||||
if (ud.recstat != 2)
|
if (ud.recstat != 2)
|
||||||
{
|
{
|
||||||
last_fifty = 1;
|
last_fifty = 1;
|
||||||
|
@ -1992,8 +1974,6 @@ cheat_for_port_credits:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (g_movesPerPacket == 4 && connecthead != myconnectindex)
|
|
||||||
break;
|
|
||||||
last_fifty = 2;
|
last_fifty = 2;
|
||||||
ChangeToMenu(300);
|
ChangeToMenu(300);
|
||||||
break;
|
break;
|
||||||
|
@ -2030,18 +2010,9 @@ cheat_for_port_credits:
|
||||||
if (KB_KeyPressed(sc_Q))
|
if (KB_KeyPressed(sc_Q))
|
||||||
ChangeToMenu(500);
|
ChangeToMenu(500);
|
||||||
|
|
||||||
if (g_movesPerPacket == 4 && connecthead != myconnectindex)
|
menutext(c,67 ,MENUHIGHLIGHT(0),PHX(-2),"NEW GAME");
|
||||||
{
|
menutext(c,67+16 ,MENUHIGHLIGHT(1),PHX(-3),"SAVE GAME");
|
||||||
menutext(c,67 ,MENUHIGHLIGHT(0),1,"NEW GAME");
|
menutext(c,67+16+16 ,MENUHIGHLIGHT(2),PHX(-4),"LOAD GAME");
|
||||||
menutext(c,67+16 ,MENUHIGHLIGHT(1),1,"SAVE GAME");
|
|
||||||
menutext(c,67+16+16 ,MENUHIGHLIGHT(2),1,"LOAD GAME");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
menutext(c,67 ,MENUHIGHLIGHT(0),PHX(-2),"NEW GAME");
|
|
||||||
menutext(c,67+16 ,MENUHIGHLIGHT(1),PHX(-3),"SAVE GAME");
|
|
||||||
menutext(c,67+16+16 ,MENUHIGHLIGHT(2),PHX(-4),"LOAD GAME");
|
|
||||||
}
|
|
||||||
|
|
||||||
menutext(c,67+16+16+16 ,MENUHIGHLIGHT(3),PHX(-5),"OPTIONS");
|
menutext(c,67+16+16+16 ,MENUHIGHLIGHT(3),PHX(-5),"OPTIONS");
|
||||||
if (!VOLUMEALL)
|
if (!VOLUMEALL)
|
||||||
|
@ -5102,11 +5073,11 @@ VOLUME_ALL_40x:
|
||||||
tempbuf[0] = PACKET_MAP_VOTE_CANCEL;
|
tempbuf[0] = PACKET_MAP_VOTE_CANCEL;
|
||||||
tempbuf[1] = myconnectindex;
|
tempbuf[1] = myconnectindex;
|
||||||
|
|
||||||
TRAVERSE_CONNECT(c)
|
if (net_client)
|
||||||
{
|
enet_peer_send(net_peer, 0, enet_packet_create(tempbuf, 2, ENET_PACKET_FLAG_RELIABLE));
|
||||||
if (c != myconnectindex) mmulti_sendpacket(c,tempbuf,2);
|
else if (net_server)
|
||||||
if ((!g_networkBroadcastMode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master
|
enet_host_broadcast(net_server, 0, enet_packet_create(tempbuf, 2, ENET_PACKET_FLAG_RELIABLE));
|
||||||
}
|
|
||||||
voting = -1;
|
voting = -1;
|
||||||
}
|
}
|
||||||
ChangeToMenu(0);
|
ChangeToMenu(0);
|
||||||
|
@ -5117,9 +5088,9 @@ VOLUME_ALL_40x:
|
||||||
plrvotes += g_player[i].vote;
|
plrvotes += g_player[i].vote;
|
||||||
j += g_player[i].gotvote;
|
j += g_player[i].gotvote;
|
||||||
}
|
}
|
||||||
if (j == numplayers || !g_player[myconnectindex].ps->i || (plrvotes > (numplayers>>1)) || (!g_networkBroadcastMode && myconnectindex == connecthead))
|
if (j == numplayers || !g_player[myconnectindex].ps->i || (plrvotes > (numplayers>>1)) || (net_server))
|
||||||
{
|
{
|
||||||
if (plrvotes > (numplayers>>1) || !g_player[myconnectindex].ps->i || (!g_networkBroadcastMode && myconnectindex == connecthead))
|
if (plrvotes > (numplayers>>1) || !g_player[myconnectindex].ps->i || (net_server))
|
||||||
{
|
{
|
||||||
if (ud.m_player_skill == 3) ud.m_respawn_monsters = 1;
|
if (ud.m_player_skill == 3) ud.m_respawn_monsters = 1;
|
||||||
else ud.m_respawn_monsters = 0;
|
else ud.m_respawn_monsters = 0;
|
||||||
|
@ -5138,7 +5109,7 @@ VOLUME_ALL_40x:
|
||||||
|
|
||||||
Net_NewGame(ud.m_volume_number,ud.m_level_number);
|
Net_NewGame(ud.m_volume_number,ud.m_level_number);
|
||||||
|
|
||||||
if (voting == myconnectindex && !(!g_networkBroadcastMode && myconnectindex == connecthead))
|
if (voting == myconnectindex && !(net_server))
|
||||||
G_AddUserQuote("VOTE SUCCEEDED");
|
G_AddUserQuote("VOTE SUCCEEDED");
|
||||||
|
|
||||||
G_NewGame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill+1);
|
G_NewGame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill+1);
|
||||||
|
@ -5159,12 +5130,12 @@ VOLUME_ALL_40x:
|
||||||
tempbuf[0] = PACKET_MAP_VOTE_CANCEL;
|
tempbuf[0] = PACKET_MAP_VOTE_CANCEL;
|
||||||
tempbuf[1] = myconnectindex;
|
tempbuf[1] = myconnectindex;
|
||||||
tempbuf[2] = 1;
|
tempbuf[2] = 1;
|
||||||
|
tempbuf[3] = myconnectindex;
|
||||||
|
|
||||||
TRAVERSE_CONNECT(c)
|
if (net_client)
|
||||||
{
|
enet_peer_send(net_peer, 0, enet_packet_create(tempbuf, 4, ENET_PACKET_FLAG_RELIABLE));
|
||||||
if (c != myconnectindex) mmulti_sendpacket(c,tempbuf,3);
|
else if (net_server)
|
||||||
if ((!g_networkBroadcastMode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master
|
enet_host_broadcast(net_server, 0, enet_packet_create(tempbuf, 4, ENET_PACKET_FLAG_RELIABLE));
|
||||||
}
|
|
||||||
|
|
||||||
Bsprintf(ScriptQuotes[116],"VOTE FAILED");
|
Bsprintf(ScriptQuotes[116],"VOTE FAILED");
|
||||||
P_DoQuote(116,g_player[myconnectindex].ps);
|
P_DoQuote(116,g_player[myconnectindex].ps);
|
||||||
|
@ -5290,7 +5261,7 @@ VOLUME_ALL_40x:
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// master does whatever it wants
|
// master does whatever it wants
|
||||||
if (!g_networkBroadcastMode && myconnectindex == connecthead)
|
if (net_server)
|
||||||
{
|
{
|
||||||
ChangeToMenu(603);
|
ChangeToMenu(603);
|
||||||
break;
|
break;
|
||||||
|
@ -5311,12 +5282,12 @@ VOLUME_ALL_40x:
|
||||||
tempbuf[1] = myconnectindex;
|
tempbuf[1] = myconnectindex;
|
||||||
tempbuf[2] = ud.m_volume_number;
|
tempbuf[2] = ud.m_volume_number;
|
||||||
tempbuf[3] = ud.m_level_number;
|
tempbuf[3] = ud.m_level_number;
|
||||||
|
tempbuf[4] = myconnectindex;
|
||||||
|
|
||||||
TRAVERSE_CONNECT(c)
|
if (net_client)
|
||||||
{
|
enet_peer_send(net_peer, 0, enet_packet_create(tempbuf, 5, ENET_PACKET_FLAG_RELIABLE));
|
||||||
if (c != myconnectindex) mmulti_sendpacket(c,tempbuf,4);
|
else if (net_server)
|
||||||
if ((!g_networkBroadcastMode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master
|
enet_host_broadcast(net_server, 0, enet_packet_create(tempbuf, 5, ENET_PACKET_FLAG_RELIABLE));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((GametypeFlags[ud.m_coop] & GAMETYPE_PLAYERSFRIENDLY) && !(GametypeFlags[ud.m_coop] & GAMETYPE_TDM))
|
if ((GametypeFlags[ud.m_coop] & GAMETYPE_PLAYERSFRIENDLY) && !(GametypeFlags[ud.m_coop] & GAMETYPE_TDM))
|
||||||
ud.m_noexits = 0;
|
ud.m_noexits = 0;
|
||||||
|
|
|
@ -102,7 +102,7 @@ static int32_t osdcmd_changelevel(const osdfuncparm_t *parm)
|
||||||
|
|
||||||
if (numplayers > 1)
|
if (numplayers > 1)
|
||||||
{
|
{
|
||||||
if (myconnectindex == connecthead && g_networkBroadcastMode == 0)
|
if (net_server)
|
||||||
Net_NewGame(volume,level);
|
Net_NewGame(volume,level);
|
||||||
else if (voting == -1)
|
else if (voting == -1)
|
||||||
{
|
{
|
||||||
|
@ -128,11 +128,7 @@ static int32_t osdcmd_changelevel(const osdfuncparm_t *parm)
|
||||||
tempbuf[2] = ud.m_volume_number;
|
tempbuf[2] = ud.m_volume_number;
|
||||||
tempbuf[3] = ud.m_level_number;
|
tempbuf[3] = ud.m_level_number;
|
||||||
|
|
||||||
TRAVERSE_CONNECT(i)
|
enet_peer_send(net_peer, 0, enet_packet_create(tempbuf, 4, ENET_PACKET_FLAG_RELIABLE));
|
||||||
{
|
|
||||||
if (i != myconnectindex) mmulti_sendpacket(i,tempbuf,4);
|
|
||||||
if ((!g_networkBroadcastMode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((GametypeFlags[ud.m_coop] & GAMETYPE_PLAYERSFRIENDLY) && !(GametypeFlags[ud.m_coop] & GAMETYPE_TDM))
|
if ((GametypeFlags[ud.m_coop] & GAMETYPE_PLAYERSFRIENDLY) && !(GametypeFlags[ud.m_coop] & GAMETYPE_TDM))
|
||||||
ud.m_noexits = 0;
|
ud.m_noexits = 0;
|
||||||
|
@ -254,7 +250,7 @@ static int32_t osdcmd_map(const osdfuncparm_t *parm)
|
||||||
|
|
||||||
if (numplayers > 1)
|
if (numplayers > 1)
|
||||||
{
|
{
|
||||||
if (myconnectindex == connecthead && g_networkBroadcastMode == 0)
|
if (net_server)
|
||||||
{
|
{
|
||||||
Net_SendUserMapName();
|
Net_SendUserMapName();
|
||||||
ud.m_volume_number = 0;
|
ud.m_volume_number = 0;
|
||||||
|
@ -286,11 +282,7 @@ static int32_t osdcmd_map(const osdfuncparm_t *parm)
|
||||||
tempbuf[2] = ud.m_volume_number;
|
tempbuf[2] = ud.m_volume_number;
|
||||||
tempbuf[3] = ud.m_level_number;
|
tempbuf[3] = ud.m_level_number;
|
||||||
|
|
||||||
TRAVERSE_CONNECT(i)
|
enet_peer_send(net_peer, 0, enet_packet_create(tempbuf, 4, ENET_PACKET_FLAG_RELIABLE));
|
||||||
{
|
|
||||||
if (i != myconnectindex) mmulti_sendpacket(i,tempbuf,4);
|
|
||||||
if ((!g_networkBroadcastMode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((GametypeFlags[ud.m_coop] & GAMETYPE_PLAYERSFRIENDLY) && !(GametypeFlags[ud.m_coop] & GAMETYPE_TDM))
|
if ((GametypeFlags[ud.m_coop] & GAMETYPE_PLAYERSFRIENDLY) && !(GametypeFlags[ud.m_coop] & GAMETYPE_TDM))
|
||||||
ud.m_noexits = 0;
|
ud.m_noexits = 0;
|
||||||
|
@ -1115,9 +1107,6 @@ static int32_t osdcmd_screenshot(const osdfuncparm_t *parm)
|
||||||
return OSDCMD_OK;
|
return OSDCMD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void G_SaveMapState(mapstate_t *save);
|
|
||||||
extern void G_RestoreMapState(mapstate_t *save);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int32_t osdcmd_savestate(const osdfuncparm_t *parm)
|
static int32_t osdcmd_savestate(const osdfuncparm_t *parm)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3317,9 +3317,11 @@ void getinput(int32_t snum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numplayers > 1)
|
/*
|
||||||
daang = myang;
|
if (numplayers > 1)
|
||||||
else daang = p->ang;
|
daang = myang;
|
||||||
|
else*/
|
||||||
|
daang = p->ang;
|
||||||
|
|
||||||
momx = mulscale9(vel,sintable[(daang+2560)&2047]);
|
momx = mulscale9(vel,sintable[(daang+2560)&2047]);
|
||||||
momy = mulscale9(vel,sintable[(daang+2048)&2047]);
|
momy = mulscale9(vel,sintable[(daang+2048)&2047]);
|
||||||
|
@ -4142,14 +4144,6 @@ void P_ProcessInput(int32_t snum)
|
||||||
G_AddUserQuote(tempbuf);
|
G_AddUserQuote(tempbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myconnectindex == connecthead)
|
|
||||||
{
|
|
||||||
Bsprintf(tempbuf,"frag %d killed %d\n",p->frag_ps+1,snum+1);
|
|
||||||
sendscore(tempbuf);
|
|
||||||
// printf(tempbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
p->frag_ps = snum;
|
p->frag_ps = snum;
|
||||||
pus = NUMPAGES;
|
pus = NUMPAGES;
|
||||||
}
|
}
|
||||||
|
|
|
@ -621,7 +621,7 @@ void P_RandomSpawnPoint(int32_t snum)
|
||||||
p->cursectnum = g_playerSpawnPoints[i].os;
|
p->cursectnum = g_playerSpawnPoints[i].os;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_ResetStatus(int32_t snum)
|
void P_ResetStatus(int32_t snum)
|
||||||
{
|
{
|
||||||
DukePlayer_t *p = g_player[snum].ps;
|
DukePlayer_t *p = g_player[snum].ps;
|
||||||
|
|
||||||
|
@ -1304,20 +1304,6 @@ quick:
|
||||||
|
|
||||||
display_mirror = 0;
|
display_mirror = 0;
|
||||||
|
|
||||||
if (ud.multimode > 1)
|
|
||||||
{
|
|
||||||
if (numplayers < 2)
|
|
||||||
{
|
|
||||||
connecthead = 0;
|
|
||||||
for (i=0; i<MAXPLAYERS; i++) connectpoint2[i] = i+1;
|
|
||||||
connectpoint2[ud.multimode-1] = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
connecthead = 0;
|
|
||||||
connectpoint2[0] = -1;
|
|
||||||
}
|
|
||||||
X_OnEvent(EVENT_NEWGAME, g_player[screenpeek].ps->i, screenpeek, -1);
|
X_OnEvent(EVENT_NEWGAME, g_player[screenpeek].ps->i, screenpeek, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1333,7 +1319,7 @@ static void resetpspritevars(char g)
|
||||||
APLAYER,0,0,0,g_player[0].ps->ang,0,0,0,10);
|
APLAYER,0,0,0,g_player[0].ps->ang,0,0,0,10);
|
||||||
|
|
||||||
if (ud.recstat != 2)
|
if (ud.recstat != 2)
|
||||||
for (i=0; i<ud.multimode; i++)
|
TRAVERSE_CONNECT(i)
|
||||||
{
|
{
|
||||||
aimmode[i] = g_player[i].ps->aim_mode;
|
aimmode[i] = g_player[i].ps->aim_mode;
|
||||||
autoaim[i] = g_player[i].ps->auto_aim;
|
autoaim[i] = g_player[i].ps->auto_aim;
|
||||||
|
@ -1362,11 +1348,11 @@ static void resetpspritevars(char g)
|
||||||
|
|
||||||
P_ResetStatus(0);
|
P_ResetStatus(0);
|
||||||
|
|
||||||
for (i=1; i<ud.multimode; i++)
|
TRAVERSE_CONNECT(i)
|
||||||
Bmemcpy(g_player[i].ps,g_player[0].ps,sizeof(DukePlayer_t));
|
Bmemcpy(g_player[i].ps,g_player[0].ps,sizeof(DukePlayer_t));
|
||||||
|
|
||||||
if (ud.recstat != 2)
|
if (ud.recstat != 2)
|
||||||
for (i=0; i<ud.multimode; i++)
|
TRAVERSE_CONNECT(i)
|
||||||
{
|
{
|
||||||
g_player[i].ps->aim_mode = aimmode[i];
|
g_player[i].ps->aim_mode = aimmode[i];
|
||||||
g_player[i].ps->auto_aim = autoaim[i];
|
g_player[i].ps->auto_aim = autoaim[i];
|
||||||
|
@ -1396,7 +1382,7 @@ static void resetpspritevars(char g)
|
||||||
circ = 2048/ud.multimode;
|
circ = 2048/ud.multimode;
|
||||||
|
|
||||||
g_whichPalForPlayer = 9;
|
g_whichPalForPlayer = 9;
|
||||||
j = connecthead;
|
j = 0;
|
||||||
i = headspritestat[STAT_PLAYER];
|
i = headspritestat[STAT_PLAYER];
|
||||||
while (i >= 0)
|
while (i >= 0)
|
||||||
{
|
{
|
||||||
|
@ -1419,73 +1405,76 @@ static void resetpspritevars(char g)
|
||||||
g_playerSpawnPoints[(uint8_t)g_numPlayerSprites].os = s->sectnum;
|
g_playerSpawnPoints[(uint8_t)g_numPlayerSprites].os = s->sectnum;
|
||||||
|
|
||||||
g_numPlayerSprites++;
|
g_numPlayerSprites++;
|
||||||
if (j >= 0)
|
|
||||||
|
if (j < MAXPLAYERS)
|
||||||
{
|
{
|
||||||
s->owner = i;
|
s->owner = i;
|
||||||
s->shade = 0;
|
s->shade = 0;
|
||||||
s->xrepeat = 42;
|
s->xrepeat = 42;
|
||||||
s->yrepeat = 36;
|
s->yrepeat = 36;
|
||||||
s->cstat = 1+256;
|
s->cstat = j < numplayers ? 1+256 : 32768;
|
||||||
s->xoffset = 0;
|
s->xoffset = 0;
|
||||||
s->clipdist = 64;
|
s->clipdist = 64;
|
||||||
|
|
||||||
if ((g&MODE_EOL) != MODE_EOL || g_player[j].ps->last_extra == 0)
|
// if (j < playerswhenstarted)
|
||||||
{
|
{
|
||||||
g_player[j].ps->last_extra = g_player[j].ps->max_player_health;
|
if ((g&MODE_EOL) != MODE_EOL || g_player[j].ps->last_extra == 0)
|
||||||
s->extra = g_player[j].ps->max_player_health;
|
|
||||||
g_player[j].ps->runspeed = g_playerFriction;
|
|
||||||
}
|
|
||||||
else s->extra = g_player[j].ps->last_extra;
|
|
||||||
|
|
||||||
s->yvel = j;
|
|
||||||
|
|
||||||
if (!g_player[j].pcolor && ud.multimode > 1 && !(GametypeFlags[ud.coop] & GAMETYPE_TDM))
|
|
||||||
{
|
|
||||||
if (s->pal == 0)
|
|
||||||
{
|
{
|
||||||
int32_t k = 0;
|
g_player[j].ps->last_extra = g_player[j].ps->max_player_health;
|
||||||
|
s->extra = g_player[j].ps->max_player_health;
|
||||||
|
g_player[j].ps->runspeed = g_playerFriction;
|
||||||
|
}
|
||||||
|
else s->extra = g_player[j].ps->last_extra;
|
||||||
|
|
||||||
for (; k<ud.multimode; k++)
|
s->yvel = j;
|
||||||
|
|
||||||
|
if (!g_player[j].pcolor && ud.multimode > 1 && !(GametypeFlags[ud.coop] & GAMETYPE_TDM))
|
||||||
|
{
|
||||||
|
if (s->pal == 0)
|
||||||
{
|
{
|
||||||
if (g_whichPalForPlayer == g_player[k].ps->palookup)
|
int32_t k = 0;
|
||||||
|
|
||||||
|
for (; k<ud.multimode; k++)
|
||||||
{
|
{
|
||||||
g_whichPalForPlayer++;
|
if (g_whichPalForPlayer == g_player[k].ps->palookup)
|
||||||
if (g_whichPalForPlayer >= 17)
|
{
|
||||||
g_whichPalForPlayer = 9;
|
g_whichPalForPlayer++;
|
||||||
k=0;
|
if (g_whichPalForPlayer >= 17)
|
||||||
|
g_whichPalForPlayer = 9;
|
||||||
|
k=0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
g_player[j].pcolor = s->pal = g_player[j].ps->palookup = g_whichPalForPlayer++;
|
||||||
|
if (g_whichPalForPlayer >= 17)
|
||||||
|
g_whichPalForPlayer = 9;
|
||||||
}
|
}
|
||||||
g_player[j].pcolor = s->pal = g_player[j].ps->palookup = g_whichPalForPlayer++;
|
else g_player[j].pcolor = g_player[j].ps->palookup = s->pal;
|
||||||
if (g_whichPalForPlayer >= 17)
|
|
||||||
g_whichPalForPlayer = 9;
|
|
||||||
}
|
}
|
||||||
else g_player[j].pcolor = g_player[j].ps->palookup = s->pal;
|
else
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int32_t k = g_player[j].pcolor;
|
|
||||||
|
|
||||||
if (GametypeFlags[ud.coop] & GAMETYPE_TDM)
|
|
||||||
{
|
{
|
||||||
k = G_GetTeamPalette(g_player[j].pteam);
|
int32_t k = g_player[j].pcolor;
|
||||||
g_player[j].ps->team = g_player[j].pteam;
|
|
||||||
|
if (GametypeFlags[ud.coop] & GAMETYPE_TDM)
|
||||||
|
{
|
||||||
|
k = G_GetTeamPalette(g_player[j].pteam);
|
||||||
|
g_player[j].ps->team = g_player[j].pteam;
|
||||||
|
}
|
||||||
|
s->pal = g_player[j].ps->palookup = k;
|
||||||
}
|
}
|
||||||
s->pal = g_player[j].ps->palookup = k;
|
|
||||||
|
g_player[j].ps->i = i;
|
||||||
|
g_player[j].ps->frag_ps = j;
|
||||||
|
ActorExtra[i].owner = i;
|
||||||
|
|
||||||
|
ActorExtra[i].bposx = g_player[j].ps->bobposx = g_player[j].ps->oposx = g_player[j].ps->posx = s->x;
|
||||||
|
ActorExtra[i].bposy = g_player[j].ps->bobposy = g_player[j].ps->oposy = g_player[j].ps->posy = s->y;
|
||||||
|
ActorExtra[i].bposz = g_player[j].ps->oposz = g_player[j].ps->posz = s->z;
|
||||||
|
g_player[j].ps->oang = g_player[j].ps->ang = s->ang;
|
||||||
|
|
||||||
|
updatesector(s->x,s->y,&g_player[j].ps->cursectnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_player[j].ps->i = i;
|
j++;
|
||||||
g_player[j].ps->frag_ps = j;
|
|
||||||
ActorExtra[i].owner = i;
|
|
||||||
|
|
||||||
ActorExtra[i].bposx = g_player[j].ps->bobposx = g_player[j].ps->oposx = g_player[j].ps->posx = s->x;
|
|
||||||
ActorExtra[i].bposy = g_player[j].ps->bobposy = g_player[j].ps->oposy = g_player[j].ps->posy = s->y;
|
|
||||||
ActorExtra[i].bposz = g_player[j].ps->oposz = g_player[j].ps->posz = s->z;
|
|
||||||
g_player[j].ps->oang = g_player[j].ps->ang = s->ang;
|
|
||||||
|
|
||||||
updatesector(s->x,s->y,&g_player[j].ps->cursectnum);
|
|
||||||
|
|
||||||
j = connectpoint2[j];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else deletesprite(i);
|
else deletesprite(i);
|
||||||
i = nexti;
|
i = nexti;
|
||||||
|
@ -1518,20 +1507,15 @@ void G_ResetTimers(void)
|
||||||
|
|
||||||
void Net_WaitForEverybody(void)
|
void Net_WaitForEverybody(void)
|
||||||
{
|
{
|
||||||
int32_t i;
|
int32_t server_ready = g_player[0].playerreadyflag;
|
||||||
|
|
||||||
|
if (numplayers < 2 || net_server) return;
|
||||||
|
|
||||||
if (numplayers < 2) return;
|
|
||||||
packbuf[0] = PACKET_PLAYER_READY;
|
packbuf[0] = PACKET_PLAYER_READY;
|
||||||
|
packbuf[1] = myconnectindex;
|
||||||
|
|
||||||
g_player[myconnectindex].playerreadyflag++;
|
if (net_client)
|
||||||
|
enet_peer_send(net_peer, 0, enet_packet_create(packbuf, 2, ENET_PACKET_FLAG_RELIABLE));
|
||||||
// if we're a peer or slave, not a master
|
|
||||||
if ((g_networkBroadcastMode == 1) || (!g_networkBroadcastMode && (myconnectindex != connecthead)))
|
|
||||||
TRAVERSE_CONNECT(i)
|
|
||||||
{
|
|
||||||
if (i != myconnectindex) mmulti_sendpacket(i,packbuf,1);
|
|
||||||
if ((!g_networkBroadcastMode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ud.multimode > 1)
|
if (ud.multimode > 1)
|
||||||
{
|
{
|
||||||
|
@ -1543,7 +1527,7 @@ void Net_WaitForEverybody(void)
|
||||||
if (PLUTOPAK) // JBF 20030804
|
if (PLUTOPAK) // JBF 20030804
|
||||||
rotatesprite(160<<16,(151)<<16,30<<11,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1);
|
rotatesprite(160<<16,(151)<<16,30<<11,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1);
|
||||||
|
|
||||||
gametext(160,190,"WAITING FOR PLAYERS",14,2);
|
gametext(160,190,"WAITING FOR SERVER",14,2);
|
||||||
nextpage();
|
nextpage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1551,28 +1535,11 @@ void Net_WaitForEverybody(void)
|
||||||
{
|
{
|
||||||
if (quitevent || keystatus[1]) G_GameExit("");
|
if (quitevent || keystatus[1]) G_GameExit("");
|
||||||
|
|
||||||
|
handleevents();
|
||||||
Net_GetPackets();
|
Net_GetPackets();
|
||||||
|
|
||||||
TRAVERSE_CONNECT(i)
|
if (g_player[0].playerreadyflag > server_ready)
|
||||||
{
|
{
|
||||||
if (g_player[i].playerreadyflag < g_player[myconnectindex].playerreadyflag) break;
|
|
||||||
if ((!g_networkBroadcastMode) && (myconnectindex != connecthead))
|
|
||||||
{
|
|
||||||
// we're a slave
|
|
||||||
i = -1; break;
|
|
||||||
}
|
|
||||||
//slaves in M/S mode only wait for master
|
|
||||||
}
|
|
||||||
if (i < 0)
|
|
||||||
{
|
|
||||||
// master sends ready packet once it hears from all slaves
|
|
||||||
if (!g_networkBroadcastMode && myconnectindex == connecthead)
|
|
||||||
TRAVERSE_CONNECT(i)
|
|
||||||
{
|
|
||||||
packbuf[0] = PACKET_PLAYER_READY;
|
|
||||||
if (i != myconnectindex) mmulti_sendpacket(i,packbuf,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
P_SetGamePalette(g_player[myconnectindex].ps, palette, 11);
|
P_SetGamePalette(g_player[myconnectindex].ps, palette, 11);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1580,8 +1547,6 @@ void Net_WaitForEverybody(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int32_t jump_input;
|
extern int32_t jump_input;
|
||||||
extern char g_szfirstSyncMsg[MAXSYNCBYTES][60];
|
|
||||||
extern int32_t g_foundSyncError;
|
|
||||||
|
|
||||||
void clearfifo(void)
|
void clearfifo(void)
|
||||||
{
|
{
|
||||||
|
@ -1590,8 +1555,6 @@ void clearfifo(void)
|
||||||
syncvaltail = 0L;
|
syncvaltail = 0L;
|
||||||
syncvaltottail = 0L;
|
syncvaltottail = 0L;
|
||||||
memset(&syncstat, 0, sizeof(syncstat));
|
memset(&syncstat, 0, sizeof(syncstat));
|
||||||
memset(&g_szfirstSyncMsg, 0, sizeof(g_szfirstSyncMsg));
|
|
||||||
g_foundSyncError = 0;
|
|
||||||
bufferjitter = 1;
|
bufferjitter = 1;
|
||||||
mymaxlag = otherminlag = 0;
|
mymaxlag = otherminlag = 0;
|
||||||
jump_input = 0;
|
jump_input = 0;
|
||||||
|
@ -1952,7 +1915,7 @@ int32_t G_EnterLevel(int32_t g)
|
||||||
if (!premap_quickenterlevel)
|
if (!premap_quickenterlevel)
|
||||||
{
|
{
|
||||||
Net_WaitForEverybody();
|
Net_WaitForEverybody();
|
||||||
mmulti_flushpackets();
|
// mmulti_flushpackets();
|
||||||
|
|
||||||
G_FadePalette(0,0,0,0);
|
G_FadePalette(0,0,0,0);
|
||||||
G_UpdateScreenArea();
|
G_UpdateScreenArea();
|
||||||
|
@ -1961,8 +1924,6 @@ int32_t G_EnterLevel(int32_t g)
|
||||||
G_DrawRooms(myconnectindex,65536);
|
G_DrawRooms(myconnectindex,65536);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<ud.multimode; i++)
|
|
||||||
clearbufbyte(&g_player[i].playerquitflag,1,0x01010101);
|
|
||||||
g_player[myconnectindex].ps->over_shoulder_on = 0;
|
g_player[myconnectindex].ps->over_shoulder_on = 0;
|
||||||
|
|
||||||
clearfrags();
|
clearfrags();
|
||||||
|
|
|
@ -190,8 +190,8 @@ int32_t isanearoperator(int32_t lotag)
|
||||||
|
|
||||||
inline int32_t G_CheckPlayerInSector(int32_t sect)
|
inline int32_t G_CheckPlayerInSector(int32_t sect)
|
||||||
{
|
{
|
||||||
int32_t i = connecthead;
|
int32_t i;
|
||||||
for (; i>=0; i=connectpoint2[i])
|
TRAVERSE_CONNECT(i)
|
||||||
if (sprite[g_player[i].ps->i].sectnum == sect) return i;
|
if (sprite[g_player[i].ps->i].sectnum == sect) return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,7 @@ void G_DoSectorAnimations(void)
|
||||||
{
|
{
|
||||||
my.z += v;
|
my.z += v;
|
||||||
myvel.z = 0;
|
myvel.z = 0;
|
||||||
myzbak[((movefifoplc-1)&(MOVEFIFOSIZ-1))] = g_player[p].ps->posz;
|
myzbak[0] = g_player[p].ps->posz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -386,7 +386,7 @@ void Net_GetSyncData(char *packbuf, int32_t packbufleng, int32_t *j, int32_t oth
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
for (i = connectpoint2[connecthead]; i >= 0; i = connectpoint2[i])
|
TRAVERSE_CONNECT(i)
|
||||||
{
|
{
|
||||||
for (sb = 0; sb < g_numSyncBytes; sb++)
|
for (sb = 0; sb < g_numSyncBytes; sb++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue