mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-06-04 11:10:48 +00:00
Update to ZDoom r1476:
- Moved weapon slot initialization into APlayerPawn::PostBeginPlay() so that they can be initialized when players respawn in multiplayer. - Added a Check for the Vavoom namespace to the UDMF parser. Functionally it's 100% identical with ZDoom's own but needs to be checked for in case Vavoom compatible UDMF maps are released. - Added an SDL output plugin, so FMOD can produce sound using SDL's audio support instead of its own OSS/ALSA/ESD support. This is selectable by setting snd_output to "sdl". - Fixed: On Linux systems with ALSA but no OSS support, trying to start the sound system with snd_output "default" would fail instead of trying to use ALSA. - Added sdl_nokeyrepeat to disable key repeating in the menus and console on Linux. - Added support for zip/pk3 files with LZMA and bzip2 compression to ZDoom. - Added more output to zipdir and a -q option to turn it off. - Added -u option to zipdir to only recompress those files in a zip that have changed. - Added -d and -f options to zipdir. -d forces deflate compression, and -f forces a write of the zip, even if it's newer than all the files it contains. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@307 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
parent
8d22dbb5af
commit
42f732ac66
23 changed files with 782 additions and 179 deletions
|
@ -1,4 +1,77 @@
|
||||||
February 28, 2009
|
March 11, 2009
|
||||||
|
- Moved weapon slot initialization into APlayerPawn::PostBeginPlay() so that
|
||||||
|
they can be initialized when players respawn in multiplayer.
|
||||||
|
|
||||||
|
March 11, 2009 (Changes by Graf Zahl)
|
||||||
|
- Added a Check for the Vavoom namespace to the UDMF parser. Functionally
|
||||||
|
it's 100% identical with ZDoom's own but needs to be checked for in
|
||||||
|
case Vavoom compatible UDMF maps are released.
|
||||||
|
|
||||||
|
March 10, 2009
|
||||||
|
- Added an SDL output plugin, so FMOD can produce sound using SDL's audio
|
||||||
|
support instead of its own OSS/ALSA/ESD support. This is selectable by
|
||||||
|
setting snd_output to "sdl".
|
||||||
|
- Fixed: On Linux systems with ALSA but no OSS support, trying to start
|
||||||
|
the sound system with snd_output "default" would fail instead of trying
|
||||||
|
to use ALSA.
|
||||||
|
- Added sdl_nokeyrepeat to disable key repeating in the menus and console
|
||||||
|
on Linux.
|
||||||
|
- Added support for zip/pk3 files with LZMA and bzip2 compression to ZDoom.
|
||||||
|
- Added more output to zipdir and a -q option to turn it off.
|
||||||
|
- Added -u option to zipdir to only recompress those files in a zip that have
|
||||||
|
changed.
|
||||||
|
|
||||||
|
March 7, 2009
|
||||||
|
- Added -d and -f options to zipdir. -d forces deflate compression, and -f
|
||||||
|
forces a write of the zip, even if it's newer than all the files it contains.
|
||||||
|
|
||||||
|
March 7, 2009 (Changes by Graf Zahl)
|
||||||
|
- Fixed: P_CompleteWeaponSetup was missing a NULL pointer check for the player.
|
||||||
|
- Adjusted some gravity related thresholds for the fix from Feb 28. Also removed
|
||||||
|
some unnecessary floating point math from this code.
|
||||||
|
|
||||||
|
March 6, 2009
|
||||||
|
- Added support for bzip2 and LZMA compression to zipdir.
|
||||||
|
|
||||||
|
March 6, 2009 (Changes by Graf Zahl)
|
||||||
|
- Added Hirogen2's patch for unlimited ammo CVAR.
|
||||||
|
|
||||||
|
March 4, 2009
|
||||||
|
- Fixed: You couldn't easily play with the compatibility options menu during
|
||||||
|
the title screen, because the demo loop reset the server cvars after each
|
||||||
|
attempt to play a demo, even though the demos never actually played. The
|
||||||
|
proper long-term solution would be to make shadow copies of all cvars
|
||||||
|
touched by demos and use those for the demo and the real things for
|
||||||
|
everything else, but this should do for now and is a lot easier.
|
||||||
|
- Fixed: When using BOOM-style sector flags and specials together, the
|
||||||
|
special was ignored unless it was "secret".
|
||||||
|
- Fixed: One byte is too short for DUMB_IT_SIGRENDERER to store song tempo.
|
||||||
|
Changed it to a word.
|
||||||
|
- Went back to using RDTSC for timing on Win32. Ironically,
|
||||||
|
QueryPerformanceCounter() is obviously using the TSC for its timing on my
|
||||||
|
machine, yet the overhead it has to do to keep the timer sane is apparently
|
||||||
|
noticeable on a few maps. I suppose I should at some time check
|
||||||
|
clock_gettime() and see if it has similar issues on Linux.
|
||||||
|
|
||||||
|
March 3, 2009 (Changes by Graf Zahl)
|
||||||
|
- changed: If a monster with the BOSSDEATH flag is crushed A_BossDeath will
|
||||||
|
be called now.
|
||||||
|
- fixed: D'Sparil's second form was missing the BOSSDEATH flag.
|
||||||
|
- fixed: D'Sparil's first form requires the DONTGIB flag.
|
||||||
|
- fixed: Heretic doesn't crush monsters. To handle this in a more generic
|
||||||
|
fashion this depends on the presence of a gib sprite now.
|
||||||
|
|
||||||
|
March 1, 2009 (Changes by Graf Zahl)
|
||||||
|
- Changed burn and Acolyte death sequences so that they leave corpses that
|
||||||
|
don't vanish.
|
||||||
|
- Fixed: AActor::SetOrigin must call P_FindFloorCeiling to get the true
|
||||||
|
floor and ceiling heights. Otherwise the actor will fall right through
|
||||||
|
3DMidtex textures (and 3D-floors.)
|
||||||
|
|
||||||
|
February 29, 2008
|
||||||
|
- Version bump to 2.3.0.
|
||||||
|
|
||||||
|
February 28, 2009
|
||||||
- Fixed: The TeleporterBeacon tried to enter its See state rather than its
|
- Fixed: The TeleporterBeacon tried to enter its See state rather than its
|
||||||
Drop state. Also changed it to fade out when it's done rather than
|
Drop state. Also changed it to fade out when it's done rather than
|
||||||
disappearing abruptly.
|
disappearing abruptly.
|
||||||
|
|
|
@ -51,6 +51,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zipdir", "tools\zipdir\zipd
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gdtoa", "gdtoa\gdtoa.vcproj", "{B68E0ABF-B627-48A3-A92F-D8F827A75054}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gdtoa", "gdtoa\gdtoa.vcproj", "{B68E0ABF-B627-48A3-A92F-D8F827A75054}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lzmalib", "lzma\lzmalib.vcproj", "{6EB27E78-7C7A-4F08-8E19-957E8EB3A20F}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzip2", "bzip2\bzip2.vcproj", "{A7DE5C73-D623-4118-A48A-BDFD1FAE97D4}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="src\win32,src\sound,src,zlib,src\g_shared,src\g_doom,src\g_raven,src\g_heretic,src\g_hexen,src\g_strife;flac;jpeg-6b;snes_spc\snes_spc;gdtoa"
|
AdditionalIncludeDirectories="src\win32,src\sound,src,zlib,src\g_shared,src\g_doom,src\g_raven,src\g_heretic,src\g_hexen,src\g_strife;flac;jpeg-6b;snes_spc\snes_spc;gdtoa;bzip2;lzma\C"
|
||||||
PreprocessorDefinitions="NDEBUG,WIN32,_WIN32,_WINDOWS,USEASM,NO_MANIFEST"
|
PreprocessorDefinitions="NDEBUG,WIN32,_WIN32,_WINDOWS,USEASM,NO_MANIFEST"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
|
@ -172,7 +172,7 @@
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
InlineFunctionExpansion="0"
|
InlineFunctionExpansion="0"
|
||||||
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;flac;jpeg-6b;snes_spc\snes_spc;gdtoa"
|
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;flac;jpeg-6b;snes_spc\snes_spc;gdtoa;bzip2;lzma\C"
|
||||||
PreprocessorDefinitions="WIN32,_DEBUG,_WIN32,_WINDOWS,USEASM,_CRTDBG_MAP_ALLOC,NO_MANIFEST"
|
PreprocessorDefinitions="WIN32,_DEBUG,_WIN32,_WINDOWS,USEASM,_CRTDBG_MAP_ALLOC,NO_MANIFEST"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
|
@ -280,7 +280,7 @@
|
||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;jpeg-6b;snes_spc\snes_spc"
|
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;jpeg-6b;snes_spc\snes_spc;bzip2;lzma\C"
|
||||||
PreprocessorDefinitions="NDEBUG,WIN32,_WIN32,_WINDOWS,USEASM,HAVE_STRUPR,HAVE_FILELENGTH,NOASM"
|
PreprocessorDefinitions="NDEBUG,WIN32,_WIN32,_WINDOWS,USEASM,HAVE_STRUPR,HAVE_FILELENGTH,NOASM"
|
||||||
StringPooling="true"
|
StringPooling="true"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
|
@ -390,7 +390,7 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;flac"
|
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;flac;bzip2;lzma\C"
|
||||||
PreprocessorDefinitions="WIN32,_DEBUG,_WIN32,_WINDOWS,USEASM,_CRTDBG_MAP_ALLOC,HAVE_STRUPR,HAVE_FILELENGTH,NOASM"
|
PreprocessorDefinitions="WIN32,_DEBUG,_WIN32,_WINDOWS,USEASM,_CRTDBG_MAP_ALLOC,HAVE_STRUPR,HAVE_FILELENGTH,NOASM"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
RuntimeLibrary="1"
|
RuntimeLibrary="1"
|
||||||
|
|
|
@ -761,7 +761,7 @@ add_executable( zdoom WIN32
|
||||||
set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" )
|
set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" )
|
||||||
set_source_files_properties( sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" )
|
set_source_files_properties( sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" )
|
||||||
|
|
||||||
target_link_libraries( zdoom ${ZDOOM_LIBS} snes_spc gdtoa dumb )
|
target_link_libraries( zdoom ${ZDOOM_LIBS} snes_spc gdtoa dumb bzip2 lzma )
|
||||||
include_directories( .
|
include_directories( .
|
||||||
g_doom
|
g_doom
|
||||||
g_heretic
|
g_heretic
|
||||||
|
|
|
@ -144,6 +144,7 @@ void ParseCompatibility()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
x = 0;
|
||||||
sc.ScriptError("MD5 signature must be a hexadecimal value");
|
sc.ScriptError("MD5 signature must be a hexadecimal value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,7 @@ class APlayerPawn : public AActor
|
||||||
public:
|
public:
|
||||||
virtual void Serialize (FArchive &arc);
|
virtual void Serialize (FArchive &arc);
|
||||||
|
|
||||||
|
virtual void PostBeginPlay();
|
||||||
virtual void Tick();
|
virtual void Tick();
|
||||||
virtual void AddInventory (AInventory *item);
|
virtual void AddInventory (AInventory *item);
|
||||||
virtual void RemoveInventory (AInventory *item);
|
virtual void RemoveInventory (AInventory *item);
|
||||||
|
|
200
src/files.cpp
200
src/files.cpp
|
@ -266,6 +266,205 @@ void FileReaderZ::FillBuffer ()
|
||||||
Stream.avail_in = numread;
|
Stream.avail_in = numread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FileReaderZ
|
||||||
|
//
|
||||||
|
// The bzip2 wrapper
|
||||||
|
// reads data from a libbzip2 compressed stream
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FileReaderBZ2::FileReaderBZ2 (FileReader &file)
|
||||||
|
: File(file), SawEOF(false)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
FillBuffer ();
|
||||||
|
|
||||||
|
Stream.bzalloc = NULL;
|
||||||
|
Stream.bzfree = NULL;
|
||||||
|
Stream.opaque = NULL;
|
||||||
|
|
||||||
|
err = BZ2_bzDecompressInit(&Stream, 0, 0);
|
||||||
|
|
||||||
|
if (err != BZ_OK)
|
||||||
|
{
|
||||||
|
I_Error ("FileReaderBZ2: bzDecompressInit failed: %d\n", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderBZ2::~FileReaderBZ2 ()
|
||||||
|
{
|
||||||
|
BZ2_bzDecompressEnd (&Stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
long FileReaderBZ2::Read (void *buffer, long len)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
Stream.next_out = (char *)buffer;
|
||||||
|
Stream.avail_out = len;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
err = BZ2_bzDecompress(&Stream);
|
||||||
|
if (Stream.avail_in == 0 && !SawEOF)
|
||||||
|
{
|
||||||
|
FillBuffer ();
|
||||||
|
}
|
||||||
|
} while (err == BZ_OK && Stream.avail_out != 0);
|
||||||
|
|
||||||
|
if (err != BZ_OK && err != BZ_STREAM_END)
|
||||||
|
{
|
||||||
|
I_Error ("Corrupt bzip2 stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Stream.avail_out != 0)
|
||||||
|
{
|
||||||
|
I_Error ("Ran out of data in bzip2 stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
return len - Stream.avail_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileReaderBZ2::FillBuffer ()
|
||||||
|
{
|
||||||
|
long numread = File.Read(InBuff, BUFF_SIZE);
|
||||||
|
|
||||||
|
if (numread < BUFF_SIZE)
|
||||||
|
{
|
||||||
|
SawEOF = true;
|
||||||
|
}
|
||||||
|
Stream.next_in = (char *)InBuff;
|
||||||
|
Stream.avail_in = numread;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// bz_internal_error
|
||||||
|
//
|
||||||
|
// libbzip2 wants this, since we build it with BZ_NO_STDIO set.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
extern "C" void bz_internal_error (int errcode)
|
||||||
|
{
|
||||||
|
I_FatalError("libbzip2: internal error number %d\n", errcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FileReaderLZMA
|
||||||
|
//
|
||||||
|
// The lzma wrapper
|
||||||
|
// reads data from a LZMA compressed stream
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
|
||||||
|
static void SzFree(void *p, void *address) { p = p; free(address); }
|
||||||
|
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
|
FileReaderLZMA::FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip)
|
||||||
|
: File(file), SawEOF(false)
|
||||||
|
{
|
||||||
|
BYTE header[4 + LZMA_PROPS_SIZE];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
assert(zip == true);
|
||||||
|
|
||||||
|
Size = uncompressed_size;
|
||||||
|
OutProcessed = 0;
|
||||||
|
|
||||||
|
// Read zip LZMA properties header
|
||||||
|
if (File.Read(header, sizeof(header)) < (long)sizeof(header))
|
||||||
|
{
|
||||||
|
I_Error("FileReaderLZMA: File too shart\n");
|
||||||
|
}
|
||||||
|
if (header[2] + header[3] * 256 != LZMA_PROPS_SIZE)
|
||||||
|
{
|
||||||
|
I_Error("FileReaderLZMA: LZMA props size is %d (expected %d)\n",
|
||||||
|
header[2] + header[3] * 256, LZMA_PROPS_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
FillBuffer();
|
||||||
|
|
||||||
|
LzmaDec_Construct(&Stream);
|
||||||
|
err = LzmaDec_Allocate(&Stream, header + 4, LZMA_PROPS_SIZE, &g_Alloc);
|
||||||
|
|
||||||
|
if (err != SZ_OK)
|
||||||
|
{
|
||||||
|
I_Error("FileReaderLZMA: LzmaDec_Allocate failed: %d\n", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
LzmaDec_Init(&Stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderLZMA::~FileReaderLZMA ()
|
||||||
|
{
|
||||||
|
LzmaDec_Free(&Stream, &g_Alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
long FileReaderLZMA::Read (void *buffer, long len)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
Byte *next_out = (Byte *)buffer;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ELzmaFinishMode finish_mode = LZMA_FINISH_ANY;
|
||||||
|
ELzmaStatus status;
|
||||||
|
size_t out_processed = len;
|
||||||
|
size_t in_processed = InSize;
|
||||||
|
|
||||||
|
err = LzmaDec_DecodeToBuf(&Stream, next_out, &out_processed, InBuff + InPos, &in_processed, finish_mode, &status);
|
||||||
|
InPos += in_processed;
|
||||||
|
InSize -= in_processed;
|
||||||
|
next_out += out_processed;
|
||||||
|
len = (long)(len - out_processed);
|
||||||
|
if (err != SZ_OK)
|
||||||
|
{
|
||||||
|
I_Error ("Corrupt LZMA stream");
|
||||||
|
}
|
||||||
|
if (in_processed == 0 && out_processed == 0)
|
||||||
|
{
|
||||||
|
if (status != LZMA_STATUS_FINISHED_WITH_MARK)
|
||||||
|
{
|
||||||
|
I_Error ("Corrupt LZMA stream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (InSize == 0 && !SawEOF)
|
||||||
|
{
|
||||||
|
FillBuffer ();
|
||||||
|
}
|
||||||
|
} while (err == SZ_OK && len != 0);
|
||||||
|
|
||||||
|
if (err != Z_OK && err != Z_STREAM_END)
|
||||||
|
{
|
||||||
|
I_Error ("Corrupt LZMA stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len != 0)
|
||||||
|
{
|
||||||
|
I_Error ("Ran out of data in LZMA stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (long)(next_out - (Byte *)buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileReaderLZMA::FillBuffer ()
|
||||||
|
{
|
||||||
|
long numread = File.Read(InBuff, BUFF_SIZE);
|
||||||
|
|
||||||
|
if (numread < BUFF_SIZE)
|
||||||
|
{
|
||||||
|
SawEOF = true;
|
||||||
|
}
|
||||||
|
InPos = 0;
|
||||||
|
InSize = numread;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// MemoryReader
|
// MemoryReader
|
||||||
|
@ -320,4 +519,3 @@ char *MemoryReader::Gets(char *strbuf, int len)
|
||||||
{
|
{
|
||||||
return GetsFromBuffer(bufptr, strbuf, len);
|
return GetsFromBuffer(bufptr, strbuf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
128
src/files.h
128
src/files.h
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
#include "bzlib.h"
|
||||||
|
#include "LzmaDec.h"
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "m_swap.h"
|
#include "m_swap.h"
|
||||||
|
|
||||||
|
@ -140,6 +142,132 @@ private:
|
||||||
FileReaderZ &operator= (const FileReaderZ &) { return *this; }
|
FileReaderZ &operator= (const FileReaderZ &) { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Wraps around a FileReader to decompress a bzip2 stream
|
||||||
|
class FileReaderBZ2
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileReaderBZ2 (FileReader &file);
|
||||||
|
~FileReaderBZ2 ();
|
||||||
|
|
||||||
|
long Read (void *buffer, long len);
|
||||||
|
|
||||||
|
FileReaderBZ2 &operator>> (BYTE &v)
|
||||||
|
{
|
||||||
|
Read (&v, 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderBZ2 &operator>> (SBYTE &v)
|
||||||
|
{
|
||||||
|
Read (&v, 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderBZ2 &operator>> (WORD &v)
|
||||||
|
{
|
||||||
|
Read (&v, 2);
|
||||||
|
v = LittleShort(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderBZ2 &operator>> (SWORD &v)
|
||||||
|
{
|
||||||
|
Read (&v, 2);
|
||||||
|
v = LittleShort(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderBZ2 &operator>> (DWORD &v)
|
||||||
|
{
|
||||||
|
Read (&v, 4);
|
||||||
|
v = LittleLong(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderBZ2 &operator>> (fixed_t &v)
|
||||||
|
{
|
||||||
|
Read (&v, 4);
|
||||||
|
v = LittleLong(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum { BUFF_SIZE = 4096 };
|
||||||
|
|
||||||
|
FileReader &File;
|
||||||
|
bool SawEOF;
|
||||||
|
bz_stream Stream;
|
||||||
|
BYTE InBuff[BUFF_SIZE];
|
||||||
|
|
||||||
|
void FillBuffer ();
|
||||||
|
|
||||||
|
FileReaderBZ2 &operator= (const FileReaderBZ2 &) { return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wraps around a FileReader to decompress a lzma stream
|
||||||
|
class FileReaderLZMA
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip);
|
||||||
|
~FileReaderLZMA ();
|
||||||
|
|
||||||
|
long Read (void *buffer, long len);
|
||||||
|
|
||||||
|
FileReaderLZMA &operator>> (BYTE &v)
|
||||||
|
{
|
||||||
|
Read (&v, 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderLZMA &operator>> (SBYTE &v)
|
||||||
|
{
|
||||||
|
Read (&v, 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderLZMA &operator>> (WORD &v)
|
||||||
|
{
|
||||||
|
Read (&v, 2);
|
||||||
|
v = LittleShort(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderLZMA &operator>> (SWORD &v)
|
||||||
|
{
|
||||||
|
Read (&v, 2);
|
||||||
|
v = LittleShort(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderLZMA &operator>> (DWORD &v)
|
||||||
|
{
|
||||||
|
Read (&v, 4);
|
||||||
|
v = LittleLong(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileReaderLZMA &operator>> (fixed_t &v)
|
||||||
|
{
|
||||||
|
Read (&v, 4);
|
||||||
|
v = LittleLong(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum { BUFF_SIZE = 4096 };
|
||||||
|
|
||||||
|
FileReader &File;
|
||||||
|
bool SawEOF;
|
||||||
|
CLzmaDec Stream;
|
||||||
|
size_t Size;
|
||||||
|
size_t InPos, InSize;
|
||||||
|
size_t OutProcessed;
|
||||||
|
BYTE InBuff[BUFF_SIZE];
|
||||||
|
|
||||||
|
void FillBuffer ();
|
||||||
|
|
||||||
|
FileReaderLZMA &operator= (const FileReaderLZMA &) { return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
class MemoryReader : public FileReader
|
class MemoryReader : public FileReader
|
||||||
{
|
{
|
||||||
|
|
|
@ -941,7 +941,6 @@ void G_DoLoadLevel (int position, bool autosave)
|
||||||
}
|
}
|
||||||
|
|
||||||
P_SetupLevel (level.mapname, position);
|
P_SetupLevel (level.mapname, position);
|
||||||
P_CompleteWeaponSetup();
|
|
||||||
|
|
||||||
AM_LevelInit();
|
AM_LevelInit();
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,15 @@ class AWeapon;
|
||||||
class FWeaponSlot
|
class FWeaponSlot
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
FWeaponSlot() { Clear(); }
|
||||||
|
FWeaponSlot(const FWeaponSlot &other) { Weapons = other.Weapons; }
|
||||||
FWeaponSlot &operator= (const FWeaponSlot &other) { Weapons = other.Weapons; return *this; }
|
FWeaponSlot &operator= (const FWeaponSlot &other) { Weapons = other.Weapons; return *this; }
|
||||||
void Clear() { Weapons.Clear(); }
|
void Clear() { Weapons.Clear(); }
|
||||||
bool AddWeapon (const char *type);
|
bool AddWeapon (const char *type);
|
||||||
bool AddWeapon (const PClass *type);
|
bool AddWeapon (const PClass *type);
|
||||||
void AddWeaponList (const char *list, bool clear);
|
void AddWeaponList (const char *list, bool clear);
|
||||||
AWeapon *PickWeapon (player_t *player);
|
AWeapon *PickWeapon (player_t *player);
|
||||||
int Size () { return (int)Weapons.Size(); }
|
int Size () const { return (int)Weapons.Size(); }
|
||||||
int LocateWeapon (const PClass *type);
|
int LocateWeapon (const PClass *type);
|
||||||
|
|
||||||
inline const PClass *GetWeapon (int index) const
|
inline const PClass *GetWeapon (int index) const
|
||||||
|
@ -59,6 +61,9 @@ enum ESlotDef
|
||||||
|
|
||||||
struct FWeaponSlots
|
struct FWeaponSlots
|
||||||
{
|
{
|
||||||
|
FWeaponSlots() { Clear(); }
|
||||||
|
FWeaponSlots(const FWeaponSlots &other);
|
||||||
|
|
||||||
FWeaponSlot Slots[NUM_WEAPON_SLOTS];
|
FWeaponSlot Slots[NUM_WEAPON_SLOTS];
|
||||||
|
|
||||||
AWeapon *PickNextWeapon (player_t *player);
|
AWeapon *PickNextWeapon (player_t *player);
|
||||||
|
@ -69,7 +74,9 @@ struct FWeaponSlots
|
||||||
ESlotDef AddDefaultWeapon (int slot, const PClass *type);
|
ESlotDef AddDefaultWeapon (int slot, const PClass *type);
|
||||||
void AddExtraWeapons();
|
void AddExtraWeapons();
|
||||||
void SetFromPlayer(const PClass *type);
|
void SetFromPlayer(const PClass *type);
|
||||||
void CompleteSetup(const PClass *type);
|
void StandardSetup(const PClass *type);
|
||||||
|
void LocalSetup(const PClass *type);
|
||||||
|
void SendDifferences(const FWeaponSlots &other);
|
||||||
int RestoreSlots (FConfigFile *config, const char *section);
|
int RestoreSlots (FConfigFile *config, const char *section);
|
||||||
void PrintSettings();
|
void PrintSettings();
|
||||||
|
|
||||||
|
@ -78,8 +85,7 @@ struct FWeaponSlots
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void P_PlaybackKeyConfWeapons();
|
void P_PlaybackKeyConfWeapons(FWeaponSlots *slots);
|
||||||
void P_CompleteWeaponSetup();
|
|
||||||
void Net_WriteWeapon(const PClass *type);
|
void Net_WriteWeapon(const PClass *type);
|
||||||
const PClass *Net_ReadWeapon(BYTE **stream);
|
const PClass *Net_ReadWeapon(BYTE **stream);
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ END_POINTERS
|
||||||
|
|
||||||
FString WeaponSection;
|
FString WeaponSection;
|
||||||
TArray<FString> KeyConfWeapons;
|
TArray<FString> KeyConfWeapons;
|
||||||
bool PlayingKeyConf;
|
FWeaponSlots *PlayingKeyConf;
|
||||||
|
|
||||||
TArray<const PClass *> Weapons_ntoh;
|
TArray<const PClass *> Weapons_ntoh;
|
||||||
TMap<const PClass *, int> Weapons_hton;
|
TMap<const PClass *, int> Weapons_hton;
|
||||||
|
@ -642,8 +642,6 @@ bool AWeaponGiver::TryPickup(AActor *&toucher)
|
||||||
|
|
||||||
/* Weapon slots ***********************************************************/
|
/* Weapon slots ***********************************************************/
|
||||||
|
|
||||||
FWeaponSlots LocalWeapons;
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// FWeaponSlot :: AddWeapon
|
// FWeaponSlot :: AddWeapon
|
||||||
|
@ -756,7 +754,7 @@ AWeapon *FWeaponSlot::PickWeapon(player_t *player)
|
||||||
}
|
}
|
||||||
if (player->ReadyWeapon != NULL)
|
if (player->ReadyWeapon != NULL)
|
||||||
{
|
{
|
||||||
for (i = 0; i < Weapons.Size(); i++)
|
for (i = 0; (unsigned)i < Weapons.Size(); i++)
|
||||||
{
|
{
|
||||||
if (Weapons[i].Type == player->ReadyWeapon->GetClass() ||
|
if (Weapons[i].Type == player->ReadyWeapon->GetClass() ||
|
||||||
(player->ReadyWeapon->WeaponFlags & WIF_POWERED_UP &&
|
(player->ReadyWeapon->WeaponFlags & WIF_POWERED_UP &&
|
||||||
|
@ -844,6 +842,20 @@ void FWeaponSlot::Sort()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FWeaponSlots - Copy Constructor
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FWeaponSlots::FWeaponSlots(const FWeaponSlots &other)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||||
|
{
|
||||||
|
Slots[i] = other.Slots[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// FWeaponSlots :: Clear
|
// FWeaponSlots :: Clear
|
||||||
|
@ -1105,24 +1117,36 @@ void FWeaponSlots::AddExtraWeapons()
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// FWeaponSlots :: CompleteSetup
|
// FWeaponSlots :: StandardSetup
|
||||||
//
|
//
|
||||||
// Sets up local weapon slots in this order:
|
// Setup weapons in this order:
|
||||||
// 1. Use slots from player class.
|
// 1. Use slots from player class.
|
||||||
// 2. Add extra weapons that specify their own slot.
|
// 2. Add extra weapons that specify their own slots.
|
||||||
// 3. Run KEYCONF weapon commands, affecting slots accordingly.
|
//
|
||||||
// 4. Read config slots, overriding current slots. If WeaponSection is set,
|
//===========================================================================
|
||||||
|
|
||||||
|
void FWeaponSlots::StandardSetup(const PClass *type)
|
||||||
|
{
|
||||||
|
SetFromPlayer(type);
|
||||||
|
AddExtraWeapons();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FWeaponSlots :: LocalSetup
|
||||||
|
//
|
||||||
|
// Setup weapons in this order:
|
||||||
|
// 1. Run KEYCONF weapon commands, affecting slots accordingly.
|
||||||
|
// 2. Read config slots, overriding current slots. If WeaponSection is set,
|
||||||
// then [<WeaponSection>.<PlayerClass>.Weapons] is tried, followed by
|
// then [<WeaponSection>.<PlayerClass>.Weapons] is tried, followed by
|
||||||
// [<WeaponSection>.Weapons] if that did not exist. If WeaponSection is
|
// [<WeaponSection>.Weapons] if that did not exist. If WeaponSection is
|
||||||
// empty, then the slots are read from [<PlayerClass>.Weapons].
|
// empty, then the slots are read from [<PlayerClass>.Weapons].
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void FWeaponSlots::CompleteSetup(const PClass *type)
|
void FWeaponSlots::LocalSetup(const PClass *type)
|
||||||
{
|
{
|
||||||
SetFromPlayer(type);
|
P_PlaybackKeyConfWeapons(this);
|
||||||
AddExtraWeapons();
|
|
||||||
P_PlaybackKeyConfWeapons();
|
|
||||||
if (WeaponSection.IsNotEmpty())
|
if (WeaponSection.IsNotEmpty())
|
||||||
{
|
{
|
||||||
FString sectionclass(WeaponSection);
|
FString sectionclass(WeaponSection);
|
||||||
|
@ -1138,25 +1162,41 @@ void FWeaponSlots::CompleteSetup(const PClass *type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_CompleteWeaponSetup()
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FWeaponSlots :: SendDifferences
|
||||||
|
//
|
||||||
|
// Sends the weapon slots from this instance that differ from other's.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void FWeaponSlots::SendDifferences(const FWeaponSlots &other)
|
||||||
{
|
{
|
||||||
if (players[consoleplayer].mo != NULL)
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||||
{
|
{
|
||||||
// Set up the weapon slots locally
|
if (other.Slots[i].Size() == Slots[i].Size())
|
||||||
LocalWeapons.CompleteSetup(players[consoleplayer].mo->GetClass());
|
|
||||||
// Now transmit them across the network
|
|
||||||
for (int i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
|
||||||
{
|
{
|
||||||
if (LocalWeapons.Slots[i].Size() > 0)
|
for (j = (int)Slots[i].Size(); j-- > 0; )
|
||||||
{
|
{
|
||||||
Net_WriteByte(DEM_SETSLOT);
|
if (other.Slots[i].GetWeapon(j) != Slots[i].GetWeapon(j))
|
||||||
Net_WriteByte(i);
|
|
||||||
Net_WriteByte(LocalWeapons.Slots[i].Size());
|
|
||||||
for(int j = 0; j < LocalWeapons.Slots[i].Size(); j++)
|
|
||||||
{
|
{
|
||||||
Net_WriteWeapon(LocalWeapons.Slots[i].GetWeapon(j));
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (j < 0)
|
||||||
|
{ // The two slots are the same.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The slots differ. Send mine.
|
||||||
|
Net_WriteByte(DEM_SETSLOT);
|
||||||
|
Net_WriteByte(i);
|
||||||
|
Net_WriteByte(Slots[i].Size());
|
||||||
|
for (j = 0; j < Slots[i].Size(); ++j)
|
||||||
|
{
|
||||||
|
Net_WriteWeapon(Slots[i].GetWeapon(j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1268,12 +1308,12 @@ CCMD (setslot)
|
||||||
{
|
{
|
||||||
KeyConfWeapons.Push(argv.args());
|
KeyConfWeapons.Push(argv.args());
|
||||||
}
|
}
|
||||||
else if (PlayingKeyConf)
|
else if (PlayingKeyConf != NULL)
|
||||||
{
|
{
|
||||||
LocalWeapons.Slots[slot].Clear();
|
PlayingKeyConf->Slots[slot].Clear();
|
||||||
for (int i = 2; i < argv.argc(); ++i)
|
for (int i = 2; i < argv.argc(); ++i)
|
||||||
{
|
{
|
||||||
LocalWeapons.Slots[slot].AddWeapon(argv[i]);
|
PlayingKeyConf->Slots[slot].AddWeapon(argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1303,7 +1343,7 @@ void FWeaponSlots::AddSlot(int slot, const PClass *type, bool feedback)
|
||||||
{
|
{
|
||||||
if (type != NULL && !Slots[slot].AddWeapon(type) && feedback)
|
if (type != NULL && !Slots[slot].AddWeapon(type) && feedback)
|
||||||
{
|
{
|
||||||
Printf ("Could not add %s to slot %zu\n", type->TypeName.GetChars(), slot);
|
Printf ("Could not add %s to slot %d\n", type->TypeName.GetChars(), slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1321,9 +1361,9 @@ CCMD (addslot)
|
||||||
{
|
{
|
||||||
KeyConfWeapons.Push(argv.args());
|
KeyConfWeapons.Push(argv.args());
|
||||||
}
|
}
|
||||||
else if (PlayingKeyConf)
|
else if (PlayingKeyConf != NULL)
|
||||||
{
|
{
|
||||||
LocalWeapons.AddSlot(int(slot), PClass::FindClass(argv[2]), false);
|
PlayingKeyConf->AddSlot(int(slot), PClass::FindClass(argv[2]), false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1397,9 +1437,9 @@ CCMD (addslotdefault)
|
||||||
{
|
{
|
||||||
KeyConfWeapons.Push(argv.args());
|
KeyConfWeapons.Push(argv.args());
|
||||||
}
|
}
|
||||||
else if (PlayingKeyConf)
|
else if (PlayingKeyConf != NULL)
|
||||||
{
|
{
|
||||||
LocalWeapons.AddSlotDefault(int(slot), PClass::FindClass(argv[2]), false);
|
PlayingKeyConf->AddSlotDefault(int(slot), PClass::FindClass(argv[2]), false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1417,15 +1457,15 @@ CCMD (addslotdefault)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void P_PlaybackKeyConfWeapons()
|
void P_PlaybackKeyConfWeapons(FWeaponSlots *slots)
|
||||||
{
|
{
|
||||||
PlayingKeyConf = true;
|
PlayingKeyConf = slots;
|
||||||
for (unsigned int i = 0; i < KeyConfWeapons.Size(); ++i)
|
for (unsigned int i = 0; i < KeyConfWeapons.Size(); ++i)
|
||||||
{
|
{
|
||||||
FString cmd(KeyConfWeapons[i]);
|
FString cmd(KeyConfWeapons[i]);
|
||||||
AddCommandString(cmd.LockBuffer());
|
AddCommandString(cmd.LockBuffer());
|
||||||
}
|
}
|
||||||
PlayingKeyConf = false;
|
PlayingKeyConf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -1593,7 +1633,7 @@ const PClass *Net_ReadWeapon(BYTE **stream)
|
||||||
{
|
{
|
||||||
index = (index & 0x7F) | (ReadByte(stream) << 7);
|
index = (index & 0x7F) | (ReadByte(stream) << 7);
|
||||||
}
|
}
|
||||||
if (index >= Weapons_ntoh.Size())
|
if ((unsigned)index >= Weapons_ntoh.Size())
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1234,6 +1234,7 @@ static valueenum_t Outputs[] =
|
||||||
#elif defined(unix)
|
#elif defined(unix)
|
||||||
{ "OSS", "OSS" },
|
{ "OSS", "OSS" },
|
||||||
{ "ALSA", "ALSA" },
|
{ "ALSA", "ALSA" },
|
||||||
|
{ "SDL", "SDL" },
|
||||||
{ "ESD", "ESD" },
|
{ "ESD", "ESD" },
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
{ "Sound Manager", "Sound Manager" },
|
{ "Sound Manager", "Sound Manager" },
|
||||||
|
|
|
@ -491,7 +491,26 @@ void APlayerPawn::Tick()
|
||||||
Super::Tick();
|
Super::Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// APlayerPawn :: PostBeginPlay
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void APlayerPawn::PostBeginPlay()
|
||||||
|
{
|
||||||
|
// If we're not a voodoo doll, set up our weapons.
|
||||||
|
if (player != NULL && player->mo == this)
|
||||||
|
{
|
||||||
|
player->weapons.StandardSetup(GetClass());
|
||||||
|
if (player - players == consoleplayer)
|
||||||
|
{ // If we're the local player, then there's a bit more work to do.
|
||||||
|
FWeaponSlots local_slots(player->weapons);
|
||||||
|
local_slots.LocalSetup(GetClass());
|
||||||
|
local_slots.SendDifferences(player->weapons);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -1122,6 +1122,7 @@ void STACK_ARGS FScriptPosition::Message (int severity, const char *message, ...
|
||||||
case MSG_FATAL:
|
case MSG_FATAL:
|
||||||
I_Error ("Script error, \"%s\" line %d:\n%s\n",
|
I_Error ("Script error, \"%s\" line %d:\n%s\n",
|
||||||
FileName.GetChars(), ScriptLine, composed.GetChars());
|
FileName.GetChars(), ScriptLine, composed.GetChars());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
Printf (level, "%sScript %s, \"%s\" line %d:\n%s%s\n",
|
Printf (level, "%sScript %s, \"%s\" line %d:\n%s%s\n",
|
||||||
color, type, FileName.GetChars(), ScriptLine, color, composed.GetChars());
|
color, type, FileName.GetChars(), ScriptLine, color, composed.GetChars());
|
||||||
|
|
|
@ -29,6 +29,7 @@ extern int paused;
|
||||||
CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
|
CVAR (Bool, sdl_nokeyrepeat, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
|
|
||||||
float JoyAxes[6];
|
float JoyAxes[6];
|
||||||
//static int JoyActive;
|
//static int JoyActive;
|
||||||
|
@ -200,6 +201,10 @@ static void InitKeySymMap ()
|
||||||
static void I_CheckGUICapture ()
|
static void I_CheckGUICapture ()
|
||||||
{
|
{
|
||||||
bool wantCapt;
|
bool wantCapt;
|
||||||
|
bool repeat;
|
||||||
|
int oldrepeat, interval;
|
||||||
|
|
||||||
|
SDL_GetKeyRepeat(&oldrepeat, &interval);
|
||||||
|
|
||||||
if (menuactive == MENU_Off)
|
if (menuactive == MENU_Off)
|
||||||
{
|
{
|
||||||
|
@ -217,15 +222,34 @@ static void I_CheckGUICapture ()
|
||||||
{
|
{
|
||||||
FlushDIKState ();
|
FlushDIKState ();
|
||||||
memset (DownState, 0, sizeof(DownState));
|
memset (DownState, 0, sizeof(DownState));
|
||||||
SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
repeat = !sdl_nokeyrepeat;
|
||||||
SDL_EnableUNICODE (1);
|
SDL_EnableUNICODE (1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SDL_EnableKeyRepeat (0, 0);
|
repeat = false;
|
||||||
SDL_EnableUNICODE (0);
|
SDL_EnableUNICODE (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (wantCapt)
|
||||||
|
{
|
||||||
|
repeat = !sdl_nokeyrepeat;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
repeat = false;
|
||||||
|
}
|
||||||
|
if (repeat != (oldrepeat != 0))
|
||||||
|
{
|
||||||
|
if (repeat)
|
||||||
|
{
|
||||||
|
SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_EnableKeyRepeat (0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CenterMouse ()
|
static void CenterMouse ()
|
||||||
|
|
|
@ -167,16 +167,14 @@ namespace FMOD
|
||||||
FMOD_RESULT getDSPClock (unsigned int *hi, unsigned int *lo) { return FMOD_System_GetDSPClock(this, hi, lo); }
|
FMOD_RESULT getDSPClock (unsigned int *hi, unsigned int *lo) { return FMOD_System_GetDSPClock(this, hi, lo); }
|
||||||
|
|
||||||
// Recording API.
|
// Recording API.
|
||||||
FMOD_RESULT setRecordDriver (int driver) { return FMOD_System_SetRecordDriver(this, driver); }
|
|
||||||
FMOD_RESULT getRecordDriver (int *driver) { return FMOD_System_GetRecordDriver(this, driver); }
|
|
||||||
FMOD_RESULT getRecordNumDrivers (int *numdrivers) { return FMOD_System_GetRecordNumDrivers(this, numdrivers); }
|
FMOD_RESULT getRecordNumDrivers (int *numdrivers) { return FMOD_System_GetRecordNumDrivers(this, numdrivers); }
|
||||||
FMOD_RESULT getRecordDriverInfo (int id, char *name, int namelen, FMOD_GUID *guid) { return FMOD_System_GetRecordDriverInfo(this, id, name, namelen, guid); }
|
FMOD_RESULT getRecordDriverInfo (int id, char *name, int namelen, FMOD_GUID *guid) { return FMOD_System_GetRecordDriverInfo(this, id, name, namelen, guid); }
|
||||||
FMOD_RESULT getRecordDriverCaps (int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency) { return FMOD_System_GetRecordDriverCaps(this, id, caps, minfrequency, maxfrequency); }
|
FMOD_RESULT getRecordDriverCaps (int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency) { return FMOD_System_GetRecordDriverCaps(this, id, caps, minfrequency, maxfrequency); }
|
||||||
FMOD_RESULT getRecordPosition (unsigned int *position) { return FMOD_System_GetRecordPosition(this, position); }
|
FMOD_RESULT getRecordPosition (int id, unsigned int *position) { return FMOD_System_GetRecordPosition(this, id, position); }
|
||||||
|
|
||||||
FMOD_RESULT recordStart (Sound *sound, bool loop) { return FMOD_System_RecordStart(this, (FMOD_SOUND *)sound, loop); }
|
FMOD_RESULT recordStart (int id, Sound *sound, bool loop) { return FMOD_System_RecordStart(this, id, (FMOD_SOUND *)sound, loop); }
|
||||||
FMOD_RESULT recordStop () { return FMOD_System_RecordStop(this); }
|
FMOD_RESULT recordStop (int id) { return FMOD_System_RecordStop(this, id); }
|
||||||
FMOD_RESULT isRecording (bool *recording) { FMOD_BOOL b; FMOD_RESULT res = FMOD_System_IsRecording(this, &b); *recording = b; return res; }
|
FMOD_RESULT isRecording (int id, bool *recording) { FMOD_BOOL b; FMOD_RESULT res = FMOD_System_IsRecording(this, id, &b); *recording = b; return res; }
|
||||||
|
|
||||||
// Geometry API.
|
// Geometry API.
|
||||||
FMOD_RESULT createGeometry (int maxpolygons, int maxvertices, Geometry **geometry) { return FMOD_System_CreateGeometry(this, maxpolygons, maxvertices, (FMOD_GEOMETRY **)geometry); }
|
FMOD_RESULT createGeometry (int maxpolygons, int maxvertices, Geometry **geometry) { return FMOD_System_CreateGeometry(this, maxpolygons, maxvertices, (FMOD_GEOMETRY **)geometry); }
|
||||||
|
|
|
@ -54,6 +54,7 @@ extern HWND Window;
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
|
#include "cmdlib.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -159,6 +160,7 @@ static const FEnumList OutputNames[] =
|
||||||
{ "OSS", FMOD_OUTPUTTYPE_OSS },
|
{ "OSS", FMOD_OUTPUTTYPE_OSS },
|
||||||
{ "ALSA", FMOD_OUTPUTTYPE_ALSA },
|
{ "ALSA", FMOD_OUTPUTTYPE_ALSA },
|
||||||
{ "ESD", FMOD_OUTPUTTYPE_ESD },
|
{ "ESD", FMOD_OUTPUTTYPE_ESD },
|
||||||
|
{ "SDL", 666 },
|
||||||
|
|
||||||
// Mac
|
// Mac
|
||||||
{ "Sound Manager", FMOD_OUTPUTTYPE_SOUNDMANAGER },
|
{ "Sound Manager", FMOD_OUTPUTTYPE_SOUNDMANAGER },
|
||||||
|
@ -612,6 +614,7 @@ bool FMODSoundRenderer::Init()
|
||||||
ChannelGroupTargetUnit = NULL;
|
ChannelGroupTargetUnit = NULL;
|
||||||
SfxReverbHooked = false;
|
SfxReverbHooked = false;
|
||||||
SfxReverbPlaceholder = NULL;
|
SfxReverbPlaceholder = NULL;
|
||||||
|
OutputPlugin = 0;
|
||||||
|
|
||||||
Printf("I_InitSound: Initializing FMOD\n");
|
Printf("I_InitSound: Initializing FMOD\n");
|
||||||
|
|
||||||
|
@ -692,21 +695,65 @@ bool FMODSoundRenderer::Init()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
// Try to load SDL output plugin
|
||||||
|
result = Sys->setPluginPath(progdir); // Should we really look for it in the program directory?
|
||||||
|
result = Sys->loadPlugin("liboutput_sdl.so", &OutputPlugin);
|
||||||
|
if (result != FMOD_OK)
|
||||||
|
{
|
||||||
|
OutputPlugin = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set the user specified output mode.
|
// Set the user specified output mode.
|
||||||
eval = Enum_NumForName(OutputNames, snd_output);
|
eval = Enum_NumForName(OutputNames, snd_output);
|
||||||
if (eval >= 0)
|
if (eval >= 0)
|
||||||
{
|
{
|
||||||
result = Sys->setOutput(FMOD_OUTPUTTYPE(eval));
|
if (eval == 666 && OutputPlugin != 0)
|
||||||
|
{
|
||||||
|
result = Sys->setOutputByPlugin(OutputPlugin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = Sys->setOutput(FMOD_OUTPUTTYPE(eval));
|
||||||
|
}
|
||||||
if (result != FMOD_OK)
|
if (result != FMOD_OK)
|
||||||
{
|
{
|
||||||
Printf(TEXTCOLOR_BLUE"Setting output type '%s' failed. Using default instead. (Error %d)\n", *snd_output, result);
|
Printf(TEXTCOLOR_BLUE"Setting output type '%s' failed. Using default instead. (Error %d)\n", *snd_output, result);
|
||||||
|
eval = FMOD_OUTPUTTYPE_AUTODETECT;
|
||||||
Sys->setOutput(FMOD_OUTPUTTYPE_AUTODETECT);
|
Sys->setOutput(FMOD_OUTPUTTYPE_AUTODETECT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Sys->getNumDrivers(&driver);
|
result = Sys->getNumDrivers(&driver);
|
||||||
|
#ifdef unix
|
||||||
if (result == FMOD_OK)
|
if (result == FMOD_OK)
|
||||||
{
|
{
|
||||||
|
// On Linux, FMOD defaults to OSS. If OSS is not present, it doesn't
|
||||||
|
// try ALSA, it just fails. We'll try for it, but only if OSS wasn't
|
||||||
|
// explicitly specified for snd_output.
|
||||||
|
if (driver == 0 && eval == FMOD_OUTPUTTYPE_AUTODETECT)
|
||||||
|
{
|
||||||
|
FMOD_OUTPUTTYPE output;
|
||||||
|
if (FMOD_OK == Sys->getOutput(&output))
|
||||||
|
{
|
||||||
|
if (output == FMOD_OUTPUTTYPE_OSS)
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_BLUE"OSS could not be initialized. Trying ALSA.\n");
|
||||||
|
Sys->setOutput(FMOD_OUTPUTTYPE_ALSA);
|
||||||
|
result = Sys->getNumDrivers(&driver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (result == FMOD_OK)
|
||||||
|
{
|
||||||
|
if (driver == 0)
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_ORANGE"No working sound devices found. Try a different snd_output?\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (snd_driver >= driver)
|
if (snd_driver >= driver)
|
||||||
{
|
{
|
||||||
Printf(TEXTCOLOR_BLUE"Driver %d does not exist. Using 0.\n", *snd_driver);
|
Printf(TEXTCOLOR_BLUE"Driver %d does not exist. Using 0.\n", *snd_driver);
|
||||||
|
@ -1056,6 +1103,11 @@ void FMODSoundRenderer::Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
Sys->close();
|
Sys->close();
|
||||||
|
if (OutputPlugin != 0)
|
||||||
|
{
|
||||||
|
Sys->unloadPlugin(OutputPlugin);
|
||||||
|
OutputPlugin = 0;
|
||||||
|
}
|
||||||
Sys->release();
|
Sys->release();
|
||||||
Sys = NULL;
|
Sys = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ private:
|
||||||
FMOD::DSP *SfxReverbPlaceholder;
|
FMOD::DSP *SfxReverbPlaceholder;
|
||||||
bool SfxReverbHooked;
|
bool SfxReverbHooked;
|
||||||
float LastWaterLP;
|
float LastWaterLP;
|
||||||
|
unsigned int OutputPlugin;
|
||||||
|
|
||||||
// Just for snd_status display
|
// Just for snd_status display
|
||||||
int Driver_MinFrequency;
|
int Driver_MinFrequency;
|
||||||
|
|
|
@ -131,7 +131,7 @@ inline volatile unsigned long long rdtsc()
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
register unsigned long long tsc asm("eax");
|
register unsigned long long tsc asm("eax");
|
||||||
asm volatile ("\trdtsc\n" : : : "eax, "edx");
|
asm volatile ("\trdtsc\n" : : : "eax", "edx");
|
||||||
return tsc;
|
return tsc;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -325,7 +325,7 @@ do_stop:
|
||||||
sc.ScriptError("Negative jump offsets are not allowed");
|
sc.ScriptError("Negative jump offsets are not allowed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x > 0)
|
if (v > 0)
|
||||||
{
|
{
|
||||||
x = new FxStateByIndex(bag.statedef.GetStateCount() + v, sc);
|
x = new FxStateByIndex(bag.statedef.GetStateCount() + v, sc);
|
||||||
}
|
}
|
||||||
|
|
195
src/w_wad.cpp
195
src/w_wad.cpp
|
@ -91,6 +91,7 @@ struct FWadCollection::LumpRecord
|
||||||
{
|
{
|
||||||
char * fullname; // only valid for files loaded from a .zip file
|
char * fullname; // only valid for files loaded from a .zip file
|
||||||
char name[9];
|
char name[9];
|
||||||
|
BYTE method; // zip compression method
|
||||||
short wadnum;
|
short wadnum;
|
||||||
WORD flags;
|
WORD flags;
|
||||||
int position;
|
int position;
|
||||||
|
@ -299,7 +300,7 @@ int FWadCollection::AddExternalFile(const char *filename)
|
||||||
|
|
||||||
static DWORD Zip_FindCentralDir(FileReader * fin)
|
static DWORD Zip_FindCentralDir(FileReader * fin)
|
||||||
{
|
{
|
||||||
unsigned char* buf;
|
unsigned char buf[BUFREADCOMMENT + 4];
|
||||||
DWORD FileSize;
|
DWORD FileSize;
|
||||||
DWORD uBackRead;
|
DWORD uBackRead;
|
||||||
DWORD uMaxBack; // maximum size of global comment
|
DWORD uMaxBack; // maximum size of global comment
|
||||||
|
@ -310,38 +311,35 @@ static DWORD Zip_FindCentralDir(FileReader * fin)
|
||||||
FileSize = fin->Tell();
|
FileSize = fin->Tell();
|
||||||
uMaxBack = MIN<DWORD>(0xffff, FileSize);
|
uMaxBack = MIN<DWORD>(0xffff, FileSize);
|
||||||
|
|
||||||
buf = (unsigned char*)malloc(BUFREADCOMMENT+4);
|
|
||||||
if (buf == NULL) return 0;
|
|
||||||
|
|
||||||
uBackRead = 4;
|
uBackRead = 4;
|
||||||
while (uBackRead < uMaxBack)
|
while (uBackRead < uMaxBack)
|
||||||
{
|
{
|
||||||
DWORD uReadSize, uReadPos;
|
DWORD uReadSize, uReadPos;
|
||||||
int i;
|
int i;
|
||||||
if (uBackRead +BUFREADCOMMENT > uMaxBack)
|
if (uBackRead + BUFREADCOMMENT > uMaxBack)
|
||||||
uBackRead = uMaxBack;
|
uBackRead = uMaxBack;
|
||||||
else
|
else
|
||||||
uBackRead += BUFREADCOMMENT;
|
uBackRead += BUFREADCOMMENT;
|
||||||
uReadPos = FileSize - uBackRead ;
|
uReadPos = FileSize - uBackRead;
|
||||||
|
|
||||||
uReadSize = MIN<DWORD>((BUFREADCOMMENT+4) , (FileSize-uReadPos));
|
uReadSize = MIN<DWORD>((BUFREADCOMMENT + 4), (FileSize - uReadPos));
|
||||||
|
|
||||||
if (fin->Seek(uReadPos,SEEK_SET) != 0) break;
|
if (fin->Seek(uReadPos, SEEK_SET) != 0) break;
|
||||||
|
|
||||||
if (fin->Read(buf, (SDWORD)uReadSize) != (SDWORD)uReadSize) break;
|
if (fin->Read(buf, (SDWORD)uReadSize) != (SDWORD)uReadSize) break;
|
||||||
|
|
||||||
for (i=(int)uReadSize-3; (i--)>0;)
|
for (i = (int)uReadSize - 3; (i--) > 0;)
|
||||||
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
|
{
|
||||||
((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
|
if (buf[i] == 'P' && buf[i+1] == 'K' && buf[i+2] == 5 && buf[i+3] == 6)
|
||||||
{
|
{
|
||||||
uPosFound = uReadPos+i;
|
uPosFound = uReadPos + i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (uPosFound!=0)
|
if (uPosFound != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(buf);
|
|
||||||
return uPosFound;
|
return uPosFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +371,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
||||||
int startlump;
|
int startlump;
|
||||||
wadlump_t* fileinfo = NULL, *fileinfo2free = NULL;
|
wadlump_t* fileinfo = NULL, *fileinfo2free = NULL;
|
||||||
wadlump_t singleinfo;
|
wadlump_t singleinfo;
|
||||||
TArray<FZipFileInfo *> EmbeddedWADs;
|
TArray<FZipCentralDirectoryInfo *> EmbeddedWADs;
|
||||||
void * directory = NULL;
|
void * directory = NULL;
|
||||||
|
|
||||||
if (length==-1)
|
if (length==-1)
|
||||||
|
@ -508,10 +506,10 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
||||||
else if (header.magic[0] == ZIP_ID)
|
else if (header.magic[0] == ZIP_ID)
|
||||||
{
|
{
|
||||||
DWORD centraldir = Zip_FindCentralDir(wadinfo);
|
DWORD centraldir = Zip_FindCentralDir(wadinfo);
|
||||||
FZipCentralInfo info;
|
FZipEndOfCentralDirectory info;
|
||||||
int skipped = 0;
|
int skipped = 0;
|
||||||
|
|
||||||
if (centraldir==0)
|
if (centraldir == 0)
|
||||||
{
|
{
|
||||||
Printf("\n%s: ZIP file corrupt!\n", filename);
|
Printf("\n%s: ZIP file corrupt!\n", filename);
|
||||||
return;
|
return;
|
||||||
|
@ -519,56 +517,61 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
||||||
|
|
||||||
// Read the central directory info.
|
// Read the central directory info.
|
||||||
wadinfo->Seek(centraldir, SEEK_SET);
|
wadinfo->Seek(centraldir, SEEK_SET);
|
||||||
wadinfo->Read(&info, sizeof(FZipCentralInfo));
|
wadinfo->Read(&info, sizeof(FZipEndOfCentralDirectory));
|
||||||
|
|
||||||
// No multi-disk zips!
|
// No multi-disk zips!
|
||||||
if (info.wEntryCount != info.wTotalEntryCount ||
|
if (info.NumEntries != info.NumEntriesOnAllDisks ||
|
||||||
info.wNumberDiskWithCD != 0 || info.wNumberDisk != 0)
|
info.FirstDisk != 0 || info.DiskNumber != 0)
|
||||||
{
|
{
|
||||||
Printf("\n%s: Multipart Zip files are not supported.\n", filename);
|
Printf("\n%s: Multipart Zip files are not supported.\n", filename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NumLumps += LittleShort(info.wEntryCount);
|
NumLumps += LittleShort(info.NumEntries);
|
||||||
LumpInfo.Resize(NumLumps);
|
LumpInfo.Resize(NumLumps);
|
||||||
lump_p = &LumpInfo[startlump];
|
lump_p = &LumpInfo[startlump];
|
||||||
|
|
||||||
// Load the entire central directory. Too bad that this contains variable length entries...
|
// Load the entire central directory. Too bad that this contains variable length entries...
|
||||||
directory = malloc(LittleLong(info.dwCDSize));
|
directory = malloc(LittleLong(info.DirectorySize));
|
||||||
wadinfo->Seek(LittleLong(info.dwCDOffset), SEEK_SET);
|
wadinfo->Seek(LittleLong(info.DirectoryOffset), SEEK_SET);
|
||||||
wadinfo->Read(directory, LittleLong(info.dwCDSize));
|
wadinfo->Read(directory, LittleLong(info.DirectorySize));
|
||||||
|
|
||||||
char * dirptr =(char*)directory;
|
char *dirptr = (char*)directory;
|
||||||
for (int i = 0; i < LittleShort(info.wEntryCount); i++)
|
for (int i = 0; i < LittleShort(info.NumEntries); i++)
|
||||||
{
|
{
|
||||||
FZipFileInfo * zip_fh = (FZipFileInfo*)dirptr;
|
FZipCentralDirectoryInfo *zip_fh = (FZipCentralDirectoryInfo *)dirptr;
|
||||||
|
|
||||||
char name[256];
|
char name[256];
|
||||||
char base[256];
|
char base[256];
|
||||||
|
|
||||||
int len = LittleShort(zip_fh->wFileNameSize);
|
int len = LittleShort(zip_fh->NameLength);
|
||||||
strncpy(name, dirptr + sizeof(FZipFileInfo), MIN<int>(len, 255));
|
strncpy(name, dirptr + sizeof(FZipCentralDirectoryInfo), MIN<int>(len, 255));
|
||||||
name[len]=0;
|
name[len] = 0;
|
||||||
dirptr += sizeof(FZipFileInfo) +
|
dirptr += sizeof(FZipCentralDirectoryInfo) +
|
||||||
LittleShort(zip_fh->wFileNameSize) +
|
LittleShort(zip_fh->NameLength) +
|
||||||
LittleShort(zip_fh->wExtraSize) +
|
LittleShort(zip_fh->ExtraLength) +
|
||||||
LittleShort(zip_fh->wCommentSize);
|
LittleShort(zip_fh->CommentLength);
|
||||||
|
|
||||||
// skip Directories
|
// skip Directories
|
||||||
if(name[len - 1] == '/' && LittleLong(zip_fh->dwSize) == 0)
|
if(name[len - 1] == '/' && LittleLong(zip_fh->UncompressedSize) == 0)
|
||||||
{
|
{
|
||||||
skipped++;
|
skipped++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore obsolete compression formats
|
// Ignore unknown compression formats
|
||||||
if(LittleShort(zip_fh->wCompression) != 0 && LittleShort(zip_fh->wCompression) != Z_DEFLATED)
|
zip_fh->Method = LittleShort(zip_fh->Method);
|
||||||
|
if (zip_fh->Method != METHOD_STORED &&
|
||||||
|
zip_fh->Method != METHOD_DEFLATE &&
|
||||||
|
zip_fh->Method != METHOD_LZMA &&
|
||||||
|
zip_fh->Method != METHOD_BZIP2)
|
||||||
{
|
{
|
||||||
Printf("\n: %s: '%s' uses an unsupported compression algorithm.\n", filename, name);
|
Printf("\n: %s: '%s' uses an unsupported compression algorithm (#%d).\n", filename, name, zip_fh->Method);
|
||||||
skipped++;
|
skipped++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Also ignore encrypted entries
|
// Also ignore encrypted entries
|
||||||
if(LittleShort(zip_fh->wFlags) & ZF_ENCRYPTED)
|
if(LittleShort(zip_fh->Flags) & ZF_ENCRYPTED)
|
||||||
{
|
{
|
||||||
Printf("\n%s: '%s' is encrypted. Encryption is not supported.\n", filename, name);
|
Printf("\n%s: '%s' is encrypted. Encryption is not supported.\n", filename, name);
|
||||||
skipped++;
|
skipped++;
|
||||||
|
@ -591,16 +594,16 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
||||||
}
|
}
|
||||||
|
|
||||||
//ExtractFileBase(name, base);
|
//ExtractFileBase(name, base);
|
||||||
char * lname=strrchr(name,'/');
|
char *lname = strrchr(name,'/');
|
||||||
if (!lname) lname=name;
|
if (!lname) lname = name;
|
||||||
else lname++;
|
else lname++;
|
||||||
strcpy(base, lname);
|
strcpy(base, lname);
|
||||||
char * dot = strrchr(base,'.');
|
char *dot = strrchr(base, '.');
|
||||||
if (dot) *dot=0;
|
if (dot) *dot = 0;
|
||||||
uppercopy(lump_p->name, base);
|
uppercopy(lump_p->name, base);
|
||||||
lump_p->name[8] = 0;
|
lump_p->name[8] = 0;
|
||||||
lump_p->fullname = copystring(name);
|
lump_p->fullname = copystring(name);
|
||||||
lump_p->size = zip_fh->dwSize;
|
lump_p->size = LittleLong(zip_fh->UncompressedSize);
|
||||||
|
|
||||||
// Map some directories to WAD namespaces.
|
// Map some directories to WAD namespaces.
|
||||||
// Note that some of these namespaces don't exist in WADS.
|
// Note that some of these namespaces don't exist in WADS.
|
||||||
|
@ -621,15 +624,15 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
||||||
// Anything that is not in one of these subdirectories or the main directory
|
// Anything that is not in one of these subdirectories or the main directory
|
||||||
// should not be accessible through the standard WAD functions but only through
|
// should not be accessible through the standard WAD functions but only through
|
||||||
// the ones which look for the full name.
|
// the ones which look for the full name.
|
||||||
if (lump_p->namespc==-1)
|
if (lump_p->namespc == -1)
|
||||||
{
|
{
|
||||||
memset(lump_p->name, 0, 8);
|
memset(lump_p->name, 0, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
lump_p->wadnum = (WORD)Wads.Size();
|
lump_p->wadnum = (WORD)Wads.Size();
|
||||||
lump_p->flags = LittleShort(zip_fh->wCompression) == Z_DEFLATED?
|
lump_p->flags = (zip_fh->Method != METHOD_STORED) ? LUMPF_COMPRESSED|LUMPF_ZIPFILE : LUMPF_ZIPFILE;
|
||||||
LUMPF_COMPRESSED|LUMPF_ZIPFILE : LUMPF_ZIPFILE;
|
lump_p->method = zip_fh->Method;
|
||||||
lump_p->compressedsize = LittleLong(zip_fh->dwCompressedSize);
|
lump_p->compressedsize = LittleLong(zip_fh->CompressedSize);
|
||||||
|
|
||||||
// Since '\' can't be used as a file name's part inside a ZIP
|
// Since '\' can't be used as a file name's part inside a ZIP
|
||||||
// we have to work around this for sprites because it is a valid
|
// we have to work around this for sprites because it is a valid
|
||||||
|
@ -638,15 +641,15 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
||||||
{
|
{
|
||||||
char * c;
|
char * c;
|
||||||
|
|
||||||
while ((c=(char*)memchr(lump_p->name, '^', 8)))
|
while ((c = (char*)memchr(lump_p->name, '^', 8)))
|
||||||
{
|
{
|
||||||
*c='\\';
|
*c = '\\';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The start of the file will be determined the first time it is accessed.
|
// The start of the file will be determined the first time it is accessed.
|
||||||
lump_p->flags |= LUMPF_NEEDFILESTART;
|
lump_p->flags |= LUMPF_NEEDFILESTART;
|
||||||
lump_p->position = LittleLong(zip_fh->dwFileOffset);
|
lump_p->position = LittleLong(zip_fh->LocalHeaderOffset);
|
||||||
lump_p++;
|
lump_p++;
|
||||||
}
|
}
|
||||||
// Resize the lump record array to its actual size
|
// Resize the lump record array to its actual size
|
||||||
|
@ -716,30 +719,40 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
||||||
|
|
||||||
for(unsigned int i = 0; i < EmbeddedWADs.Size(); i++)
|
for(unsigned int i = 0; i < EmbeddedWADs.Size(); i++)
|
||||||
{
|
{
|
||||||
FZipFileInfo * zip_fh = EmbeddedWADs[i];
|
FZipCentralDirectoryInfo *zip_fh = EmbeddedWADs[i];
|
||||||
FZipLocalHeader localHeader;
|
FZipLocalFileHeader localHeader;
|
||||||
|
|
||||||
*wadstr=0;
|
*wadstr = 0;
|
||||||
size_t len = LittleShort(zip_fh->wFileNameSize);
|
size_t len = LittleShort(zip_fh->NameLength);
|
||||||
if (len+strlen(path) > 255) len = 255-strlen(path);
|
if (len + strlen(path) > 255) len = 255 - strlen(path);
|
||||||
strncpy(wadstr, ((char*)zip_fh) + sizeof(FZipFileInfo), len);
|
strncpy(wadstr, ((char*)zip_fh) + sizeof(FZipCentralDirectoryInfo), len);
|
||||||
wadstr[len]=0;
|
wadstr[len] = 0;
|
||||||
|
|
||||||
DWORD size = LittleLong(zip_fh->dwSize);
|
DWORD size = LittleLong(zip_fh->UncompressedSize);
|
||||||
char * buffer = new char[size];
|
char *buffer = new char[size];
|
||||||
|
|
||||||
int position = LittleLong(zip_fh->dwFileOffset) ;
|
int position = LittleLong(zip_fh->LocalHeaderOffset) ;
|
||||||
|
|
||||||
wadinfo->Seek(position, SEEK_SET);
|
wadinfo->Seek(position, SEEK_SET);
|
||||||
wadinfo->Read(&localHeader, sizeof(localHeader));
|
wadinfo->Read(&localHeader, sizeof(localHeader));
|
||||||
position += LittleShort(localHeader.wExtraSize) + sizeof(FZipLocalHeader) + LittleShort(zip_fh->wFileNameSize);
|
position += sizeof(FZipLocalFileHeader) + LittleShort(localHeader.ExtraLength) + LittleShort(zip_fh->NameLength);
|
||||||
|
|
||||||
wadinfo->Seek(position, SEEK_SET);
|
wadinfo->Seek(position, SEEK_SET);
|
||||||
if (zip_fh->wCompression == Z_DEFLATED)
|
if (LittleShort(zip_fh->Method) == METHOD_DEFLATE)
|
||||||
{
|
{
|
||||||
FileReaderZ frz(*wadinfo, true);
|
FileReaderZ frz(*wadinfo, true);
|
||||||
frz.Read(buffer, size);
|
frz.Read(buffer, size);
|
||||||
}
|
}
|
||||||
|
else if (LittleShort(zip_fh->Method) == METHOD_LZMA)
|
||||||
|
{
|
||||||
|
FileReaderLZMA frz(*wadinfo, size, true);
|
||||||
|
frz.Read(buffer, size);
|
||||||
|
}
|
||||||
|
else if (LittleShort(zip_fh->Method) == METHOD_BZIP2)
|
||||||
|
{
|
||||||
|
FileReaderBZ2 frz(*wadinfo);
|
||||||
|
frz.Read(buffer, size);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wadinfo->Read(buffer, size);
|
wadinfo->Read(buffer, size);
|
||||||
|
@ -1746,16 +1759,16 @@ void FWadCollection::SetLumpAddress(LumpRecord *l)
|
||||||
// This file is inside a zip and has not been opened before.
|
// This file is inside a zip and has not been opened before.
|
||||||
// Position points to the start of the local file header, which we must
|
// Position points to the start of the local file header, which we must
|
||||||
// read and skip so that we can get to the actual file data.
|
// read and skip so that we can get to the actual file data.
|
||||||
FZipLocalHeader localHeader;
|
FZipLocalFileHeader localHeader;
|
||||||
int skiplen;
|
int skiplen;
|
||||||
int address;
|
int address;
|
||||||
|
|
||||||
WadFileRecord *wad = Wads[l->wadnum];
|
WadFileRecord *wad = Wads[l->wadnum];
|
||||||
|
|
||||||
address = wad->Tell();
|
address = wad->Tell();
|
||||||
wad->Seek (l->position, SEEK_SET);
|
wad->Seek(l->position, SEEK_SET);
|
||||||
wad->Read (&localHeader, sizeof(localHeader));
|
wad->Read(&localHeader, sizeof(localHeader));
|
||||||
skiplen = LittleShort(localHeader.wFileNameSize) + LittleShort(localHeader.wExtraSize);
|
skiplen = LittleShort(localHeader.NameLength) + LittleShort(localHeader.ExtraLength);
|
||||||
l->position += sizeof(localHeader) + skiplen;
|
l->position += sizeof(localHeader) + skiplen;
|
||||||
l->flags &= ~LUMPF_NEEDFILESTART;
|
l->flags &= ~LUMPF_NEEDFILESTART;
|
||||||
}
|
}
|
||||||
|
@ -1792,10 +1805,27 @@ FWadLump FWadCollection::OpenLumpNum (int lump)
|
||||||
if (l->flags & LUMPF_COMPRESSED)
|
if (l->flags & LUMPF_COMPRESSED)
|
||||||
{
|
{
|
||||||
// A compressed entry in a .zip file
|
// A compressed entry in a .zip file
|
||||||
char * buffer = new char[l->size+1]; // the last byte is used as a reference counter
|
char *buffer = new char[l->size + 1]; // the last byte is used as a reference counter
|
||||||
buffer[l->size] = 0;
|
buffer[l->size] = 0;
|
||||||
FileReaderZ frz(*wad, true);
|
if (l->method == METHOD_DEFLATE)
|
||||||
frz.Read(buffer, l->size);
|
{
|
||||||
|
FileReaderZ frz(*wad, true);
|
||||||
|
frz.Read(buffer, l->size);
|
||||||
|
}
|
||||||
|
else if (l->method == METHOD_LZMA)
|
||||||
|
{
|
||||||
|
FileReaderLZMA frz(*wad, l->size, true);
|
||||||
|
frz.Read(buffer, l->size);
|
||||||
|
}
|
||||||
|
else if (l->method == METHOD_BZIP2)
|
||||||
|
{
|
||||||
|
FileReaderBZ2 frz(*wad);
|
||||||
|
frz.Read(buffer, l->size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(0); // Should not get here
|
||||||
|
}
|
||||||
return FWadLump(buffer, l->size, true);
|
return FWadLump(buffer, l->size, true);
|
||||||
}
|
}
|
||||||
else if (l->flags & LUMPF_EXTERNAL)
|
else if (l->flags & LUMPF_EXTERNAL)
|
||||||
|
@ -1875,10 +1905,27 @@ FWadLump *FWadCollection::ReopenLumpNum (int lump)
|
||||||
{
|
{
|
||||||
// A compressed entry in a .zip file
|
// A compressed entry in a .zip file
|
||||||
int address = wad->Tell(); // read from the existing WadFileRecord without reopening
|
int address = wad->Tell(); // read from the existing WadFileRecord without reopening
|
||||||
char * buffer = new char[l->size+1]; // the last byte is used as a reference counter
|
char *buffer = new char[l->size + 1]; // the last byte is used as a reference counter
|
||||||
wad->Seek(l->position, SEEK_SET);
|
wad->Seek(l->position, SEEK_SET);
|
||||||
FileReaderZ frz(*wad, true);
|
if (l->method == METHOD_DEFLATE)
|
||||||
frz.Read(buffer, l->size);
|
{
|
||||||
|
FileReaderZ frz(*wad, true);
|
||||||
|
frz.Read(buffer, l->size);
|
||||||
|
}
|
||||||
|
else if (l->method == METHOD_LZMA)
|
||||||
|
{
|
||||||
|
FileReaderLZMA frz(*wad, l->size, true);
|
||||||
|
frz.Read(buffer, l->size);
|
||||||
|
}
|
||||||
|
else if (l->method == METHOD_BZIP2)
|
||||||
|
{
|
||||||
|
FileReaderBZ2 frz(*wad);
|
||||||
|
frz.Read(buffer, l->size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(0); // Should not get here
|
||||||
|
}
|
||||||
wad->Seek(address, SEEK_SET);
|
wad->Seek(address, SEEK_SET);
|
||||||
return new FWadLump(buffer, l->size, true); //... but restore the file pointer afterward!
|
return new FWadLump(buffer, l->size, true); //... but restore the file pointer afterward!
|
||||||
}
|
}
|
||||||
|
|
96
src/w_zip.h
96
src/w_zip.h
|
@ -1,62 +1,72 @@
|
||||||
#ifndef __W_ZIP
|
#ifndef __W_ZIP
|
||||||
#define __W_ZIP
|
#define __W_ZIP
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(push, 1)
|
||||||
struct FZipCentralInfo
|
// FZipCentralInfo
|
||||||
|
struct FZipEndOfCentralDirectory
|
||||||
{
|
{
|
||||||
// patched together from information from Q3's unzip.c
|
DWORD Magic;
|
||||||
DWORD dwSignature;
|
WORD DiskNumber;
|
||||||
WORD wNumberDisk;
|
WORD FirstDisk;
|
||||||
WORD wNumberDiskWithCD;
|
WORD NumEntries;
|
||||||
WORD wEntryCount;
|
WORD NumEntriesOnAllDisks;
|
||||||
WORD wTotalEntryCount;
|
DWORD DirectorySize;
|
||||||
DWORD dwCDSize;
|
DWORD DirectoryOffset;
|
||||||
DWORD dwCDOffset;
|
WORD ZipCommentLength;
|
||||||
WORD wCommentSize;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FZipFileInfo
|
// FZipFileInfo
|
||||||
|
struct FZipCentralDirectoryInfo
|
||||||
{
|
{
|
||||||
// patched together from information from Q3's unzip.c
|
DWORD Magic;
|
||||||
DWORD dwSignature;
|
BYTE VersionMadeBy[2];
|
||||||
WORD wVersion;
|
BYTE VersionToExtract[2];
|
||||||
WORD wRequiredVersion;
|
WORD Flags;
|
||||||
WORD wFlags;
|
WORD Method;
|
||||||
WORD wCompression;
|
WORD ModTime;
|
||||||
DWORD dwLastModified;
|
WORD ModDate;
|
||||||
DWORD dwCrc;
|
DWORD CRC32;
|
||||||
DWORD dwCompressedSize;
|
DWORD CompressedSize;
|
||||||
DWORD dwSize;
|
DWORD UncompressedSize;
|
||||||
WORD wFileNameSize;
|
WORD NameLength;
|
||||||
WORD wExtraSize;
|
WORD ExtraLength;
|
||||||
WORD wCommentSize;
|
WORD CommentLength;
|
||||||
WORD wDiskStart;
|
WORD StartingDiskNumber;
|
||||||
WORD wInternalAttributes;
|
WORD InternalAttributes;
|
||||||
DWORD wExternalAttributes;
|
DWORD ExternalAttributes;
|
||||||
DWORD dwFileOffset;
|
DWORD LocalHeaderOffset;
|
||||||
// file name and other variable length info follows
|
// file name and other variable length info follows
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FZipLocalHeader
|
// FZipLocalHeader
|
||||||
|
struct FZipLocalFileHeader
|
||||||
{
|
{
|
||||||
// patched together from information from Q3's unzip.c
|
DWORD Magic;
|
||||||
DWORD dwSignature;
|
BYTE VersionToExtract[2];
|
||||||
WORD wRequiredVersion;
|
WORD Flags;
|
||||||
WORD wFlags;
|
WORD Method;
|
||||||
WORD wCompression;
|
WORD ModTime;
|
||||||
DWORD dwLastModified;
|
WORD ModDate;
|
||||||
DWORD dwCrc;
|
DWORD CRC32;
|
||||||
DWORD dwCompressedSize;
|
DWORD CompressedSize;
|
||||||
DWORD dwSize;
|
DWORD UncompressedSize;
|
||||||
WORD wFileNameSize;
|
WORD NameLength;
|
||||||
WORD wExtraSize;
|
WORD ExtraLength;
|
||||||
// file name and other variable length info follows
|
// file name and other variable length info follows
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack(pop)
|
||||||
|
|
||||||
#define Z_DEFLATED 8
|
#define ZIP_LOCALFILE MAKE_ID('P','K',3,4)
|
||||||
|
#define ZIP_CENTRALFILE MAKE_ID('P','K',1,2)
|
||||||
|
#define ZIP_ENDOFDIR MAKE_ID('P','K',5,6)
|
||||||
|
|
||||||
|
#define METHOD_STORED 0
|
||||||
|
#define METHOD_DEFLATE 8
|
||||||
|
#define METHOD_BZIP2 12
|
||||||
|
#define METHOD_LZMA 14
|
||||||
|
#define METHOD_PPMD 98
|
||||||
|
|
||||||
// File header flags.
|
// File header flags.
|
||||||
#define ZF_ENCRYPTED 0x1
|
#define ZF_ENCRYPTED 0x1
|
||||||
|
|
|
@ -1004,7 +1004,7 @@ static void StackWalk (HANDLE file, void *dumpaddress, DWORD *topOfStack, DWORD
|
||||||
const BYTE *bytep = (BYTE *)code;
|
const BYTE *bytep = (BYTE *)code;
|
||||||
BYTE peekb;
|
BYTE peekb;
|
||||||
|
|
||||||
#define chkbyte(x,m,v) SafeReadMemory(x, &peekb, 1) && ((peekb & m) == v)
|
#define chkbyte(x,m,v) (SafeReadMemory(x, &peekb, 1) && ((peekb & m) == v))
|
||||||
|
|
||||||
if (chkbyte(bytep - 5, 0xFF, 0xE8) || chkbyte(bytep - 5, 0xFF, 0xE9))
|
if (chkbyte(bytep - 5, 0xFF, 0xE8) || chkbyte(bytep - 5, 0xFF, 0xE9))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue