mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-28 06:42:09 +00:00
- Fixed: Modern versions of GCC on PowerPC inserted padding to the end of pragma packed structures.
- Worked aorund modern GCC bug where C++ exceptions in Objective-C++ code would result in an ICE (bug is already on their tracker, but I doubt it will be fixed unless I decide to dig into the issue myself). - Turn off fused floating point instructions since these can cause slight deviations in floating point code. - Use -static-libgcc when compiling on the Mac with GCC since we need to use a custom version of GCC to do so now. - Note: ZDoom will currently still crash on exit on PowerPC since it seems to be deciding that NameManager needs to be destructed before the console commands.
This commit is contained in:
parent
0269aeea80
commit
93be5aca05
10 changed files with 125 additions and 71 deletions
|
@ -167,6 +167,11 @@ else()
|
||||||
set( ALL_C_FLAGS "" )
|
set( ALL_C_FLAGS "" )
|
||||||
set( REL_C_FLAGS "" )
|
set( REL_C_FLAGS "" )
|
||||||
set( DEB_C_FLAGS "" )
|
set( DEB_C_FLAGS "" )
|
||||||
|
|
||||||
|
# If we're compiling with a custom GCC on the Mac (which we know since g++-4.2 doesn't support C++11) statically link libgcc.
|
||||||
|
if( APPLE AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" )
|
||||||
|
set( ALL_C_FLAGS "-static-libgcc" )
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${REL_LINKER_FLAGS}" )
|
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${REL_LINKER_FLAGS}" )
|
||||||
|
@ -193,7 +198,7 @@ option(FORCE_INTERNAL_GME "Use internal gme" ON)
|
||||||
# Fast math flags, required by some subprojects
|
# Fast math flags, required by some subprojects
|
||||||
set( ZD_FASTMATH_FLAG "" )
|
set( ZD_FASTMATH_FLAG "" )
|
||||||
if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||||
set( ZD_FASTMATH_FLAG "-ffast-math" )
|
set( ZD_FASTMATH_FLAG "-ffast-math -ffp-contract=fast" )
|
||||||
elseif( MSVC )
|
elseif( MSVC )
|
||||||
set( ZD_FASTMATH_FLAG "/fp:fast" )
|
set( ZD_FASTMATH_FLAG "/fp:fast" )
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -465,28 +465,28 @@ if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
|
||||||
set( CMAKE_C_FLAGS "-Wno-unused-result ${CMAKE_C_FLAGS}" )
|
set( CMAKE_C_FLAGS "-Wno-unused-result ${CMAKE_C_FLAGS}" )
|
||||||
set( CMAKE_CXX_FLAGS "-Wno-unused-result ${CMAKE_CXX_FLAGS}" )
|
set( CMAKE_CXX_FLAGS "-Wno-unused-result ${CMAKE_CXX_FLAGS}" )
|
||||||
endif()
|
endif()
|
||||||
set( CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers ${CMAKE_C_FLAGS}" )
|
set( CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers -ffp-contract=off ${CMAKE_C_FLAGS}" )
|
||||||
set( CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers ${CMAKE_CXX_FLAGS}" )
|
set( CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused -Wno-unused-parameter -Wno-missing-field-initializers -ffp-contract=off ${CMAKE_CXX_FLAGS}" )
|
||||||
|
|
||||||
# Use the highest C++ standard available since VS2015 compiles with C++14
|
# Use the highest C++ standard available since VS2015 compiles with C++14
|
||||||
# but we only require C++11. The recommended way to do this in CMake is to
|
# but we only require C++11. The recommended way to do this in CMake is to
|
||||||
# probably to use target_compile_features, but I don't feel like maintaining
|
# probably to use target_compile_features, but I don't feel like maintaining
|
||||||
# a list of features we use.
|
# a list of features we use.
|
||||||
CHECK_CXX_COMPILER_FLAG( "-std=c++14" CAN_DO_CPP14 )
|
CHECK_CXX_COMPILER_FLAG( "-std=gnu++14" CAN_DO_CPP14 )
|
||||||
if ( CAN_DO_CPP14 )
|
if ( CAN_DO_CPP14 )
|
||||||
set ( CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}" )
|
set ( CMAKE_CXX_FLAGS "-std=gnu++14 ${CMAKE_CXX_FLAGS}" )
|
||||||
else ()
|
else ()
|
||||||
CHECK_CXX_COMPILER_FLAG( "-std=c++1y" CAN_DO_CPP1Y )
|
CHECK_CXX_COMPILER_FLAG( "-std=gnu++1y" CAN_DO_CPP1Y )
|
||||||
if ( CAN_DO_CPP1Y )
|
if ( CAN_DO_CPP1Y )
|
||||||
set ( CMAKE_CXX_FLAGS "-std=c++1y ${CMAKE_CXX_FLAGS}" )
|
set ( CMAKE_CXX_FLAGS "-std=gnu++1y ${CMAKE_CXX_FLAGS}" )
|
||||||
else ()
|
else ()
|
||||||
CHECK_CXX_COMPILER_FLAG( "-std=c++11" CAN_DO_CPP11 )
|
CHECK_CXX_COMPILER_FLAG( "-std=gnu++11" CAN_DO_CPP11 )
|
||||||
if ( CAN_DO_CPP11 )
|
if ( CAN_DO_CPP11 )
|
||||||
set ( CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}" )
|
set ( CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}" )
|
||||||
else ()
|
else ()
|
||||||
CHECK_CXX_COMPILER_FLAG( "-std=c++0x" CAN_DO_CPP0X )
|
CHECK_CXX_COMPILER_FLAG( "-std=gnu++0x" CAN_DO_CPP0X )
|
||||||
if ( CAN_DO_CPP0X )
|
if ( CAN_DO_CPP0X )
|
||||||
set ( CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}" )
|
set ( CMAKE_CXX_FLAGS "-std=gnu++0x ${CMAKE_CXX_FLAGS}" )
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -645,6 +645,7 @@ set( PLAT_COCOA_SOURCES
|
||||||
posix/cocoa/i_input.mm
|
posix/cocoa/i_input.mm
|
||||||
posix/cocoa/i_joystick.cpp
|
posix/cocoa/i_joystick.cpp
|
||||||
posix/cocoa/i_main.mm
|
posix/cocoa/i_main.mm
|
||||||
|
posix/cocoa/i_main_except.cpp
|
||||||
posix/cocoa/i_system.mm
|
posix/cocoa/i_system.mm
|
||||||
posix/cocoa/i_timer.cpp
|
posix/cocoa/i_timer.cpp
|
||||||
posix/cocoa/i_video.mm
|
posix/cocoa/i_video.mm
|
||||||
|
@ -681,6 +682,7 @@ elseif( APPLE )
|
||||||
|
|
||||||
set_source_files_properties( posix/osx/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
|
set_source_files_properties( posix/osx/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
|
||||||
set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks )
|
set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks )
|
||||||
|
set_source_files_properties( posix/osx/iwadpicker_cocoa.mm PROPERTIES COMPILE_FLAGS -fobjc-exceptions )
|
||||||
else()
|
else()
|
||||||
set( SYSTEM_SOURCES_DIR posix posix/sdl )
|
set( SYSTEM_SOURCES_DIR posix posix/sdl )
|
||||||
set( SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} )
|
set( SYSTEM_SOURCES ${PLAT_POSIX_SOURCES} ${PLAT_SDL_SOURCES} )
|
||||||
|
|
|
@ -123,6 +123,18 @@ typedef TMap<int, PClassActor *> FClassMap;
|
||||||
#define NO_SANITIZE
|
#define NO_SANITIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
// With versions of GCC newer than 4.2, it appears it was determined that the
|
||||||
|
// cost of an unaligned pointer on PPC was high enough to add padding to the
|
||||||
|
// end of packed structs. For whatever reason __packed__ and pragma pack are
|
||||||
|
// handled differently in this regard. Note that this only needs to be applied
|
||||||
|
// to types which are used in arrays or sizeof is needed. This also prevents
|
||||||
|
// code from taking references to the struct members.
|
||||||
|
#define FORCE_PACKED __attribute__((__packed__))
|
||||||
|
#else
|
||||||
|
#define FORCE_PACKED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "basictypes.h"
|
#include "basictypes.h"
|
||||||
|
|
||||||
extern bool batchrun;
|
extern bool batchrun;
|
||||||
|
|
|
@ -149,6 +149,8 @@ static const NSOpenGLPixelFormatAttribute NSOpenGLPFAAllowOfflineRenderers = NSO
|
||||||
- (void)setCollectionBehavior:(NSUInteger)collectionBehavior;
|
- (void)setCollectionBehavior:(NSUInteger)collectionBehavior;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
typedef NSUInteger NSWindowCollectionBehavior;
|
||||||
|
|
||||||
#endif // prior to 10.5
|
#endif // prior to 10.5
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,6 @@ EXTERN_CVAR(Bool, fullscreen )
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -78,6 +77,9 @@ void (*TermFuncs[MAX_TERMS])();
|
||||||
const char *TermNames[MAX_TERMS];
|
const char *TermNames[MAX_TERMS];
|
||||||
size_t NumTerms;
|
size_t NumTerms;
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
|
// Expose this for i_main_except.cpp
|
||||||
void call_terms()
|
void call_terms()
|
||||||
{
|
{
|
||||||
while (NumTerms > 0)
|
while (NumTerms > 0)
|
||||||
|
@ -86,8 +88,6 @@ void call_terms()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
|
||||||
|
|
||||||
|
|
||||||
void addterm(void (*func)(), const char *name)
|
void addterm(void (*func)(), const char *name)
|
||||||
{
|
{
|
||||||
|
@ -133,6 +133,41 @@ void Mac_I_FatalError(const char* const message)
|
||||||
DArgs* Args; // command line arguments
|
DArgs* Args; // command line arguments
|
||||||
|
|
||||||
|
|
||||||
|
// Newer versions of GCC than 4.2 have a bug with C++ exceptions in Objective-C++ code.
|
||||||
|
// To work around we'll implement the try and catch in standard C++.
|
||||||
|
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61759
|
||||||
|
void OriginalMainExcept(int argc, char** argv);
|
||||||
|
void OriginalMainTry(int argc, char** argv)
|
||||||
|
{
|
||||||
|
Args = new DArgs(argc, argv);
|
||||||
|
|
||||||
|
/*
|
||||||
|
killough 1/98:
|
||||||
|
|
||||||
|
This fixes some problems with exit handling
|
||||||
|
during abnormal situations.
|
||||||
|
|
||||||
|
The old code called I_Quit() to end program,
|
||||||
|
while now I_Quit() is installed as an exit
|
||||||
|
handler and exit() is called to exit, either
|
||||||
|
normally or abnormally. Seg faults are caught
|
||||||
|
and the error handler is used, to prevent
|
||||||
|
being left in graphics mode or having very
|
||||||
|
loud SFX noise because the sound card is
|
||||||
|
left in an unstable state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
atexit(call_terms);
|
||||||
|
atterm(I_Quit);
|
||||||
|
|
||||||
|
NSString* exePath = [[NSBundle mainBundle] executablePath];
|
||||||
|
progdir = [[exePath stringByDeletingLastPathComponent] UTF8String];
|
||||||
|
progdir += "/";
|
||||||
|
|
||||||
|
C_InitConsole(80 * 8, 25 * 8, false);
|
||||||
|
D_DoomMain();
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -151,7 +186,6 @@ void NewFailure()
|
||||||
I_FatalError("Failed to allocate memory from system heap");
|
I_FatalError("Failed to allocate memory from system heap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int OriginalMain(int argc, char** argv)
|
int OriginalMain(int argc, char** argv)
|
||||||
{
|
{
|
||||||
printf(GAMENAME" %s - %s - Cocoa version\nCompiled on %s\n\n",
|
printf(GAMENAME" %s - %s - Cocoa version\nCompiled on %s\n\n",
|
||||||
|
@ -174,53 +208,7 @@ int OriginalMain(int argc, char** argv)
|
||||||
vid_vsync = true;
|
vid_vsync = true;
|
||||||
fullscreen = true;
|
fullscreen = true;
|
||||||
|
|
||||||
try
|
OriginalMainExcept(argc, argv);
|
||||||
{
|
|
||||||
Args = new DArgs(argc, argv);
|
|
||||||
|
|
||||||
/*
|
|
||||||
killough 1/98:
|
|
||||||
|
|
||||||
This fixes some problems with exit handling
|
|
||||||
during abnormal situations.
|
|
||||||
|
|
||||||
The old code called I_Quit() to end program,
|
|
||||||
while now I_Quit() is installed as an exit
|
|
||||||
handler and exit() is called to exit, either
|
|
||||||
normally or abnormally. Seg faults are caught
|
|
||||||
and the error handler is used, to prevent
|
|
||||||
being left in graphics mode or having very
|
|
||||||
loud SFX noise because the sound card is
|
|
||||||
left in an unstable state.
|
|
||||||
*/
|
|
||||||
|
|
||||||
atexit(call_terms);
|
|
||||||
atterm(I_Quit);
|
|
||||||
|
|
||||||
NSString* exePath = [[NSBundle mainBundle] executablePath];
|
|
||||||
progdir = [[exePath stringByDeletingLastPathComponent] UTF8String];
|
|
||||||
progdir += "/";
|
|
||||||
|
|
||||||
C_InitConsole(80 * 8, 25 * 8, false);
|
|
||||||
D_DoomMain();
|
|
||||||
}
|
|
||||||
catch(const CDoomError& error)
|
|
||||||
{
|
|
||||||
const char* const message = error.GetMessage();
|
|
||||||
|
|
||||||
if (NULL != message)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s\n", message);
|
|
||||||
Mac_I_FatalError(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
call_terms();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
34
src/posix/cocoa/i_main_except.cpp
Normal file
34
src/posix/cocoa/i_main_except.cpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// Workaround for GCC Objective-C++ with C++ exceptions bug.
|
||||||
|
|
||||||
|
#include "doomerrors.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Import some functions from i_main.mm
|
||||||
|
void call_terms();
|
||||||
|
void Mac_I_FatalError(const char* const message);
|
||||||
|
void OriginalMainTry(int argc, char** argv);
|
||||||
|
|
||||||
|
void OriginalMainExcept(int argc, char** argv)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OriginalMainTry(argc, argv);
|
||||||
|
}
|
||||||
|
catch(const CDoomError& error)
|
||||||
|
{
|
||||||
|
const char* const message = error.GetMessage();
|
||||||
|
|
||||||
|
if (NULL != message)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s\n", message);
|
||||||
|
Mac_I_FatalError(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
call_terms();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
|
@ -100,14 +100,14 @@ typedef struct tagITFILEHEADER
|
||||||
DWORD reserved2;
|
DWORD reserved2;
|
||||||
BYTE chnpan[64];
|
BYTE chnpan[64];
|
||||||
BYTE chnvol[64];
|
BYTE chnvol[64];
|
||||||
} ITFILEHEADER, *PITFILEHEADER;
|
} FORCE_PACKED ITFILEHEADER, *PITFILEHEADER;
|
||||||
|
|
||||||
typedef struct MODMIDICFG
|
typedef struct MODMIDICFG
|
||||||
{
|
{
|
||||||
char szMidiGlb[9*32]; // changed from CHAR
|
char szMidiGlb[9*32]; // changed from CHAR
|
||||||
char szMidiSFXExt[16*32]; // changed from CHAR
|
char szMidiSFXExt[16*32]; // changed from CHAR
|
||||||
char szMidiZXXExt[128*32]; // changed from CHAR
|
char szMidiZXXExt[128*32]; // changed from CHAR
|
||||||
} MODMIDICFG, *LPMODMIDICFG;
|
} FORCE_PACKED MODMIDICFG, *LPMODMIDICFG;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct PCXHeader
|
||||||
|
|
||||||
BYTE padding[54];
|
BYTE padding[54];
|
||||||
|
|
||||||
};
|
} FORCE_PACKED;
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -13,7 +13,7 @@ struct FZipEndOfCentralDirectory
|
||||||
DWORD DirectorySize;
|
DWORD DirectorySize;
|
||||||
DWORD DirectoryOffset;
|
DWORD DirectoryOffset;
|
||||||
WORD ZipCommentLength;
|
WORD ZipCommentLength;
|
||||||
};
|
} FORCE_PACKED;
|
||||||
|
|
||||||
// FZipFileInfo
|
// FZipFileInfo
|
||||||
struct FZipCentralDirectoryInfo
|
struct FZipCentralDirectoryInfo
|
||||||
|
@ -36,7 +36,7 @@ struct FZipCentralDirectoryInfo
|
||||||
DWORD ExternalAttributes;
|
DWORD ExternalAttributes;
|
||||||
DWORD LocalHeaderOffset;
|
DWORD LocalHeaderOffset;
|
||||||
// file name and other variable length info follows
|
// file name and other variable length info follows
|
||||||
};
|
} FORCE_PACKED;
|
||||||
|
|
||||||
// FZipLocalHeader
|
// FZipLocalHeader
|
||||||
struct FZipLocalFileHeader
|
struct FZipLocalFileHeader
|
||||||
|
@ -53,7 +53,7 @@ struct FZipLocalFileHeader
|
||||||
WORD NameLength;
|
WORD NameLength;
|
||||||
WORD ExtraLength;
|
WORD ExtraLength;
|
||||||
// file name and other variable length info follows
|
// file name and other variable length info follows
|
||||||
};
|
} FORCE_PACKED;
|
||||||
|
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
|
@ -60,6 +60,17 @@
|
||||||
#define __cdecl
|
#define __cdecl
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
// With versions of GCC newer than 4.2, it appears it was determined that the
|
||||||
|
// cost of an unaligned pointer on PPC was high enough to add padding to the
|
||||||
|
// end of packed structs. For whatever reason __packed__ and pragma pack are
|
||||||
|
// handled differently in this regard. Note that this only needs to be applied
|
||||||
|
// to types which are used in arrays.
|
||||||
|
#define FORCE_PACKED __attribute__((__packed__))
|
||||||
|
#else
|
||||||
|
#define FORCE_PACKED
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __BIG_ENDIAN__
|
#ifndef __BIG_ENDIAN__
|
||||||
#define MAKE_ID(a,b,c,d) ((a)|((b)<<8)|((c)<<16)|((d)<<24))
|
#define MAKE_ID(a,b,c,d) ((a)|((b)<<8)|((c)<<16)|((d)<<24))
|
||||||
#define LittleShort(x) (x)
|
#define LittleShort(x) (x)
|
||||||
|
@ -150,7 +161,7 @@ typedef struct
|
||||||
UINT32 UncompressedSize; // 22
|
UINT32 UncompressedSize; // 22
|
||||||
WORD NameLength; // 26
|
WORD NameLength; // 26
|
||||||
WORD ExtraLength; // 28
|
WORD ExtraLength; // 28
|
||||||
} LocalFileHeader;
|
} FORCE_PACKED LocalFileHeader;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -171,7 +182,7 @@ typedef struct
|
||||||
WORD InternalAttributes;
|
WORD InternalAttributes;
|
||||||
UINT32 ExternalAttributes;
|
UINT32 ExternalAttributes;
|
||||||
UINT32 LocalHeaderOffset;
|
UINT32 LocalHeaderOffset;
|
||||||
} CentralDirectoryEntry;
|
} FORCE_PACKED CentralDirectoryEntry;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -183,7 +194,7 @@ typedef struct
|
||||||
UINT32 DirectorySize;
|
UINT32 DirectorySize;
|
||||||
UINT32 DirectoryOffset;
|
UINT32 DirectoryOffset;
|
||||||
WORD ZipCommentLength;
|
WORD ZipCommentLength;
|
||||||
} EndOfCentralDirectory;
|
} FORCE_PACKED EndOfCentralDirectory;
|
||||||
//#pragma pack(pop)
|
//#pragma pack(pop)
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue