mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-06-04 19:20:53 +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
|
||||
Drop state. Also changed it to fade out when it's done rather than
|
||||
disappearing abruptly.
|
||||
|
|
|
@ -51,6 +51,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zipdir", "tools\zipdir\zipd
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gdtoa", "gdtoa\gdtoa.vcproj", "{B68E0ABF-B627-48A3-A92F-D8F827A75054}"
|
||||
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
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
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"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
|
@ -172,7 +172,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
Optimization="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"
|
||||
MinimalRebuild="true"
|
||||
RuntimeLibrary="1"
|
||||
|
@ -280,7 +280,7 @@
|
|||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
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"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
|
@ -390,7 +390,7 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
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"
|
||||
MinimalRebuild="true"
|
||||
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( 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( .
|
||||
g_doom
|
||||
g_heretic
|
||||
|
|
|
@ -144,6 +144,7 @@ void ParseCompatibility()
|
|||
}
|
||||
else
|
||||
{
|
||||
x = 0;
|
||||
sc.ScriptError("MD5 signature must be a hexadecimal value");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ class APlayerPawn : public AActor
|
|||
public:
|
||||
virtual void Serialize (FArchive &arc);
|
||||
|
||||
virtual void PostBeginPlay();
|
||||
virtual void Tick();
|
||||
virtual void AddInventory (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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// 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
|
||||
|
@ -320,4 +519,3 @@ char *MemoryReader::Gets(char *strbuf, int len)
|
|||
{
|
||||
return GetsFromBuffer(bufptr, strbuf, len);
|
||||
}
|
||||
|
||||
|
|
128
src/files.h
128
src/files.h
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <zlib.h>
|
||||
#include "bzlib.h"
|
||||
#include "LzmaDec.h"
|
||||
#include "doomtype.h"
|
||||
#include "m_swap.h"
|
||||
|
||||
|
@ -140,6 +142,132 @@ private:
|
|||
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
|
||||
{
|
||||
|
|
|
@ -941,7 +941,6 @@ void G_DoLoadLevel (int position, bool autosave)
|
|||
}
|
||||
|
||||
P_SetupLevel (level.mapname, position);
|
||||
P_CompleteWeaponSetup();
|
||||
|
||||
AM_LevelInit();
|
||||
|
||||
|
|
|
@ -16,13 +16,15 @@ class AWeapon;
|
|||
class FWeaponSlot
|
||||
{
|
||||
public:
|
||||
FWeaponSlot() { Clear(); }
|
||||
FWeaponSlot(const FWeaponSlot &other) { Weapons = other.Weapons; }
|
||||
FWeaponSlot &operator= (const FWeaponSlot &other) { Weapons = other.Weapons; return *this; }
|
||||
void Clear() { Weapons.Clear(); }
|
||||
bool AddWeapon (const char *type);
|
||||
bool AddWeapon (const PClass *type);
|
||||
void AddWeaponList (const char *list, bool clear);
|
||||
AWeapon *PickWeapon (player_t *player);
|
||||
int Size () { return (int)Weapons.Size(); }
|
||||
int Size () const { return (int)Weapons.Size(); }
|
||||
int LocateWeapon (const PClass *type);
|
||||
|
||||
inline const PClass *GetWeapon (int index) const
|
||||
|
@ -59,6 +61,9 @@ enum ESlotDef
|
|||
|
||||
struct FWeaponSlots
|
||||
{
|
||||
FWeaponSlots() { Clear(); }
|
||||
FWeaponSlots(const FWeaponSlots &other);
|
||||
|
||||
FWeaponSlot Slots[NUM_WEAPON_SLOTS];
|
||||
|
||||
AWeapon *PickNextWeapon (player_t *player);
|
||||
|
@ -69,7 +74,9 @@ struct FWeaponSlots
|
|||
ESlotDef AddDefaultWeapon (int slot, const PClass *type);
|
||||
void AddExtraWeapons();
|
||||
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);
|
||||
void PrintSettings();
|
||||
|
||||
|
@ -78,8 +85,7 @@ struct FWeaponSlots
|
|||
|
||||
};
|
||||
|
||||
void P_PlaybackKeyConfWeapons();
|
||||
void P_CompleteWeaponSetup();
|
||||
void P_PlaybackKeyConfWeapons(FWeaponSlots *slots);
|
||||
void Net_WriteWeapon(const PClass *type);
|
||||
const PClass *Net_ReadWeapon(BYTE **stream);
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ END_POINTERS
|
|||
|
||||
FString WeaponSection;
|
||||
TArray<FString> KeyConfWeapons;
|
||||
bool PlayingKeyConf;
|
||||
FWeaponSlots *PlayingKeyConf;
|
||||
|
||||
TArray<const PClass *> Weapons_ntoh;
|
||||
TMap<const PClass *, int> Weapons_hton;
|
||||
|
@ -642,8 +642,6 @@ bool AWeaponGiver::TryPickup(AActor *&toucher)
|
|||
|
||||
/* Weapon slots ***********************************************************/
|
||||
|
||||
FWeaponSlots LocalWeapons;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlot :: AddWeapon
|
||||
|
@ -756,7 +754,7 @@ AWeapon *FWeaponSlot::PickWeapon(player_t *player)
|
|||
}
|
||||
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() ||
|
||||
(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
|
||||
|
@ -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.
|
||||
// 2. Add extra weapons that specify their own slot.
|
||||
// 3. Run KEYCONF weapon commands, affecting slots accordingly.
|
||||
// 4. Read config slots, overriding current slots. If WeaponSection is set,
|
||||
// 2. Add extra weapons that specify their own slots.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
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
|
||||
// [<WeaponSection>.Weapons] if that did not exist. If WeaponSection is
|
||||
// empty, then the slots are read from [<PlayerClass>.Weapons].
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FWeaponSlots::CompleteSetup(const PClass *type)
|
||||
void FWeaponSlots::LocalSetup(const PClass *type)
|
||||
{
|
||||
SetFromPlayer(type);
|
||||
AddExtraWeapons();
|
||||
P_PlaybackKeyConfWeapons();
|
||||
P_PlaybackKeyConfWeapons(this);
|
||||
if (WeaponSection.IsNotEmpty())
|
||||
{
|
||||
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
|
||||
LocalWeapons.CompleteSetup(players[consoleplayer].mo->GetClass());
|
||||
// Now transmit them across the network
|
||||
for (int i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||
if (other.Slots[i].Size() == Slots[i].Size())
|
||||
{
|
||||
if (LocalWeapons.Slots[i].Size() > 0)
|
||||
for (j = (int)Slots[i].Size(); j-- > 0; )
|
||||
{
|
||||
if (other.Slots[i].GetWeapon(j) != 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(LocalWeapons.Slots[i].Size());
|
||||
for(int j = 0; j < LocalWeapons.Slots[i].Size(); j++)
|
||||
Net_WriteByte(Slots[i].Size());
|
||||
for (j = 0; j < Slots[i].Size(); ++j)
|
||||
{
|
||||
Net_WriteWeapon(LocalWeapons.Slots[i].GetWeapon(j));
|
||||
}
|
||||
}
|
||||
Net_WriteWeapon(Slots[i].GetWeapon(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1268,12 +1308,12 @@ CCMD (setslot)
|
|||
{
|
||||
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)
|
||||
{
|
||||
LocalWeapons.Slots[slot].AddWeapon(argv[i]);
|
||||
PlayingKeyConf->Slots[slot].AddWeapon(argv[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1303,7 +1343,7 @@ void FWeaponSlots::AddSlot(int slot, const PClass *type, bool 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());
|
||||
}
|
||||
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
|
||||
{
|
||||
|
@ -1397,9 +1437,9 @@ CCMD (addslotdefault)
|
|||
{
|
||||
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
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
FString cmd(KeyConfWeapons[i]);
|
||||
AddCommandString(cmd.LockBuffer());
|
||||
}
|
||||
PlayingKeyConf = false;
|
||||
PlayingKeyConf = NULL;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -1593,7 +1633,7 @@ const PClass *Net_ReadWeapon(BYTE **stream)
|
|||
{
|
||||
index = (index & 0x7F) | (ReadByte(stream) << 7);
|
||||
}
|
||||
if (index >= Weapons_ntoh.Size())
|
||||
if ((unsigned)index >= Weapons_ntoh.Size())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1234,6 +1234,7 @@ static valueenum_t Outputs[] =
|
|||
#elif defined(unix)
|
||||
{ "OSS", "OSS" },
|
||||
{ "ALSA", "ALSA" },
|
||||
{ "SDL", "SDL" },
|
||||
{ "ESD", "ESD" },
|
||||
#elif defined(__APPLE__)
|
||||
{ "Sound Manager", "Sound Manager" },
|
||||
|
|
|
@ -491,7 +491,26 @@ void APlayerPawn::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:
|
||||
I_Error ("Script error, \"%s\" line %d:\n%s\n",
|
||||
FileName.GetChars(), ScriptLine, composed.GetChars());
|
||||
return;
|
||||
}
|
||||
Printf (level, "%sScript %s, \"%s\" line %d:\n%s%s\n",
|
||||
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, m_noprescale, 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];
|
||||
//static int JoyActive;
|
||||
|
@ -200,6 +201,10 @@ static void InitKeySymMap ()
|
|||
static void I_CheckGUICapture ()
|
||||
{
|
||||
bool wantCapt;
|
||||
bool repeat;
|
||||
int oldrepeat, interval;
|
||||
|
||||
SDL_GetKeyRepeat(&oldrepeat, &interval);
|
||||
|
||||
if (menuactive == MENU_Off)
|
||||
{
|
||||
|
@ -217,15 +222,34 @@ static void I_CheckGUICapture ()
|
|||
{
|
||||
FlushDIKState ();
|
||||
memset (DownState, 0, sizeof(DownState));
|
||||
SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
repeat = !sdl_nokeyrepeat;
|
||||
SDL_EnableUNICODE (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_EnableKeyRepeat (0, 0);
|
||||
repeat = false;
|
||||
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 ()
|
||||
|
|
|
@ -167,16 +167,14 @@ namespace FMOD
|
|||
FMOD_RESULT getDSPClock (unsigned int *hi, unsigned int *lo) { return FMOD_System_GetDSPClock(this, hi, lo); }
|
||||
|
||||
// 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 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 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 recordStop () { return FMOD_System_RecordStop(this); }
|
||||
FMOD_RESULT isRecording (bool *recording) { FMOD_BOOL b; FMOD_RESULT res = FMOD_System_IsRecording(this, &b); *recording = b; return res; }
|
||||
FMOD_RESULT recordStart (int id, Sound *sound, bool loop) { return FMOD_System_RecordStart(this, id, (FMOD_SOUND *)sound, loop); }
|
||||
FMOD_RESULT recordStop (int id) { return FMOD_System_RecordStop(this, id); }
|
||||
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.
|
||||
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_video.h"
|
||||
#include "v_palette.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -159,6 +160,7 @@ static const FEnumList OutputNames[] =
|
|||
{ "OSS", FMOD_OUTPUTTYPE_OSS },
|
||||
{ "ALSA", FMOD_OUTPUTTYPE_ALSA },
|
||||
{ "ESD", FMOD_OUTPUTTYPE_ESD },
|
||||
{ "SDL", 666 },
|
||||
|
||||
// Mac
|
||||
{ "Sound Manager", FMOD_OUTPUTTYPE_SOUNDMANAGER },
|
||||
|
@ -612,6 +614,7 @@ bool FMODSoundRenderer::Init()
|
|||
ChannelGroupTargetUnit = NULL;
|
||||
SfxReverbHooked = false;
|
||||
SfxReverbPlaceholder = NULL;
|
||||
OutputPlugin = 0;
|
||||
|
||||
Printf("I_InitSound: Initializing FMOD\n");
|
||||
|
||||
|
@ -692,21 +695,65 @@ bool FMODSoundRenderer::Init()
|
|||
}
|
||||
#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.
|
||||
eval = Enum_NumForName(OutputNames, snd_output);
|
||||
if (eval >= 0)
|
||||
{
|
||||
if (eval == 666 && OutputPlugin != 0)
|
||||
{
|
||||
result = Sys->setOutputByPlugin(OutputPlugin);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = Sys->setOutput(FMOD_OUTPUTTYPE(eval));
|
||||
}
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
result = Sys->getNumDrivers(&driver);
|
||||
#ifdef unix
|
||||
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)
|
||||
{
|
||||
Printf(TEXTCOLOR_BLUE"Driver %d does not exist. Using 0.\n", *snd_driver);
|
||||
|
@ -1056,6 +1103,11 @@ void FMODSoundRenderer::Shutdown()
|
|||
}
|
||||
|
||||
Sys->close();
|
||||
if (OutputPlugin != 0)
|
||||
{
|
||||
Sys->unloadPlugin(OutputPlugin);
|
||||
OutputPlugin = 0;
|
||||
}
|
||||
Sys->release();
|
||||
Sys = NULL;
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ private:
|
|||
FMOD::DSP *SfxReverbPlaceholder;
|
||||
bool SfxReverbHooked;
|
||||
float LastWaterLP;
|
||||
unsigned int OutputPlugin;
|
||||
|
||||
// Just for snd_status display
|
||||
int Driver_MinFrequency;
|
||||
|
|
|
@ -131,7 +131,7 @@ inline volatile unsigned long long rdtsc()
|
|||
#endif
|
||||
{
|
||||
register unsigned long long tsc asm("eax");
|
||||
asm volatile ("\trdtsc\n" : : : "eax, "edx");
|
||||
asm volatile ("\trdtsc\n" : : : "eax", "edx");
|
||||
return tsc;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -325,7 +325,7 @@ do_stop:
|
|||
sc.ScriptError("Negative jump offsets are not allowed");
|
||||
}
|
||||
|
||||
if (x > 0)
|
||||
if (v > 0)
|
||||
{
|
||||
x = new FxStateByIndex(bag.statedef.GetStateCount() + v, sc);
|
||||
}
|
||||
|
|
135
src/w_wad.cpp
135
src/w_wad.cpp
|
@ -91,6 +91,7 @@ struct FWadCollection::LumpRecord
|
|||
{
|
||||
char * fullname; // only valid for files loaded from a .zip file
|
||||
char name[9];
|
||||
BYTE method; // zip compression method
|
||||
short wadnum;
|
||||
WORD flags;
|
||||
int position;
|
||||
|
@ -299,7 +300,7 @@ int FWadCollection::AddExternalFile(const char *filename)
|
|||
|
||||
static DWORD Zip_FindCentralDir(FileReader * fin)
|
||||
{
|
||||
unsigned char* buf;
|
||||
unsigned char buf[BUFREADCOMMENT + 4];
|
||||
DWORD FileSize;
|
||||
DWORD uBackRead;
|
||||
DWORD uMaxBack; // maximum size of global comment
|
||||
|
@ -310,9 +311,6 @@ static DWORD Zip_FindCentralDir(FileReader * fin)
|
|||
FileSize = fin->Tell();
|
||||
uMaxBack = MIN<DWORD>(0xffff, FileSize);
|
||||
|
||||
buf = (unsigned char*)malloc(BUFREADCOMMENT+4);
|
||||
if (buf == NULL) return 0;
|
||||
|
||||
uBackRead = 4;
|
||||
while (uBackRead < uMaxBack)
|
||||
{
|
||||
|
@ -331,17 +329,17 @@ static DWORD Zip_FindCentralDir(FileReader * fin)
|
|||
if (fin->Read(buf, (SDWORD)uReadSize) != (SDWORD)uReadSize) break;
|
||||
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uPosFound != 0)
|
||||
break;
|
||||
}
|
||||
free(buf);
|
||||
return uPosFound;
|
||||
}
|
||||
|
||||
|
@ -373,7 +371,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
|||
int startlump;
|
||||
wadlump_t* fileinfo = NULL, *fileinfo2free = NULL;
|
||||
wadlump_t singleinfo;
|
||||
TArray<FZipFileInfo *> EmbeddedWADs;
|
||||
TArray<FZipCentralDirectoryInfo *> EmbeddedWADs;
|
||||
void * directory = NULL;
|
||||
|
||||
if (length==-1)
|
||||
|
@ -508,7 +506,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
|||
else if (header.magic[0] == ZIP_ID)
|
||||
{
|
||||
DWORD centraldir = Zip_FindCentralDir(wadinfo);
|
||||
FZipCentralInfo info;
|
||||
FZipEndOfCentralDirectory info;
|
||||
int skipped = 0;
|
||||
|
||||
if (centraldir == 0)
|
||||
|
@ -519,56 +517,61 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
|||
|
||||
// Read the central directory info.
|
||||
wadinfo->Seek(centraldir, SEEK_SET);
|
||||
wadinfo->Read(&info, sizeof(FZipCentralInfo));
|
||||
wadinfo->Read(&info, sizeof(FZipEndOfCentralDirectory));
|
||||
|
||||
// No multi-disk zips!
|
||||
if (info.wEntryCount != info.wTotalEntryCount ||
|
||||
info.wNumberDiskWithCD != 0 || info.wNumberDisk != 0)
|
||||
if (info.NumEntries != info.NumEntriesOnAllDisks ||
|
||||
info.FirstDisk != 0 || info.DiskNumber != 0)
|
||||
{
|
||||
Printf("\n%s: Multipart Zip files are not supported.\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
NumLumps += LittleShort(info.wEntryCount);
|
||||
NumLumps += LittleShort(info.NumEntries);
|
||||
LumpInfo.Resize(NumLumps);
|
||||
lump_p = &LumpInfo[startlump];
|
||||
|
||||
// Load the entire central directory. Too bad that this contains variable length entries...
|
||||
directory = malloc(LittleLong(info.dwCDSize));
|
||||
wadinfo->Seek(LittleLong(info.dwCDOffset), SEEK_SET);
|
||||
wadinfo->Read(directory, LittleLong(info.dwCDSize));
|
||||
directory = malloc(LittleLong(info.DirectorySize));
|
||||
wadinfo->Seek(LittleLong(info.DirectoryOffset), SEEK_SET);
|
||||
wadinfo->Read(directory, LittleLong(info.DirectorySize));
|
||||
|
||||
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 base[256];
|
||||
|
||||
int len = LittleShort(zip_fh->wFileNameSize);
|
||||
strncpy(name, dirptr + sizeof(FZipFileInfo), MIN<int>(len, 255));
|
||||
int len = LittleShort(zip_fh->NameLength);
|
||||
strncpy(name, dirptr + sizeof(FZipCentralDirectoryInfo), MIN<int>(len, 255));
|
||||
name[len] = 0;
|
||||
dirptr += sizeof(FZipFileInfo) +
|
||||
LittleShort(zip_fh->wFileNameSize) +
|
||||
LittleShort(zip_fh->wExtraSize) +
|
||||
LittleShort(zip_fh->wCommentSize);
|
||||
dirptr += sizeof(FZipCentralDirectoryInfo) +
|
||||
LittleShort(zip_fh->NameLength) +
|
||||
LittleShort(zip_fh->ExtraLength) +
|
||||
LittleShort(zip_fh->CommentLength);
|
||||
|
||||
// skip Directories
|
||||
if(name[len - 1] == '/' && LittleLong(zip_fh->dwSize) == 0)
|
||||
if(name[len - 1] == '/' && LittleLong(zip_fh->UncompressedSize) == 0)
|
||||
{
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore obsolete compression formats
|
||||
if(LittleShort(zip_fh->wCompression) != 0 && LittleShort(zip_fh->wCompression) != Z_DEFLATED)
|
||||
// Ignore unknown compression formats
|
||||
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++;
|
||||
continue;
|
||||
}
|
||||
// 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);
|
||||
skipped++;
|
||||
|
@ -600,7 +603,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
|||
uppercopy(lump_p->name, base);
|
||||
lump_p->name[8] = 0;
|
||||
lump_p->fullname = copystring(name);
|
||||
lump_p->size = zip_fh->dwSize;
|
||||
lump_p->size = LittleLong(zip_fh->UncompressedSize);
|
||||
|
||||
// Map some directories to WAD namespaces.
|
||||
// Note that some of these namespaces don't exist in WADS.
|
||||
|
@ -627,9 +630,9 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
|||
}
|
||||
|
||||
lump_p->wadnum = (WORD)Wads.Size();
|
||||
lump_p->flags = LittleShort(zip_fh->wCompression) == Z_DEFLATED?
|
||||
LUMPF_COMPRESSED|LUMPF_ZIPFILE : LUMPF_ZIPFILE;
|
||||
lump_p->compressedsize = LittleLong(zip_fh->dwCompressedSize);
|
||||
lump_p->flags = (zip_fh->Method != METHOD_STORED) ? LUMPF_COMPRESSED|LUMPF_ZIPFILE : LUMPF_ZIPFILE;
|
||||
lump_p->method = zip_fh->Method;
|
||||
lump_p->compressedsize = LittleLong(zip_fh->CompressedSize);
|
||||
|
||||
// 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
|
||||
|
@ -646,7 +649,7 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
|
|||
|
||||
// The start of the file will be determined the first time it is accessed.
|
||||
lump_p->flags |= LUMPF_NEEDFILESTART;
|
||||
lump_p->position = LittleLong(zip_fh->dwFileOffset);
|
||||
lump_p->position = LittleLong(zip_fh->LocalHeaderOffset);
|
||||
lump_p++;
|
||||
}
|
||||
// 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++)
|
||||
{
|
||||
FZipFileInfo * zip_fh = EmbeddedWADs[i];
|
||||
FZipLocalHeader localHeader;
|
||||
FZipCentralDirectoryInfo *zip_fh = EmbeddedWADs[i];
|
||||
FZipLocalFileHeader localHeader;
|
||||
|
||||
*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);
|
||||
strncpy(wadstr, ((char*)zip_fh) + sizeof(FZipFileInfo), len);
|
||||
strncpy(wadstr, ((char*)zip_fh) + sizeof(FZipCentralDirectoryInfo), len);
|
||||
wadstr[len] = 0;
|
||||
|
||||
DWORD size = LittleLong(zip_fh->dwSize);
|
||||
DWORD size = LittleLong(zip_fh->UncompressedSize);
|
||||
char *buffer = new char[size];
|
||||
|
||||
int position = LittleLong(zip_fh->dwFileOffset) ;
|
||||
int position = LittleLong(zip_fh->LocalHeaderOffset) ;
|
||||
|
||||
wadinfo->Seek(position, SEEK_SET);
|
||||
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);
|
||||
if (zip_fh->wCompression == Z_DEFLATED)
|
||||
if (LittleShort(zip_fh->Method) == METHOD_DEFLATE)
|
||||
{
|
||||
FileReaderZ frz(*wadinfo, true);
|
||||
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
|
||||
{
|
||||
wadinfo->Read(buffer, size);
|
||||
|
@ -1746,7 +1759,7 @@ void FWadCollection::SetLumpAddress(LumpRecord *l)
|
|||
// 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
|
||||
// read and skip so that we can get to the actual file data.
|
||||
FZipLocalHeader localHeader;
|
||||
FZipLocalFileHeader localHeader;
|
||||
int skiplen;
|
||||
int address;
|
||||
|
||||
|
@ -1755,7 +1768,7 @@ void FWadCollection::SetLumpAddress(LumpRecord *l)
|
|||
address = wad->Tell();
|
||||
wad->Seek(l->position, SEEK_SET);
|
||||
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->flags &= ~LUMPF_NEEDFILESTART;
|
||||
}
|
||||
|
@ -1794,8 +1807,25 @@ FWadLump FWadCollection::OpenLumpNum (int lump)
|
|||
// A compressed entry in a .zip file
|
||||
char *buffer = new char[l->size + 1]; // the last byte is used as a reference counter
|
||||
buffer[l->size] = 0;
|
||||
if (l->method == METHOD_DEFLATE)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else if (l->flags & LUMPF_EXTERNAL)
|
||||
|
@ -1877,8 +1907,25 @@ FWadLump *FWadCollection::ReopenLumpNum (int lump)
|
|||
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
|
||||
wad->Seek(l->position, SEEK_SET);
|
||||
if (l->method == METHOD_DEFLATE)
|
||||
{
|
||||
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);
|
||||
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
|
||||
#define __W_ZIP
|
||||
|
||||
#pragma pack(1)
|
||||
struct FZipCentralInfo
|
||||
#pragma pack(push, 1)
|
||||
// FZipCentralInfo
|
||||
struct FZipEndOfCentralDirectory
|
||||
{
|
||||
// patched together from information from Q3's unzip.c
|
||||
DWORD dwSignature;
|
||||
WORD wNumberDisk;
|
||||
WORD wNumberDiskWithCD;
|
||||
WORD wEntryCount;
|
||||
WORD wTotalEntryCount;
|
||||
DWORD dwCDSize;
|
||||
DWORD dwCDOffset;
|
||||
WORD wCommentSize;
|
||||
DWORD Magic;
|
||||
WORD DiskNumber;
|
||||
WORD FirstDisk;
|
||||
WORD NumEntries;
|
||||
WORD NumEntriesOnAllDisks;
|
||||
DWORD DirectorySize;
|
||||
DWORD DirectoryOffset;
|
||||
WORD ZipCommentLength;
|
||||
};
|
||||
|
||||
struct FZipFileInfo
|
||||
// FZipFileInfo
|
||||
struct FZipCentralDirectoryInfo
|
||||
{
|
||||
// patched together from information from Q3's unzip.c
|
||||
DWORD dwSignature;
|
||||
WORD wVersion;
|
||||
WORD wRequiredVersion;
|
||||
WORD wFlags;
|
||||
WORD wCompression;
|
||||
DWORD dwLastModified;
|
||||
DWORD dwCrc;
|
||||
DWORD dwCompressedSize;
|
||||
DWORD dwSize;
|
||||
WORD wFileNameSize;
|
||||
WORD wExtraSize;
|
||||
WORD wCommentSize;
|
||||
WORD wDiskStart;
|
||||
WORD wInternalAttributes;
|
||||
DWORD wExternalAttributes;
|
||||
DWORD dwFileOffset;
|
||||
DWORD Magic;
|
||||
BYTE VersionMadeBy[2];
|
||||
BYTE VersionToExtract[2];
|
||||
WORD Flags;
|
||||
WORD Method;
|
||||
WORD ModTime;
|
||||
WORD ModDate;
|
||||
DWORD CRC32;
|
||||
DWORD CompressedSize;
|
||||
DWORD UncompressedSize;
|
||||
WORD NameLength;
|
||||
WORD ExtraLength;
|
||||
WORD CommentLength;
|
||||
WORD StartingDiskNumber;
|
||||
WORD InternalAttributes;
|
||||
DWORD ExternalAttributes;
|
||||
DWORD LocalHeaderOffset;
|
||||
// file name and other variable length info follows
|
||||
};
|
||||
|
||||
struct FZipLocalHeader
|
||||
// FZipLocalHeader
|
||||
struct FZipLocalFileHeader
|
||||
{
|
||||
// patched together from information from Q3's unzip.c
|
||||
DWORD dwSignature;
|
||||
WORD wRequiredVersion;
|
||||
WORD wFlags;
|
||||
WORD wCompression;
|
||||
DWORD dwLastModified;
|
||||
DWORD dwCrc;
|
||||
DWORD dwCompressedSize;
|
||||
DWORD dwSize;
|
||||
WORD wFileNameSize;
|
||||
WORD wExtraSize;
|
||||
DWORD Magic;
|
||||
BYTE VersionToExtract[2];
|
||||
WORD Flags;
|
||||
WORD Method;
|
||||
WORD ModTime;
|
||||
WORD ModDate;
|
||||
DWORD CRC32;
|
||||
DWORD CompressedSize;
|
||||
DWORD UncompressedSize;
|
||||
WORD NameLength;
|
||||
WORD ExtraLength;
|
||||
// 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.
|
||||
#define ZF_ENCRYPTED 0x1
|
||||
|
|
|
@ -1004,7 +1004,7 @@ static void StackWalk (HANDLE file, void *dumpaddress, DWORD *topOfStack, DWORD
|
|||
const BYTE *bytep = (BYTE *)code;
|
||||
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))
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue