updated standards to webkit standard
This commit is contained in:
parent
87bc6ca10a
commit
5bf44d19be
108
.clang-format
108
.clang-format
|
@ -1,84 +1,90 @@
|
|||
---
|
||||
AccessModifierOffset: 0
|
||||
AlignAfterOpenBracket: true
|
||||
Language: Cpp
|
||||
# BasedOnStyle: WebKit
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignConsecutiveAssignments: false
|
||||
#uncomment for clang 3.9
|
||||
#AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AlignOperands: false
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
# AlwaysBreakAfterDefinitionReturnType: None
|
||||
#uncomment for clang 3.9
|
||||
#AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: false
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
# BraceWrapping: (not set since BreakBeforeBraces is not Custom)
|
||||
BreakBeforeBinaryOperators: None
|
||||
# BreakAfterJavaFieldAnnotations: (not java)
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Linux
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeBraces: WebKit
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
#uncomment for clang 3.9
|
||||
#BreakStringLiterals: false
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '\*\<'
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
ColumnLimit: 0
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ NC_LIST_FOREACH ]
|
||||
#Uncomment for clang 3.9
|
||||
#IncludeCategories:
|
||||
# - Regex: '^"'
|
||||
# Priority: 1
|
||||
# IncludeIsMainRegex: (project doesn't use a main includes that can add other includes via regex)
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
- Regex: '^(<|"(gtest|isl|json)/)'
|
||||
Priority: 3
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 8
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
# JavaScriptQuotes: (not javascript)
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
Language: Cpp
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
# ObjCBlockIndentWidth: (not objc)
|
||||
# ObjCSpaceAfterProperty: (not objc)
|
||||
# ObjCSpaceBeforeProtocolList: (not objc)
|
||||
PenaltyBreakBeforeFirstCallParameter: 400
|
||||
PenaltyBreakComment: 0
|
||||
# PenaltyBreakFirstLessLess: (not cpp)
|
||||
PenaltyBreakString: 500
|
||||
PenaltyExcessCharacter: 10000
|
||||
PenaltyReturnTypeOnItsOwnLine: 600
|
||||
PointerAlignment: Right
|
||||
#uncomment for clang 3.9
|
||||
#ReflowComments: true
|
||||
#uncomment for clang 3.9
|
||||
#SortIncludes: true
|
||||
NamespaceIndentation: Inner
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
# SpacesInContainerLiterals: (not objc or javascript)
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
Standard: Cpp03
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
...
|
||||
|
||||
|
|
199
fex/7z_C/7z.h
199
fex/7z_C/7z.h
|
@ -13,66 +13,62 @@ EXTERN_C_BEGIN
|
|||
extern Byte k7zSignature[k7zSignatureSize];
|
||||
#define k7zMajorVersion 0
|
||||
|
||||
enum EIdEnum
|
||||
{
|
||||
k7zIdEnd,
|
||||
k7zIdHeader,
|
||||
k7zIdArchiveProperties,
|
||||
k7zIdAdditionalStreamsInfo,
|
||||
k7zIdMainStreamsInfo,
|
||||
k7zIdFilesInfo,
|
||||
k7zIdPackInfo,
|
||||
k7zIdUnpackInfo,
|
||||
k7zIdSubStreamsInfo,
|
||||
k7zIdSize,
|
||||
k7zIdCRC,
|
||||
k7zIdFolder,
|
||||
k7zIdCodersUnpackSize,
|
||||
k7zIdNumUnpackStream,
|
||||
k7zIdEmptyStream,
|
||||
k7zIdEmptyFile,
|
||||
k7zIdAnti,
|
||||
k7zIdName,
|
||||
k7zIdCTime,
|
||||
k7zIdATime,
|
||||
k7zIdMTime,
|
||||
k7zIdWinAttributes,
|
||||
k7zIdComment,
|
||||
k7zIdEncodedHeader,
|
||||
k7zIdStartPos,
|
||||
k7zIdDummy
|
||||
enum EIdEnum {
|
||||
k7zIdEnd,
|
||||
k7zIdHeader,
|
||||
k7zIdArchiveProperties,
|
||||
k7zIdAdditionalStreamsInfo,
|
||||
k7zIdMainStreamsInfo,
|
||||
k7zIdFilesInfo,
|
||||
k7zIdPackInfo,
|
||||
k7zIdUnpackInfo,
|
||||
k7zIdSubStreamsInfo,
|
||||
k7zIdSize,
|
||||
k7zIdCRC,
|
||||
k7zIdFolder,
|
||||
k7zIdCodersUnpackSize,
|
||||
k7zIdNumUnpackStream,
|
||||
k7zIdEmptyStream,
|
||||
k7zIdEmptyFile,
|
||||
k7zIdAnti,
|
||||
k7zIdName,
|
||||
k7zIdCTime,
|
||||
k7zIdATime,
|
||||
k7zIdMTime,
|
||||
k7zIdWinAttributes,
|
||||
k7zIdComment,
|
||||
k7zIdEncodedHeader,
|
||||
k7zIdStartPos,
|
||||
k7zIdDummy
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
UInt64 MethodID;
|
||||
CBuf Props;
|
||||
typedef struct {
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
UInt64 MethodID;
|
||||
CBuf Props;
|
||||
} CSzCoderInfo;
|
||||
|
||||
void SzCoderInfo_Init(CSzCoderInfo *p);
|
||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 InIndex;
|
||||
UInt32 OutIndex;
|
||||
typedef struct {
|
||||
UInt32 InIndex;
|
||||
UInt32 OutIndex;
|
||||
} CSzBindPair;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CSzCoderInfo *Coders;
|
||||
CSzBindPair *BindPairs;
|
||||
UInt32 *PackStreams;
|
||||
UInt64 *UnpackSizes;
|
||||
UInt32 NumCoders;
|
||||
UInt32 NumBindPairs;
|
||||
UInt32 NumPackStreams;
|
||||
int UnpackCRCDefined;
|
||||
UInt32 UnpackCRC;
|
||||
typedef struct {
|
||||
CSzCoderInfo *Coders;
|
||||
CSzBindPair *BindPairs;
|
||||
UInt32 *PackStreams;
|
||||
UInt64 *UnpackSizes;
|
||||
UInt32 NumCoders;
|
||||
UInt32 NumBindPairs;
|
||||
UInt32 NumPackStreams;
|
||||
int UnpackCRCDefined;
|
||||
UInt32 UnpackCRC;
|
||||
|
||||
UInt32 NumUnpackStreams;
|
||||
UInt32 NumUnpackStreams;
|
||||
} CSzFolder;
|
||||
|
||||
void SzFolder_Init(CSzFolder *p);
|
||||
|
@ -81,48 +77,43 @@ int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
|||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||
|
||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *stream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, ILookInStream *stream,
|
||||
UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 Low;
|
||||
UInt32 High;
|
||||
typedef struct {
|
||||
UInt32 Low;
|
||||
UInt32 High;
|
||||
} CNtfsFileTime;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CNtfsFileTime MTime;
|
||||
UInt64 Size;
|
||||
UInt32 Crc;
|
||||
UInt32 Attrib;
|
||||
Byte HasStream;
|
||||
Byte IsDir;
|
||||
Byte IsAnti;
|
||||
Byte CrcDefined;
|
||||
Byte MTimeDefined;
|
||||
Byte AttribDefined;
|
||||
typedef struct {
|
||||
CNtfsFileTime MTime;
|
||||
UInt64 Size;
|
||||
UInt32 Crc;
|
||||
UInt32 Attrib;
|
||||
Byte HasStream;
|
||||
Byte IsDir;
|
||||
Byte IsAnti;
|
||||
Byte CrcDefined;
|
||||
Byte MTimeDefined;
|
||||
Byte AttribDefined;
|
||||
} CSzFileItem;
|
||||
|
||||
void SzFile_Init(CSzFileItem *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt64 *PackSizes;
|
||||
Byte *PackCRCsDefined;
|
||||
UInt32 *PackCRCs;
|
||||
CSzFolder *Folders;
|
||||
CSzFileItem *Files;
|
||||
UInt32 NumPackStreams;
|
||||
UInt32 NumFolders;
|
||||
UInt32 NumFiles;
|
||||
typedef struct {
|
||||
UInt64 *PackSizes;
|
||||
Byte *PackCRCsDefined;
|
||||
UInt32 *PackCRCs;
|
||||
CSzFolder *Folders;
|
||||
CSzFileItem *Files;
|
||||
UInt32 NumPackStreams;
|
||||
UInt32 NumFolders;
|
||||
UInt32 NumFiles;
|
||||
} CSzAr;
|
||||
|
||||
void SzAr_Init(CSzAr *p);
|
||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
||||
|
||||
|
||||
/*
|
||||
SzExtract extracts file from archive
|
||||
|
||||
|
@ -136,27 +127,26 @@ void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
|||
*outBufferSize
|
||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||
it will increase decompression speed.
|
||||
|
||||
|
||||
If you use external function, you can declare these 3 cache variables
|
||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||
|
||||
|
||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CSzAr db;
|
||||
|
||||
UInt64 startPosAfterHeader;
|
||||
UInt64 dataPos;
|
||||
typedef struct {
|
||||
CSzAr db;
|
||||
|
||||
UInt32 *FolderStartPackStreamIndex;
|
||||
UInt64 *PackStreamStartPositions;
|
||||
UInt32 *FolderStartFileIndex;
|
||||
UInt32 *FileIndexToFolderIndexMap;
|
||||
UInt64 startPosAfterHeader;
|
||||
UInt64 dataPos;
|
||||
|
||||
size_t *FileNameOffsets; /* in 2-byte steps */
|
||||
CBuf FileNames; /* UTF-16-LE */
|
||||
UInt32 *FolderStartPackStreamIndex;
|
||||
UInt64 *PackStreamStartPositions;
|
||||
UInt32 *FolderStartFileIndex;
|
||||
UInt32 *FileIndexToFolderIndexMap;
|
||||
|
||||
size_t *FileNameOffsets; /* in 2-byte steps */
|
||||
CBuf FileNames; /* UTF-16-LE */
|
||||
} CSzArEx;
|
||||
|
||||
void SzArEx_Init(CSzArEx *p);
|
||||
|
@ -172,18 +162,15 @@ if dest != NULL, the return value specifies the number of 16-bit characters that
|
|||
|
||||
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
||||
|
||||
SRes SzArEx_Extract(
|
||||
const CSzArEx *db,
|
||||
ILookInStream *inStream,
|
||||
UInt32 fileIndex, /* index of file */
|
||||
UInt32 *blockIndex, /* index of solid block */
|
||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||
size_t *outBufferSize, /* buffer size for output buffer */
|
||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||
ISzAlloc *allocMain,
|
||||
ISzAlloc *allocTemp);
|
||||
|
||||
SRes SzArEx_Extract(const CSzArEx *db, ILookInStream *inStream, UInt32 fileIndex, /* index of file
|
||||
*/
|
||||
UInt32 *blockIndex, /* index of solid block */
|
||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with
|
||||
allocMain) */
|
||||
size_t *outBufferSize, /* buffer size for output buffer */
|
||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||
ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
||||
|
||||
/*
|
||||
SzArEx_Open Errors:
|
||||
|
|
|
@ -20,57 +20,55 @@ int g_allocCountTemp = 0;
|
|||
|
||||
void *SzAlloc(void *p, size_t size)
|
||||
{
|
||||
p = p;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
|
||||
g_allocCount++;
|
||||
#endif
|
||||
return malloc(size);
|
||||
p = p;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
|
||||
g_allocCount++;
|
||||
#endif
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SzFree(void *p, void *address)
|
||||
{
|
||||
p = p;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
{
|
||||
g_allocCount--;
|
||||
fprintf(stderr, "\nFree; count = %10d", g_allocCount);
|
||||
}
|
||||
#endif
|
||||
free(address);
|
||||
p = p;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0) {
|
||||
g_allocCount--;
|
||||
fprintf(stderr, "\nFree; count = %10d", g_allocCount);
|
||||
}
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
|
||||
void *SzAllocTemp(void *p, size_t size)
|
||||
{
|
||||
p = p;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
|
||||
g_allocCountTemp++;
|
||||
#ifdef _WIN32
|
||||
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||
#endif
|
||||
#endif
|
||||
return malloc(size);
|
||||
p = p;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
|
||||
g_allocCountTemp++;
|
||||
#ifdef _WIN32
|
||||
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||
#endif
|
||||
#endif
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SzFreeTemp(void *p, void *address)
|
||||
{
|
||||
p = p;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
{
|
||||
g_allocCountTemp--;
|
||||
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
HeapFree(GetProcessHeap(), 0, address);
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
free(address);
|
||||
p = p;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0) {
|
||||
g_allocCountTemp--;
|
||||
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
HeapFree(GetProcessHeap(), 0, address);
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
|
|
|
@ -7,30 +7,28 @@ Public domain */
|
|||
|
||||
void Buf_Init(CBuf *p)
|
||||
{
|
||||
p->data = 0;
|
||||
p->size = 0;
|
||||
p->data = 0;
|
||||
p->size = 0;
|
||||
}
|
||||
|
||||
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
|
||||
{
|
||||
p->size = 0;
|
||||
if (size == 0)
|
||||
{
|
||||
p->data = 0;
|
||||
return 1;
|
||||
}
|
||||
p->data = (Byte *)alloc->Alloc(alloc, size);
|
||||
if (p->data != 0)
|
||||
{
|
||||
p->size = size;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
p->size = 0;
|
||||
if (size == 0) {
|
||||
p->data = 0;
|
||||
return 1;
|
||||
}
|
||||
p->data = (Byte *)alloc->Alloc(alloc, size);
|
||||
if (p->data != 0) {
|
||||
p->size = size;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Buf_Free(CBuf *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->data);
|
||||
p->data = 0;
|
||||
p->size = 0;
|
||||
alloc->Free(alloc, p->data);
|
||||
p->data = 0;
|
||||
p->size = 0;
|
||||
}
|
||||
|
|
|
@ -10,21 +10,19 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte *data;
|
||||
size_t size;
|
||||
typedef struct {
|
||||
Byte *data;
|
||||
size_t size;
|
||||
} CBuf;
|
||||
|
||||
void Buf_Init(CBuf *p);
|
||||
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
|
||||
void Buf_Free(CBuf *p, ISzAlloc *alloc);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte *data;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
typedef struct {
|
||||
Byte *data;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
} CDynBuf;
|
||||
|
||||
void DynBuf_Construct(CDynBuf *p);
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
#define CRC_NUM_TABLES 1
|
||||
#endif
|
||||
|
||||
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
typedef UInt32(MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size,
|
||||
const UInt32 *table);
|
||||
|
||||
static CRC_FUNC g_CrcUpdate;
|
||||
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
||||
|
@ -23,10 +24,10 @@ UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
|||
|
||||
static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
return v;
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
return v;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -38,37 +39,35 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
|
|||
|
||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
||||
{
|
||||
return g_CrcUpdate(v, data, size, g_CrcTable);
|
||||
return g_CrcUpdate(v, data, size, g_CrcTable);
|
||||
}
|
||||
|
||||
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
|
||||
{
|
||||
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
|
||||
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
|
||||
}
|
||||
|
||||
void MY_FAST_CALL CrcGenerateTable()
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
UInt32 r = i;
|
||||
unsigned j;
|
||||
for (j = 0; j < 8; j++)
|
||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||
g_CrcTable[i] = r;
|
||||
}
|
||||
#if CRC_NUM_TABLES == 1
|
||||
g_CrcUpdate = CrcUpdateT1;
|
||||
#else
|
||||
for (; i < 256 * CRC_NUM_TABLES; i++)
|
||||
{
|
||||
UInt32 r = g_CrcTable[i - 256];
|
||||
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
||||
}
|
||||
g_CrcUpdate = CrcUpdateT4;
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
if (!CPU_Is_InOrder())
|
||||
g_CrcUpdate = CrcUpdateT8;
|
||||
#endif
|
||||
#endif
|
||||
UInt32 i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
UInt32 r = i;
|
||||
unsigned j;
|
||||
for (j = 0; j < 8; j++)
|
||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||
g_CrcTable[i] = r;
|
||||
}
|
||||
#if CRC_NUM_TABLES == 1
|
||||
g_CrcUpdate = CrcUpdateT1;
|
||||
#else
|
||||
for (; i < 256 * CRC_NUM_TABLES; i++) {
|
||||
UInt32 r = g_CrcTable[i - 256];
|
||||
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
||||
}
|
||||
g_CrcUpdate = CrcUpdateT4;
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
if (!CPU_Is_InOrder())
|
||||
g_CrcUpdate = CrcUpdateT8;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -9,26 +9,22 @@
|
|||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
for (; size >= 4; size -= 4, p += 4)
|
||||
{
|
||||
v ^= *(const UInt32 *)p;
|
||||
v =
|
||||
table[0x300 + (v & 0xFF)] ^
|
||||
table[0x200 + ((v >> 8) & 0xFF)] ^
|
||||
table[0x100 + ((v >> 16) & 0xFF)] ^
|
||||
table[0x000 + ((v >> 24))];
|
||||
}
|
||||
for (; size > 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
return v;
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
for (; size >= 4; size -= 4, p += 4) {
|
||||
v ^= *(const UInt32 *)p;
|
||||
v = table[0x300 + (v & 0xFF)] ^ table[0x200 + ((v >> 8) & 0xFF)] ^
|
||||
table[0x100 + ((v >> 16) & 0xFF)] ^ table[0x000 + ((v >> 24))];
|
||||
}
|
||||
for (; size > 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
return v;
|
||||
}
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
{
|
||||
return CrcUpdateT4(v, data, size, table);
|
||||
return CrcUpdateT4(v, data, size, table);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
755
fex/7z_C/7zDec.c
755
fex/7z_C/7zDec.c
|
@ -10,461 +10,456 @@
|
|||
#include "Bcj2.h"
|
||||
#include "Bra.h"
|
||||
#include "CpuArch.h"
|
||||
#include "LzmaDec.h"
|
||||
#include "Lzma2Dec.h"
|
||||
#include "LzmaDec.h"
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
#include "Ppmd7.h"
|
||||
#endif
|
||||
|
||||
#define k_Copy 0
|
||||
#define k_LZMA2 0x21
|
||||
#define k_LZMA 0x30101
|
||||
#define k_BCJ 0x03030103
|
||||
#define k_PPC 0x03030205
|
||||
#define k_ARM 0x03030501
|
||||
#define k_ARMT 0x03030701
|
||||
#define k_LZMA 0x30101
|
||||
#define k_BCJ 0x03030103
|
||||
#define k_PPC 0x03030205
|
||||
#define k_ARM 0x03030501
|
||||
#define k_ARMT 0x03030701
|
||||
#define k_SPARC 0x03030805
|
||||
#define k_BCJ2 0x0303011B
|
||||
#define k_BCJ2 0x0303011B
|
||||
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
|
||||
#define k_PPMD 0x30401
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IByteIn p;
|
||||
const Byte *cur;
|
||||
const Byte *end;
|
||||
const Byte *begin;
|
||||
UInt64 processed;
|
||||
Bool extra;
|
||||
SRes res;
|
||||
ILookInStream *inStream;
|
||||
typedef struct {
|
||||
IByteIn p;
|
||||
const Byte *cur;
|
||||
const Byte *end;
|
||||
const Byte *begin;
|
||||
UInt64 processed;
|
||||
Bool extra;
|
||||
SRes res;
|
||||
ILookInStream *inStream;
|
||||
} CByteInToLook;
|
||||
|
||||
static Byte ReadByte(void *pp)
|
||||
{
|
||||
CByteInToLook *p = (CByteInToLook *)pp;
|
||||
if (p->cur != p->end)
|
||||
return *p->cur++;
|
||||
if (p->res == SZ_OK)
|
||||
{
|
||||
size_t size = p->cur - p->begin;
|
||||
p->processed += size;
|
||||
p->res = p->inStream->Skip(p->inStream, size);
|
||||
size = (1 << 25);
|
||||
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
|
||||
p->cur = p->begin;
|
||||
p->end = p->begin + size;
|
||||
if (size != 0)
|
||||
return *p->cur++;;
|
||||
}
|
||||
p->extra = True;
|
||||
return 0;
|
||||
CByteInToLook *p = (CByteInToLook *)pp;
|
||||
if (p->cur != p->end)
|
||||
return *p->cur++;
|
||||
if (p->res == SZ_OK) {
|
||||
size_t size = p->cur - p->begin;
|
||||
p->processed += size;
|
||||
p->res = p->inStream->Skip(p->inStream, size);
|
||||
size = (1 << 25);
|
||||
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
|
||||
p->cur = p->begin;
|
||||
p->end = p->begin + size;
|
||||
if (size != 0)
|
||||
return *p->cur++;
|
||||
;
|
||||
}
|
||||
p->extra = True;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CPpmd7 ppmd;
|
||||
CByteInToLook s;
|
||||
SRes res = SZ_OK;
|
||||
CPpmd7 ppmd;
|
||||
CByteInToLook s;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
s.p.Read = ReadByte;
|
||||
s.inStream = inStream;
|
||||
s.begin = s.end = s.cur = NULL;
|
||||
s.extra = False;
|
||||
s.res = SZ_OK;
|
||||
s.processed = 0;
|
||||
s.p.Read = ReadByte;
|
||||
s.inStream = inStream;
|
||||
s.begin = s.end = s.cur = NULL;
|
||||
s.extra = False;
|
||||
s.res = SZ_OK;
|
||||
s.processed = 0;
|
||||
|
||||
if (coder->Props.size != 5)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (coder->Props.size != 5)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
|
||||
{
|
||||
unsigned order = coder->Props.data[0];
|
||||
UInt32 memSize = GetUi32(coder->Props.data + 1);
|
||||
if (order < PPMD7_MIN_ORDER ||
|
||||
order > PPMD7_MAX_ORDER ||
|
||||
memSize < PPMD7_MIN_MEM_SIZE ||
|
||||
memSize > PPMD7_MAX_MEM_SIZE)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
Ppmd7_Construct(&ppmd);
|
||||
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
|
||||
return SZ_ERROR_MEM;
|
||||
Ppmd7_Init(&ppmd, order);
|
||||
}
|
||||
{
|
||||
CPpmd7z_RangeDec rc;
|
||||
Ppmd7z_RangeDec_CreateVTable(&rc);
|
||||
rc.Stream = &s.p;
|
||||
if (!Ppmd7z_RangeDec_Init(&rc))
|
||||
res = SZ_ERROR_DATA;
|
||||
else if (s.extra)
|
||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||
else
|
||||
{
|
||||
SizeT i;
|
||||
for (i = 0; i < outSize; i++)
|
||||
{
|
||||
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
|
||||
if (s.extra || sym < 0)
|
||||
break;
|
||||
outBuffer[i] = (Byte)sym;
|
||||
}
|
||||
if (i != outSize)
|
||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||
else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
|
||||
res = SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
Ppmd7_Free(&ppmd, allocMain);
|
||||
return res;
|
||||
{
|
||||
unsigned order = coder->Props.data[0];
|
||||
UInt32 memSize = GetUi32(coder->Props.data + 1);
|
||||
if (order < PPMD7_MIN_ORDER || order > PPMD7_MAX_ORDER ||
|
||||
memSize < PPMD7_MIN_MEM_SIZE || memSize > PPMD7_MAX_MEM_SIZE)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
Ppmd7_Construct(&ppmd);
|
||||
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
|
||||
return SZ_ERROR_MEM;
|
||||
Ppmd7_Init(&ppmd, order);
|
||||
}
|
||||
{
|
||||
CPpmd7z_RangeDec rc;
|
||||
Ppmd7z_RangeDec_CreateVTable(&rc);
|
||||
rc.Stream = &s.p;
|
||||
if (!Ppmd7z_RangeDec_Init(&rc))
|
||||
res = SZ_ERROR_DATA;
|
||||
else if (s.extra)
|
||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||
else {
|
||||
SizeT i;
|
||||
for (i = 0; i < outSize; i++) {
|
||||
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
|
||||
if (s.extra || sym < 0)
|
||||
break;
|
||||
outBuffer[i] = (Byte)sym;
|
||||
}
|
||||
if (i != outSize)
|
||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||
else if (s.processed + (s.cur - s.begin) != inSize ||
|
||||
!Ppmd7z_RangeDec_IsFinishedOK(&rc))
|
||||
res = SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
Ppmd7_Free(&ppmd, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CLzmaDec state;
|
||||
SRes res = SZ_OK;
|
||||
CLzmaDec state;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
LzmaDec_Construct(&state);
|
||||
RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
|
||||
state.dic = outBuffer;
|
||||
state.dicBufSize = outSize;
|
||||
LzmaDec_Init(&state);
|
||||
LzmaDec_Construct(&state);
|
||||
RINOK(LzmaDec_AllocateProbs(&state,
|
||||
coder->Props.data,
|
||||
(unsigned)coder->Props.size,
|
||||
allocMain));
|
||||
state.dic = outBuffer;
|
||||
state.dicBufSize = outSize;
|
||||
LzmaDec_Init(&state);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
for (;;) {
|
||||
Byte *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
|
||||
{
|
||||
if (state.dicBufSize != outSize || lookahead != 0 ||
|
||||
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
|
||||
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
res = inStream->Skip((void *)inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = LzmaDec_DecodeToDic(&state,
|
||||
outSize,
|
||||
inBuf,
|
||||
&inProcessed,
|
||||
LZMA_FINISH_END,
|
||||
&status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
if (state.dicPos == state.dicBufSize ||
|
||||
(inProcessed == 0 && dicPos == state.dicPos)) {
|
||||
if (state.dicBufSize != outSize || lookahead != 0 ||
|
||||
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
|
||||
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
res = inStream->Skip((void *)inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LzmaDec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
LzmaDec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CLzma2Dec state;
|
||||
SRes res = SZ_OK;
|
||||
CLzma2Dec state;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
Lzma2Dec_Construct(&state);
|
||||
if (coder->Props.size != 1)
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
|
||||
state.decoder.dic = outBuffer;
|
||||
state.decoder.dicBufSize = outSize;
|
||||
Lzma2Dec_Init(&state);
|
||||
Lzma2Dec_Construct(&state);
|
||||
if (coder->Props.size != 1)
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
|
||||
state.decoder.dic = outBuffer;
|
||||
state.decoder.dicBufSize = outSize;
|
||||
Lzma2Dec_Init(&state);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
for (;;) {
|
||||
Byte *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
|
||||
{
|
||||
if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
|
||||
(status != LZMA_STATUS_FINISHED_WITH_MARK))
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
res = inStream->Skip((void *)inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = Lzma2Dec_DecodeToDic(&state,
|
||||
outSize,
|
||||
inBuf,
|
||||
&inProcessed,
|
||||
LZMA_FINISH_END,
|
||||
&status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
if (state.decoder.dicPos == state.decoder.dicBufSize ||
|
||||
(inProcessed == 0 && dicPos == state.decoder.dicPos)) {
|
||||
if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
|
||||
(status != LZMA_STATUS_FINISHED_WITH_MARK))
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
res = inStream->Skip((void *)inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Lzma2Dec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
Lzma2Dec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
|
||||
{
|
||||
while (inSize > 0)
|
||||
{
|
||||
void *inBuf;
|
||||
size_t curSize = (1 << 18);
|
||||
if (curSize > inSize)
|
||||
curSize = (size_t)inSize;
|
||||
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
|
||||
if (curSize == 0)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
memcpy(outBuffer, inBuf, curSize);
|
||||
outBuffer += curSize;
|
||||
inSize -= curSize;
|
||||
RINOK(inStream->Skip((void *)inStream, curSize));
|
||||
}
|
||||
return SZ_OK;
|
||||
while (inSize > 0) {
|
||||
void *inBuf;
|
||||
size_t curSize = (1 << 18);
|
||||
if (curSize > inSize)
|
||||
curSize = (size_t)inSize;
|
||||
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
|
||||
if (curSize == 0)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
memcpy(outBuffer, inBuf, curSize);
|
||||
outBuffer += curSize;
|
||||
inSize -= curSize;
|
||||
RINOK(inStream->Skip((void *)inStream, curSize));
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static Bool IS_MAIN_METHOD(UInt32 m)
|
||||
{
|
||||
switch(m)
|
||||
{
|
||||
case k_Copy:
|
||||
case k_LZMA:
|
||||
case k_LZMA2:
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
case k_PPMD:
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
switch (m) {
|
||||
case k_Copy:
|
||||
case k_LZMA:
|
||||
case k_LZMA2:
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
case k_PPMD:
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
||||
{
|
||||
return
|
||||
c->NumInStreams == 1 &&
|
||||
c->NumOutStreams == 1 &&
|
||||
c->MethodID <= (UInt32)0xFFFFFFFF &&
|
||||
IS_MAIN_METHOD((UInt32)c->MethodID);
|
||||
return c->NumInStreams == 1 && c->NumOutStreams == 1 && c->MethodID <= (UInt32)0xFFFFFFFF &&
|
||||
IS_MAIN_METHOD((UInt32)c->MethodID);
|
||||
}
|
||||
|
||||
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
|
||||
|
||||
static SRes CheckSupportedFolder(const CSzFolder *f)
|
||||
{
|
||||
if (f->NumCoders < 1 || f->NumCoders > 4)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumCoders == 1)
|
||||
{
|
||||
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 2)
|
||||
{
|
||||
CSzCoderInfo *c = &f->Coders[1];
|
||||
if (c->MethodID > (UInt32)0xFFFFFFFF ||
|
||||
c->NumInStreams != 1 ||
|
||||
c->NumOutStreams != 1 ||
|
||||
f->NumPackStreams != 1 ||
|
||||
f->PackStreams[0] != 0 ||
|
||||
f->NumBindPairs != 1 ||
|
||||
f->BindPairs[0].InIndex != 1 ||
|
||||
f->BindPairs[0].OutIndex != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
switch ((UInt32)c->MethodID)
|
||||
{
|
||||
case k_BCJ:
|
||||
case k_ARM:
|
||||
break;
|
||||
default:
|
||||
if (f->NumCoders < 1 || f->NumCoders > 4)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumCoders == 1) {
|
||||
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 2) {
|
||||
CSzCoderInfo *c = &f->Coders[1];
|
||||
if (c->MethodID > (UInt32)0xFFFFFFFF || c->NumInStreams != 1 ||
|
||||
c->NumOutStreams != 1 || f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
|
||||
f->NumBindPairs != 1 || f->BindPairs[0].InIndex != 1 ||
|
||||
f->BindPairs[0].OutIndex != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
switch ((UInt32)c->MethodID) {
|
||||
case k_BCJ:
|
||||
case k_ARM:
|
||||
break;
|
||||
default:
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 4) {
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[1]) || !IS_SUPPORTED_CODER(&f->Coders[2]) ||
|
||||
!IS_BCJ2(&f->Coders[3]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumPackStreams != 4 || f->PackStreams[0] != 2 || f->PackStreams[1] != 6 ||
|
||||
f->PackStreams[2] != 1 || f->PackStreams[3] != 0 || f->NumBindPairs != 3 ||
|
||||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
|
||||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
|
||||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 4)
|
||||
{
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
|
||||
!IS_SUPPORTED_CODER(&f->Coders[2]) ||
|
||||
!IS_BCJ2(&f->Coders[3]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumPackStreams != 4 ||
|
||||
f->PackStreams[0] != 2 ||
|
||||
f->PackStreams[1] != 6 ||
|
||||
f->PackStreams[2] != 1 ||
|
||||
f->PackStreams[3] != 0 ||
|
||||
f->NumBindPairs != 3 ||
|
||||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
|
||||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
|
||||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||
{
|
||||
UInt64 sum = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < index; i++)
|
||||
sum += values[i];
|
||||
return sum;
|
||||
UInt64 sum = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < index; i++)
|
||||
sum += values[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
|
||||
#define CASE_BRA_CONV(isa) \
|
||||
case k_##isa: \
|
||||
isa##_Convert(outBuffer, outSize, 0, 0); \
|
||||
break;
|
||||
|
||||
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
||||
Byte *tempBuf[])
|
||||
ILookInStream *inStream, UInt64 startPos, Byte *outBuffer,
|
||||
SizeT outSize, ISzAlloc *allocMain, Byte *tempBuf[])
|
||||
{
|
||||
UInt32 ci;
|
||||
SizeT tempSizes[3] = { 0, 0, 0};
|
||||
SizeT tempSize3 = 0;
|
||||
Byte *tempBuf3 = 0;
|
||||
UInt32 ci;
|
||||
SizeT tempSizes[3] = { 0, 0, 0 };
|
||||
SizeT tempSize3 = 0;
|
||||
Byte *tempBuf3 = 0;
|
||||
|
||||
RINOK(CheckSupportedFolder(folder));
|
||||
RINOK(CheckSupportedFolder(folder));
|
||||
|
||||
for (ci = 0; ci < folder->NumCoders; ci++)
|
||||
{
|
||||
CSzCoderInfo *coder = &folder->Coders[ci];
|
||||
for (ci = 0; ci < folder->NumCoders; ci++) {
|
||||
CSzCoderInfo *coder = &folder->Coders[ci];
|
||||
|
||||
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
|
||||
{
|
||||
UInt32 si = 0;
|
||||
UInt64 offset;
|
||||
UInt64 inSize;
|
||||
Byte *outBufCur = outBuffer;
|
||||
SizeT outSizeCur = outSize;
|
||||
if (folder->NumCoders == 4)
|
||||
{
|
||||
UInt32 indices[] = { 3, 2, 0 };
|
||||
UInt64 unpackSize = folder->UnpackSizes[ci];
|
||||
si = indices[ci];
|
||||
if (ci < 2)
|
||||
{
|
||||
Byte *temp;
|
||||
outSizeCur = (SizeT)unpackSize;
|
||||
if (outSizeCur != unpackSize)
|
||||
return SZ_ERROR_MEM;
|
||||
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
||||
if (temp == 0 && outSizeCur != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
outBufCur = tempBuf[1 - ci] = temp;
|
||||
tempSizes[1 - ci] = outSizeCur;
|
||||
if (IS_MAIN_METHOD((UInt32)coder->MethodID)) {
|
||||
UInt32 si = 0;
|
||||
UInt64 offset;
|
||||
UInt64 inSize;
|
||||
Byte *outBufCur = outBuffer;
|
||||
SizeT outSizeCur = outSize;
|
||||
if (folder->NumCoders == 4) {
|
||||
UInt32 indices[] = { 3, 2, 0 };
|
||||
UInt64 unpackSize = folder->UnpackSizes[ci];
|
||||
si = indices[ci];
|
||||
if (ci < 2) {
|
||||
Byte *temp;
|
||||
outSizeCur = (SizeT)unpackSize;
|
||||
if (outSizeCur != unpackSize)
|
||||
return SZ_ERROR_MEM;
|
||||
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
||||
if (temp == 0 && outSizeCur != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
outBufCur = tempBuf[1 - ci] = temp;
|
||||
tempSizes[1 - ci] = outSizeCur;
|
||||
} else if (ci == 2) {
|
||||
if (unpackSize > outSize) /* check it */
|
||||
return SZ_ERROR_PARAM;
|
||||
tempBuf3 = outBufCur =
|
||||
outBuffer + (outSize - (size_t)unpackSize);
|
||||
tempSize3 = outSizeCur = (SizeT)unpackSize;
|
||||
} else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
offset = GetSum(packSizes, si);
|
||||
inSize = packSizes[si];
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
|
||||
if (coder->MethodID == k_Copy) {
|
||||
if (inSize != outSizeCur) /* check it */
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
||||
} else if (coder->MethodID == k_LZMA) {
|
||||
RINOK(SzDecodeLzma(coder,
|
||||
inSize,
|
||||
inStream,
|
||||
outBufCur,
|
||||
outSizeCur,
|
||||
allocMain));
|
||||
} else if (coder->MethodID == k_LZMA2) {
|
||||
RINOK(SzDecodeLzma2(coder,
|
||||
inSize,
|
||||
inStream,
|
||||
outBufCur,
|
||||
outSizeCur,
|
||||
allocMain));
|
||||
} else {
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
RINOK(SzDecodePpmd(coder,
|
||||
inSize,
|
||||
inStream,
|
||||
outBufCur,
|
||||
outSizeCur,
|
||||
allocMain));
|
||||
#else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
#endif
|
||||
}
|
||||
} else if (coder->MethodID == k_BCJ2) {
|
||||
UInt64 offset = GetSum(packSizes, 1);
|
||||
UInt64 s3Size = packSizes[1];
|
||||
SRes res;
|
||||
if (ci != 3)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
tempSizes[2] = (SizeT)s3Size;
|
||||
if (tempSizes[2] != s3Size)
|
||||
return SZ_ERROR_MEM;
|
||||
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
|
||||
if (tempBuf[2] == 0 && tempSizes[2] != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
||||
RINOK(res)
|
||||
|
||||
res = Bcj2_Decode(tempBuf3,
|
||||
tempSize3,
|
||||
tempBuf[0],
|
||||
tempSizes[0],
|
||||
tempBuf[1],
|
||||
tempSizes[1],
|
||||
tempBuf[2],
|
||||
tempSizes[2],
|
||||
outBuffer,
|
||||
outSize);
|
||||
RINOK(res)
|
||||
} else {
|
||||
if (ci != 1)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
switch (coder->MethodID) {
|
||||
case k_BCJ: {
|
||||
UInt32 state;
|
||||
x86_Convert_Init(state);
|
||||
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||
break;
|
||||
}
|
||||
CASE_BRA_CONV(ARM)
|
||||
default:
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ci == 2)
|
||||
{
|
||||
if (unpackSize > outSize) /* check it */
|
||||
return SZ_ERROR_PARAM;
|
||||
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
|
||||
tempSize3 = outSizeCur = (SizeT)unpackSize;
|
||||
}
|
||||
else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
offset = GetSum(packSizes, si);
|
||||
inSize = packSizes[si];
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
|
||||
if (coder->MethodID == k_Copy)
|
||||
{
|
||||
if (inSize != outSizeCur) /* check it */
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
||||
}
|
||||
else if (coder->MethodID == k_LZMA)
|
||||
{
|
||||
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
}
|
||||
else if (coder->MethodID == k_LZMA2)
|
||||
{
|
||||
RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
#else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ2)
|
||||
{
|
||||
UInt64 offset = GetSum(packSizes, 1);
|
||||
UInt64 s3Size = packSizes[1];
|
||||
SRes res;
|
||||
if (ci != 3)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
tempSizes[2] = (SizeT)s3Size;
|
||||
if (tempSizes[2] != s3Size)
|
||||
return SZ_ERROR_MEM;
|
||||
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
|
||||
if (tempBuf[2] == 0 && tempSizes[2] != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
||||
RINOK(res)
|
||||
|
||||
res = Bcj2_Decode(
|
||||
tempBuf3, tempSize3,
|
||||
tempBuf[0], tempSizes[0],
|
||||
tempBuf[1], tempSizes[1],
|
||||
tempBuf[2], tempSizes[2],
|
||||
outBuffer, outSize);
|
||||
RINOK(res)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ci != 1)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
switch(coder->MethodID)
|
||||
{
|
||||
case k_BCJ:
|
||||
{
|
||||
UInt32 state;
|
||||
x86_Convert_Init(state);
|
||||
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||
break;
|
||||
}
|
||||
CASE_BRA_CONV(ARM)
|
||||
default:
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SZ_OK;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes, ILookInStream *inStream,
|
||||
UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
Byte *tempBuf[3] = { 0, 0, 0};
|
||||
int i;
|
||||
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
|
||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||
for (i = 0; i < 3; i++)
|
||||
IAlloc_Free(allocMain, tempBuf[i]);
|
||||
return res;
|
||||
Byte *tempBuf[3] = { 0, 0, 0 };
|
||||
int i;
|
||||
SRes res = SzFolder_Decode2(folder,
|
||||
packSizes,
|
||||
inStream,
|
||||
startPos,
|
||||
outBuffer,
|
||||
(SizeT)outSize,
|
||||
allocMain,
|
||||
tempBuf);
|
||||
for (i = 0; i < 3; i++)
|
||||
IAlloc_Free(allocMain, tempBuf[i]);
|
||||
return res;
|
||||
}
|
||||
|
|
2226
fex/7z_C/7zIn.c
2226
fex/7z_C/7zIn.c
File diff suppressed because it is too large
Load Diff
|
@ -7,163 +7,157 @@
|
|||
|
||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
||||
{
|
||||
while (size != 0)
|
||||
{
|
||||
size_t processed = size;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
if (processed == 0)
|
||||
return errorType;
|
||||
buf = (void *)((Byte *)buf + processed);
|
||||
size -= processed;
|
||||
}
|
||||
return SZ_OK;
|
||||
while (size != 0) {
|
||||
size_t processed = size;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
if (processed == 0)
|
||||
return errorType;
|
||||
buf = (void *)((Byte *)buf + processed);
|
||||
size -= processed;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
|
||||
{
|
||||
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
}
|
||||
|
||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
|
||||
{
|
||||
size_t processed = 1;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
||||
size_t processed = 1;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
||||
}
|
||||
|
||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
||||
{
|
||||
Int64 t = offset;
|
||||
return stream->Seek(stream, &t, SZ_SEEK_SET);
|
||||
Int64 t = offset;
|
||||
return stream->Seek(stream, &t, SZ_SEEK_SET);
|
||||
}
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
|
||||
{
|
||||
const void *lookBuf;
|
||||
if (*size == 0)
|
||||
return SZ_OK;
|
||||
RINOK(stream->Look(stream, &lookBuf, size));
|
||||
memcpy(buf, lookBuf, *size);
|
||||
return stream->Skip(stream, *size);
|
||||
const void *lookBuf;
|
||||
if (*size == 0)
|
||||
return SZ_OK;
|
||||
RINOK(stream->Look(stream, &lookBuf, size));
|
||||
memcpy(buf, lookBuf, *size);
|
||||
return stream->Skip(stream, *size);
|
||||
}
|
||||
|
||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
||||
{
|
||||
while (size != 0)
|
||||
{
|
||||
size_t processed = size;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
if (processed == 0)
|
||||
return errorType;
|
||||
buf = (void *)((Byte *)buf + processed);
|
||||
size -= processed;
|
||||
}
|
||||
return SZ_OK;
|
||||
while (size != 0) {
|
||||
size_t processed = size;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
if (processed == 0)
|
||||
return errorType;
|
||||
buf = (void *)((Byte *)buf + processed);
|
||||
size -= processed;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
|
||||
{
|
||||
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
}
|
||||
|
||||
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size > 0)
|
||||
{
|
||||
p->pos = 0;
|
||||
size2 = LookToRead_BUF_SIZE;
|
||||
res = p->realStream->Read(p->realStream, p->buf, &size2);
|
||||
p->size = size2;
|
||||
}
|
||||
if (size2 < *size)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
return res;
|
||||
SRes res = SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size > 0) {
|
||||
p->pos = 0;
|
||||
size2 = LookToRead_BUF_SIZE;
|
||||
res = p->realStream->Read(p->realStream, p->buf, &size2);
|
||||
p->size = size2;
|
||||
}
|
||||
if (size2 < *size)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size > 0)
|
||||
{
|
||||
p->pos = 0;
|
||||
if (*size > LookToRead_BUF_SIZE)
|
||||
*size = LookToRead_BUF_SIZE;
|
||||
res = p->realStream->Read(p->realStream, p->buf, size);
|
||||
size2 = p->size = *size;
|
||||
}
|
||||
if (size2 < *size)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
return res;
|
||||
SRes res = SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size > 0) {
|
||||
p->pos = 0;
|
||||
if (*size > LookToRead_BUF_SIZE)
|
||||
*size = LookToRead_BUF_SIZE;
|
||||
res = p->realStream->Read(p->realStream, p->buf, size);
|
||||
size2 = p->size = *size;
|
||||
}
|
||||
if (size2 < *size)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Skip(void *pp, size_t offset)
|
||||
{
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
p->pos += offset;
|
||||
return SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
p->pos += offset;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t rem = p->size - p->pos;
|
||||
if (rem == 0)
|
||||
return p->realStream->Read(p->realStream, buf, size);
|
||||
if (rem > *size)
|
||||
rem = *size;
|
||||
memcpy(buf, p->buf + p->pos, rem);
|
||||
p->pos += rem;
|
||||
*size = rem;
|
||||
return SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t rem = p->size - p->pos;
|
||||
if (rem == 0)
|
||||
return p->realStream->Read(p->realStream, buf, size);
|
||||
if (rem > *size)
|
||||
rem = *size;
|
||||
memcpy(buf, p->buf + p->pos, rem);
|
||||
p->pos += rem;
|
||||
*size = rem;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
p->pos = p->size = 0;
|
||||
return p->realStream->Seek(p->realStream, pos, origin);
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
p->pos = p->size = 0;
|
||||
return p->realStream->Seek(p->realStream, pos, origin);
|
||||
}
|
||||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
|
||||
{
|
||||
p->s.Look = lookahead ?
|
||||
LookToRead_Look_Lookahead :
|
||||
LookToRead_Look_Exact;
|
||||
p->s.Skip = LookToRead_Skip;
|
||||
p->s.Read = LookToRead_Read;
|
||||
p->s.Seek = LookToRead_Seek;
|
||||
p->s.Look = lookahead ? LookToRead_Look_Lookahead : LookToRead_Look_Exact;
|
||||
p->s.Skip = LookToRead_Skip;
|
||||
p->s.Read = LookToRead_Read;
|
||||
p->s.Seek = LookToRead_Seek;
|
||||
}
|
||||
|
||||
void LookToRead_Init(CLookToRead *p)
|
||||
{
|
||||
p->pos = p->size = 0;
|
||||
p->pos = p->size = 0;
|
||||
}
|
||||
|
||||
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CSecToLook *p = (CSecToLook *)pp;
|
||||
return LookInStream_LookRead(p->realStream, buf, size);
|
||||
CSecToLook *p = (CSecToLook *)pp;
|
||||
return LookInStream_LookRead(p->realStream, buf, size);
|
||||
}
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p)
|
||||
{
|
||||
p->s.Read = SecToLook_Read;
|
||||
p->s.Read = SecToLook_Read;
|
||||
}
|
||||
|
||||
static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CSecToRead *p = (CSecToRead *)pp;
|
||||
return p->realStream->Read(p->realStream, buf, size);
|
||||
CSecToRead *p = (CSecToRead *)pp;
|
||||
return p->realStream->Read(p->realStream, buf, size);
|
||||
}
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p)
|
||||
{
|
||||
p->s.Read = SecToRead_Read;
|
||||
p->s.Read = SecToRead_Read;
|
||||
}
|
||||
|
|
211
fex/7z_C/Bcj2.c
211
fex/7z_C/Bcj2.c
|
@ -9,7 +9,7 @@
|
|||
#define CProb UInt16
|
||||
#endif
|
||||
|
||||
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
|
||||
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1)&0xF0) == 0x80)
|
||||
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
|
||||
|
||||
#define kNumTopBits 24
|
||||
|
@ -20,113 +20,132 @@
|
|||
#define kNumMoveBits 5
|
||||
|
||||
#define RC_READ_BYTE (*buffer++)
|
||||
#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
|
||||
#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
|
||||
{ int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
|
||||
#define RC_TEST \
|
||||
{ \
|
||||
if (buffer == bufferLim) \
|
||||
return SZ_ERROR_DATA; \
|
||||
}
|
||||
#define RC_INIT2 \
|
||||
code = 0; \
|
||||
range = 0xFFFFFFFF; \
|
||||
{ \
|
||||
int i; \
|
||||
for (i = 0; i < 5; i++) { \
|
||||
RC_TEST; \
|
||||
code = (code << 8) | RC_READ_BYTE; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
|
||||
#define NORMALIZE \
|
||||
if (range < kTopValue) { \
|
||||
RC_TEST; \
|
||||
range <<= 8; \
|
||||
code = (code << 8) | RC_READ_BYTE; \
|
||||
}
|
||||
|
||||
#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||
#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
|
||||
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
|
||||
#define IF_BIT_0(p) \
|
||||
ttt = *(p); \
|
||||
bound = (range >> kNumBitModelTotalBits) * ttt; \
|
||||
if (code < bound)
|
||||
#define UPDATE_0(p) \
|
||||
range = bound; \
|
||||
*(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); \
|
||||
NORMALIZE;
|
||||
#define UPDATE_1(p) \
|
||||
range -= bound; \
|
||||
code -= bound; \
|
||||
*(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); \
|
||||
NORMALIZE;
|
||||
|
||||
int Bcj2_Decode(
|
||||
const Byte *buf0, SizeT size0,
|
||||
const Byte *buf1, SizeT size1,
|
||||
const Byte *buf2, SizeT size2,
|
||||
const Byte *buf3, SizeT size3,
|
||||
Byte *outBuf, SizeT outSize)
|
||||
int Bcj2_Decode(const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, const Byte *buf2,
|
||||
SizeT size2, const Byte *buf3, SizeT size3, Byte *outBuf, SizeT outSize)
|
||||
{
|
||||
CProb p[256 + 2];
|
||||
SizeT inPos = 0, outPos = 0;
|
||||
CProb p[256 + 2];
|
||||
SizeT inPos = 0, outPos = 0;
|
||||
|
||||
const Byte *buffer, *bufferLim;
|
||||
UInt32 range, code;
|
||||
Byte prevByte = 0;
|
||||
const Byte *buffer, *bufferLim;
|
||||
UInt32 range, code;
|
||||
Byte prevByte = 0;
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
||||
p[i] = kBitModelTotal >> 1;
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
||||
p[i] = kBitModelTotal >> 1;
|
||||
|
||||
buffer = buf3;
|
||||
bufferLim = buffer + size3;
|
||||
RC_INIT2
|
||||
buffer = buf3;
|
||||
bufferLim = buffer + size3;
|
||||
RC_INIT2
|
||||
|
||||
if (outSize == 0)
|
||||
return SZ_OK;
|
||||
if (outSize == 0)
|
||||
return SZ_OK;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte b;
|
||||
CProb *prob;
|
||||
UInt32 bound;
|
||||
UInt32 ttt;
|
||||
for (;;) {
|
||||
Byte b;
|
||||
CProb *prob;
|
||||
UInt32 bound;
|
||||
UInt32 ttt;
|
||||
|
||||
SizeT limit = size0 - inPos;
|
||||
if (outSize - outPos < limit)
|
||||
limit = outSize - outPos;
|
||||
while (limit != 0)
|
||||
{
|
||||
Byte b = buf0[inPos];
|
||||
outBuf[outPos++] = b;
|
||||
if (IsJ(prevByte, b))
|
||||
break;
|
||||
inPos++;
|
||||
prevByte = b;
|
||||
limit--;
|
||||
}
|
||||
SizeT limit = size0 - inPos;
|
||||
if (outSize - outPos < limit)
|
||||
limit = outSize - outPos;
|
||||
while (limit != 0) {
|
||||
Byte b = buf0[inPos];
|
||||
outBuf[outPos++] = b;
|
||||
if (IsJ(prevByte, b))
|
||||
break;
|
||||
inPos++;
|
||||
prevByte = b;
|
||||
limit--;
|
||||
}
|
||||
|
||||
if (limit == 0 || outPos == outSize)
|
||||
break;
|
||||
if (limit == 0 || outPos == outSize)
|
||||
break;
|
||||
|
||||
b = buf0[inPos++];
|
||||
b = buf0[inPos++];
|
||||
|
||||
if (b == 0xE8)
|
||||
prob = p + prevByte;
|
||||
else if (b == 0xE9)
|
||||
prob = p + 256;
|
||||
else
|
||||
prob = p + 257;
|
||||
if (b == 0xE8)
|
||||
prob = p + prevByte;
|
||||
else if (b == 0xE9)
|
||||
prob = p + 256;
|
||||
else
|
||||
prob = p + 257;
|
||||
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob)
|
||||
prevByte = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 dest;
|
||||
const Byte *v;
|
||||
UPDATE_1(prob)
|
||||
if (b == 0xE8)
|
||||
{
|
||||
v = buf1;
|
||||
if (size1 < 4)
|
||||
return SZ_ERROR_DATA;
|
||||
buf1 += 4;
|
||||
size1 -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = buf2;
|
||||
if (size2 < 4)
|
||||
return SZ_ERROR_DATA;
|
||||
buf2 += 4;
|
||||
size2 -= 4;
|
||||
}
|
||||
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
|
||||
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
|
||||
outBuf[outPos++] = (Byte)dest;
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = (Byte)(dest >> 8);
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = (Byte)(dest >> 16);
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
|
||||
}
|
||||
}
|
||||
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob)
|
||||
prevByte = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 dest;
|
||||
const Byte *v;
|
||||
UPDATE_1(prob)
|
||||
if (b == 0xE8) {
|
||||
v = buf1;
|
||||
if (size1 < 4)
|
||||
return SZ_ERROR_DATA;
|
||||
buf1 += 4;
|
||||
size1 -= 4;
|
||||
} else {
|
||||
v = buf2;
|
||||
if (size2 < 4)
|
||||
return SZ_ERROR_DATA;
|
||||
buf2 += 4;
|
||||
size2 -= 4;
|
||||
}
|
||||
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | ((UInt32)v[2] << 8) |
|
||||
((UInt32)v[3])) -
|
||||
((UInt32)outPos + 4);
|
||||
outBuf[outPos++] = (Byte)dest;
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = (Byte)(dest >> 8);
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = (Byte)(dest >> 16);
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
|
||||
}
|
||||
}
|
||||
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
|
||||
}
|
||||
|
|
|
@ -24,12 +24,8 @@ Returns:
|
|||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
int Bcj2_Decode(
|
||||
const Byte *buf0, SizeT size0,
|
||||
const Byte *buf1, SizeT size1,
|
||||
const Byte *buf2, SizeT size2,
|
||||
const Byte *buf3, SizeT size3,
|
||||
Byte *outBuf, SizeT outSize);
|
||||
int Bcj2_Decode(const Byte *buf0, SizeT size0, const Byte *buf1, SizeT size1, const Byte *buf2,
|
||||
SizeT size2, const Byte *buf3, SizeT size3, Byte *outBuf, SizeT outSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
211
fex/7z_C/Bra.c
211
fex/7z_C/Bra.c
|
@ -5,129 +5,116 @@
|
|||
|
||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 8;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0xEB)
|
||||
{
|
||||
UInt32 dest;
|
||||
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 2;
|
||||
data[i + 2] = (Byte)(dest >> 16);
|
||||
data[i + 1] = (Byte)(dest >> 8);
|
||||
data[i + 0] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 8;
|
||||
for (i = 0; i <= size; i += 4) {
|
||||
if (data[i + 3] == 0xEB) {
|
||||
UInt32 dest;
|
||||
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) |
|
||||
(data[i + 0]);
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 2;
|
||||
data[i + 2] = (Byte)(dest >> 16);
|
||||
data[i + 1] = (Byte)(dest >> 8);
|
||||
data[i + 0] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 4;
|
||||
for (i = 0; i <= size; i += 2)
|
||||
{
|
||||
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
||||
(data[i + 3] & 0xF8) == 0xF8)
|
||||
{
|
||||
UInt32 dest;
|
||||
UInt32 src =
|
||||
(((UInt32)data[i + 1] & 0x7) << 19) |
|
||||
((UInt32)data[i + 0] << 11) |
|
||||
(((UInt32)data[i + 3] & 0x7) << 8) |
|
||||
(data[i + 2]);
|
||||
|
||||
src <<= 1;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 1;
|
||||
|
||||
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
|
||||
data[i + 0] = (Byte)(dest >> 11);
|
||||
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
|
||||
data[i + 2] = (Byte)dest;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 4;
|
||||
for (i = 0; i <= size; i += 2) {
|
||||
if ((data[i + 1] & 0xF8) == 0xF0 && (data[i + 3] & 0xF8) == 0xF8) {
|
||||
UInt32 dest;
|
||||
UInt32 src = (((UInt32)data[i + 1] & 0x7) << 19) |
|
||||
((UInt32)data[i + 0] << 11) |
|
||||
(((UInt32)data[i + 3] & 0x7) << 8) | (data[i + 2]);
|
||||
|
||||
src <<= 1;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 1;
|
||||
|
||||
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
|
||||
data[i + 0] = (Byte)(dest >> 11);
|
||||
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
|
||||
data[i + 2] = (Byte)dest;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
|
||||
{
|
||||
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3] & (~3));
|
||||
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] &= 0x3;
|
||||
data[i + 3] |= dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4) {
|
||||
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) {
|
||||
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
|
||||
((UInt32)data[i + 1] << 16) | ((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3] & (~3));
|
||||
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] &= 0x3;
|
||||
data[i + 3] |= dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
UInt32 i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
|
||||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
|
||||
{
|
||||
UInt32 src =
|
||||
((UInt32)data[i + 0] << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3]);
|
||||
UInt32 dest;
|
||||
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + i + src;
|
||||
else
|
||||
dest = src - (ip + i);
|
||||
dest >>= 2;
|
||||
|
||||
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
|
||||
UInt32 i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4) {
|
||||
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
|
||||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) {
|
||||
UInt32 src = ((UInt32)data[i + 0] << 24) | ((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) | ((UInt32)data[i + 3]);
|
||||
UInt32 dest;
|
||||
|
||||
data[i + 0] = (Byte)(dest >> 24);
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + i + src;
|
||||
else
|
||||
dest = src - (ip + i);
|
||||
dest >>= 2;
|
||||
|
||||
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) |
|
||||
0x40000000;
|
||||
|
||||
data[i + 0] = (Byte)(dest >> 24);
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -13,23 +13,23 @@ extern "C" {
|
|||
/*
|
||||
These functions convert relative addresses to absolute addresses
|
||||
in CALL instructions to increase the compression ratio.
|
||||
|
||||
|
||||
In:
|
||||
data - data buffer
|
||||
size - size of data
|
||||
ip - current virtual Instruction Pinter (IP) value
|
||||
state - state variable for x86 converter
|
||||
encoding - 0 (for decoding), 1 (for encoding)
|
||||
|
||||
|
||||
Out:
|
||||
state - state variable for x86 converter
|
||||
|
||||
Returns:
|
||||
The number of processed bytes. If you call these functions with multiple calls,
|
||||
you must start next call with first byte after block of processed bytes.
|
||||
|
||||
|
||||
Type Endian Alignment LookAhead
|
||||
|
||||
|
||||
x86 little 1 4
|
||||
ARMT little 2 2
|
||||
ARM little 4 0
|
||||
|
@ -53,7 +53,10 @@ in CALL instructions to increase the compression ratio.
|
|||
}
|
||||
*/
|
||||
|
||||
#define x86_Convert_Init(state) { state = 0; }
|
||||
#define x86_Convert_Init(state) \
|
||||
{ \
|
||||
state = 0; \
|
||||
}
|
||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
|
||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
|
|
137
fex/7z_C/Bra86.c
137
fex/7z_C/Bra86.c
|
@ -5,81 +5,74 @@
|
|||
|
||||
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
|
||||
|
||||
const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
||||
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||
const Byte kMaskToAllowedStatus[8] = { 1, 1, 1, 0, 1, 0, 0, 0 };
|
||||
const Byte kMaskToBitNumber[8] = { 0, 1, 2, 2, 3, 3, 3, 3 };
|
||||
|
||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
||||
{
|
||||
SizeT bufferPos = 0, prevPosT;
|
||||
UInt32 prevMask = *state & 0x7;
|
||||
if (size < 5)
|
||||
return 0;
|
||||
ip += 5;
|
||||
prevPosT = (SizeT)0 - 1;
|
||||
SizeT bufferPos = 0, prevPosT;
|
||||
UInt32 prevMask = *state & 0x7;
|
||||
if (size < 5)
|
||||
return 0;
|
||||
ip += 5;
|
||||
prevPosT = (SizeT)0 - 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *p = data + bufferPos;
|
||||
Byte *limit = data + size - 4;
|
||||
for (; p < limit; p++)
|
||||
if ((*p & 0xFE) == 0xE8)
|
||||
break;
|
||||
bufferPos = (SizeT)(p - data);
|
||||
if (p >= limit)
|
||||
break;
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
if (prevPosT > 3)
|
||||
prevMask = 0;
|
||||
else
|
||||
{
|
||||
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
|
||||
if (prevMask != 0)
|
||||
{
|
||||
Byte b = p[4 - kMaskToBitNumber[prevMask]];
|
||||
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
|
||||
{
|
||||
prevPosT = bufferPos;
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
continue;
|
||||
for (;;) {
|
||||
Byte *p = data + bufferPos;
|
||||
Byte *limit = data + size - 4;
|
||||
for (; p < limit; p++)
|
||||
if ((*p & 0xFE) == 0xE8)
|
||||
break;
|
||||
bufferPos = (SizeT)(p - data);
|
||||
if (p >= limit)
|
||||
break;
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
if (prevPosT > 3)
|
||||
prevMask = 0;
|
||||
else {
|
||||
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
|
||||
if (prevMask != 0) {
|
||||
Byte b = p[4 - kMaskToBitNumber[prevMask]];
|
||||
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) {
|
||||
prevPosT = bufferPos;
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
prevPosT = bufferPos;
|
||||
|
||||
if (Test86MSByte(p[4])) {
|
||||
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) |
|
||||
((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||
UInt32 dest;
|
||||
for (;;) {
|
||||
Byte b;
|
||||
int index;
|
||||
if (encoding)
|
||||
dest = (ip + (UInt32)bufferPos) + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)bufferPos);
|
||||
if (prevMask == 0)
|
||||
break;
|
||||
index = kMaskToBitNumber[prevMask] * 8;
|
||||
b = (Byte)(dest >> (24 - index));
|
||||
if (!Test86MSByte(b))
|
||||
break;
|
||||
src = dest ^ ((1 << (32 - index)) - 1);
|
||||
}
|
||||
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
||||
p[3] = (Byte)(dest >> 16);
|
||||
p[2] = (Byte)(dest >> 8);
|
||||
p[1] = (Byte)dest;
|
||||
bufferPos += 5;
|
||||
} else {
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prevPosT = bufferPos;
|
||||
|
||||
if (Test86MSByte(p[4]))
|
||||
{
|
||||
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||
UInt32 dest;
|
||||
for (;;)
|
||||
{
|
||||
Byte b;
|
||||
int index;
|
||||
if (encoding)
|
||||
dest = (ip + (UInt32)bufferPos) + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)bufferPos);
|
||||
if (prevMask == 0)
|
||||
break;
|
||||
index = kMaskToBitNumber[prevMask] * 8;
|
||||
b = (Byte)(dest >> (24 - index));
|
||||
if (!Test86MSByte(b))
|
||||
break;
|
||||
src = dest ^ ((1 << (32 - index)) - 1);
|
||||
}
|
||||
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
||||
p[3] = (Byte)(dest >> 16);
|
||||
p[2] = (Byte)(dest >> 8);
|
||||
p[1] = (Byte)dest;
|
||||
bufferPos += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
}
|
||||
}
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
|
||||
return bufferPos;
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
|
||||
return bufferPos;
|
||||
}
|
||||
|
|
|
@ -12,162 +12,157 @@
|
|||
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
|
||||
static UInt32 CheckFlag(UInt32 flag)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
__asm pushfd;
|
||||
__asm pop EAX;
|
||||
__asm mov EDX, EAX;
|
||||
__asm xor EAX, flag;
|
||||
__asm push EAX;
|
||||
__asm popfd;
|
||||
__asm pushfd;
|
||||
__asm pop EAX;
|
||||
__asm xor EAX, EDX;
|
||||
__asm push EDX;
|
||||
__asm popfd;
|
||||
__asm and flag, EAX;
|
||||
#else
|
||||
__asm__ __volatile__ (
|
||||
"pushf\n\t"
|
||||
"pop %%EAX\n\t"
|
||||
"movl %%EAX,%%EDX\n\t"
|
||||
"xorl %0,%%EAX\n\t"
|
||||
"push %%EAX\n\t"
|
||||
"popf\n\t"
|
||||
"pushf\n\t"
|
||||
"pop %%EAX\n\t"
|
||||
"xorl %%EDX,%%EAX\n\t"
|
||||
"push %%EDX\n\t"
|
||||
"popf\n\t"
|
||||
"andl %%EAX, %0\n\t":
|
||||
"=c" (flag) : "c" (flag));
|
||||
#endif
|
||||
return flag;
|
||||
#ifdef _MSC_VER
|
||||
__asm pushfd;
|
||||
__asm pop EAX;
|
||||
__asm mov EDX, EAX;
|
||||
__asm xor EAX, flag;
|
||||
__asm push EAX;
|
||||
__asm popfd;
|
||||
__asm pushfd;
|
||||
__asm pop EAX;
|
||||
__asm xor EAX, EDX;
|
||||
__asm push EDX;
|
||||
__asm popfd;
|
||||
__asm and flag, EAX;
|
||||
#else
|
||||
__asm__ __volatile__(
|
||||
"pushf\n\t"
|
||||
"pop %%EAX\n\t"
|
||||
"movl %%EAX,%%EDX\n\t"
|
||||
"xorl %0,%%EAX\n\t"
|
||||
"push %%EAX\n\t"
|
||||
"popf\n\t"
|
||||
"pushf\n\t"
|
||||
"pop %%EAX\n\t"
|
||||
"xorl %%EDX,%%EAX\n\t"
|
||||
"push %%EDX\n\t"
|
||||
"popf\n\t"
|
||||
"andl %%EAX, %0\n\t"
|
||||
: "=c"(flag)
|
||||
: "c"(flag));
|
||||
#endif
|
||||
return flag;
|
||||
}
|
||||
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
|
||||
#define CHECK_CPUID_IS_SUPPORTED \
|
||||
if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) \
|
||||
return False;
|
||||
#else
|
||||
#define CHECK_CPUID_IS_SUPPORTED
|
||||
#endif
|
||||
|
||||
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
||||
{
|
||||
#ifdef USE_ASM
|
||||
#ifdef USE_ASM
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
|
||||
UInt32 a2, b2, c2, d2;
|
||||
__asm xor EBX, EBX;
|
||||
__asm xor ECX, ECX;
|
||||
__asm xor EDX, EDX;
|
||||
__asm mov EAX, function;
|
||||
__asm cpuid;
|
||||
__asm mov a2, EAX;
|
||||
__asm mov b2, EBX;
|
||||
__asm mov c2, ECX;
|
||||
__asm mov d2, EDX;
|
||||
UInt32 a2, b2, c2, d2;
|
||||
__asm xor EBX, EBX;
|
||||
__asm xor ECX, ECX;
|
||||
__asm xor EDX, EDX;
|
||||
__asm mov EAX, function;
|
||||
__asm cpuid;
|
||||
__asm mov a2, EAX;
|
||||
__asm mov b2, EBX;
|
||||
__asm mov c2, ECX;
|
||||
__asm mov d2, EDX;
|
||||
|
||||
*a = a2;
|
||||
*b = b2;
|
||||
*c = c2;
|
||||
*d = d2;
|
||||
*a = a2;
|
||||
*b = b2;
|
||||
*c = c2;
|
||||
*d = d2;
|
||||
|
||||
#else
|
||||
#else
|
||||
|
||||
// Mac cross-compile compiler:
|
||||
// can't find register in class 'BREG' while reloading 'asm'
|
||||
// so use class 'r' register var binding
|
||||
register _b asm("%bx");
|
||||
__asm__ __volatile__ (
|
||||
"cpuid"
|
||||
: "=a" (*a) ,
|
||||
"=r" (_b) ,
|
||||
"=c" (*c) ,
|
||||
"=d" (*d)
|
||||
: "0" (function)) ;
|
||||
*b = _b;
|
||||
// Mac cross-compile compiler:
|
||||
// can't find register in class 'BREG' while reloading 'asm'
|
||||
// so use class 'r' register var binding
|
||||
register _b asm("%bx");
|
||||
__asm__ __volatile__("cpuid" : "=a"(*a), "=r"(_b), "=c"(*c), "=d"(*d) : "0"(function));
|
||||
*b = _b;
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#endif
|
||||
|
||||
int CPUInfo[4];
|
||||
__cpuid(CPUInfo, function);
|
||||
*a = CPUInfo[0];
|
||||
*b = CPUInfo[1];
|
||||
*c = CPUInfo[2];
|
||||
*d = CPUInfo[3];
|
||||
#else
|
||||
|
||||
#endif
|
||||
int CPUInfo[4];
|
||||
__cpuid(CPUInfo, function);
|
||||
*a = CPUInfo[0];
|
||||
*b = CPUInfo[1];
|
||||
*c = CPUInfo[2];
|
||||
*d = CPUInfo[3];
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
|
||||
{
|
||||
CHECK_CPUID_IS_SUPPORTED
|
||||
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
|
||||
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
|
||||
return True;
|
||||
CHECK_CPUID_IS_SUPPORTED
|
||||
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
|
||||
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
|
||||
return True;
|
||||
}
|
||||
|
||||
static UInt32 kVendors[][3] =
|
||||
{
|
||||
{ 0x756E6547, 0x49656E69, 0x6C65746E},
|
||||
{ 0x68747541, 0x69746E65, 0x444D4163},
|
||||
{ 0x746E6543, 0x48727561, 0x736C7561}
|
||||
};
|
||||
static UInt32 kVendors[][3] = { { 0x756E6547, 0x49656E69, 0x6C65746E },
|
||||
{ 0x68747541, 0x69746E65, 0x444D4163 },
|
||||
{ 0x746E6543, 0x48727561, 0x736C7561 } };
|
||||
|
||||
int x86cpuid_GetFirm(const Cx86cpuid *p)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
|
||||
{
|
||||
const UInt32 *v = kVendors[i];
|
||||
if (v[0] == p->vendor[0] &&
|
||||
v[1] == p->vendor[1] &&
|
||||
v[2] == p->vendor[2])
|
||||
return (int)i;
|
||||
}
|
||||
return -1;
|
||||
unsigned i;
|
||||
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) {
|
||||
const UInt32 *v = kVendors[i];
|
||||
if (v[0] == p->vendor[0] && v[1] == p->vendor[1] && v[2] == p->vendor[2])
|
||||
return (int)i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Bool CPU_Is_InOrder()
|
||||
{
|
||||
Cx86cpuid p;
|
||||
int firm;
|
||||
UInt32 family, model;
|
||||
if (!x86cpuid_CheckAndRead(&p))
|
||||
return True;
|
||||
family = x86cpuid_GetFamily(&p);
|
||||
model = x86cpuid_GetModel(&p);
|
||||
firm = x86cpuid_GetFirm(&p);
|
||||
switch (firm)
|
||||
{
|
||||
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
|
||||
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
||||
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
|
||||
}
|
||||
return True;
|
||||
Cx86cpuid p;
|
||||
int firm;
|
||||
UInt32 family, model;
|
||||
if (!x86cpuid_CheckAndRead(&p))
|
||||
return True;
|
||||
family = x86cpuid_GetFamily(&p);
|
||||
model = x86cpuid_GetModel(&p);
|
||||
firm = x86cpuid_GetFirm(&p);
|
||||
switch (firm) {
|
||||
case CPU_FIRM_INTEL:
|
||||
return (family < 6 || (family == 6 && model == 0x100C));
|
||||
case CPU_FIRM_AMD:
|
||||
return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
||||
case CPU_FIRM_VIA:
|
||||
return (family < 6 || (family == 6 && model < 0xF));
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
|
||||
static Bool CPU_Sys_Is_SSE_Supported()
|
||||
{
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (!GetVersionEx(&vi))
|
||||
return False;
|
||||
return (vi.dwMajorVersion >= 5);
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (!GetVersionEx(&vi))
|
||||
return False;
|
||||
return (vi.dwMajorVersion >= 5);
|
||||
}
|
||||
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
|
||||
#define CHECK_SYS_SSE_SUPPORT \
|
||||
if (!CPU_Sys_Is_SSE_Supported()) \
|
||||
return False;
|
||||
#else
|
||||
#define CHECK_SYS_SSE_SUPPORT
|
||||
#endif
|
||||
|
||||
Bool CPU_Is_Aes_Supported()
|
||||
{
|
||||
Cx86cpuid p;
|
||||
CHECK_SYS_SSE_SUPPORT
|
||||
if (!x86cpuid_CheckAndRead(&p))
|
||||
return False;
|
||||
return (p.c >> 25) & 1;
|
||||
Cx86cpuid p;
|
||||
CHECK_SYS_SSE_SUPPORT
|
||||
if (!x86cpuid_CheckAndRead(&p))
|
||||
return False;
|
||||
return (p.c >> 25) & 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,7 +10,8 @@ EXTERN_C_BEGIN
|
|||
|
||||
/*
|
||||
MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
||||
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
|
||||
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE
|
||||
ENDIAN).
|
||||
|
||||
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
||||
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
|
||||
|
@ -48,7 +49,8 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
|
|||
#define MY_CPU_LE_UNALIGN
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
|
||||
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || \
|
||||
defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
|
||||
#define MY_CPU_LE
|
||||
#endif
|
||||
|
||||
|
@ -73,27 +75,34 @@ Stop_Compiling_Bad_Endian
|
|||
|
||||
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
|
||||
|
||||
#define GetUi32(p) ( \
|
||||
((const Byte *)(p))[0] | \
|
||||
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[3] << 24))
|
||||
#define GetUi32(p) \
|
||||
(((const Byte *)(p))[0] | ((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 16) | ((UInt32)((const Byte *)(p))[3] << 24))
|
||||
|
||||
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||
|
||||
#define SetUi16(p, d) { UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
|
||||
#define SetUi16(p, d) \
|
||||
{ \
|
||||
UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
||||
}
|
||||
|
||||
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
||||
#define SetUi32(p, d) \
|
||||
{ \
|
||||
UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); \
|
||||
}
|
||||
|
||||
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
|
||||
SetUi32(p, (UInt32)_x64_); \
|
||||
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
|
||||
#define SetUi64(p, d) \
|
||||
{ \
|
||||
UInt64 _x64_ = (d); \
|
||||
SetUi32(p, (UInt32)_x64_); \
|
||||
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -106,11 +115,9 @@ Stop_Compiling_Bad_Endian
|
|||
|
||||
#else
|
||||
|
||||
#define GetBe32(p) ( \
|
||||
((UInt32)((const Byte *)(p))[0] << 24) | \
|
||||
((UInt32)((const Byte *)(p))[1] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 8) | \
|
||||
((const Byte *)(p))[3] )
|
||||
#define GetBe32(p) \
|
||||
(((UInt32)((const Byte *)(p))[0] << 24) | ((UInt32)((const Byte *)(p))[1] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 8) | ((const Byte *)(p))[3])
|
||||
|
||||
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||
|
||||
|
@ -118,25 +125,18 @@ Stop_Compiling_Bad_Endian
|
|||
|
||||
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
||||
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 maxFunc;
|
||||
UInt32 vendor[3];
|
||||
UInt32 ver;
|
||||
UInt32 b;
|
||||
UInt32 c;
|
||||
UInt32 d;
|
||||
typedef struct {
|
||||
UInt32 maxFunc;
|
||||
UInt32 vendor[3];
|
||||
UInt32 ver;
|
||||
UInt32 b;
|
||||
UInt32 c;
|
||||
UInt32 d;
|
||||
} Cx86cpuid;
|
||||
|
||||
enum
|
||||
{
|
||||
CPU_FIRM_INTEL,
|
||||
CPU_FIRM_AMD,
|
||||
CPU_FIRM_VIA
|
||||
};
|
||||
enum { CPU_FIRM_INTEL, CPU_FIRM_AMD, CPU_FIRM_VIA };
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||||
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
|
||||
|
||||
#define LZMA2_LCLP_MAX 4
|
||||
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
|
||||
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p)&1)) << ((p) / 2 + 11))
|
||||
|
||||
#ifdef SHOW_DEBUG_INFO
|
||||
#define PRF(x) x
|
||||
|
@ -44,313 +44,301 @@
|
|||
#define PRF(x)
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA2_STATE_CONTROL,
|
||||
LZMA2_STATE_UNPACK0,
|
||||
LZMA2_STATE_UNPACK1,
|
||||
LZMA2_STATE_PACK0,
|
||||
LZMA2_STATE_PACK1,
|
||||
LZMA2_STATE_PROP,
|
||||
LZMA2_STATE_DATA,
|
||||
LZMA2_STATE_DATA_CONT,
|
||||
LZMA2_STATE_FINISHED,
|
||||
LZMA2_STATE_ERROR
|
||||
typedef enum {
|
||||
LZMA2_STATE_CONTROL,
|
||||
LZMA2_STATE_UNPACK0,
|
||||
LZMA2_STATE_UNPACK1,
|
||||
LZMA2_STATE_PACK0,
|
||||
LZMA2_STATE_PACK1,
|
||||
LZMA2_STATE_PROP,
|
||||
LZMA2_STATE_DATA,
|
||||
LZMA2_STATE_DATA_CONT,
|
||||
LZMA2_STATE_FINISHED,
|
||||
LZMA2_STATE_ERROR
|
||||
} ELzma2State;
|
||||
|
||||
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
if (prop > 40)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
|
||||
props[0] = (Byte)LZMA2_LCLP_MAX;
|
||||
props[1] = (Byte)(dicSize);
|
||||
props[2] = (Byte)(dicSize >> 8);
|
||||
props[3] = (Byte)(dicSize >> 16);
|
||||
props[4] = (Byte)(dicSize >> 24);
|
||||
return SZ_OK;
|
||||
UInt32 dicSize;
|
||||
if (prop > 40)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
|
||||
props[0] = (Byte)LZMA2_LCLP_MAX;
|
||||
props[1] = (Byte)(dicSize);
|
||||
props[2] = (Byte)(dicSize >> 8);
|
||||
props[3] = (Byte)(dicSize >> 16);
|
||||
props[4] = (Byte)(dicSize >> 24);
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
||||
{
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||
}
|
||||
|
||||
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
||||
{
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||
}
|
||||
|
||||
void Lzma2Dec_Init(CLzma2Dec *p)
|
||||
{
|
||||
p->state = LZMA2_STATE_CONTROL;
|
||||
p->needInitDic = True;
|
||||
p->needInitState = True;
|
||||
p->needInitProp = True;
|
||||
LzmaDec_Init(&p->decoder);
|
||||
p->state = LZMA2_STATE_CONTROL;
|
||||
p->needInitDic = True;
|
||||
p->needInitState = True;
|
||||
p->needInitProp = True;
|
||||
LzmaDec_Init(&p->decoder);
|
||||
}
|
||||
|
||||
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
|
||||
{
|
||||
switch(p->state)
|
||||
{
|
||||
case LZMA2_STATE_CONTROL:
|
||||
p->control = b;
|
||||
PRF(printf("\n %4X ", p->decoder.dicPos));
|
||||
PRF(printf(" %2X", b));
|
||||
if (p->control == 0)
|
||||
return LZMA2_STATE_FINISHED;
|
||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||
{
|
||||
if ((p->control & 0x7F) > 2)
|
||||
return LZMA2_STATE_ERROR;
|
||||
p->unpackSize = 0;
|
||||
}
|
||||
else
|
||||
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
|
||||
return LZMA2_STATE_UNPACK0;
|
||||
|
||||
case LZMA2_STATE_UNPACK0:
|
||||
p->unpackSize |= (UInt32)b << 8;
|
||||
return LZMA2_STATE_UNPACK1;
|
||||
|
||||
case LZMA2_STATE_UNPACK1:
|
||||
p->unpackSize |= (UInt32)b;
|
||||
p->unpackSize++;
|
||||
PRF(printf(" %8d", p->unpackSize));
|
||||
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
|
||||
|
||||
case LZMA2_STATE_PACK0:
|
||||
p->packSize = (UInt32)b << 8;
|
||||
return LZMA2_STATE_PACK1;
|
||||
switch (p->state) {
|
||||
case LZMA2_STATE_CONTROL:
|
||||
p->control = b;
|
||||
PRF(printf("\n %4X ", p->decoder.dicPos));
|
||||
PRF(printf(" %2X", b));
|
||||
if (p->control == 0)
|
||||
return LZMA2_STATE_FINISHED;
|
||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) {
|
||||
if ((p->control & 0x7F) > 2)
|
||||
return LZMA2_STATE_ERROR;
|
||||
p->unpackSize = 0;
|
||||
} else
|
||||
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
|
||||
return LZMA2_STATE_UNPACK0;
|
||||
|
||||
case LZMA2_STATE_PACK1:
|
||||
p->packSize |= (UInt32)b;
|
||||
p->packSize++;
|
||||
PRF(printf(" %8d", p->packSize));
|
||||
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
|
||||
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
|
||||
case LZMA2_STATE_UNPACK0:
|
||||
p->unpackSize |= (UInt32)b << 8;
|
||||
return LZMA2_STATE_UNPACK1;
|
||||
|
||||
case LZMA2_STATE_PROP:
|
||||
{
|
||||
int lc, lp;
|
||||
if (b >= (9 * 5 * 5))
|
||||
case LZMA2_STATE_UNPACK1:
|
||||
p->unpackSize |= (UInt32)b;
|
||||
p->unpackSize++;
|
||||
PRF(printf(" %8d", p->unpackSize));
|
||||
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
|
||||
|
||||
case LZMA2_STATE_PACK0:
|
||||
p->packSize = (UInt32)b << 8;
|
||||
return LZMA2_STATE_PACK1;
|
||||
|
||||
case LZMA2_STATE_PACK1:
|
||||
p->packSize |= (UInt32)b;
|
||||
p->packSize++;
|
||||
PRF(printf(" %8d", p->packSize));
|
||||
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p))
|
||||
? LZMA2_STATE_PROP
|
||||
: (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
|
||||
|
||||
case LZMA2_STATE_PROP: {
|
||||
int lc, lp;
|
||||
if (b >= (9 * 5 * 5))
|
||||
return LZMA2_STATE_ERROR;
|
||||
lc = b % 9;
|
||||
b /= 9;
|
||||
p->decoder.prop.pb = b / 5;
|
||||
lp = b % 5;
|
||||
if (lc + lp > LZMA2_LCLP_MAX)
|
||||
return LZMA2_STATE_ERROR;
|
||||
p->decoder.prop.lc = lc;
|
||||
p->decoder.prop.lp = lp;
|
||||
p->needInitProp = False;
|
||||
return LZMA2_STATE_DATA;
|
||||
}
|
||||
}
|
||||
return LZMA2_STATE_ERROR;
|
||||
lc = b % 9;
|
||||
b /= 9;
|
||||
p->decoder.prop.pb = b / 5;
|
||||
lp = b % 5;
|
||||
if (lc + lp > LZMA2_LCLP_MAX)
|
||||
return LZMA2_STATE_ERROR;
|
||||
p->decoder.prop.lc = lc;
|
||||
p->decoder.prop.lp = lp;
|
||||
p->needInitProp = False;
|
||||
return LZMA2_STATE_DATA;
|
||||
}
|
||||
}
|
||||
return LZMA2_STATE_ERROR;
|
||||
}
|
||||
|
||||
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
|
||||
{
|
||||
memcpy(p->dic + p->dicPos, src, size);
|
||||
p->dicPos += size;
|
||||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
p->processedPos += (UInt32)size;
|
||||
memcpy(p->dic + p->dicPos, src, size);
|
||||
p->dicPos += size;
|
||||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
p->processedPos += (UInt32)size;
|
||||
}
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
|
||||
|
||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT inSize = *srcLen;
|
||||
*srcLen = 0;
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
SizeT inSize = *srcLen;
|
||||
*srcLen = 0;
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
|
||||
while (p->state != LZMA2_STATE_FINISHED)
|
||||
{
|
||||
SizeT dicPos = p->decoder.dicPos;
|
||||
if (p->state == LZMA2_STATE_ERROR)
|
||||
return SZ_ERROR_DATA;
|
||||
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
|
||||
{
|
||||
if (*srcLen == inSize)
|
||||
{
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
while (p->state != LZMA2_STATE_FINISHED) {
|
||||
SizeT dicPos = p->decoder.dicPos;
|
||||
if (p->state == LZMA2_STATE_ERROR)
|
||||
return SZ_ERROR_DATA;
|
||||
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) {
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) {
|
||||
if (*srcLen == inSize) {
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
(*srcLen)++;
|
||||
p->state = Lzma2Dec_UpdateState(p, *src++);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
SizeT destSizeCur = dicLimit - dicPos;
|
||||
SizeT srcSizeCur = inSize - *srcLen;
|
||||
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
|
||||
|
||||
if (p->unpackSize <= destSizeCur) {
|
||||
destSizeCur = (SizeT)p->unpackSize;
|
||||
curFinishMode = LZMA_FINISH_END;
|
||||
}
|
||||
|
||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) {
|
||||
if (*srcLen == inSize) {
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
if (p->state == LZMA2_STATE_DATA) {
|
||||
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
|
||||
if (initDic)
|
||||
p->needInitProp = p->needInitState = True;
|
||||
else if (p->needInitDic)
|
||||
return SZ_ERROR_DATA;
|
||||
p->needInitDic = False;
|
||||
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
||||
}
|
||||
|
||||
if (srcSizeCur > destSizeCur)
|
||||
srcSizeCur = destSizeCur;
|
||||
|
||||
if (srcSizeCur == 0)
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
|
||||
|
||||
src += srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
p->unpackSize -= (UInt32)srcSizeCur;
|
||||
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL
|
||||
: LZMA2_STATE_DATA_CONT;
|
||||
} else {
|
||||
SizeT outSizeProcessed;
|
||||
SRes res;
|
||||
|
||||
if (p->state == LZMA2_STATE_DATA) {
|
||||
int mode = LZMA2_GET_LZMA_MODE(p);
|
||||
Bool initDic = (mode == 3);
|
||||
Bool initState = (mode > 0);
|
||||
if ((!initDic && p->needInitDic) ||
|
||||
(!initState && p->needInitState))
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
||||
p->needInitDic = False;
|
||||
p->needInitState = False;
|
||||
p->state = LZMA2_STATE_DATA_CONT;
|
||||
}
|
||||
if (srcSizeCur > p->packSize)
|
||||
srcSizeCur = (SizeT)p->packSize;
|
||||
|
||||
res = LzmaDec_DecodeToDic(&p->decoder,
|
||||
dicPos + destSizeCur,
|
||||
src,
|
||||
&srcSizeCur,
|
||||
curFinishMode,
|
||||
status);
|
||||
|
||||
src += srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
p->packSize -= (UInt32)srcSizeCur;
|
||||
|
||||
outSizeProcessed = p->decoder.dicPos - dicPos;
|
||||
p->unpackSize -= (UInt32)outSizeProcessed;
|
||||
|
||||
RINOK(res);
|
||||
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||
return res;
|
||||
|
||||
if (srcSizeCur == 0 && outSizeProcessed == 0) {
|
||||
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
|
||||
p->unpackSize != 0 || p->packSize != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
p->state = LZMA2_STATE_CONTROL;
|
||||
}
|
||||
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
}
|
||||
}
|
||||
}
|
||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||
return SZ_OK;
|
||||
}
|
||||
(*srcLen)++;
|
||||
p->state = Lzma2Dec_UpdateState(p, *src++);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
SizeT destSizeCur = dicLimit - dicPos;
|
||||
SizeT srcSizeCur = inSize - *srcLen;
|
||||
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
|
||||
|
||||
if (p->unpackSize <= destSizeCur)
|
||||
{
|
||||
destSizeCur = (SizeT)p->unpackSize;
|
||||
curFinishMode = LZMA_FINISH_END;
|
||||
}
|
||||
}
|
||||
|
||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||
{
|
||||
if (*srcLen == inSize)
|
||||
{
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT outSize = *destLen, inSize = *srcLen;
|
||||
*srcLen = *destLen = 0;
|
||||
for (;;) {
|
||||
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
|
||||
ELzmaFinishMode curFinishMode;
|
||||
SRes res;
|
||||
if (p->decoder.dicPos == p->decoder.dicBufSize)
|
||||
p->decoder.dicPos = 0;
|
||||
dicPos = p->decoder.dicPos;
|
||||
if (outSize > p->decoder.dicBufSize - dicPos) {
|
||||
outSizeCur = p->decoder.dicBufSize;
|
||||
curFinishMode = LZMA_FINISH_ANY;
|
||||
} else {
|
||||
outSizeCur = dicPos + outSize;
|
||||
curFinishMode = finishMode;
|
||||
}
|
||||
|
||||
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||
src += srcSizeCur;
|
||||
inSize -= srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
outSizeCur = p->decoder.dicPos - dicPos;
|
||||
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
|
||||
dest += outSizeCur;
|
||||
outSize -= outSizeCur;
|
||||
*destLen += outSizeCur;
|
||||
if (res != 0)
|
||||
return res;
|
||||
if (outSizeCur == 0 || outSize == 0)
|
||||
return SZ_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->state == LZMA2_STATE_DATA)
|
||||
{
|
||||
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
|
||||
if (initDic)
|
||||
p->needInitProp = p->needInitState = True;
|
||||
else if (p->needInitDic)
|
||||
return SZ_ERROR_DATA;
|
||||
p->needInitDic = False;
|
||||
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
||||
}
|
||||
|
||||
if (srcSizeCur > destSizeCur)
|
||||
srcSizeCur = destSizeCur;
|
||||
|
||||
if (srcSizeCur == 0)
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
|
||||
|
||||
src += srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
p->unpackSize -= (UInt32)srcSizeCur;
|
||||
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
|
||||
}
|
||||
else
|
||||
{
|
||||
SizeT outSizeProcessed;
|
||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
|
||||
{
|
||||
CLzma2Dec decoder;
|
||||
SRes res;
|
||||
SizeT outSize = *destLen, inSize = *srcLen;
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
|
||||
if (p->state == LZMA2_STATE_DATA)
|
||||
{
|
||||
int mode = LZMA2_GET_LZMA_MODE(p);
|
||||
Bool initDic = (mode == 3);
|
||||
Bool initState = (mode > 0);
|
||||
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
||||
p->needInitDic = False;
|
||||
p->needInitState = False;
|
||||
p->state = LZMA2_STATE_DATA_CONT;
|
||||
}
|
||||
if (srcSizeCur > p->packSize)
|
||||
srcSizeCur = (SizeT)p->packSize;
|
||||
|
||||
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||
|
||||
src += srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
p->packSize -= (UInt32)srcSizeCur;
|
||||
Lzma2Dec_Construct(&decoder);
|
||||
|
||||
outSizeProcessed = p->decoder.dicPos - dicPos;
|
||||
p->unpackSize -= (UInt32)outSizeProcessed;
|
||||
*destLen = *srcLen = 0;
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
decoder.decoder.dic = dest;
|
||||
decoder.decoder.dicBufSize = outSize;
|
||||
|
||||
RINOK(res);
|
||||
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||
return res;
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
|
||||
|
||||
if (srcSizeCur == 0 && outSizeProcessed == 0)
|
||||
{
|
||||
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
|
||||
p->unpackSize != 0 || p->packSize != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
p->state = LZMA2_STATE_CONTROL;
|
||||
}
|
||||
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
}
|
||||
}
|
||||
}
|
||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT outSize = *destLen, inSize = *srcLen;
|
||||
*srcLen = *destLen = 0;
|
||||
for (;;)
|
||||
{
|
||||
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
|
||||
ELzmaFinishMode curFinishMode;
|
||||
SRes res;
|
||||
if (p->decoder.dicPos == p->decoder.dicBufSize)
|
||||
p->decoder.dicPos = 0;
|
||||
dicPos = p->decoder.dicPos;
|
||||
if (outSize > p->decoder.dicBufSize - dicPos)
|
||||
{
|
||||
outSizeCur = p->decoder.dicBufSize;
|
||||
curFinishMode = LZMA_FINISH_ANY;
|
||||
}
|
||||
else
|
||||
{
|
||||
outSizeCur = dicPos + outSize;
|
||||
curFinishMode = finishMode;
|
||||
}
|
||||
|
||||
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||
src += srcSizeCur;
|
||||
inSize -= srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
outSizeCur = p->decoder.dicPos - dicPos;
|
||||
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
|
||||
dest += outSizeCur;
|
||||
outSize -= outSizeCur;
|
||||
*destLen += outSizeCur;
|
||||
if (res != 0)
|
||||
return res;
|
||||
if (outSizeCur == 0 || outSize == 0)
|
||||
return SZ_OK;
|
||||
}
|
||||
}
|
||||
|
||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
|
||||
{
|
||||
CLzma2Dec decoder;
|
||||
SRes res;
|
||||
SizeT outSize = *destLen, inSize = *srcLen;
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
|
||||
Lzma2Dec_Construct(&decoder);
|
||||
|
||||
*destLen = *srcLen = 0;
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
decoder.decoder.dic = dest;
|
||||
decoder.decoder.dicBufSize = outSize;
|
||||
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
|
||||
|
||||
*srcLen = inSize;
|
||||
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
|
||||
*destLen = decoder.decoder.dicPos;
|
||||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||
res = SZ_ERROR_INPUT_EOF;
|
||||
|
||||
LzmaDec_FreeProbs(&decoder.decoder, alloc);
|
||||
return res;
|
||||
*srcLen = inSize;
|
||||
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
|
||||
*destLen = decoder.decoder.dicPos;
|
||||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||
res = SZ_ERROR_INPUT_EOF;
|
||||
|
||||
LzmaDec_FreeProbs(&decoder.decoder, alloc);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -12,16 +12,15 @@ extern "C" {
|
|||
|
||||
/* ---------- State Interface ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaDec decoder;
|
||||
UInt32 packSize;
|
||||
UInt32 unpackSize;
|
||||
int state;
|
||||
Byte control;
|
||||
Bool needInitDic;
|
||||
Bool needInitState;
|
||||
Bool needInitProp;
|
||||
typedef struct {
|
||||
CLzmaDec decoder;
|
||||
UInt32 packSize;
|
||||
UInt32 unpackSize;
|
||||
int state;
|
||||
Byte control;
|
||||
Bool needInitDic;
|
||||
Bool needInitState;
|
||||
Bool needInitProp;
|
||||
} CLzma2Dec;
|
||||
|
||||
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
|
||||
|
@ -32,7 +31,6 @@ SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
|||
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
||||
void Lzma2Dec_Init(CLzma2Dec *p);
|
||||
|
||||
|
||||
/*
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
|
||||
|
@ -48,12 +46,11 @@ Returns:
|
|||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
|
@ -74,8 +71,8 @@ Returns:
|
|||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
*/
|
||||
|
||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
|
||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Byte prop,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
1633
fex/7z_C/LzmaDec.c
1633
fex/7z_C/LzmaDec.c
File diff suppressed because it is too large
Load Diff
|
@ -20,15 +20,13 @@ extern "C" {
|
|||
#define CLzmaProb UInt16
|
||||
#endif
|
||||
|
||||
|
||||
/* ---------- LZMA Properties ---------- */
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaProps
|
||||
{
|
||||
unsigned lc, lp, pb;
|
||||
UInt32 dicSize;
|
||||
typedef struct _CLzmaProps {
|
||||
unsigned lc, lp, pb;
|
||||
UInt32 dicSize;
|
||||
} CLzmaProps;
|
||||
|
||||
/* LzmaProps_Decode - decodes properties
|
||||
|
@ -39,7 +37,6 @@ Returns:
|
|||
|
||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||
|
||||
|
||||
/* ---------- LZMA Decoder state ---------- */
|
||||
|
||||
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||
|
@ -47,28 +44,31 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
|||
|
||||
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaProps prop;
|
||||
CLzmaProb *probs;
|
||||
Byte *dic;
|
||||
const Byte *buf;
|
||||
UInt32 range, code;
|
||||
SizeT dicPos;
|
||||
SizeT dicBufSize;
|
||||
UInt32 processedPos;
|
||||
UInt32 checkDicSize;
|
||||
unsigned state;
|
||||
UInt32 reps[4];
|
||||
unsigned remainLen;
|
||||
int needFlush;
|
||||
int needInitState;
|
||||
UInt32 numProbs;
|
||||
unsigned tempBufSize;
|
||||
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||
typedef struct {
|
||||
CLzmaProps prop;
|
||||
CLzmaProb *probs;
|
||||
Byte *dic;
|
||||
const Byte *buf;
|
||||
UInt32 range, code;
|
||||
SizeT dicPos;
|
||||
SizeT dicBufSize;
|
||||
UInt32 processedPos;
|
||||
UInt32 checkDicSize;
|
||||
unsigned state;
|
||||
UInt32 reps[4];
|
||||
unsigned remainLen;
|
||||
int needFlush;
|
||||
int needInitState;
|
||||
UInt32 numProbs;
|
||||
unsigned tempBufSize;
|
||||
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||
} CLzmaDec;
|
||||
|
||||
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||
#define LzmaDec_Construct(p) \
|
||||
{ \
|
||||
(p)->dic = 0; \
|
||||
(p)->probs = 0; \
|
||||
}
|
||||
|
||||
void LzmaDec_Init(CLzmaDec *p);
|
||||
|
||||
|
@ -76,10 +76,9 @@ void LzmaDec_Init(CLzmaDec *p);
|
|||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_FINISH_ANY, /* finish at any point */
|
||||
LZMA_FINISH_END /* block must be finished at the end */
|
||||
typedef enum {
|
||||
LZMA_FINISH_ANY, /* finish at any point */
|
||||
LZMA_FINISH_END /* block must be finished at the end */
|
||||
} ELzmaFinishMode;
|
||||
|
||||
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||
|
@ -97,18 +96,17 @@ typedef enum
|
|||
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||
You must use correct finish mode in that case. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
||||
typedef enum {
|
||||
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished
|
||||
without end mark */
|
||||
} ELzmaStatus;
|
||||
|
||||
/* ELzmaStatus is used only as output value for function call */
|
||||
|
||||
|
||||
/* ---------- Interfaces ---------- */
|
||||
|
||||
/* There are 3 levels of interfaces:
|
||||
|
@ -118,7 +116,6 @@ typedef enum
|
|||
You can select any of these interfaces, but don't mix functions from different
|
||||
groups for same object. */
|
||||
|
||||
|
||||
/* There are two variants to allocate state for Dictionary Interface:
|
||||
1) LzmaDec_Allocate / LzmaDec_Free
|
||||
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||
|
@ -130,7 +127,7 @@ LzmaDec_Allocate* can return:
|
|||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
|
||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||
|
||||
|
@ -159,7 +156,7 @@ void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
|||
*/
|
||||
|
||||
/* LzmaDec_DecodeToDic
|
||||
|
||||
|
||||
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||
|
||||
|
@ -178,9 +175,8 @@ Returns:
|
|||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
/* ---------- Buffer Interface ---------- */
|
||||
|
||||
|
@ -195,9 +191,8 @@ finishMode:
|
|||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
|
@ -220,9 +215,9 @@ Returns:
|
|||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
*/
|
||||
|
||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc);
|
||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, const Byte *propData,
|
||||
unsigned propSize, ELzmaFinishMode finishMode, ELzmaStatus *status,
|
||||
ISzAlloc *alloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
|||
#ifndef __PPMD_H
|
||||
#define __PPMD_H
|
||||
|
||||
#include "Types.h"
|
||||
#include "CpuArch.h"
|
||||
#include "Types.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#ifdef MY_CPU_32BIT
|
||||
#define PPMD_32BIT
|
||||
#define PPMD_32BIT
|
||||
#endif
|
||||
|
||||
#define PPMD_INT_BITS 7
|
||||
|
@ -21,7 +21,7 @@ EXTERN_C_BEGIN
|
|||
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
|
||||
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
|
||||
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
|
||||
#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
|
||||
#define PPMD_UPDATE_PROB_1(prob) ((prob)-PPMD_GET_MEAN(prob))
|
||||
|
||||
#define PPMD_N1 4
|
||||
#define PPMD_N2 4
|
||||
|
@ -30,52 +30,58 @@ EXTERN_C_BEGIN
|
|||
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
|
||||
|
||||
/* SEE-contexts for PPM-contexts with masked symbols */
|
||||
typedef struct
|
||||
{
|
||||
UInt16 Summ; /* Freq */
|
||||
Byte Shift; /* Speed of Freq change; low Shift is for fast change */
|
||||
Byte Count; /* Count to next change of Shift */
|
||||
typedef struct {
|
||||
UInt16 Summ; /* Freq */
|
||||
Byte Shift; /* Speed of Freq change; low Shift is for fast change */
|
||||
Byte Count; /* Count to next change of Shift */
|
||||
} CPpmd_See;
|
||||
|
||||
#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
|
||||
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
|
||||
#define Ppmd_See_Update(p) \
|
||||
if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) { \
|
||||
(p)->Summ <<= 1; \
|
||||
(p)->Count = (Byte)(3 << (p)->Shift++); \
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte Symbol;
|
||||
Byte Freq;
|
||||
UInt16 SuccessorLow;
|
||||
UInt16 SuccessorHigh;
|
||||
typedef struct {
|
||||
Byte Symbol;
|
||||
Byte Freq;
|
||||
UInt16 SuccessorLow;
|
||||
UInt16 SuccessorHigh;
|
||||
} CPpmd_State;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
#ifdef PPMD_32BIT
|
||||
CPpmd_State *
|
||||
#else
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd_State_Ref;
|
||||
#endif
|
||||
CPpmd_State_Ref;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
#ifdef PPMD_32BIT
|
||||
void *
|
||||
#else
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd_Void_Ref;
|
||||
#endif
|
||||
CPpmd_Void_Ref;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
#ifdef PPMD_32BIT
|
||||
Byte *
|
||||
#else
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd_Byte_Ref;
|
||||
#endif
|
||||
CPpmd_Byte_Ref;
|
||||
|
||||
#define PPMD_SetAllBitsIn256Bytes(p) \
|
||||
{ unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
|
||||
p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
|
||||
#define PPMD_SetAllBitsIn256Bytes(p) \
|
||||
{ \
|
||||
unsigned i; \
|
||||
for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
|
||||
p[i + 7] = p[i + 6] = p[i + 5] = p[i + 4] = p[i + 3] = p[i + 2] = \
|
||||
p[i + 1] = p[i + 0] = ~(size_t)0; \
|
||||
} \
|
||||
}
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
|
||||
#endif
|
||||
|
|
1083
fex/7z_C/Ppmd7.c
1083
fex/7z_C/Ppmd7.c
File diff suppressed because it is too large
Load Diff
113
fex/7z_C/Ppmd7.h
113
fex/7z_C/Ppmd7.h
|
@ -22,41 +22,39 @@ EXTERN_C_BEGIN
|
|||
struct CPpmd7_Context_;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
#ifdef PPMD_32BIT
|
||||
struct CPpmd7_Context_ *
|
||||
#else
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd7_Context_Ref;
|
||||
#endif
|
||||
CPpmd7_Context_Ref;
|
||||
|
||||
typedef struct CPpmd7_Context_
|
||||
{
|
||||
UInt16 NumStats;
|
||||
UInt16 SummFreq;
|
||||
CPpmd_State_Ref Stats;
|
||||
CPpmd7_Context_Ref Suffix;
|
||||
typedef struct CPpmd7_Context_ {
|
||||
UInt16 NumStats;
|
||||
UInt16 SummFreq;
|
||||
CPpmd_State_Ref Stats;
|
||||
CPpmd7_Context_Ref Suffix;
|
||||
} CPpmd7_Context;
|
||||
|
||||
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CPpmd7_Context *MinContext, *MaxContext;
|
||||
CPpmd_State *FoundState;
|
||||
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
|
||||
Int32 RunLength, InitRL; /* must be 32-bit at least */
|
||||
typedef struct {
|
||||
CPpmd7_Context *MinContext, *MaxContext;
|
||||
CPpmd_State *FoundState;
|
||||
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
|
||||
Int32 RunLength, InitRL; /* must be 32-bit at least */
|
||||
|
||||
UInt32 Size;
|
||||
UInt32 GlueCount;
|
||||
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
|
||||
UInt32 AlignOffset;
|
||||
UInt32 Size;
|
||||
UInt32 GlueCount;
|
||||
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
|
||||
UInt32 AlignOffset;
|
||||
|
||||
Byte Indx2Units[PPMD_NUM_INDEXES];
|
||||
Byte Units2Indx[128];
|
||||
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
|
||||
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
|
||||
CPpmd_See DummySee, See[25][16];
|
||||
UInt16 BinSumm[128][64];
|
||||
Byte Indx2Units[PPMD_NUM_INDEXES];
|
||||
Byte Units2Indx[128];
|
||||
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
|
||||
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
|
||||
CPpmd_See DummySee, See[25][16];
|
||||
UInt16 BinSumm[128][64];
|
||||
} CPpmd7;
|
||||
|
||||
void Ppmd7_Construct(CPpmd7 *p);
|
||||
|
@ -65,19 +63,18 @@ void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);
|
|||
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
|
||||
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
||||
|
||||
|
||||
/* ---------- Internal Functions ---------- */
|
||||
|
||||
extern const Byte PPMD7_kExpEscape[16];
|
||||
|
||||
#ifdef PPMD_32BIT
|
||||
#define Ppmd7_GetPtr(p, ptr) (ptr)
|
||||
#define Ppmd7_GetContext(p, ptr) (ptr)
|
||||
#define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
|
||||
#define Ppmd7_GetPtr(p, ptr) (ptr)
|
||||
#define Ppmd7_GetContext(p, ptr) (ptr)
|
||||
#define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
|
||||
#else
|
||||
#define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
|
||||
#define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
|
||||
#define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
|
||||
#define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
|
||||
#define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
|
||||
#define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
|
||||
#endif
|
||||
|
||||
void Ppmd7_Update1(CPpmd7 *p);
|
||||
|
@ -85,31 +82,29 @@ void Ppmd7_Update1_0(CPpmd7 *p);
|
|||
void Ppmd7_Update2(CPpmd7 *p);
|
||||
void Ppmd7_UpdateBin(CPpmd7 *p);
|
||||
|
||||
#define Ppmd7_GetBinSumm(p) \
|
||||
&p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
|
||||
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
|
||||
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
|
||||
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
|
||||
((p->RunLength >> 26) & 0x20)]
|
||||
#define Ppmd7_GetBinSumm(p) \
|
||||
&p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1] \
|
||||
[p->PrevSuccess + \
|
||||
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
|
||||
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
|
||||
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
|
||||
((p->RunLength >> 26) & 0x20)]
|
||||
|
||||
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
|
||||
|
||||
|
||||
/* ---------- Decode ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 (*GetThreshold)(void *p, UInt32 total);
|
||||
void (*Decode)(void *p, UInt32 start, UInt32 size);
|
||||
UInt32 (*DecodeBit)(void *p, UInt32 size0);
|
||||
typedef struct {
|
||||
UInt32 (*GetThreshold)(void *p, UInt32 total);
|
||||
void (*Decode)(void *p, UInt32 start, UInt32 size);
|
||||
UInt32 (*DecodeBit)(void *p, UInt32 size0);
|
||||
} IPpmd7_RangeDec;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IPpmd7_RangeDec p;
|
||||
UInt32 Range;
|
||||
UInt32 Code;
|
||||
IByteIn *Stream;
|
||||
typedef struct {
|
||||
IPpmd7_RangeDec p;
|
||||
UInt32 Range;
|
||||
UInt32 Code;
|
||||
IByteIn *Stream;
|
||||
} CPpmd7z_RangeDec;
|
||||
|
||||
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
|
||||
|
@ -118,16 +113,14 @@ Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
|
|||
|
||||
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
|
||||
|
||||
|
||||
/* ---------- Encode ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt64 Low;
|
||||
UInt32 Range;
|
||||
Byte Cache;
|
||||
UInt64 CacheSize;
|
||||
IByteOut *Stream;
|
||||
typedef struct {
|
||||
UInt64 Low;
|
||||
UInt32 Range;
|
||||
Byte Cache;
|
||||
UInt64 CacheSize;
|
||||
IByteOut *Stream;
|
||||
} CPpmd7z_RangeEnc;
|
||||
|
||||
void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p);
|
||||
|
@ -136,5 +129,5 @@ void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p);
|
|||
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,180 +8,165 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
|||
|
||||
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
|
||||
{
|
||||
unsigned i;
|
||||
p->Code = 0;
|
||||
p->Range = 0xFFFFFFFF;
|
||||
if (p->Stream->Read((void *)p->Stream) != 0)
|
||||
return False;
|
||||
for (i = 0; i < 4; i++)
|
||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||
return (p->Code < 0xFFFFFFFF);
|
||||
unsigned i;
|
||||
p->Code = 0;
|
||||
p->Range = 0xFFFFFFFF;
|
||||
if (p->Stream->Read((void *)p->Stream) != 0)
|
||||
return False;
|
||||
for (i = 0; i < 4; i++)
|
||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||
return (p->Code < 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static UInt32 Range_GetThreshold(void *pp, UInt32 total)
|
||||
{
|
||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||
return (p->Code) / (p->Range /= total);
|
||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||
return (p->Code) / (p->Range /= total);
|
||||
}
|
||||
|
||||
static void Range_Normalize(CPpmd7z_RangeDec *p)
|
||||
{
|
||||
if (p->Range < kTopValue)
|
||||
{
|
||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||
p->Range <<= 8;
|
||||
if (p->Range < kTopValue)
|
||||
{
|
||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||
p->Range <<= 8;
|
||||
}
|
||||
}
|
||||
if (p->Range < kTopValue) {
|
||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||
p->Range <<= 8;
|
||||
if (p->Range < kTopValue) {
|
||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||
p->Range <<= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Range_Decode(void *pp, UInt32 start, UInt32 size)
|
||||
{
|
||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||
p->Code -= start * p->Range;
|
||||
p->Range *= size;
|
||||
Range_Normalize(p);
|
||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||
p->Code -= start * p->Range;
|
||||
p->Range *= size;
|
||||
Range_Normalize(p);
|
||||
}
|
||||
|
||||
static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
|
||||
{
|
||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||
UInt32 newBound = (p->Range >> 14) * size0;
|
||||
UInt32 symbol;
|
||||
if (p->Code < newBound)
|
||||
{
|
||||
symbol = 0;
|
||||
p->Range = newBound;
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol = 1;
|
||||
p->Code -= newBound;
|
||||
p->Range -= newBound;
|
||||
}
|
||||
Range_Normalize(p);
|
||||
return symbol;
|
||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||
UInt32 newBound = (p->Range >> 14) * size0;
|
||||
UInt32 symbol;
|
||||
if (p->Code < newBound) {
|
||||
symbol = 0;
|
||||
p->Range = newBound;
|
||||
} else {
|
||||
symbol = 1;
|
||||
p->Code -= newBound;
|
||||
p->Range -= newBound;
|
||||
}
|
||||
Range_Normalize(p);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
|
||||
{
|
||||
p->p.GetThreshold = Range_GetThreshold;
|
||||
p->p.Decode = Range_Decode;
|
||||
p->p.DecodeBit = Range_DecodeBit;
|
||||
p->p.GetThreshold = Range_GetThreshold;
|
||||
p->p.Decode = Range_Decode;
|
||||
p->p.DecodeBit = Range_DecodeBit;
|
||||
}
|
||||
|
||||
|
||||
#define MASK(sym) ((signed char *)charMask)[sym]
|
||||
|
||||
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
|
||||
{
|
||||
size_t charMask[256 / sizeof(size_t)];
|
||||
if (p->MinContext->NumStats != 1)
|
||||
{
|
||||
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
|
||||
unsigned i;
|
||||
UInt32 count, hiCnt;
|
||||
if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
|
||||
{
|
||||
Byte symbol;
|
||||
rc->Decode(rc, 0, s->Freq);
|
||||
p->FoundState = s;
|
||||
symbol = s->Symbol;
|
||||
Ppmd7_Update1_0(p);
|
||||
return symbol;
|
||||
}
|
||||
p->PrevSuccess = 0;
|
||||
i = p->MinContext->NumStats - 1;
|
||||
do
|
||||
{
|
||||
if ((hiCnt += (++s)->Freq) > count)
|
||||
{
|
||||
Byte symbol;
|
||||
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
|
||||
p->FoundState = s;
|
||||
symbol = s->Symbol;
|
||||
Ppmd7_Update1(p);
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
while (--i);
|
||||
if (count >= p->MinContext->SummFreq)
|
||||
return -2;
|
||||
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
|
||||
rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
|
||||
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||
MASK(s->Symbol) = 0;
|
||||
i = p->MinContext->NumStats - 1;
|
||||
do { MASK((--s)->Symbol) = 0; } while (--i);
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt16 *prob = Ppmd7_GetBinSumm(p);
|
||||
if (rc->DecodeBit(rc, *prob) == 0)
|
||||
{
|
||||
Byte symbol;
|
||||
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
|
||||
symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
|
||||
Ppmd7_UpdateBin(p);
|
||||
return symbol;
|
||||
}
|
||||
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
|
||||
p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
|
||||
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
|
||||
p->PrevSuccess = 0;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
CPpmd_State *ps[256], *s;
|
||||
UInt32 freqSum, count, hiCnt;
|
||||
CPpmd_See *see;
|
||||
unsigned i, num, numMasked = p->MinContext->NumStats;
|
||||
do
|
||||
{
|
||||
p->OrderFall++;
|
||||
if (!p->MinContext->Suffix)
|
||||
return -1;
|
||||
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
|
||||
}
|
||||
while (p->MinContext->NumStats == numMasked);
|
||||
hiCnt = 0;
|
||||
s = Ppmd7_GetStats(p, p->MinContext);
|
||||
i = 0;
|
||||
num = p->MinContext->NumStats - numMasked;
|
||||
do
|
||||
{
|
||||
int k = (int)(MASK(s->Symbol));
|
||||
hiCnt += (s->Freq & k);
|
||||
ps[i] = s++;
|
||||
i -= k;
|
||||
}
|
||||
while (i != num);
|
||||
|
||||
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
|
||||
freqSum += hiCnt;
|
||||
count = rc->GetThreshold(rc, freqSum);
|
||||
|
||||
if (count < hiCnt)
|
||||
{
|
||||
Byte symbol;
|
||||
CPpmd_State **pps = ps;
|
||||
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
|
||||
s = *pps;
|
||||
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
|
||||
Ppmd_See_Update(see);
|
||||
p->FoundState = s;
|
||||
symbol = s->Symbol;
|
||||
Ppmd7_Update2(p);
|
||||
return symbol;
|
||||
}
|
||||
if (count >= freqSum)
|
||||
return -2;
|
||||
rc->Decode(rc, hiCnt, freqSum - hiCnt);
|
||||
see->Summ = (UInt16)(see->Summ + freqSum);
|
||||
do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
|
||||
}
|
||||
size_t charMask[256 / sizeof(size_t)];
|
||||
if (p->MinContext->NumStats != 1) {
|
||||
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
|
||||
unsigned i;
|
||||
UInt32 count, hiCnt;
|
||||
if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) {
|
||||
Byte symbol;
|
||||
rc->Decode(rc, 0, s->Freq);
|
||||
p->FoundState = s;
|
||||
symbol = s->Symbol;
|
||||
Ppmd7_Update1_0(p);
|
||||
return symbol;
|
||||
}
|
||||
p->PrevSuccess = 0;
|
||||
i = p->MinContext->NumStats - 1;
|
||||
do {
|
||||
if ((hiCnt += (++s)->Freq) > count) {
|
||||
Byte symbol;
|
||||
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
|
||||
p->FoundState = s;
|
||||
symbol = s->Symbol;
|
||||
Ppmd7_Update1(p);
|
||||
return symbol;
|
||||
}
|
||||
} while (--i);
|
||||
if (count >= p->MinContext->SummFreq)
|
||||
return -2;
|
||||
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
|
||||
rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
|
||||
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||
MASK(s->Symbol) = 0;
|
||||
i = p->MinContext->NumStats - 1;
|
||||
do {
|
||||
MASK((--s)->Symbol) = 0;
|
||||
} while (--i);
|
||||
} else {
|
||||
UInt16 *prob = Ppmd7_GetBinSumm(p);
|
||||
if (rc->DecodeBit(rc, *prob) == 0) {
|
||||
Byte symbol;
|
||||
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
|
||||
symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
|
||||
Ppmd7_UpdateBin(p);
|
||||
return symbol;
|
||||
}
|
||||
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
|
||||
p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
|
||||
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
|
||||
p->PrevSuccess = 0;
|
||||
}
|
||||
for (;;) {
|
||||
CPpmd_State *ps[256], *s;
|
||||
UInt32 freqSum, count, hiCnt;
|
||||
CPpmd_See *see;
|
||||
unsigned i, num, numMasked = p->MinContext->NumStats;
|
||||
do {
|
||||
p->OrderFall++;
|
||||
if (!p->MinContext->Suffix)
|
||||
return -1;
|
||||
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
|
||||
} while (p->MinContext->NumStats == numMasked);
|
||||
hiCnt = 0;
|
||||
s = Ppmd7_GetStats(p, p->MinContext);
|
||||
i = 0;
|
||||
num = p->MinContext->NumStats - numMasked;
|
||||
do {
|
||||
int k = (int)(MASK(s->Symbol));
|
||||
hiCnt += (s->Freq & k);
|
||||
ps[i] = s++;
|
||||
i -= k;
|
||||
} while (i != num);
|
||||
|
||||
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
|
||||
freqSum += hiCnt;
|
||||
count = rc->GetThreshold(rc, freqSum);
|
||||
|
||||
if (count < hiCnt) {
|
||||
Byte symbol;
|
||||
CPpmd_State **pps = ps;
|
||||
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++)
|
||||
;
|
||||
s = *pps;
|
||||
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
|
||||
Ppmd_See_Update(see);
|
||||
p->FoundState = s;
|
||||
symbol = s->Symbol;
|
||||
Ppmd7_Update2(p);
|
||||
return symbol;
|
||||
}
|
||||
if (count >= freqSum)
|
||||
return -2;
|
||||
rc->Decode(rc, hiCnt, freqSum - hiCnt);
|
||||
see->Summ = (UInt16)(see->Summ + freqSum);
|
||||
do {
|
||||
MASK(ps[--i]->Symbol) = 0;
|
||||
} while (i != 0);
|
||||
}
|
||||
}
|
||||
|
|
117
fex/7z_C/Types.h
117
fex/7z_C/Types.h
|
@ -49,7 +49,12 @@ typedef int WRes;
|
|||
#endif
|
||||
|
||||
#ifndef RINOK
|
||||
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||
#define RINOK(x) \
|
||||
{ \
|
||||
int __result__ = (x); \
|
||||
if (__result__ != 0) \
|
||||
return __result__; \
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef unsigned char Byte;
|
||||
|
@ -81,7 +86,7 @@ typedef unsigned __int64 UInt64;
|
|||
#else
|
||||
typedef long long int Int64;
|
||||
typedef unsigned long long int UInt64;
|
||||
#define UINT64_CONST(n) n ## ULL
|
||||
#define UINT64_CONST(n) n##ULL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -96,7 +101,6 @@ typedef int Bool;
|
|||
#define True 1
|
||||
#define False 0
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define MY_STD_CALL __stdcall
|
||||
#else
|
||||
|
@ -121,24 +125,20 @@ typedef int Bool;
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
/* The following interfaces use first parameter as pointer to structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||
typedef struct {
|
||||
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||
} IByteIn;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*Write)(void *p, Byte b);
|
||||
typedef struct {
|
||||
void (*Write)(void *p, Byte b);
|
||||
} IByteOut;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
typedef struct {
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
} ISeqInStream;
|
||||
|
||||
/* it can return SZ_ERROR_INPUT_EOF */
|
||||
|
@ -146,38 +146,30 @@ SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
|||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||
/* Returns: result - the number of actually written bytes.
|
||||
(result < size) means error */
|
||||
typedef struct {
|
||||
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||
/* Returns: result - the number of actually written bytes.
|
||||
(result < size) means error */
|
||||
} ISeqOutStream;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SZ_SEEK_SET = 0,
|
||||
SZ_SEEK_CUR = 1,
|
||||
SZ_SEEK_END = 2
|
||||
} ESzSeek;
|
||||
typedef enum { SZ_SEEK_SET = 0, SZ_SEEK_CUR = 1, SZ_SEEK_END = 2 } ESzSeek;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
typedef struct {
|
||||
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ISeekInStream;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Look)(void *p, const void **buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) > input(*size)) is not allowed
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
SRes (*Skip)(void *p, size_t offset);
|
||||
/* offset must be <= output(*size) of Look */
|
||||
typedef struct {
|
||||
SRes (*Look)(void *p, const void **buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) > input(*size)) is not allowed
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
SRes (*Skip)(void *p, size_t offset);
|
||||
/* offset must be <= output(*size) of Look */
|
||||
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ILookInStream;
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
||||
|
@ -189,45 +181,40 @@ SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
|||
|
||||
#define LookToRead_BUF_SIZE (1 << 14)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ILookInStream s;
|
||||
ISeekInStream *realStream;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
Byte buf[LookToRead_BUF_SIZE];
|
||||
typedef struct {
|
||||
ILookInStream s;
|
||||
ISeekInStream *realStream;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
Byte buf[LookToRead_BUF_SIZE];
|
||||
} CLookToRead;
|
||||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
||||
void LookToRead_Init(CLookToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
typedef struct {
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToLook;
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
typedef struct {
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToRead;
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||
/* Returns: result. (result != SZ_OK) means break.
|
||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||
typedef struct {
|
||||
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||
/* Returns: result. (result != SZ_OK) means break.
|
||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||
} ICompressProgress;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *(*Alloc)(void *p, size_t size);
|
||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||
typedef struct {
|
||||
void *(*Alloc)(void *p, size_t size);
|
||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||
} ISzAlloc;
|
||||
|
||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||
|
|
|
@ -6,21 +6,22 @@
|
|||
|
||||
#include "File_Extractor.h"
|
||||
|
||||
class Binary_Extractor : public File_Extractor {
|
||||
public:
|
||||
Binary_Extractor();
|
||||
virtual ~Binary_Extractor();
|
||||
class Binary_Extractor : public File_Extractor
|
||||
{
|
||||
public:
|
||||
Binary_Extractor();
|
||||
virtual ~Binary_Extractor();
|
||||
|
||||
protected:
|
||||
virtual blargg_err_t open_path_v();
|
||||
virtual blargg_err_t open_v();
|
||||
virtual void close_v();
|
||||
|
||||
virtual blargg_err_t next_v();
|
||||
virtual blargg_err_t rewind_v();
|
||||
protected:
|
||||
virtual blargg_err_t open_path_v();
|
||||
virtual blargg_err_t open_v();
|
||||
virtual void close_v();
|
||||
|
||||
virtual blargg_err_t stat_v();
|
||||
virtual blargg_err_t extract_v( void*, int );
|
||||
virtual blargg_err_t next_v();
|
||||
virtual blargg_err_t rewind_v();
|
||||
|
||||
virtual blargg_err_t stat_v();
|
||||
virtual blargg_err_t extract_v(void *, int);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,249 +16,278 @@ something compiler-specific, and change all places file sizes or offsets are
|
|||
used. */
|
||||
|
||||
// Supports reading and finding out how many bytes are remaining
|
||||
class Data_Reader {
|
||||
public:
|
||||
class Data_Reader
|
||||
{
|
||||
public:
|
||||
// Reads min(*n,remain()) bytes and sets *n to this number, thus trying to read more
|
||||
// tham remain() bytes doesn't result in error, just *n being set to remain().
|
||||
blargg_err_t read_avail(void *p, int *n);
|
||||
blargg_err_t read_avail(void *p, long *n);
|
||||
|
||||
// Reads min(*n,remain()) bytes and sets *n to this number, thus trying to read more
|
||||
// tham remain() bytes doesn't result in error, just *n being set to remain().
|
||||
blargg_err_t read_avail( void* p, int* n );
|
||||
blargg_err_t read_avail( void* p, long* n );
|
||||
// Reads exactly n bytes, or returns error if they couldn't ALL be read.
|
||||
// Reading past end of file results in blargg_err_file_eof.
|
||||
blargg_err_t read(void *p, int n);
|
||||
|
||||
// Reads exactly n bytes, or returns error if they couldn't ALL be read.
|
||||
// Reading past end of file results in blargg_err_file_eof.
|
||||
blargg_err_t read( void* p, int n );
|
||||
// Number of bytes remaining until end of file
|
||||
int remain() const
|
||||
{
|
||||
return remain_;
|
||||
}
|
||||
|
||||
// Number of bytes remaining until end of file
|
||||
int remain() const { return remain_; }
|
||||
// Reads and discards n bytes. Skipping past end of file results in blargg_err_file_eof.
|
||||
blargg_err_t skip(int n);
|
||||
|
||||
// Reads and discards n bytes. Skipping past end of file results in blargg_err_file_eof.
|
||||
blargg_err_t skip( int n );
|
||||
|
||||
virtual ~Data_Reader() { }
|
||||
virtual ~Data_Reader()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
// noncopyable
|
||||
Data_Reader( const Data_Reader& );
|
||||
Data_Reader& operator = ( const Data_Reader& );
|
||||
private:
|
||||
// noncopyable
|
||||
Data_Reader(const Data_Reader &);
|
||||
Data_Reader &operator=(const Data_Reader &);
|
||||
|
||||
// Derived interface
|
||||
protected:
|
||||
Data_Reader() : remain_( 0 ) { }
|
||||
|
||||
// Sets remain
|
||||
void set_remain( int n ) { assert( n >= 0 ); remain_ = n; }
|
||||
|
||||
// Do same as read(). Guaranteed that 0 < n <= remain(). Value of remain() is updated
|
||||
// AFTER this call succeeds, not before. set_remain() should NOT be called from this.
|
||||
virtual blargg_err_t read_v( void*, int n ) BLARGG_PURE( { (void)n; return blargg_ok; } )
|
||||
|
||||
// Do same as skip(). Guaranteed that 0 < n <= remain(). Default just reads data
|
||||
// and discards it. Value of remain() is updated AFTER this call succeeds, not
|
||||
// before. set_remain() should NOT be called from this.
|
||||
virtual blargg_err_t skip_v( int n );
|
||||
// Derived interface
|
||||
protected:
|
||||
Data_Reader() : remain_(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
|
||||
private:
|
||||
int remain_;
|
||||
// Sets remain
|
||||
void set_remain(int n)
|
||||
{
|
||||
assert(n >= 0);
|
||||
remain_ = n;
|
||||
}
|
||||
|
||||
// Do same as read(). Guaranteed that 0 < n <= remain(). Value of remain() is updated
|
||||
// AFTER this call succeeds, not before. set_remain() should NOT be called from this.
|
||||
virtual blargg_err_t read_v(void *, int n) BLARGG_PURE({
|
||||
(void)n;
|
||||
return blargg_ok;
|
||||
})
|
||||
|
||||
// Do same as skip(). Guaranteed that 0 < n <= remain(). Default just reads data
|
||||
// and discards it. Value of remain() is updated AFTER this call succeeds, not
|
||||
// before. set_remain() should NOT be called from this.
|
||||
virtual blargg_err_t skip_v(int n);
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
|
||||
private:
|
||||
int remain_;
|
||||
};
|
||||
|
||||
|
||||
// Supports seeking in addition to Data_Reader operations
|
||||
class File_Reader : public Data_Reader {
|
||||
public:
|
||||
class File_Reader : public Data_Reader
|
||||
{
|
||||
public:
|
||||
// Size of file
|
||||
int size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
// Size of file
|
||||
int size() const { return size_; }
|
||||
// Current position in file
|
||||
int tell() const
|
||||
{
|
||||
return size_ - remain();
|
||||
}
|
||||
|
||||
// Current position in file
|
||||
int tell() const { return size_ - remain(); }
|
||||
// Goes to new position
|
||||
blargg_err_t seek(int);
|
||||
|
||||
// Goes to new position
|
||||
blargg_err_t seek( int );
|
||||
// Derived interface
|
||||
protected:
|
||||
// Sets size and resets position
|
||||
void set_size(int n)
|
||||
{
|
||||
size_ = n;
|
||||
Data_Reader::set_remain(n);
|
||||
}
|
||||
void set_size(long n)
|
||||
{
|
||||
set_size(STATIC_CAST(int, n));
|
||||
}
|
||||
|
||||
// Derived interface
|
||||
protected:
|
||||
// Sets size and resets position
|
||||
void set_size( int n ) { size_ = n; Data_Reader::set_remain( n ); }
|
||||
void set_size( long n ) { set_size( STATIC_CAST(int, n) ); }
|
||||
|
||||
// Sets reported position
|
||||
void set_tell( int i ) { assert( 0 <= i && i <= size_ ); Data_Reader::set_remain( size_ - i ); }
|
||||
|
||||
// Do same as seek(). Guaranteed that 0 <= n <= size(). Value of tell() is updated
|
||||
// AFTER this call succeeds, not before. set_* functions should NOT be called from this.
|
||||
virtual blargg_err_t seek_v( int n ) BLARGG_PURE( { (void)n; return blargg_ok; } )
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
File_Reader() : size_( 0 ) { }
|
||||
|
||||
virtual blargg_err_t skip_v( int );
|
||||
// Sets reported position
|
||||
void set_tell(int i)
|
||||
{
|
||||
assert(0 <= i && i <= size_);
|
||||
Data_Reader::set_remain(size_ - i);
|
||||
}
|
||||
|
||||
private:
|
||||
int size_;
|
||||
|
||||
void set_remain(); // avoid accidental use of set_remain
|
||||
// Do same as seek(). Guaranteed that 0 <= n <= size(). Value of tell() is updated
|
||||
// AFTER this call succeeds, not before. set_* functions should NOT be called from this.
|
||||
virtual blargg_err_t seek_v(int n) BLARGG_PURE({
|
||||
(void)n;
|
||||
return blargg_ok;
|
||||
})
|
||||
|
||||
// Implementation
|
||||
protected : File_Reader()
|
||||
: size_(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual blargg_err_t skip_v(int);
|
||||
|
||||
private:
|
||||
int size_;
|
||||
|
||||
void set_remain(); // avoid accidental use of set_remain
|
||||
};
|
||||
|
||||
|
||||
// Reads from file on disk
|
||||
class Std_File_Reader : public File_Reader {
|
||||
public:
|
||||
class Std_File_Reader : public File_Reader
|
||||
{
|
||||
public:
|
||||
// Opens file
|
||||
blargg_err_t open(const char path[]);
|
||||
|
||||
// Opens file
|
||||
blargg_err_t open( const char path [] );
|
||||
|
||||
// Closes file if one was open
|
||||
void close();
|
||||
// Closes file if one was open
|
||||
void close();
|
||||
|
||||
// Switches to unbuffered mode. Useful if buffering is already being
|
||||
// done at a higher level.
|
||||
void make_unbuffered();
|
||||
// Switches to unbuffered mode. Useful if buffering is already being
|
||||
// done at a higher level.
|
||||
void make_unbuffered();
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
Std_File_Reader();
|
||||
virtual ~Std_File_Reader();
|
||||
|
||||
protected:
|
||||
virtual blargg_err_t read_v( void*, int );
|
||||
virtual blargg_err_t seek_v( int );
|
||||
// Implementation
|
||||
public:
|
||||
Std_File_Reader();
|
||||
virtual ~Std_File_Reader();
|
||||
|
||||
private:
|
||||
void* file_;
|
||||
protected:
|
||||
virtual blargg_err_t read_v(void *, int);
|
||||
virtual blargg_err_t seek_v(int);
|
||||
|
||||
private:
|
||||
void *file_;
|
||||
};
|
||||
|
||||
|
||||
// Treats range of memory as a file
|
||||
class Mem_File_Reader : public File_Reader {
|
||||
public:
|
||||
class Mem_File_Reader : public File_Reader
|
||||
{
|
||||
public:
|
||||
Mem_File_Reader(const void *begin, long size);
|
||||
|
||||
Mem_File_Reader( const void* begin, long size );
|
||||
// Implementation
|
||||
protected:
|
||||
virtual blargg_err_t read_v(void *, int);
|
||||
virtual blargg_err_t seek_v(int);
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
virtual blargg_err_t read_v( void*, int );
|
||||
virtual blargg_err_t seek_v( int );
|
||||
|
||||
private:
|
||||
const char* const begin;
|
||||
private:
|
||||
const char *const begin;
|
||||
};
|
||||
|
||||
|
||||
// Allows only count bytes to be read from reader passed
|
||||
class Subset_Reader : public Data_Reader {
|
||||
public:
|
||||
class Subset_Reader : public Data_Reader
|
||||
{
|
||||
public:
|
||||
Subset_Reader(Data_Reader *, int count);
|
||||
|
||||
Subset_Reader( Data_Reader*, int count );
|
||||
// Implementation
|
||||
protected:
|
||||
virtual blargg_err_t read_v(void *, int);
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
virtual blargg_err_t read_v( void*, int );
|
||||
|
||||
private:
|
||||
Data_Reader* const in;
|
||||
private:
|
||||
Data_Reader *const in;
|
||||
};
|
||||
|
||||
|
||||
// Joins already-read header and remaining data into original file.
|
||||
// Meant for cases where you've already read header and don't want
|
||||
// to seek and re-read data (for efficiency).
|
||||
class Remaining_Reader : public Data_Reader {
|
||||
public:
|
||||
class Remaining_Reader : public Data_Reader
|
||||
{
|
||||
public:
|
||||
Remaining_Reader(void const *header, int header_size, Data_Reader *);
|
||||
|
||||
Remaining_Reader( void const* header, int header_size, Data_Reader* );
|
||||
// Implementation
|
||||
protected:
|
||||
virtual blargg_err_t read_v(void *, int);
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
virtual blargg_err_t read_v( void*, int );
|
||||
|
||||
private:
|
||||
Data_Reader* const in;
|
||||
void const* header;
|
||||
int header_remain;
|
||||
private:
|
||||
Data_Reader *const in;
|
||||
void const *header;
|
||||
int header_remain;
|
||||
};
|
||||
|
||||
|
||||
// Invokes callback function to read data
|
||||
extern "C" { // necessary to be usable from C
|
||||
typedef const char* (*callback_reader_func_t)(
|
||||
void* user_data, // Same value passed to constructor
|
||||
void* out, // Buffer to place data into
|
||||
int count // Number of bytes to read
|
||||
);
|
||||
extern "C" { // necessary to be usable from C
|
||||
typedef const char *(*callback_reader_func_t)(void *user_data, // Same value passed to constructor
|
||||
void *out, // Buffer to place data into
|
||||
int count // Number of bytes to read
|
||||
);
|
||||
}
|
||||
class Callback_Reader : public Data_Reader {
|
||||
public:
|
||||
typedef callback_reader_func_t callback_t;
|
||||
Callback_Reader( callback_t, long size, void* user_data );
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
virtual blargg_err_t read_v( void*, int );
|
||||
class Callback_Reader : public Data_Reader
|
||||
{
|
||||
public:
|
||||
typedef callback_reader_func_t callback_t;
|
||||
Callback_Reader(callback_t, long size, void *user_data);
|
||||
|
||||
private:
|
||||
callback_t const callback;
|
||||
void* const user_data;
|
||||
// Implementation
|
||||
protected:
|
||||
virtual blargg_err_t read_v(void *, int);
|
||||
|
||||
private:
|
||||
callback_t const callback;
|
||||
void *const user_data;
|
||||
};
|
||||
|
||||
|
||||
// Invokes callback function to read data
|
||||
extern "C" { // necessary to be usable from C
|
||||
typedef const char* (*callback_file_reader_func_t)(
|
||||
void* user_data, // Same value passed to constructor
|
||||
void* out, // Buffer to place data into
|
||||
int count, // Number of bytes to read
|
||||
int pos // Position in file to read from
|
||||
);
|
||||
extern "C" { // necessary to be usable from C
|
||||
typedef const char *(*callback_file_reader_func_t)(void *user_data, // Same value passed to
|
||||
// constructor
|
||||
void *out, // Buffer to place data into
|
||||
int count, // Number of bytes to read
|
||||
int pos // Position in file to read from
|
||||
);
|
||||
}
|
||||
class Callback_File_Reader : public File_Reader {
|
||||
public:
|
||||
typedef callback_file_reader_func_t callback_t;
|
||||
Callback_File_Reader( callback_t, long size, void* user_data );
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
virtual blargg_err_t read_v( void*, int );
|
||||
virtual blargg_err_t seek_v( int );
|
||||
class Callback_File_Reader : public File_Reader
|
||||
{
|
||||
public:
|
||||
typedef callback_file_reader_func_t callback_t;
|
||||
Callback_File_Reader(callback_t, long size, void *user_data);
|
||||
|
||||
private:
|
||||
callback_t const callback;
|
||||
void* const user_data;
|
||||
// Implementation
|
||||
protected:
|
||||
virtual blargg_err_t read_v(void *, int);
|
||||
virtual blargg_err_t seek_v(int);
|
||||
|
||||
private:
|
||||
callback_t const callback;
|
||||
void *const user_data;
|
||||
};
|
||||
|
||||
|
||||
#ifdef HAVE_ZLIB_H
|
||||
|
||||
// Reads file compressed with gzip (or uncompressed)
|
||||
class Gzip_File_Reader : public File_Reader {
|
||||
public:
|
||||
class Gzip_File_Reader : public File_Reader
|
||||
{
|
||||
public:
|
||||
// Opens possibly gzipped file
|
||||
blargg_err_t open(const char path[]);
|
||||
|
||||
// Opens possibly gzipped file
|
||||
blargg_err_t open( const char path [] );
|
||||
|
||||
// Closes file if one was open
|
||||
void close();
|
||||
// Closes file if one was open
|
||||
void close();
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
Gzip_File_Reader();
|
||||
~Gzip_File_Reader();
|
||||
|
||||
protected:
|
||||
virtual blargg_err_t read_v( void*, int );
|
||||
virtual blargg_err_t seek_v( int );
|
||||
|
||||
private:
|
||||
// void* so "zlib.h" doesn't have to be included here
|
||||
void* file_;
|
||||
// Implementation
|
||||
public:
|
||||
Gzip_File_Reader();
|
||||
~Gzip_File_Reader();
|
||||
|
||||
protected:
|
||||
virtual blargg_err_t read_v(void *, int);
|
||||
virtual blargg_err_t seek_v(int);
|
||||
|
||||
private:
|
||||
// void* so "zlib.h" doesn't have to be included here
|
||||
void *file_;
|
||||
};
|
||||
#endif
|
||||
|
||||
char* blargg_to_utf8( const wchar_t* );
|
||||
wchar_t* blargg_to_wide( const char* );
|
||||
char *blargg_to_utf8(const wchar_t *);
|
||||
wchar_t *blargg_to_wide(const char *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,188 +4,239 @@
|
|||
#ifndef FILE_EXTRACTOR_H
|
||||
#define FILE_EXTRACTOR_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "Data_Reader.h"
|
||||
#include "blargg_common.h"
|
||||
#include "fex.h"
|
||||
|
||||
struct fex_t : private Data_Reader {
|
||||
public:
|
||||
virtual ~fex_t();
|
||||
|
||||
// Open/close
|
||||
public:
|
||||
virtual ~fex_t();
|
||||
|
||||
// Opens archive from custom data source. Keeps pointer until close().
|
||||
blargg_err_t open( File_Reader* input, const char* path = NULL );
|
||||
|
||||
// Takes ownership of File_Reader* passed to open(), so that close()
|
||||
// will delete it.
|
||||
void own_file() { own_file_ = reader_; }
|
||||
|
||||
// See fex.h
|
||||
blargg_err_t open( const char path [] );
|
||||
fex_type_t type() const { return type_; }
|
||||
void close();
|
||||
// Open/close
|
||||
|
||||
// Scanning
|
||||
// Opens archive from custom data source. Keeps pointer until close().
|
||||
blargg_err_t open(File_Reader *input, const char *path = NULL);
|
||||
|
||||
// See fex.h
|
||||
bool done() const { return done_; }
|
||||
blargg_err_t next();
|
||||
blargg_err_t rewind();
|
||||
fex_pos_t tell_arc() const;
|
||||
blargg_err_t seek_arc( fex_pos_t );
|
||||
// Takes ownership of File_Reader* passed to open(), so that close()
|
||||
// will delete it.
|
||||
void own_file()
|
||||
{
|
||||
own_file_ = reader_;
|
||||
}
|
||||
|
||||
// Info
|
||||
// See fex.h
|
||||
blargg_err_t open(const char path[]);
|
||||
fex_type_t type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
void close();
|
||||
|
||||
// See fex.h
|
||||
const char* name() const { return name_; }
|
||||
const wchar_t* wname() const { return wname_; }
|
||||
blargg_err_t stat();
|
||||
int size() const { assert( stat_called ); return size_; }
|
||||
unsigned int dos_date() const { return date_; }
|
||||
unsigned int crc32() const { return crc32_; }
|
||||
|
||||
// Extraction
|
||||
// Scanning
|
||||
|
||||
// Data_Reader to current file's data, so standard Data_Reader interface can
|
||||
// be used, rather than having to treat archives specially. stat() must have
|
||||
// been called.
|
||||
Data_Reader& reader() { assert( stat_called ); return *this; }
|
||||
// See fex.h
|
||||
bool done() const
|
||||
{
|
||||
return done_;
|
||||
}
|
||||
blargg_err_t next();
|
||||
blargg_err_t rewind();
|
||||
fex_pos_t tell_arc() const;
|
||||
blargg_err_t seek_arc(fex_pos_t);
|
||||
|
||||
// See fex.h
|
||||
blargg_err_t data( const void** data_out );
|
||||
int tell() const { return size_ - remain(); }
|
||||
|
||||
// Derived interface
|
||||
protected:
|
||||
|
||||
// Sets type of object
|
||||
fex_t( fex_type_t );
|
||||
|
||||
// Path to archive file, or "" if none supplied
|
||||
const char* arc_path() const { return path_.begin(); }
|
||||
|
||||
// Opens archive file if it's not already. If unbuffered is true, opens file
|
||||
// without any buffering.
|
||||
blargg_err_t open_arc_file( bool unbuffered = false );
|
||||
|
||||
// Archive file
|
||||
File_Reader& arc() const { return *reader_; }
|
||||
|
||||
// Sets current file name
|
||||
void set_name( const char name [], const wchar_t* wname = NULL );
|
||||
|
||||
// Sets current file information
|
||||
void set_info( int size, unsigned date = 0, unsigned crc = 0 );
|
||||
|
||||
// User overrides
|
||||
// Info
|
||||
|
||||
// Overrides must do indicated task. Non-pure functions have reasonable default
|
||||
// implementation. Overrides should avoid calling public functions like
|
||||
// next() and rewind().
|
||||
|
||||
// Open archive using file_path(). OK to delay actual file opening until later.
|
||||
// Default just calls open_arc_file(), then open_v().
|
||||
virtual blargg_err_t open_path_v();
|
||||
|
||||
// Open archive using file() for source data. If unsupported, return error.
|
||||
virtual blargg_err_t open_v() BLARGG_PURE( ; )
|
||||
|
||||
// Go to next file in archive and call set_name() and optionally set_info()
|
||||
virtual blargg_err_t next_v() BLARGG_PURE( ; )
|
||||
|
||||
// Go back to first file in archive
|
||||
virtual blargg_err_t rewind_v() BLARGG_PURE( ; )
|
||||
|
||||
// Close archive. Called even if open_path_v() or open_v() return unsuccessfully.
|
||||
virtual void close_v() BLARGG_PURE( ; )
|
||||
|
||||
// Clear any fields related to current file
|
||||
virtual void clear_file_v() { }
|
||||
|
||||
// Call set_info() if not already called by next_v()
|
||||
virtual blargg_err_t stat_v() { return blargg_ok; }
|
||||
|
||||
// Return value that allows later return to this file. Result must be >= 0.
|
||||
virtual fex_pos_t tell_arc_v() const;
|
||||
|
||||
// Return to previously saved position
|
||||
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
||||
|
||||
// One or both of the following must be overridden
|
||||
|
||||
// Provide pointer to data for current file in archive
|
||||
virtual blargg_err_t data_v( const void** out );
|
||||
|
||||
// Extract next n bytes
|
||||
virtual blargg_err_t extract_v( void* out, int n );
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
// See fex.h
|
||||
const char *name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
const wchar_t *wname() const
|
||||
{
|
||||
return wname_;
|
||||
}
|
||||
blargg_err_t stat();
|
||||
int size() const
|
||||
{
|
||||
assert(stat_called);
|
||||
return size_;
|
||||
}
|
||||
unsigned int dos_date() const
|
||||
{
|
||||
return date_;
|
||||
}
|
||||
unsigned int crc32() const
|
||||
{
|
||||
return crc32_;
|
||||
}
|
||||
|
||||
private:
|
||||
fex_type_t const type_;
|
||||
|
||||
// Archive file
|
||||
blargg_vector<char> path_;
|
||||
File_Reader* reader_;
|
||||
File_Reader* own_file_;
|
||||
bool opened_;
|
||||
|
||||
// Position in archive
|
||||
fex_pos_t tell_; // only used by default implementation of tell/seek
|
||||
bool done_;
|
||||
|
||||
// Info for current file in archive
|
||||
const char* name_;
|
||||
const wchar_t* wname_;
|
||||
unsigned date_;
|
||||
unsigned crc32_;
|
||||
int size_;
|
||||
bool stat_called;
|
||||
|
||||
// Current file contents
|
||||
void const* data_ptr_; // NULL if not read into memory
|
||||
blargg_vector<char> own_data_;
|
||||
// Extraction
|
||||
|
||||
bool opened() const { return opened_; }
|
||||
void clear_file();
|
||||
void close_();
|
||||
blargg_err_t set_path( const char* path );
|
||||
blargg_err_t rewind_file();
|
||||
blargg_err_t next_();
|
||||
|
||||
// Data_Reader overrides
|
||||
// TODO: override skip_v?
|
||||
virtual blargg_err_t read_v( void* out, int n );
|
||||
// Data_Reader to current file's data, so standard Data_Reader interface can
|
||||
// be used, rather than having to treat archives specially. stat() must have
|
||||
// been called.
|
||||
Data_Reader &reader()
|
||||
{
|
||||
assert(stat_called);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// See fex.h
|
||||
blargg_err_t data(const void **data_out);
|
||||
int tell() const
|
||||
{
|
||||
return size_ - remain();
|
||||
}
|
||||
|
||||
// Derived interface
|
||||
protected:
|
||||
// Sets type of object
|
||||
fex_t(fex_type_t);
|
||||
|
||||
// Path to archive file, or "" if none supplied
|
||||
const char *arc_path() const
|
||||
{
|
||||
return path_.begin();
|
||||
}
|
||||
|
||||
// Opens archive file if it's not already. If unbuffered is true, opens file
|
||||
// without any buffering.
|
||||
blargg_err_t open_arc_file(bool unbuffered = false);
|
||||
|
||||
// Archive file
|
||||
File_Reader &arc() const
|
||||
{
|
||||
return *reader_;
|
||||
}
|
||||
|
||||
// Sets current file name
|
||||
void set_name(const char name[], const wchar_t *wname = NULL);
|
||||
|
||||
// Sets current file information
|
||||
void set_info(int size, unsigned date = 0, unsigned crc = 0);
|
||||
|
||||
// User overrides
|
||||
|
||||
// Overrides must do indicated task. Non-pure functions have reasonable default
|
||||
// implementation. Overrides should avoid calling public functions like
|
||||
// next() and rewind().
|
||||
|
||||
// Open archive using file_path(). OK to delay actual file opening until later.
|
||||
// Default just calls open_arc_file(), then open_v().
|
||||
virtual blargg_err_t open_path_v();
|
||||
|
||||
// Open archive using file() for source data. If unsupported, return error.
|
||||
virtual blargg_err_t open_v() BLARGG_PURE(;)
|
||||
|
||||
// Go to next file in archive and call set_name() and optionally set_info()
|
||||
virtual blargg_err_t next_v() BLARGG_PURE(;)
|
||||
|
||||
// Go back to first file in archive
|
||||
virtual blargg_err_t rewind_v() BLARGG_PURE(;)
|
||||
|
||||
// Close archive. Called even if open_path_v() or open_v() return unsuccessfully.
|
||||
virtual void close_v() BLARGG_PURE(;)
|
||||
|
||||
// Clear any fields related to current file
|
||||
virtual void clear_file_v()
|
||||
{
|
||||
}
|
||||
|
||||
// Call set_info() if not already called by next_v()
|
||||
virtual blargg_err_t stat_v()
|
||||
{
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
// Return value that allows later return to this file. Result must be >= 0.
|
||||
virtual fex_pos_t tell_arc_v() const;
|
||||
|
||||
// Return to previously saved position
|
||||
virtual blargg_err_t seek_arc_v(fex_pos_t);
|
||||
|
||||
// One or both of the following must be overridden
|
||||
|
||||
// Provide pointer to data for current file in archive
|
||||
virtual blargg_err_t data_v(const void **out);
|
||||
|
||||
// Extract next n bytes
|
||||
virtual blargg_err_t extract_v(void *out, int n);
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
|
||||
private:
|
||||
fex_type_t const type_;
|
||||
|
||||
// Archive file
|
||||
blargg_vector<char> path_;
|
||||
File_Reader *reader_;
|
||||
File_Reader *own_file_;
|
||||
bool opened_;
|
||||
|
||||
// Position in archive
|
||||
fex_pos_t tell_; // only used by default implementation of tell/seek
|
||||
bool done_;
|
||||
|
||||
// Info for current file in archive
|
||||
const char *name_;
|
||||
const wchar_t *wname_;
|
||||
unsigned date_;
|
||||
unsigned crc32_;
|
||||
int size_;
|
||||
bool stat_called;
|
||||
|
||||
// Current file contents
|
||||
void const *data_ptr_; // NULL if not read into memory
|
||||
blargg_vector<char> own_data_;
|
||||
|
||||
bool opened() const
|
||||
{
|
||||
return opened_;
|
||||
}
|
||||
void clear_file();
|
||||
void close_();
|
||||
blargg_err_t set_path(const char *path);
|
||||
blargg_err_t rewind_file();
|
||||
blargg_err_t next_();
|
||||
|
||||
// Data_Reader overrides
|
||||
// TODO: override skip_v?
|
||||
virtual blargg_err_t read_v(void *out, int n);
|
||||
};
|
||||
|
||||
struct fex_type_t_
|
||||
struct fex_type_t_ {
|
||||
const char *extension;
|
||||
File_Extractor *(*new_fex)();
|
||||
const char *name;
|
||||
blargg_err_t (*init)(); // Called by fex_init(). Can be NULL.
|
||||
};
|
||||
|
||||
extern const fex_type_t_ fex_7z_type[1], fex_gz_type[1], fex_rar_type[1], fex_zip_type[1],
|
||||
fex_bin_type[1];
|
||||
|
||||
inline blargg_err_t File_Extractor::open_v()
|
||||
{
|
||||
const char* extension;
|
||||
File_Extractor* (*new_fex)();
|
||||
const char* name;
|
||||
blargg_err_t (*init)(); // Called by fex_init(). Can be NULL.
|
||||
};
|
||||
|
||||
extern const fex_type_t_
|
||||
fex_7z_type [1],
|
||||
fex_gz_type [1],
|
||||
fex_rar_type [1],
|
||||
fex_zip_type [1],
|
||||
fex_bin_type [1];
|
||||
|
||||
inline blargg_err_t File_Extractor::open_v() { return blargg_ok; }
|
||||
inline blargg_err_t File_Extractor::next_v() { return blargg_ok; }
|
||||
inline blargg_err_t File_Extractor::rewind_v() { return blargg_ok; }
|
||||
inline void File_Extractor::close_v() { }
|
||||
return blargg_ok;
|
||||
}
|
||||
inline blargg_err_t File_Extractor::next_v()
|
||||
{
|
||||
return blargg_ok;
|
||||
}
|
||||
inline blargg_err_t File_Extractor::rewind_v()
|
||||
{
|
||||
return blargg_ok;
|
||||
}
|
||||
inline void File_Extractor::close_v()
|
||||
{
|
||||
}
|
||||
|
||||
// Default to Std_File_Reader for archive access
|
||||
#ifndef FEX_FILE_READER
|
||||
#define FEX_FILE_READER Std_File_Reader
|
||||
#elif defined (FEX_FILE_READER_INCLUDE)
|
||||
#include FEX_FILE_READER_INCLUDE
|
||||
#define FEX_FILE_READER Std_File_Reader
|
||||
#elif defined(FEX_FILE_READER_INCLUDE)
|
||||
#include FEX_FILE_READER_INCLUDE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,27 +8,28 @@
|
|||
#include "File_Extractor.h"
|
||||
#include "Gzip_Reader.h"
|
||||
|
||||
class Gzip_Extractor : public File_Extractor {
|
||||
public:
|
||||
Gzip_Extractor();
|
||||
virtual ~Gzip_Extractor();
|
||||
class Gzip_Extractor : public File_Extractor
|
||||
{
|
||||
public:
|
||||
Gzip_Extractor();
|
||||
virtual ~Gzip_Extractor();
|
||||
|
||||
protected:
|
||||
virtual blargg_err_t open_path_v();
|
||||
virtual blargg_err_t open_v();
|
||||
virtual void close_v();
|
||||
|
||||
virtual blargg_err_t next_v();
|
||||
virtual blargg_err_t rewind_v();
|
||||
protected:
|
||||
virtual blargg_err_t open_path_v();
|
||||
virtual blargg_err_t open_v();
|
||||
virtual void close_v();
|
||||
|
||||
virtual blargg_err_t stat_v();
|
||||
virtual blargg_err_t extract_v( void*, int );
|
||||
|
||||
private:
|
||||
Gzip_Reader gr;
|
||||
blargg_vector<char> name;
|
||||
|
||||
void set_info_();
|
||||
virtual blargg_err_t next_v();
|
||||
virtual blargg_err_t rewind_v();
|
||||
|
||||
virtual blargg_err_t stat_v();
|
||||
virtual blargg_err_t extract_v(void *, int);
|
||||
|
||||
private:
|
||||
Gzip_Reader gr;
|
||||
blargg_vector<char> name;
|
||||
|
||||
void set_info_();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,40 +7,53 @@
|
|||
#include "Data_Reader.h"
|
||||
#include "Zlib_Inflater.h"
|
||||
|
||||
class Gzip_Reader : public Data_Reader {
|
||||
public:
|
||||
// Keeps pointer to reader until close(). If
|
||||
blargg_err_t open( File_Reader* );
|
||||
|
||||
// True if file is open
|
||||
bool opened() const { return in != NULL; }
|
||||
|
||||
// Frees memory
|
||||
void close();
|
||||
|
||||
// True if file is compressed
|
||||
bool deflated() const { return inflater.deflated(); }
|
||||
|
||||
// CRC-32 of data, of 0 if unavailable
|
||||
unsigned int crc32() const { return crc32_; }
|
||||
|
||||
// Number of bytes read since opening
|
||||
int tell() const { return size_ - remain(); }
|
||||
class Gzip_Reader : public Data_Reader
|
||||
{
|
||||
public:
|
||||
// Keeps pointer to reader until close(). If
|
||||
blargg_err_t open(File_Reader *);
|
||||
|
||||
public:
|
||||
Gzip_Reader();
|
||||
virtual ~Gzip_Reader();
|
||||
|
||||
protected:
|
||||
virtual blargg_err_t read_v( void*, int );
|
||||
// True if file is open
|
||||
bool opened() const
|
||||
{
|
||||
return in != NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
File_Reader* in;
|
||||
unsigned crc32_;
|
||||
int size_;
|
||||
Zlib_Inflater inflater;
|
||||
// Frees memory
|
||||
void close();
|
||||
|
||||
blargg_err_t calc_size();
|
||||
// True if file is compressed
|
||||
bool deflated() const
|
||||
{
|
||||
return inflater.deflated();
|
||||
}
|
||||
|
||||
// CRC-32 of data, of 0 if unavailable
|
||||
unsigned int crc32() const
|
||||
{
|
||||
return crc32_;
|
||||
}
|
||||
|
||||
// Number of bytes read since opening
|
||||
int tell() const
|
||||
{
|
||||
return size_ - remain();
|
||||
}
|
||||
|
||||
public:
|
||||
Gzip_Reader();
|
||||
virtual ~Gzip_Reader();
|
||||
|
||||
protected:
|
||||
virtual blargg_err_t read_v(void *, int);
|
||||
|
||||
private:
|
||||
File_Reader *in;
|
||||
unsigned crc32_;
|
||||
int size_;
|
||||
Zlib_Inflater inflater;
|
||||
|
||||
blargg_err_t calc_size();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,37 +7,37 @@
|
|||
#include "File_Extractor.h"
|
||||
#include "unrar/unrar.h"
|
||||
|
||||
class Rar_Extractor : public File_Extractor {
|
||||
public:
|
||||
Rar_Extractor();
|
||||
virtual ~Rar_Extractor();
|
||||
class Rar_Extractor : public File_Extractor
|
||||
{
|
||||
public:
|
||||
Rar_Extractor();
|
||||
virtual ~Rar_Extractor();
|
||||
|
||||
struct read_callback_t
|
||||
{
|
||||
const char* err;
|
||||
int pos;
|
||||
File_Reader* in;
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual blargg_err_t open_v();
|
||||
virtual void close_v();
|
||||
|
||||
virtual blargg_err_t next_v();
|
||||
virtual blargg_err_t rewind_v();
|
||||
virtual fex_pos_t tell_arc_v() const;
|
||||
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
||||
struct read_callback_t {
|
||||
const char *err;
|
||||
int pos;
|
||||
File_Reader *in;
|
||||
};
|
||||
|
||||
virtual blargg_err_t data_v( void const** );
|
||||
virtual blargg_err_t extract_v( void*, int );
|
||||
|
||||
private:
|
||||
unrar_t* unrar;
|
||||
read_callback_t reader;
|
||||
|
||||
blargg_err_t convert_err( unrar_err_t );
|
||||
blargg_err_t skip_unextractables();
|
||||
blargg_err_t next_raw();
|
||||
protected:
|
||||
virtual blargg_err_t open_v();
|
||||
virtual void close_v();
|
||||
|
||||
virtual blargg_err_t next_v();
|
||||
virtual blargg_err_t rewind_v();
|
||||
virtual fex_pos_t tell_arc_v() const;
|
||||
virtual blargg_err_t seek_arc_v(fex_pos_t);
|
||||
|
||||
virtual blargg_err_t data_v(void const **);
|
||||
virtual blargg_err_t extract_v(void *, int);
|
||||
|
||||
private:
|
||||
unrar_t *unrar;
|
||||
read_callback_t reader;
|
||||
|
||||
blargg_err_t convert_err(unrar_err_t);
|
||||
blargg_err_t skip_unextractables();
|
||||
blargg_err_t next_raw();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,31 +8,32 @@
|
|||
|
||||
struct Zip7_Extractor_Impl;
|
||||
|
||||
class Zip7_Extractor : public File_Extractor {
|
||||
public:
|
||||
Zip7_Extractor();
|
||||
virtual ~Zip7_Extractor();
|
||||
class Zip7_Extractor : public File_Extractor
|
||||
{
|
||||
public:
|
||||
Zip7_Extractor();
|
||||
virtual ~Zip7_Extractor();
|
||||
|
||||
protected:
|
||||
virtual blargg_err_t open_v();
|
||||
virtual void close_v();
|
||||
|
||||
virtual blargg_err_t next_v();
|
||||
virtual blargg_err_t rewind_v();
|
||||
virtual fex_pos_t tell_arc_v() const;
|
||||
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
||||
protected:
|
||||
virtual blargg_err_t open_v();
|
||||
virtual void close_v();
|
||||
|
||||
virtual blargg_err_t data_v( void const** out );
|
||||
|
||||
bool utf16ToUtf8( unsigned char* dest, size_t* destLen, const short* src, size_t srcLen );
|
||||
|
||||
private:
|
||||
Zip7_Extractor_Impl* impl;
|
||||
int index;
|
||||
blargg_vector<char> name8;
|
||||
blargg_vector<wchar_t> name16;
|
||||
|
||||
blargg_err_t zip7_err( int err );
|
||||
virtual blargg_err_t next_v();
|
||||
virtual blargg_err_t rewind_v();
|
||||
virtual fex_pos_t tell_arc_v() const;
|
||||
virtual blargg_err_t seek_arc_v(fex_pos_t);
|
||||
|
||||
virtual blargg_err_t data_v(void const **out);
|
||||
|
||||
bool utf16ToUtf8(unsigned char *dest, size_t *destLen, const short *src, size_t srcLen);
|
||||
|
||||
private:
|
||||
Zip7_Extractor_Impl *impl;
|
||||
int index;
|
||||
blargg_vector<char> name8;
|
||||
blargg_vector<wchar_t> name16;
|
||||
|
||||
blargg_err_t zip7_err(int err);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,39 +7,40 @@
|
|||
#include "File_Extractor.h"
|
||||
#include "Zlib_Inflater.h"
|
||||
|
||||
class Zip_Extractor : public File_Extractor {
|
||||
public:
|
||||
Zip_Extractor();
|
||||
virtual ~Zip_Extractor();
|
||||
class Zip_Extractor : public File_Extractor
|
||||
{
|
||||
public:
|
||||
Zip_Extractor();
|
||||
virtual ~Zip_Extractor();
|
||||
|
||||
protected:
|
||||
virtual blargg_err_t open_path_v();
|
||||
virtual blargg_err_t open_v();
|
||||
virtual void close_v();
|
||||
|
||||
virtual void clear_file_v();
|
||||
virtual blargg_err_t next_v();
|
||||
virtual blargg_err_t rewind_v();
|
||||
virtual fex_pos_t tell_arc_v() const;
|
||||
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
||||
|
||||
virtual blargg_err_t extract_v( void*, int );
|
||||
protected:
|
||||
virtual blargg_err_t open_path_v();
|
||||
virtual blargg_err_t open_v();
|
||||
virtual void close_v();
|
||||
|
||||
private:
|
||||
blargg_vector<char> catalog;
|
||||
int catalog_begin; // offset of first catalog entry in file (to detect corruption)
|
||||
int catalog_pos; // position of current entry in catalog
|
||||
int raw_remain; // bytes remaining to be read from zip file for current file
|
||||
unsigned crc; // ongoing CRC of extracted bytes
|
||||
unsigned correct_crc;
|
||||
bool file_deflated;
|
||||
Zlib_Inflater buf;
|
||||
virtual void clear_file_v();
|
||||
virtual blargg_err_t next_v();
|
||||
virtual blargg_err_t rewind_v();
|
||||
virtual fex_pos_t tell_arc_v() const;
|
||||
virtual blargg_err_t seek_arc_v(fex_pos_t);
|
||||
|
||||
blargg_err_t fill_buf( int offset, int buf_size, int initial_read );
|
||||
blargg_err_t update_info( bool advance_first );
|
||||
blargg_err_t first_read( int count );
|
||||
void reorder_entry_header( int offset );
|
||||
static blargg_err_t inflater_read( void* data, void* out, int* count );
|
||||
virtual blargg_err_t extract_v(void *, int);
|
||||
|
||||
private:
|
||||
blargg_vector<char> catalog;
|
||||
int catalog_begin; // offset of first catalog entry in file (to detect corruption)
|
||||
int catalog_pos; // position of current entry in catalog
|
||||
int raw_remain; // bytes remaining to be read from zip file for current file
|
||||
unsigned crc; // ongoing CRC of extracted bytes
|
||||
unsigned correct_crc;
|
||||
bool file_deflated;
|
||||
Zlib_Inflater buf;
|
||||
|
||||
blargg_err_t fill_buf(int offset, int buf_size, int initial_read);
|
||||
blargg_err_t update_info(bool advance_first);
|
||||
blargg_err_t first_read(int count);
|
||||
void reorder_entry_header(int offset);
|
||||
static blargg_err_t inflater_read(void *data, void *out, int *count);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,67 +4,78 @@
|
|||
#ifndef ZLIB_INFLATER_H
|
||||
#define ZLIB_INFLATER_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "Data_Reader.h"
|
||||
#include "blargg_common.h"
|
||||
#include "zlib.h"
|
||||
|
||||
class Zlib_Inflater {
|
||||
public:
|
||||
class Zlib_Inflater
|
||||
{
|
||||
public:
|
||||
// Reads at most min(*count,bytes_until_eof()) bytes into *out and set *count
|
||||
// to that number, or returns error if that many can't be read.
|
||||
typedef blargg_err_t (*callback_t)(void *user_data, void *out, int *count);
|
||||
|
||||
// Reads at most min(*count,bytes_until_eof()) bytes into *out and set *count
|
||||
// to that number, or returns error if that many can't be read.
|
||||
typedef blargg_err_t (*callback_t)( void* user_data, void* out, int* count );
|
||||
// Begins by setting callback and filling buffer. Default buffer is 16K and
|
||||
// filled to 4K, or specify buf_size and initial_read for custom buffer size
|
||||
// and how much to read initially.
|
||||
blargg_err_t begin(callback_t, void *user_data, int buf_size = 0, int initial_read = 0);
|
||||
|
||||
// Begins by setting callback and filling buffer. Default buffer is 16K and
|
||||
// filled to 4K, or specify buf_size and initial_read for custom buffer size
|
||||
// and how much to read initially.
|
||||
blargg_err_t begin( callback_t, void* user_data,
|
||||
int buf_size = 0, int initial_read = 0 );
|
||||
// Data read into buffer by begin()
|
||||
const unsigned char *data() const
|
||||
{
|
||||
return zbuf.next_in;
|
||||
}
|
||||
int filled() const
|
||||
{
|
||||
return zbuf.avail_in;
|
||||
}
|
||||
|
||||
// Data read into buffer by begin()
|
||||
const unsigned char* data() const { return zbuf.next_in; }
|
||||
int filled() const { return zbuf.avail_in; }
|
||||
// Begins inflation using specified mode. Using mode_auto selects between
|
||||
// mode_copy and mode_ungz by examining first two bytes of buffer. Use
|
||||
// buf_offset to specify where data begins in buffer, in case there is
|
||||
// header data that should be skipped.
|
||||
enum mode_t { mode_copy, mode_ungz, mode_raw_deflate, mode_auto };
|
||||
blargg_err_t set_mode(mode_t, int buf_offset = 0);
|
||||
|
||||
// Begins inflation using specified mode. Using mode_auto selects between
|
||||
// mode_copy and mode_ungz by examining first two bytes of buffer. Use
|
||||
// buf_offset to specify where data begins in buffer, in case there is
|
||||
// header data that should be skipped.
|
||||
enum mode_t { mode_copy, mode_ungz, mode_raw_deflate, mode_auto };
|
||||
blargg_err_t set_mode( mode_t, int buf_offset = 0 );
|
||||
// True if set_mode() has been called with mode_ungz or mode_raw_deflate
|
||||
bool deflated() const
|
||||
{
|
||||
return deflated_;
|
||||
}
|
||||
|
||||
// True if set_mode() has been called with mode_ungz or mode_raw_deflate
|
||||
bool deflated() const { return deflated_; }
|
||||
// Reads/inflates at most *count_io bytes into *out and sets *count_io to actual
|
||||
// number of bytes read (less than requested if end of data was reached).
|
||||
// Buffers source data internally, even in copy mode, so input file can be
|
||||
// unbuffered without sacrificing performance.
|
||||
blargg_err_t read(void *out, int *count_io);
|
||||
|
||||
// Reads/inflates at most *count_io bytes into *out and sets *count_io to actual
|
||||
// number of bytes read (less than requested if end of data was reached).
|
||||
// Buffers source data internally, even in copy mode, so input file can be
|
||||
// unbuffered without sacrificing performance.
|
||||
blargg_err_t read( void* out, int* count_io );
|
||||
// Total number of bytes read since begin()
|
||||
int tell() const
|
||||
{
|
||||
return zbuf.total_out;
|
||||
}
|
||||
|
||||
// Total number of bytes read since begin()
|
||||
int tell() const { return zbuf.total_out; }
|
||||
// Ends inflation and frees memory
|
||||
void end();
|
||||
|
||||
// Ends inflation and frees memory
|
||||
void end();
|
||||
private:
|
||||
// noncopyable
|
||||
Zlib_Inflater(const Zlib_Inflater &);
|
||||
Zlib_Inflater &operator=(const Zlib_Inflater &);
|
||||
|
||||
private:
|
||||
// noncopyable
|
||||
Zlib_Inflater( const Zlib_Inflater& );
|
||||
Zlib_Inflater& operator = ( const Zlib_Inflater& );
|
||||
// Implementation
|
||||
public:
|
||||
Zlib_Inflater();
|
||||
~Zlib_Inflater();
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
Zlib_Inflater();
|
||||
~Zlib_Inflater();
|
||||
private:
|
||||
z_stream_s zbuf;
|
||||
blargg_vector<unsigned char> buf;
|
||||
bool deflated_;
|
||||
callback_t callback;
|
||||
void *user_data;
|
||||
|
||||
private:
|
||||
z_stream_s zbuf;
|
||||
blargg_vector<unsigned char> buf;
|
||||
bool deflated_;
|
||||
callback_t callback;
|
||||
void* user_data;
|
||||
|
||||
blargg_err_t fill_buf( int count );
|
||||
blargg_err_t fill_buf(int count);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,57 +5,55 @@
|
|||
#ifndef BLARGG_COMMON_H
|
||||
#define BLARGG_COMMON_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef const char* blargg_err_t; // 0 on success, otherwise error string
|
||||
typedef const char *blargg_err_t; // 0 on success, otherwise error string
|
||||
|
||||
// Success; no error
|
||||
int const blargg_ok = 0;
|
||||
|
||||
// BLARGG_RESTRICT: equivalent to C99's restrict, where supported
|
||||
#if __GNUC__ >= 3 || _MSC_VER >= 1100
|
||||
#define BLARGG_RESTRICT __restrict
|
||||
#define BLARGG_RESTRICT __restrict
|
||||
#else
|
||||
#define BLARGG_RESTRICT
|
||||
#define BLARGG_RESTRICT
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 199711
|
||||
#define BLARGG_MUTABLE mutable
|
||||
#define BLARGG_MUTABLE mutable
|
||||
#else
|
||||
#define BLARGG_MUTABLE
|
||||
#define BLARGG_MUTABLE
|
||||
#endif
|
||||
|
||||
/* BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant).
|
||||
I don't just use 'abcd' because that's implementation-dependent. */
|
||||
#define BLARGG_4CHAR( a, b, c, d ) \
|
||||
((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF))
|
||||
#define BLARGG_4CHAR(a, b, c, d) \
|
||||
((a & 0xFF) * 0x1000000 + (b & 0xFF) * 0x10000 + (c & 0xFF) * 0x100 + (d & 0xFF))
|
||||
|
||||
/* BLARGG_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
|
||||
Can be used at file, function, or class scope. */
|
||||
#ifdef _MSC_VER
|
||||
// MSVC6 (_MSC_VER < 1300) __LINE__ fails when /Zl is specified
|
||||
#define BLARGG_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
|
||||
// MSVC6 (_MSC_VER < 1300) __LINE__ fails when /Zl is specified
|
||||
#define BLARGG_STATIC_ASSERT(expr) void blargg_failed_(int(*arg)[2 / (int)!!(expr)-1])
|
||||
#else
|
||||
// Others fail when declaring same function multiple times in class,
|
||||
// so differentiate them by line
|
||||
#define BLARGG_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
|
||||
// Others fail when declaring same function multiple times in class,
|
||||
// so differentiate them by line
|
||||
#define BLARGG_STATIC_ASSERT(expr) void blargg_failed_(int(*arg)[2 / !!(expr)-1][__LINE__])
|
||||
#endif
|
||||
|
||||
/* Pure virtual functions cause a vtable entry to a "called pure virtual"
|
||||
error handler, requiring linkage to the C++ runtime library. This macro is
|
||||
used in place of the "= 0", and simply expands to its argument. During
|
||||
development, it expands to "= 0", allowing detection of missing overrides. */
|
||||
#define BLARGG_PURE( def ) def
|
||||
#define BLARGG_PURE(def) def
|
||||
|
||||
/* My code depends on ASCII anywhere a character or string constant is
|
||||
compared with data read from a file, and anywhere file data is read and
|
||||
treated as a string. */
|
||||
#if '\n'!=0x0A || ' '!=0x20 || '0'!=0x30 || 'A'!=0x41 || 'a'!=0x61
|
||||
#error "ASCII character set required"
|
||||
#if '\n' != 0x0A || ' ' != 0x20 || '0' != 0x30 || 'A' != 0x41 || 'a' != 0x61
|
||||
#error "ASCII character set required"
|
||||
#endif
|
||||
|
||||
/* My code depends on int being at least 32 bits. Almost everything these days
|
||||
|
@ -64,12 +62,12 @@ to test with. The issue can't be gotten around by using a suitable blargg_int
|
|||
everywhere either, because int is often converted to implicitly when doing
|
||||
arithmetic on smaller types. */
|
||||
#if UINT_MAX < 0xFFFFFFFF
|
||||
#error "int must be at least 32 bits"
|
||||
#error "int must be at least 32 bits"
|
||||
#endif
|
||||
|
||||
// In case compiler doesn't support these properly. Used rarely.
|
||||
#define STATIC_CAST(T,expr) static_cast<T> (expr)
|
||||
#define CONST_CAST( T,expr) const_cast<T> (expr)
|
||||
#define STATIC_CAST(T, expr) static_cast<T>(expr)
|
||||
#define CONST_CAST(T, expr) const_cast<T>(expr)
|
||||
|
||||
// User configuration can override the above macros if necessary
|
||||
#include "blargg_config.h"
|
||||
|
@ -78,17 +76,17 @@ arithmetic on smaller types. */
|
|||
future version. In GCC, we can let the compiler warn. In other compilers,
|
||||
we strip it out unless BLARGG_LEGACY is true. */
|
||||
#if BLARGG_LEGACY
|
||||
// Allow old client code to work without warnings
|
||||
#define BLARGG_DEPRECATED_TEXT( text ) text
|
||||
#define BLARGG_DEPRECATED( text ) text
|
||||
// Allow old client code to work without warnings
|
||||
#define BLARGG_DEPRECATED_TEXT(text) text
|
||||
#define BLARGG_DEPRECATED(text) text
|
||||
#elif __GNUC__ >= 4
|
||||
// In GCC, we can mark declarations and let the compiler warn
|
||||
#define BLARGG_DEPRECATED_TEXT( text ) text
|
||||
#define BLARGG_DEPRECATED( text ) __attribute__ ((deprecated)) text
|
||||
// In GCC, we can mark declarations and let the compiler warn
|
||||
#define BLARGG_DEPRECATED_TEXT(text) text
|
||||
#define BLARGG_DEPRECATED(text) __attribute__((deprecated)) text
|
||||
#else
|
||||
// By default, deprecated items are removed, to avoid use in new code
|
||||
#define BLARGG_DEPRECATED_TEXT( text )
|
||||
#define BLARGG_DEPRECATED( text )
|
||||
// By default, deprecated items are removed, to avoid use in new code
|
||||
#define BLARGG_DEPRECATED_TEXT(text)
|
||||
#define BLARGG_DEPRECATED(text)
|
||||
#endif
|
||||
|
||||
/* BOOST::int8_t, BOOST::int32_t, etc.
|
||||
|
@ -97,20 +95,18 @@ for prividing the definitions. If I'm defining them, they must be scoped or
|
|||
else they could conflict with the standard ones at global scope. Even if
|
||||
HAVE_STDINT_H isn't defined, I can't assume the typedefs won't exist at
|
||||
global scope already. */
|
||||
#if defined (HAVE_STDINT_H) || \
|
||||
UCHAR_MAX != 0xFF || USHRT_MAX != 0xFFFF || UINT_MAX != 0xFFFFFFFF
|
||||
#include <stdint.h>
|
||||
#define BOOST
|
||||
#if defined(HAVE_STDINT_H) || UCHAR_MAX != 0xFF || USHRT_MAX != 0xFFFF || UINT_MAX != 0xFFFFFFFF
|
||||
#include <stdint.h>
|
||||
#define BOOST
|
||||
#else
|
||||
struct BOOST
|
||||
{
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
};
|
||||
struct BOOST {
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* My code is not written with exceptions in mind, so either uses new (nothrow)
|
||||
|
@ -121,81 +117,120 @@ interface, I override operator new to use malloc. */
|
|||
|
||||
// BLARGG_DISABLE_NOTHROW is put inside classes
|
||||
#ifndef BLARGG_DISABLE_NOTHROW
|
||||
// throw spec mandatory in ISO C++ if NULL can be returned
|
||||
#if __cplusplus >= 199711 || __GNUC__ >= 3 || _MSC_VER >= 1300
|
||||
#define BLARGG_THROWS_NOTHING throw ()
|
||||
#else
|
||||
#define BLARGG_THROWS_NOTHING
|
||||
#endif
|
||||
|
||||
#define BLARGG_DISABLE_NOTHROW \
|
||||
void* operator new ( size_t s ) BLARGG_THROWS_NOTHING { return malloc( s ); }\
|
||||
void operator delete( void* p ) BLARGG_THROWS_NOTHING { free( p ); }
|
||||
|
||||
#define BLARGG_NEW new
|
||||
// throw spec mandatory in ISO C++ if NULL can be returned
|
||||
#if __cplusplus >= 199711 || __GNUC__ >= 3 || _MSC_VER >= 1300
|
||||
#define BLARGG_THROWS_NOTHING throw()
|
||||
#else
|
||||
// BLARGG_NEW is used in place of new in library code
|
||||
#include <new>
|
||||
#define BLARGG_NEW new (std::nothrow)
|
||||
#define BLARGG_THROWS_NOTHING
|
||||
#endif
|
||||
|
||||
class blargg_vector_ {
|
||||
protected:
|
||||
void* begin_;
|
||||
size_t size_;
|
||||
void init();
|
||||
blargg_err_t resize_( size_t n, size_t elem_size );
|
||||
public:
|
||||
size_t size() const { return size_; }
|
||||
void clear();
|
||||
};
|
||||
#define BLARGG_DISABLE_NOTHROW \
|
||||
void *operator new(size_t s) BLARGG_THROWS_NOTHING \
|
||||
{ \
|
||||
return malloc(s); \
|
||||
} \
|
||||
void operator delete(void *p)BLARGG_THROWS_NOTHING \
|
||||
{ \
|
||||
free(p); \
|
||||
}
|
||||
|
||||
#define BLARGG_NEW new
|
||||
#else
|
||||
// BLARGG_NEW is used in place of new in library code
|
||||
#include <new>
|
||||
#define BLARGG_NEW new (std::nothrow)
|
||||
#endif
|
||||
|
||||
class blargg_vector_
|
||||
{
|
||||
protected:
|
||||
void *begin_;
|
||||
size_t size_;
|
||||
void init();
|
||||
blargg_err_t resize_(size_t n, size_t elem_size);
|
||||
|
||||
public:
|
||||
size_t size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
void clear();
|
||||
};
|
||||
|
||||
// Very lightweight vector for POD types (no constructor/destructor)
|
||||
template<class T>
|
||||
class blargg_vector : public blargg_vector_ {
|
||||
union T_must_be_pod { T t; }; // fails if T is not POD
|
||||
public:
|
||||
blargg_vector() { init(); }
|
||||
~blargg_vector() { clear(); }
|
||||
|
||||
blargg_err_t resize( size_t n ) { return resize_( n, sizeof (T) ); }
|
||||
|
||||
T* begin() { return static_cast<T*> (begin_); }
|
||||
const T* begin() const { return static_cast<T*> (begin_); }
|
||||
|
||||
T* end() { return static_cast<T*> (begin_) + size_; }
|
||||
const T* end() const { return static_cast<T*> (begin_) + size_; }
|
||||
|
||||
T& operator [] ( size_t n )
|
||||
{
|
||||
assert( n < size_ );
|
||||
return static_cast<T*> (begin_) [n];
|
||||
}
|
||||
|
||||
const T& operator [] ( size_t n ) const
|
||||
{
|
||||
assert( n < size_ );
|
||||
return static_cast<T*> (begin_) [n];
|
||||
}
|
||||
template <class T> class blargg_vector : public blargg_vector_
|
||||
{
|
||||
union T_must_be_pod {
|
||||
T t;
|
||||
}; // fails if T is not POD
|
||||
public:
|
||||
blargg_vector()
|
||||
{
|
||||
init();
|
||||
}
|
||||
~blargg_vector()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
blargg_err_t resize(size_t n)
|
||||
{
|
||||
return resize_(n, sizeof(T));
|
||||
}
|
||||
|
||||
T *begin()
|
||||
{
|
||||
return static_cast<T *>(begin_);
|
||||
}
|
||||
const T *begin() const
|
||||
{
|
||||
return static_cast<T *>(begin_);
|
||||
}
|
||||
|
||||
T *end()
|
||||
{
|
||||
return static_cast<T *>(begin_) + size_;
|
||||
}
|
||||
const T *end() const
|
||||
{
|
||||
return static_cast<T *>(begin_) + size_;
|
||||
}
|
||||
|
||||
T &operator[](size_t n)
|
||||
{
|
||||
assert(n < size_);
|
||||
return static_cast<T *>(begin_)[n];
|
||||
}
|
||||
|
||||
const T &operator[](size_t n) const
|
||||
{
|
||||
assert(n < size_);
|
||||
return static_cast<T *>(begin_)[n];
|
||||
}
|
||||
};
|
||||
|
||||
// Callback function with user data.
|
||||
// blargg_callback<T> set_callback; // for user, this acts like...
|
||||
// void set_callback( T func, void* user_data = NULL ); // ...this
|
||||
// To call function, do set_callback.f( .. set_callback.data ... );
|
||||
template<class T>
|
||||
struct blargg_callback
|
||||
{
|
||||
T f;
|
||||
void* data;
|
||||
blargg_callback() { f = NULL; }
|
||||
void operator () ( T callback, void* user_data = NULL ) { f = callback; data = user_data; }
|
||||
template <class T> struct blargg_callback {
|
||||
T f;
|
||||
void *data;
|
||||
blargg_callback()
|
||||
{
|
||||
f = NULL;
|
||||
}
|
||||
void operator()(T callback, void *user_data = NULL)
|
||||
{
|
||||
f = callback;
|
||||
data = user_data;
|
||||
}
|
||||
};
|
||||
|
||||
BLARGG_DEPRECATED( typedef signed int blargg_long; )
|
||||
BLARGG_DEPRECATED( typedef unsigned int blargg_ulong; )
|
||||
BLARGG_DEPRECATED(typedef signed int blargg_long;)
|
||||
BLARGG_DEPRECATED(typedef unsigned int blargg_ulong;)
|
||||
#if BLARGG_LEGACY
|
||||
#define BOOST_STATIC_ASSERT BLARGG_STATIC_ASSERT
|
||||
#define BOOST_STATIC_ASSERT BLARGG_STATIC_ASSERT
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,14 +18,11 @@
|
|||
//#define BLARGG_BUILD_DLL 1
|
||||
|
||||
// Support only the listed archive types. Remove any you don't need.
|
||||
#define FEX_TYPE_LIST \
|
||||
fex_7z_type,\
|
||||
fex_gz_type,\
|
||||
fex_zip_type,
|
||||
#define FEX_TYPE_LIST fex_7z_type, fex_gz_type, fex_zip_type,
|
||||
|
||||
// Use standard config.h if present
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,179 +7,214 @@
|
|||
#include "blargg_common.h"
|
||||
|
||||
// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
|
||||
#if defined (__i386__) || defined (__x86_64__) || defined (_M_IX86) || defined (_M_X64)
|
||||
#define BLARGG_CPU_X86 1
|
||||
#define BLARGG_CPU_CISC 1
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
|
||||
#define BLARGG_CPU_X86 1
|
||||
#define BLARGG_CPU_CISC 1
|
||||
#endif
|
||||
|
||||
#if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) || \
|
||||
defined (__POWERPC__) || defined (__powerc)
|
||||
#define BLARGG_CPU_POWERPC 1
|
||||
#define BLARGG_CPU_RISC 1
|
||||
#if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || defined(__POWERPC__) || \
|
||||
defined(__powerc)
|
||||
#define BLARGG_CPU_POWERPC 1
|
||||
#define BLARGG_CPU_RISC 1
|
||||
#endif
|
||||
|
||||
// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
|
||||
// one may be #defined to 1. Only needed if something actually depends on byte order.
|
||||
#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN)
|
||||
#if !defined(BLARGG_BIG_ENDIAN) && !defined(BLARGG_LITTLE_ENDIAN)
|
||||
#ifdef __GLIBC__
|
||||
// GCC handles this for us
|
||||
#include <endian.h>
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define BLARGG_BIG_ENDIAN 1
|
||||
#endif
|
||||
// GCC handles this for us
|
||||
#include <endian.h>
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define BLARGG_BIG_ENDIAN 1
|
||||
#endif
|
||||
#else
|
||||
|
||||
#if defined (LSB_FIRST) || defined (__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \
|
||||
(defined (LITTLE_ENDIAN) && LITTLE_ENDIAN+0 != 1234)
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#if defined(LSB_FIRST) || defined(__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \
|
||||
(defined(LITTLE_ENDIAN) && LITTLE_ENDIAN + 0 != 1234)
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
|
||||
defined (__sparc__) || BLARGG_CPU_POWERPC || \
|
||||
(defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
|
||||
#define BLARGG_BIG_ENDIAN 1
|
||||
#elif !defined (__mips__)
|
||||
// No endian specified; assume little-endian, since it's most common
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#if defined(MSB_FIRST) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN) || \
|
||||
defined(__sparc__) || BLARGG_CPU_POWERPC || (defined(BIG_ENDIAN) && BIG_ENDIAN + 0 != 4321)
|
||||
#define BLARGG_BIG_ENDIAN 1
|
||||
#elif !defined(__mips__)
|
||||
// No endian specified; assume little-endian, since it's most common
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BLARGG_LITTLE_ENDIAN && BLARGG_BIG_ENDIAN
|
||||
#undef BLARGG_LITTLE_ENDIAN
|
||||
#undef BLARGG_BIG_ENDIAN
|
||||
#undef BLARGG_LITTLE_ENDIAN
|
||||
#undef BLARGG_BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
inline void blargg_verify_byte_order()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
#if BLARGG_BIG_ENDIAN
|
||||
volatile int i = 1;
|
||||
assert( *(volatile char*) &i == 0 );
|
||||
#elif BLARGG_LITTLE_ENDIAN
|
||||
volatile int i = 1;
|
||||
assert( *(volatile char*) &i != 0 );
|
||||
#endif
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
#if BLARGG_BIG_ENDIAN
|
||||
volatile int i = 1;
|
||||
assert(*(volatile char *)&i == 0);
|
||||
#elif BLARGG_LITTLE_ENDIAN
|
||||
volatile int i = 1;
|
||||
assert(*(volatile char *)&i != 0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_le16( void const* p )
|
||||
inline unsigned get_le16(void const *p)
|
||||
{
|
||||
return (unsigned) ((unsigned char const*) p) [1] << 8 |
|
||||
(unsigned) ((unsigned char const*) p) [0];
|
||||
return (unsigned)((unsigned char const *)p)[1] << 8 |
|
||||
(unsigned)((unsigned char const *)p)[0];
|
||||
}
|
||||
|
||||
inline unsigned get_be16( void const* p )
|
||||
inline unsigned get_be16(void const *p)
|
||||
{
|
||||
return (unsigned) ((unsigned char const*) p) [0] << 8 |
|
||||
(unsigned) ((unsigned char const*) p) [1];
|
||||
return (unsigned)((unsigned char const *)p)[0] << 8 |
|
||||
(unsigned)((unsigned char const *)p)[1];
|
||||
}
|
||||
|
||||
inline unsigned get_le32( void const* p )
|
||||
inline unsigned get_le32(void const *p)
|
||||
{
|
||||
return (unsigned) ((unsigned char const*) p) [3] << 24 |
|
||||
(unsigned) ((unsigned char const*) p) [2] << 16 |
|
||||
(unsigned) ((unsigned char const*) p) [1] << 8 |
|
||||
(unsigned) ((unsigned char const*) p) [0];
|
||||
return (unsigned)((unsigned char const *)p)[3] << 24 |
|
||||
(unsigned)((unsigned char const *)p)[2] << 16 |
|
||||
(unsigned)((unsigned char const *)p)[1] << 8 |
|
||||
(unsigned)((unsigned char const *)p)[0];
|
||||
}
|
||||
|
||||
inline unsigned get_be32( void const* p )
|
||||
inline unsigned get_be32(void const *p)
|
||||
{
|
||||
return (unsigned) ((unsigned char const*) p) [0] << 24 |
|
||||
(unsigned) ((unsigned char const*) p) [1] << 16 |
|
||||
(unsigned) ((unsigned char const*) p) [2] << 8 |
|
||||
(unsigned) ((unsigned char const*) p) [3];
|
||||
return (unsigned)((unsigned char const *)p)[0] << 24 |
|
||||
(unsigned)((unsigned char const *)p)[1] << 16 |
|
||||
(unsigned)((unsigned char const *)p)[2] << 8 |
|
||||
(unsigned)((unsigned char const *)p)[3];
|
||||
}
|
||||
|
||||
inline void set_le16( void* p, unsigned n )
|
||||
inline void set_le16(void *p, unsigned n)
|
||||
{
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [0] = (unsigned char) n;
|
||||
((unsigned char *)p)[1] = (unsigned char)(n >> 8);
|
||||
((unsigned char *)p)[0] = (unsigned char)n;
|
||||
}
|
||||
|
||||
inline void set_be16( void* p, unsigned n )
|
||||
inline void set_be16(void *p, unsigned n)
|
||||
{
|
||||
((unsigned char*) p) [0] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [1] = (unsigned char) n;
|
||||
((unsigned char *)p)[0] = (unsigned char)(n >> 8);
|
||||
((unsigned char *)p)[1] = (unsigned char)n;
|
||||
}
|
||||
|
||||
inline void set_le32( void* p, unsigned n )
|
||||
inline void set_le32(void *p, unsigned n)
|
||||
{
|
||||
((unsigned char*) p) [0] = (unsigned char) n;
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
|
||||
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
|
||||
((unsigned char *)p)[0] = (unsigned char)n;
|
||||
((unsigned char *)p)[1] = (unsigned char)(n >> 8);
|
||||
((unsigned char *)p)[2] = (unsigned char)(n >> 16);
|
||||
((unsigned char *)p)[3] = (unsigned char)(n >> 24);
|
||||
}
|
||||
|
||||
inline void set_be32( void* p, unsigned n )
|
||||
inline void set_be32(void *p, unsigned n)
|
||||
{
|
||||
((unsigned char*) p) [3] = (unsigned char) n;
|
||||
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
|
||||
((unsigned char*) p) [0] = (unsigned char) (n >> 24);
|
||||
((unsigned char *)p)[3] = (unsigned char)n;
|
||||
((unsigned char *)p)[2] = (unsigned char)(n >> 8);
|
||||
((unsigned char *)p)[1] = (unsigned char)(n >> 16);
|
||||
((unsigned char *)p)[0] = (unsigned char)(n >> 24);
|
||||
}
|
||||
|
||||
#if BLARGG_NONPORTABLE
|
||||
// Optimized implementation if byte order is known
|
||||
#if BLARGG_LITTLE_ENDIAN
|
||||
#define GET_LE16( addr ) (*(BOOST::uint16_t const*) (addr))
|
||||
#define GET_LE32( addr ) (*(BOOST::uint32_t const*) (addr))
|
||||
#define SET_LE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
||||
#define SET_LE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
||||
#elif BLARGG_BIG_ENDIAN
|
||||
#define GET_BE16( addr ) (*(BOOST::uint16_t const*) (addr))
|
||||
#define GET_BE32( addr ) (*(BOOST::uint32_t const*) (addr))
|
||||
#define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
||||
#define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
||||
// Optimized implementation if byte order is known
|
||||
#if BLARGG_LITTLE_ENDIAN
|
||||
#define GET_LE16(addr) (*(BOOST::uint16_t const *)(addr))
|
||||
#define GET_LE32(addr) (*(BOOST::uint32_t const *)(addr))
|
||||
#define SET_LE16(addr, data) (void)(*(BOOST::uint16_t *)(addr) = (data))
|
||||
#define SET_LE32(addr, data) (void)(*(BOOST::uint32_t *)(addr) = (data))
|
||||
#elif BLARGG_BIG_ENDIAN
|
||||
#define GET_BE16(addr) (*(BOOST::uint16_t const *)(addr))
|
||||
#define GET_BE32(addr) (*(BOOST::uint32_t const *)(addr))
|
||||
#define SET_BE16(addr, data) (void)(*(BOOST::uint16_t *)(addr) = (data))
|
||||
#define SET_BE32(addr, data) (void)(*(BOOST::uint32_t *)(addr) = (data))
|
||||
|
||||
#if BLARGG_CPU_POWERPC
|
||||
// PowerPC has special byte-reversed instructions
|
||||
#if defined (__MWERKS__)
|
||||
#define GET_LE16( addr ) (__lhbrx( addr, 0 ))
|
||||
#define GET_LE32( addr ) (__lwbrx( addr, 0 ))
|
||||
#define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 ))
|
||||
#define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 ))
|
||||
#elif defined (__GNUC__)
|
||||
#define GET_LE16( addr ) ({unsigned short ppc_lhbrx_; __asm__ volatile( "lhbrx %0,0,%1" : "=r" (ppc_lhbrx_) : "r" (addr) : "memory" ); ppc_lhbrx_;})
|
||||
#define GET_LE32( addr ) ({unsigned short ppc_lwbrx_; __asm__ volatile( "lwbrx %0,0,%1" : "=r" (ppc_lwbrx_) : "r" (addr) : "memory" ); ppc_lwbrx_;})
|
||||
#define SET_LE16( addr, in ) ({__asm__ volatile( "sthbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
|
||||
#define SET_LE32( addr, in ) ({__asm__ volatile( "stwbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if BLARGG_CPU_POWERPC
|
||||
// PowerPC has special byte-reversed instructions
|
||||
#if defined(__MWERKS__)
|
||||
#define GET_LE16(addr) (__lhbrx(addr, 0))
|
||||
#define GET_LE32(addr) (__lwbrx(addr, 0))
|
||||
#define SET_LE16(addr, in) (__sthbrx(in, addr, 0))
|
||||
#define SET_LE32(addr, in) (__stwbrx(in, addr, 0))
|
||||
#elif defined(__GNUC__)
|
||||
#define GET_LE16(addr) \
|
||||
({ \
|
||||
unsigned short ppc_lhbrx_; \
|
||||
__asm__ volatile("lhbrx %0,0,%1" : "=r"(ppc_lhbrx_) : "r"(addr) : "memory"); \
|
||||
ppc_lhbrx_; \
|
||||
})
|
||||
#define GET_LE32(addr) \
|
||||
({ \
|
||||
unsigned short ppc_lwbrx_; \
|
||||
__asm__ volatile("lwbrx %0,0,%1" : "=r"(ppc_lwbrx_) : "r"(addr) : "memory"); \
|
||||
ppc_lwbrx_; \
|
||||
})
|
||||
#define SET_LE16(addr, in) \
|
||||
({ __asm__ volatile("sthbrx %0,0,%1" : : "r"(in), "r"(addr) : "memory"); })
|
||||
#define SET_LE32(addr, in) \
|
||||
({ __asm__ volatile("stwbrx %0,0,%1" : : "r"(in), "r"(addr) : "memory"); })
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GET_LE16
|
||||
#define GET_LE16( addr ) get_le16( addr )
|
||||
#define SET_LE16( addr, data ) set_le16( addr, data )
|
||||
#define GET_LE16(addr) get_le16(addr)
|
||||
#define SET_LE16(addr, data) set_le16(addr, data)
|
||||
#endif
|
||||
|
||||
#ifndef GET_LE32
|
||||
#define GET_LE32( addr ) get_le32( addr )
|
||||
#define SET_LE32( addr, data ) set_le32( addr, data )
|
||||
#define GET_LE32(addr) get_le32(addr)
|
||||
#define SET_LE32(addr, data) set_le32(addr, data)
|
||||
#endif
|
||||
|
||||
#ifndef GET_BE16
|
||||
#define GET_BE16( addr ) get_be16( addr )
|
||||
#define SET_BE16( addr, data ) set_be16( addr, data )
|
||||
#define GET_BE16(addr) get_be16(addr)
|
||||
#define SET_BE16(addr, data) set_be16(addr, data)
|
||||
#endif
|
||||
|
||||
#ifndef GET_BE32
|
||||
#define GET_BE32( addr ) get_be32( addr )
|
||||
#define SET_BE32( addr, data ) set_be32( addr, data )
|
||||
#define GET_BE32(addr) get_be32(addr)
|
||||
#define SET_BE32(addr, data) set_be32(addr, data)
|
||||
#endif
|
||||
|
||||
// auto-selecting versions
|
||||
|
||||
inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
|
||||
inline void set_le( BOOST::uint32_t* p, unsigned n ) { SET_LE32( p, n ); }
|
||||
inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
|
||||
inline void set_be( BOOST::uint32_t* p, unsigned n ) { SET_BE32( p, n ); }
|
||||
inline unsigned get_le( BOOST::uint16_t const* p ) { return GET_LE16( p ); }
|
||||
inline unsigned get_le( BOOST::uint32_t const* p ) { return GET_LE32( p ); }
|
||||
inline unsigned get_be( BOOST::uint16_t const* p ) { return GET_BE16( p ); }
|
||||
inline unsigned get_be( BOOST::uint32_t const* p ) { return GET_BE32( p ); }
|
||||
inline void set_le(BOOST::uint16_t *p, unsigned n)
|
||||
{
|
||||
SET_LE16(p, n);
|
||||
}
|
||||
inline void set_le(BOOST::uint32_t *p, unsigned n)
|
||||
{
|
||||
SET_LE32(p, n);
|
||||
}
|
||||
inline void set_be(BOOST::uint16_t *p, unsigned n)
|
||||
{
|
||||
SET_BE16(p, n);
|
||||
}
|
||||
inline void set_be(BOOST::uint32_t *p, unsigned n)
|
||||
{
|
||||
SET_BE32(p, n);
|
||||
}
|
||||
inline unsigned get_le(BOOST::uint16_t const *p)
|
||||
{
|
||||
return GET_LE16(p);
|
||||
}
|
||||
inline unsigned get_le(BOOST::uint32_t const *p)
|
||||
{
|
||||
return GET_LE32(p);
|
||||
}
|
||||
inline unsigned get_be(BOOST::uint16_t const *p)
|
||||
{
|
||||
return GET_BE16(p);
|
||||
}
|
||||
inline unsigned get_be(BOOST::uint32_t const *p)
|
||||
{
|
||||
return GET_BE32(p);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
#define BLARGG_ERRORS_H
|
||||
|
||||
#ifndef BLARGG_COMMON_H
|
||||
#include "blargg_common.h"
|
||||
#include "blargg_common.h"
|
||||
#endif
|
||||
|
||||
typedef const char blargg_err_def_t [];
|
||||
typedef const char blargg_err_def_t[];
|
||||
|
||||
// Basic errors
|
||||
extern blargg_err_def_t blargg_err_generic;
|
||||
|
@ -26,55 +26,55 @@ extern blargg_err_def_t blargg_err_file_full;
|
|||
extern blargg_err_def_t blargg_err_file_eof;
|
||||
|
||||
// File high-level
|
||||
extern blargg_err_def_t blargg_err_file_type; // wrong file type
|
||||
extern blargg_err_def_t blargg_err_file_type; // wrong file type
|
||||
extern blargg_err_def_t blargg_err_file_feature;
|
||||
extern blargg_err_def_t blargg_err_file_corrupt;
|
||||
|
||||
// C string describing error, or "" if err == NULL
|
||||
const char* blargg_err_str( blargg_err_t err );
|
||||
const char *blargg_err_str(blargg_err_t err);
|
||||
|
||||
// True iff error is of given type, or false if err == NULL
|
||||
bool blargg_is_err_type( blargg_err_t, const char type [] );
|
||||
bool blargg_is_err_type(blargg_err_t, const char type[]);
|
||||
|
||||
// Details of error without describing main cause, or "" if err == NULL
|
||||
const char* blargg_err_details( blargg_err_t err );
|
||||
const char *blargg_err_details(blargg_err_t err);
|
||||
|
||||
// Converts error string to integer code using mapping table. Calls blargg_is_err_type()
|
||||
// for each str and returns code on first match. Returns 0 if err == NULL.
|
||||
struct blargg_err_to_code_t {
|
||||
const char* str;
|
||||
int code;
|
||||
const char *str;
|
||||
int code;
|
||||
};
|
||||
int blargg_err_to_code( blargg_err_t err, blargg_err_to_code_t const [] );
|
||||
int blargg_err_to_code(blargg_err_t err, blargg_err_to_code_t const[]);
|
||||
|
||||
// Converts error code back to string. If code == 0, returns NULL. If not in table,
|
||||
// returns blargg_err_generic.
|
||||
blargg_err_t blargg_code_to_err( int code, blargg_err_to_code_t const [] );
|
||||
blargg_err_t blargg_code_to_err(int code, blargg_err_to_code_t const[]);
|
||||
|
||||
// Generates error string literal with details of cause
|
||||
#define BLARGG_ERR( type, str ) (type "; " str)
|
||||
#define BLARGG_ERR(type, str) (type "; " str)
|
||||
|
||||
// Extra space to make it clear when blargg_err_str() isn't called to get
|
||||
// printable version of error. At some point, I might prefix error strings
|
||||
// with a code, to speed conversion to a code.
|
||||
#define BLARGG_ERR_TYPE( str ) " " str
|
||||
#define BLARGG_ERR_TYPE(str) " " str
|
||||
|
||||
// Error types to pass to BLARGG_ERR macro
|
||||
#define BLARGG_ERR_GENERIC BLARGG_ERR_TYPE( "operation failed" )
|
||||
#define BLARGG_ERR_MEMORY BLARGG_ERR_TYPE( "out of memory" )
|
||||
#define BLARGG_ERR_CALLER BLARGG_ERR_TYPE( "internal usage bug" )
|
||||
#define BLARGG_ERR_INTERNAL BLARGG_ERR_TYPE( "internal bug" )
|
||||
#define BLARGG_ERR_LIMITATION BLARGG_ERR_TYPE( "exceeded limitation" )
|
||||
#define BLARGG_ERR_GENERIC BLARGG_ERR_TYPE("operation failed")
|
||||
#define BLARGG_ERR_MEMORY BLARGG_ERR_TYPE("out of memory")
|
||||
#define BLARGG_ERR_CALLER BLARGG_ERR_TYPE("internal usage bug")
|
||||
#define BLARGG_ERR_INTERNAL BLARGG_ERR_TYPE("internal bug")
|
||||
#define BLARGG_ERR_LIMITATION BLARGG_ERR_TYPE("exceeded limitation")
|
||||
|
||||
#define BLARGG_ERR_FILE_MISSING BLARGG_ERR_TYPE( "file not found" )
|
||||
#define BLARGG_ERR_FILE_READ BLARGG_ERR_TYPE( "couldn't open file" )
|
||||
#define BLARGG_ERR_FILE_WRITE BLARGG_ERR_TYPE( "couldn't modify file" )
|
||||
#define BLARGG_ERR_FILE_IO BLARGG_ERR_TYPE( "read/write error" )
|
||||
#define BLARGG_ERR_FILE_FULL BLARGG_ERR_TYPE( "disk full" )
|
||||
#define BLARGG_ERR_FILE_EOF BLARGG_ERR_TYPE( "truncated file" )
|
||||
#define BLARGG_ERR_FILE_MISSING BLARGG_ERR_TYPE("file not found")
|
||||
#define BLARGG_ERR_FILE_READ BLARGG_ERR_TYPE("couldn't open file")
|
||||
#define BLARGG_ERR_FILE_WRITE BLARGG_ERR_TYPE("couldn't modify file")
|
||||
#define BLARGG_ERR_FILE_IO BLARGG_ERR_TYPE("read/write error")
|
||||
#define BLARGG_ERR_FILE_FULL BLARGG_ERR_TYPE("disk full")
|
||||
#define BLARGG_ERR_FILE_EOF BLARGG_ERR_TYPE("truncated file")
|
||||
|
||||
#define BLARGG_ERR_FILE_TYPE BLARGG_ERR_TYPE( "wrong file type" )
|
||||
#define BLARGG_ERR_FILE_FEATURE BLARGG_ERR_TYPE( "unsupported file feature" )
|
||||
#define BLARGG_ERR_FILE_CORRUPT BLARGG_ERR_TYPE( "corrupt file" )
|
||||
#define BLARGG_ERR_FILE_TYPE BLARGG_ERR_TYPE("wrong file type")
|
||||
#define BLARGG_ERR_FILE_FEATURE BLARGG_ERR_TYPE("unsupported file feature")
|
||||
#define BLARGG_ERR_FILE_CORRUPT BLARGG_ERR_TYPE("corrupt file")
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,12 +8,12 @@ global namespace with unprefixed names. */
|
|||
#define BLARGG_SOURCE_H
|
||||
|
||||
#ifndef BLARGG_COMMON_H // optimization only
|
||||
#include "blargg_common.h"
|
||||
#include "blargg_common.h"
|
||||
#endif
|
||||
#include "blargg_errors.h"
|
||||
|
||||
#include <string.h> /* memcpy(), memset(), memmove() */
|
||||
#include <stddef.h> /* offsetof() */
|
||||
#include <string.h> /* memcpy(), memset(), memmove() */
|
||||
|
||||
/* The following four macros are for debugging only. Some or all might be
|
||||
defined to do nothing, depending on the circumstances. Described is what
|
||||
|
@ -33,82 +33,94 @@ control of the module. A failed requirement probably indicates a bug in YOUR
|
|||
code.
|
||||
|
||||
void require( bool expr ); */
|
||||
#undef require
|
||||
#define require( expr ) assert( expr )
|
||||
#undef require
|
||||
#define require(expr) assert(expr)
|
||||
|
||||
/* Like printf() except output goes to debugging console/file.
|
||||
|
||||
void dprintf( const char format [], ... ); */
|
||||
static inline void blargg_dprintf_( const char [], ... ) { }
|
||||
#undef dprintf
|
||||
#define dprintf (1) ? (void) 0 : blargg_dprintf_
|
||||
static inline void blargg_dprintf_(const char[], ...)
|
||||
{
|
||||
}
|
||||
#undef dprintf
|
||||
#define dprintf (1) ? (void)0 : blargg_dprintf_
|
||||
|
||||
/* If expr is false, prints file and line number to debug console/log, then
|
||||
continues execution normally. Meant for flagging potential problems or things
|
||||
that should be looked into, but that aren't serious problems.
|
||||
|
||||
void check( bool expr ); */
|
||||
#undef check
|
||||
#define check( expr ) ((void) 0)
|
||||
#undef check
|
||||
#define check(expr) ((void)0)
|
||||
|
||||
/* If expr yields non-NULL error string, returns it from current function,
|
||||
otherwise continues normally. */
|
||||
#undef RETURN_ERR
|
||||
#define RETURN_ERR( expr ) \
|
||||
do {\
|
||||
blargg_err_t blargg_return_err_ = (expr);\
|
||||
if ( blargg_return_err_ )\
|
||||
return blargg_return_err_;\
|
||||
} while ( 0 )
|
||||
#undef RETURN_ERR
|
||||
#define RETURN_ERR(expr) \
|
||||
do { \
|
||||
blargg_err_t blargg_return_err_ = (expr); \
|
||||
if (blargg_return_err_) \
|
||||
return blargg_return_err_; \
|
||||
} while (0)
|
||||
|
||||
/* If ptr is NULL, returns out-of-memory error, otherwise continues normally. */
|
||||
#undef CHECK_ALLOC
|
||||
#define CHECK_ALLOC( ptr ) \
|
||||
do {\
|
||||
if ( !(ptr) )\
|
||||
return blargg_err_memory;\
|
||||
} while ( 0 )
|
||||
#undef CHECK_ALLOC
|
||||
#define CHECK_ALLOC(ptr) \
|
||||
do { \
|
||||
if (!(ptr)) \
|
||||
return blargg_err_memory; \
|
||||
} while (0)
|
||||
|
||||
/* The usual min/max functions for built-in types.
|
||||
|
||||
template<typename T> T min( T x, T y ) { return x < y ? x : y; }
|
||||
template<typename T> T max( T x, T y ) { return x > y ? x : y; } */
|
||||
#define BLARGG_DEF_MIN_MAX( type ) \
|
||||
static inline type blargg_min( type x, type y ) { if ( y < x ) x = y; return x; }\
|
||||
static inline type blargg_max( type x, type y ) { if ( x < y ) x = y; return x; }
|
||||
#define BLARGG_DEF_MIN_MAX(type) \
|
||||
static inline type blargg_min(type x, type y) \
|
||||
{ \
|
||||
if (y < x) \
|
||||
x = y; \
|
||||
return x; \
|
||||
} \
|
||||
static inline type blargg_max(type x, type y) \
|
||||
{ \
|
||||
if (x < y) \
|
||||
x = y; \
|
||||
return x; \
|
||||
}
|
||||
|
||||
BLARGG_DEF_MIN_MAX( int )
|
||||
BLARGG_DEF_MIN_MAX( unsigned )
|
||||
BLARGG_DEF_MIN_MAX( long )
|
||||
BLARGG_DEF_MIN_MAX( unsigned long )
|
||||
BLARGG_DEF_MIN_MAX( float )
|
||||
BLARGG_DEF_MIN_MAX( double )
|
||||
BLARGG_DEF_MIN_MAX(int)
|
||||
BLARGG_DEF_MIN_MAX(unsigned)
|
||||
BLARGG_DEF_MIN_MAX(long)
|
||||
BLARGG_DEF_MIN_MAX(unsigned long)
|
||||
BLARGG_DEF_MIN_MAX(float)
|
||||
BLARGG_DEF_MIN_MAX(double)
|
||||
|
||||
#undef min
|
||||
#undef min
|
||||
#define min blargg_min
|
||||
|
||||
#undef max
|
||||
#undef max
|
||||
#define max blargg_max
|
||||
|
||||
// typedef unsigned char byte;
|
||||
typedef unsigned char blargg_byte;
|
||||
#undef byte
|
||||
#undef byte
|
||||
#define byte blargg_byte
|
||||
|
||||
#ifndef BLARGG_EXPORT
|
||||
#if defined (_WIN32) && BLARGG_BUILD_DLL
|
||||
#define BLARGG_EXPORT __declspec(dllexport)
|
||||
#elif defined (__GNUC__)
|
||||
// can always set visibility, even when not building DLL
|
||||
#define BLARGG_EXPORT __attribute__ ((visibility ("default")))
|
||||
#else
|
||||
#define BLARGG_EXPORT
|
||||
#endif
|
||||
#if defined(_WIN32) && BLARGG_BUILD_DLL
|
||||
#define BLARGG_EXPORT __declspec(dllexport)
|
||||
#elif defined(__GNUC__)
|
||||
// can always set visibility, even when not building DLL
|
||||
#define BLARGG_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define BLARGG_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BLARGG_LEGACY
|
||||
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
|
||||
#define BLARGG_RETURN_ERR RETURN_ERR
|
||||
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
|
||||
#define BLARGG_RETURN_ERR RETURN_ERR
|
||||
#endif
|
||||
|
||||
// Called after failed operation when overall operation may still complete OK.
|
||||
|
@ -119,7 +131,7 @@ typedef unsigned char blargg_byte;
|
|||
/* BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf etc.
|
||||
and check */
|
||||
#ifdef BLARGG_SOURCE_BEGIN
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
113
fex/fex/fex.h
113
fex/fex/fex.h
|
@ -7,10 +7,9 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** First parameter of most functions is fex_t*, or const fex_t* if nothing is
|
||||
changed. Once one of these functions returns an error, the archive should not
|
||||
be used any further, other than to close it. One exception is
|
||||
|
@ -20,185 +19,175 @@ typedef struct fex_t fex_t;
|
|||
/** Pointer to error, or NULL if function was successful. See error functions
|
||||
below. */
|
||||
#ifndef fex_err_t /* (#ifndef allows better testing of library) */
|
||||
typedef const char* fex_err_t;
|
||||
typedef const char *fex_err_t;
|
||||
#endif
|
||||
|
||||
|
||||
/**** File types ****/
|
||||
|
||||
/** Archive file type identifier. Can also hold NULL. */
|
||||
typedef const struct fex_type_t_* fex_type_t;
|
||||
typedef const struct fex_type_t_ *fex_type_t;
|
||||
|
||||
/** Array of supported types, with NULL at end */
|
||||
const fex_type_t* fex_type_list( void );
|
||||
const fex_type_t *fex_type_list(void);
|
||||
|
||||
/** Name of this archive type, e.g. "ZIP archive", "file" */
|
||||
const char* fex_type_name( fex_type_t );
|
||||
const char *fex_type_name(fex_type_t);
|
||||
|
||||
/** Usual file extension for type, e.g. ".zip", ".7z". For binary file type,
|
||||
returns "", since it can open any file. */
|
||||
const char* fex_type_extension( fex_type_t );
|
||||
|
||||
const char *fex_type_extension(fex_type_t);
|
||||
|
||||
/**** Wide-character file paths ****/
|
||||
|
||||
/** Converts wide-character path to form suitable for use with fex functions. */
|
||||
char* fex_wide_to_path( const wchar_t* wide );
|
||||
char *fex_wide_to_path(const wchar_t *wide);
|
||||
|
||||
/** Frees converted path. OK to pass NULL. */
|
||||
void fex_free_path( char* );
|
||||
|
||||
void fex_free_path(char *);
|
||||
|
||||
/**** Identification ****/
|
||||
|
||||
/** True if str ends in extension. If extension is "", always returns true.
|
||||
Converts str to lowercase before comparison, so extension should ALREADY be
|
||||
lowercase (i.e. pass ".zip", NOT ".ZIP"). */
|
||||
int fex_has_extension( const char str [], const char extension [] );
|
||||
int fex_has_extension(const char str[], const char extension[]);
|
||||
|
||||
/** Determines type based on first fex_identify_header_size bytes of file.
|
||||
Returns usual file extension this should have (e.g. ".zip", ".gz", etc.).
|
||||
Returns "" if file header is not recognized. */
|
||||
const char* fex_identify_header( const void* header );
|
||||
const char *fex_identify_header(const void *header);
|
||||
enum { fex_identify_header_size = 16 };
|
||||
|
||||
/** Determines type based on extension of a file path, or just a lone extension
|
||||
(must include '.', e.g. ".zip", NOT just "zip"). Returns NULL if extension is
|
||||
for an unsupported type (e.g. ".lzh"). */
|
||||
fex_type_t fex_identify_extension( const char path_or_extension [] );
|
||||
fex_type_t fex_identify_extension(const char path_or_extension[]);
|
||||
|
||||
/** Determines type based on filename extension and/or file header. Sets *out
|
||||
to determined type, or NULL if type is not supported. */
|
||||
fex_err_t fex_identify_file( fex_type_t* out, const char path [] );
|
||||
fex_err_t fex_identify_file(fex_type_t *out, const char path[]);
|
||||
|
||||
/** Type of an already-opened archive */
|
||||
fex_type_t fex_type( const fex_t* );
|
||||
|
||||
fex_type_t fex_type(const fex_t *);
|
||||
|
||||
/**** Open/close ****/
|
||||
|
||||
/** Initializes static tables used by library. Automatically called by
|
||||
fex_open(). OK to call more than once. */
|
||||
fex_err_t fex_init( void );
|
||||
fex_err_t fex_init(void);
|
||||
|
||||
/** Opens archive and points *out at it. If error, sets *out to NULL. */
|
||||
fex_err_t fex_open( fex_t** out, const char path [] );
|
||||
fex_err_t fex_open(fex_t **out, const char path[]);
|
||||
|
||||
/** Opens archive of specified type and sets *out. Returns error if file is not
|
||||
of that archive type. If error, sets *out to NULL. */
|
||||
fex_err_t fex_open_type( fex_t** out, const char path [], fex_type_t );
|
||||
fex_err_t fex_open_type(fex_t **out, const char path[], fex_type_t);
|
||||
|
||||
/** Closes archive and frees memory. OK to pass NULL. */
|
||||
void fex_close( fex_t* );
|
||||
|
||||
void fex_close(fex_t *);
|
||||
|
||||
/**** Scanning ****/
|
||||
|
||||
/** True if at end of archive. Must be called after fex_open() or fex_rewind(),
|
||||
as an archive might contain no files. */
|
||||
int fex_done( const fex_t* );
|
||||
int fex_done(const fex_t *);
|
||||
|
||||
/** Goes to next file in archive. If there are no more files, fex_done() will
|
||||
now return true. */
|
||||
fex_err_t fex_next( fex_t* );
|
||||
fex_err_t fex_next(fex_t *);
|
||||
|
||||
/** Goes back to first file in archive, as if it were just opened with
|
||||
fex_open() */
|
||||
fex_err_t fex_rewind( fex_t* );
|
||||
fex_err_t fex_rewind(fex_t *);
|
||||
|
||||
/** Saved position in archive. Can also store zero. */
|
||||
typedef int fex_pos_t;
|
||||
|
||||
/** Position of current file in archive. Never returns zero. */
|
||||
fex_pos_t fex_tell_arc( const fex_t* );
|
||||
fex_pos_t fex_tell_arc(const fex_t *);
|
||||
|
||||
/** Returns to file at previously-saved position */
|
||||
fex_err_t fex_seek_arc( fex_t*, fex_pos_t );
|
||||
|
||||
fex_err_t fex_seek_arc(fex_t *, fex_pos_t);
|
||||
|
||||
/**** Info ****/
|
||||
|
||||
/** Name of current file */
|
||||
const char* fex_name( const fex_t* );
|
||||
const char *fex_name(const fex_t *);
|
||||
|
||||
/** Wide-character name of current file, or NULL if unavailable */
|
||||
const wchar_t* fex_wname( const fex_t* );
|
||||
const wchar_t *fex_wname(const fex_t *);
|
||||
|
||||
/** Makes further information available for file */
|
||||
fex_err_t fex_stat( fex_t* );
|
||||
fex_err_t fex_stat(fex_t *);
|
||||
|
||||
/** Size of current file. fex_stat() or fex_data() must have been called. */
|
||||
int fex_size( const fex_t* );
|
||||
int fex_size(const fex_t *);
|
||||
|
||||
/** Modification date of current file (MS-DOS format), or 0 if unavailable.
|
||||
fex_stat() must have been called. */
|
||||
unsigned int fex_dos_date( const fex_t* );
|
||||
unsigned int fex_dos_date(const fex_t *);
|
||||
|
||||
/** CRC-32 checksum of current file's contents, or 0 if unavailable. Doesn't
|
||||
require calculation; simply gets it from file's header. fex_stat() must have
|
||||
been called. */
|
||||
unsigned int fex_crc32( const fex_t* );
|
||||
|
||||
unsigned int fex_crc32(const fex_t *);
|
||||
|
||||
/**** Extraction ****/
|
||||
|
||||
/** Reads n bytes from current file. Reading past end of file results in
|
||||
fex_err_file_eof. */
|
||||
fex_err_t fex_read( fex_t*, void* out, int n );
|
||||
fex_err_t fex_read(fex_t *, void *out, int n);
|
||||
|
||||
/** Number of bytes read from current file */
|
||||
int fex_tell( const fex_t* );
|
||||
int fex_tell(const fex_t *);
|
||||
|
||||
/** Points *out at current file's data in memory. Pointer is valid until
|
||||
fex_next(), fex_rewind(), fex_seek_arc(), or fex_close() is called. Pointer
|
||||
must NOT be freed(); library frees it automatically. If error, sets *out to
|
||||
NULL. */
|
||||
fex_err_t fex_data( fex_t*, const void** out );
|
||||
|
||||
fex_err_t fex_data(fex_t *, const void **out);
|
||||
|
||||
/**** Errors ****/
|
||||
|
||||
/** Error string associated with err. Returns "" if err is NULL. Returns err
|
||||
unchanged if it isn't a fex_err_t returned by library. */
|
||||
const char* fex_err_str( fex_err_t err );
|
||||
const char *fex_err_str(fex_err_t err);
|
||||
|
||||
/** Details of error beyond main cause, or "" if none or err is NULL. Returns
|
||||
err unchanged if it isn't a fex_err_t returned by library. */
|
||||
const char* fex_err_details( fex_err_t err );
|
||||
const char *fex_err_details(fex_err_t err);
|
||||
|
||||
/** Numeric code corresponding to err. Returns fex_ok if err is NULL. Returns
|
||||
fex_err_generic if err isn't a fex_err_t returned by library. */
|
||||
int fex_err_code( fex_err_t err );
|
||||
int fex_err_code(fex_err_t err);
|
||||
|
||||
enum {
|
||||
fex_ok = 0,/**< Successful call. Guaranteed to be zero. */
|
||||
fex_err_generic = 0x01,/**< Error of unspecified type */
|
||||
fex_err_memory = 0x02,/**< Out of memory */
|
||||
fex_err_caller = 0x03,/**< Caller called function with bad args */
|
||||
fex_err_internal = 0x04,/**< Internal problem, bug, etc. */
|
||||
fex_err_limitation = 0x05,/**< Exceeded program limit */
|
||||
|
||||
fex_err_file_missing = 0x20,/**< File not found at specified path */
|
||||
fex_err_file_read = 0x21,/**< Couldn't open file for reading */
|
||||
fex_err_file_io = 0x23,/**< Read/write error */
|
||||
fex_err_file_eof = 0x25,/**< Tried to read past end of file */
|
||||
|
||||
fex_err_file_type = 0x30,/**< File is of wrong type */
|
||||
fex_err_file_feature = 0x32,/**< File requires unsupported feature */
|
||||
fex_err_file_corrupt = 0x33 /**< File is corrupt */
|
||||
enum { fex_ok = 0, /**< Successful call. Guaranteed to be zero. */
|
||||
fex_err_generic = 0x01, /**< Error of unspecified type */
|
||||
fex_err_memory = 0x02, /**< Out of memory */
|
||||
fex_err_caller = 0x03, /**< Caller called function with bad args */
|
||||
fex_err_internal = 0x04, /**< Internal problem, bug, etc. */
|
||||
fex_err_limitation = 0x05, /**< Exceeded program limit */
|
||||
|
||||
fex_err_file_missing = 0x20, /**< File not found at specified path */
|
||||
fex_err_file_read = 0x21, /**< Couldn't open file for reading */
|
||||
fex_err_file_io = 0x23, /**< Read/write error */
|
||||
fex_err_file_eof = 0x25, /**< Tried to read past end of file */
|
||||
|
||||
fex_err_file_type = 0x30, /**< File is of wrong type */
|
||||
fex_err_file_feature = 0x32, /**< File requires unsupported feature */
|
||||
fex_err_file_corrupt = 0x33 /**< File is corrupt */
|
||||
};
|
||||
|
||||
/** fex_err_t corresponding to numeric code. Note that this might not recover
|
||||
the original fex_err_t before it was converted to a numeric code; in
|
||||
particular, fex_err_details(fex_code_to_err(code)) will be "" in most cases. */
|
||||
fex_err_t fex_code_to_err( int code );
|
||||
|
||||
fex_err_t fex_code_to_err(int code);
|
||||
|
||||
/* Deprecated */
|
||||
typedef fex_t File_Extractor;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
#ifndef __AUTOBUILD_H__
|
||||
#define __AUTOBUILD_H__
|
||||
#include "version.h"
|
||||
//change the FALSE to TRUE for autoincrement of build number
|
||||
// change the FALSE to TRUE for autoincrement of build number
|
||||
#define INCREMENT_VERSION FALSE
|
||||
#define FILEVER 2,0,0,600
|
||||
#define PRODUCTVER 2,0,0,600
|
||||
#define STRFILEVER "2, 0, 0, 600\0"
|
||||
#define STRPRODUCTVER "2, 0, 0, 600\0"
|
||||
#define FILEVER 2, 0, 0, 600
|
||||
#define PRODUCTVER 2, 0, 0, 600
|
||||
#define STRFILEVER "2, 0, 0, 600\0"
|
||||
#define STRPRODUCTVER "2, 0, 0, 600\0"
|
||||
#endif //__AUTOBUILD_H__
|
||||
|
|
84
src/NLS.h
84
src/NLS.h
|
@ -1,45 +1,45 @@
|
|||
#define N_(String) (String)
|
||||
|
||||
#define MSG_UNSUPPORTED_VBA_SGM 1
|
||||
#define MSG_CANNOT_LOAD_SGM 2
|
||||
#define MSG_SAVE_GAME_NOT_USING_BIOS 3
|
||||
#define MSG_SAVE_GAME_USING_BIOS 4
|
||||
#define MSG_UNSUPPORTED_SAVE_TYPE 5
|
||||
#define MSG_CANNOT_OPEN_FILE 6
|
||||
#define MSG_BAD_ZIP_FILE 7
|
||||
#define MSG_NO_IMAGE_ON_ZIP 8
|
||||
#define MSG_ERROR_OPENING_IMAGE 9
|
||||
#define MSG_ERROR_READING_IMAGE 10
|
||||
#define MSG_UNSUPPORTED_BIOS_FUNCTION 11
|
||||
#define MSG_INVALID_BIOS_FILE_SIZE 12
|
||||
#define MSG_INVALID_CHEAT_CODE 13
|
||||
#define MSG_UNKNOWN_ARM_OPCODE 14
|
||||
#define MSG_UNKNOWN_THUMB_OPCODE 15
|
||||
#define MSG_ERROR_CREATING_FILE 16
|
||||
#define MSG_FAILED_TO_READ_SGM 17
|
||||
#define MSG_FAILED_TO_READ_RTC 18
|
||||
#define MSG_UNSUPPORTED_VB_SGM 19
|
||||
#define MSG_CANNOT_LOAD_SGM_FOR 20
|
||||
#define MSG_ERROR_OPENING_IMAGE_FROM 21
|
||||
#define MSG_ERROR_READING_IMAGE_FROM 22
|
||||
#define MSG_UNSUPPORTED_ROM_SIZE 23
|
||||
#define MSG_UNSUPPORTED_RAM_SIZE 24
|
||||
#define MSG_UNKNOWN_CARTRIDGE_TYPE 25
|
||||
#define MSG_MAXIMUM_NUMBER_OF_CHEATS 26
|
||||
#define MSG_INVALID_GAMESHARK_CODE 27
|
||||
#define MSG_INVALID_GAMEGENIE_CODE 28
|
||||
#define MSG_INVALID_CHEAT_TO_REMOVE 29
|
||||
#define MSG_INVALID_CHEAT_CODE_ADDRESS 30
|
||||
#define MSG_UNSUPPORTED_VBA_SGM 1
|
||||
#define MSG_CANNOT_LOAD_SGM 2
|
||||
#define MSG_SAVE_GAME_NOT_USING_BIOS 3
|
||||
#define MSG_SAVE_GAME_USING_BIOS 4
|
||||
#define MSG_UNSUPPORTED_SAVE_TYPE 5
|
||||
#define MSG_CANNOT_OPEN_FILE 6
|
||||
#define MSG_BAD_ZIP_FILE 7
|
||||
#define MSG_NO_IMAGE_ON_ZIP 8
|
||||
#define MSG_ERROR_OPENING_IMAGE 9
|
||||
#define MSG_ERROR_READING_IMAGE 10
|
||||
#define MSG_UNSUPPORTED_BIOS_FUNCTION 11
|
||||
#define MSG_INVALID_BIOS_FILE_SIZE 12
|
||||
#define MSG_INVALID_CHEAT_CODE 13
|
||||
#define MSG_UNKNOWN_ARM_OPCODE 14
|
||||
#define MSG_UNKNOWN_THUMB_OPCODE 15
|
||||
#define MSG_ERROR_CREATING_FILE 16
|
||||
#define MSG_FAILED_TO_READ_SGM 17
|
||||
#define MSG_FAILED_TO_READ_RTC 18
|
||||
#define MSG_UNSUPPORTED_VB_SGM 19
|
||||
#define MSG_CANNOT_LOAD_SGM_FOR 20
|
||||
#define MSG_ERROR_OPENING_IMAGE_FROM 21
|
||||
#define MSG_ERROR_READING_IMAGE_FROM 22
|
||||
#define MSG_UNSUPPORTED_ROM_SIZE 23
|
||||
#define MSG_UNSUPPORTED_RAM_SIZE 24
|
||||
#define MSG_UNKNOWN_CARTRIDGE_TYPE 25
|
||||
#define MSG_MAXIMUM_NUMBER_OF_CHEATS 26
|
||||
#define MSG_INVALID_GAMESHARK_CODE 27
|
||||
#define MSG_INVALID_GAMEGENIE_CODE 28
|
||||
#define MSG_INVALID_CHEAT_TO_REMOVE 29
|
||||
#define MSG_INVALID_CHEAT_CODE_ADDRESS 30
|
||||
#define MSG_UNSUPPORTED_CHEAT_LIST_VERSION 31
|
||||
#define MSG_UNSUPPORTED_CHEAT_LIST_TYPE 32
|
||||
#define MSG_INVALID_GSA_CODE 33
|
||||
#define MSG_CANNOT_IMPORT_SNAPSHOT_FOR 34
|
||||
#define MSG_UNSUPPORTED_SNAPSHOT_FILE 35
|
||||
#define MSG_UNSUPPORTED_ARM_MODE 36
|
||||
#define MSG_UNSUPPORTED_CODE_FILE 37
|
||||
#define MSG_GBA_CODE_WARNING 38
|
||||
#define MSG_INVALID_CBA_CODE 39
|
||||
#define MSG_CBA_CODE_WARNING 40
|
||||
#define MSG_OUT_OF_MEMORY 41
|
||||
#define MSG_WRONG_GAMESHARK_CODE 42
|
||||
#define MSG_UNSUPPORTED_GAMESHARK_CODE 43
|
||||
#define MSG_UNSUPPORTED_CHEAT_LIST_TYPE 32
|
||||
#define MSG_INVALID_GSA_CODE 33
|
||||
#define MSG_CANNOT_IMPORT_SNAPSHOT_FOR 34
|
||||
#define MSG_UNSUPPORTED_SNAPSHOT_FILE 35
|
||||
#define MSG_UNSUPPORTED_ARM_MODE 36
|
||||
#define MSG_UNSUPPORTED_CODE_FILE 37
|
||||
#define MSG_GBA_CODE_WARNING 38
|
||||
#define MSG_INVALID_CBA_CODE 39
|
||||
#define MSG_CBA_CODE_WARNING 40
|
||||
#define MSG_OUT_OF_MEMORY 41
|
||||
#define MSG_WRONG_GAMESHARK_CODE 42
|
||||
#define MSG_UNSUPPORTED_GAMESHARK_CODE 43
|
||||
|
|
76
src/System.h
76
src/System.h
|
@ -10,46 +10,46 @@
|
|||
class SoundDriver;
|
||||
|
||||
struct EmulatedSystem {
|
||||
// main emulation function
|
||||
void (*emuMain)(int);
|
||||
// reset emulator
|
||||
void (*emuReset)();
|
||||
// clean up memory
|
||||
void (*emuCleanUp)();
|
||||
// load battery file
|
||||
bool (*emuReadBattery)(const char *);
|
||||
// write battery file
|
||||
bool (*emuWriteBattery)(const char *);
|
||||
// main emulation function
|
||||
void (*emuMain)(int);
|
||||
// reset emulator
|
||||
void (*emuReset)();
|
||||
// clean up memory
|
||||
void (*emuCleanUp)();
|
||||
// load battery file
|
||||
bool (*emuReadBattery)(const char *);
|
||||
// write battery file
|
||||
bool (*emuWriteBattery)(const char *);
|
||||
#ifdef __LIBRETRO__
|
||||
// load state
|
||||
bool (*emuReadState)(const u8*, unsigned);
|
||||
// load state
|
||||
unsigned (*emuWriteState)(u8*, unsigned);
|
||||
// load state
|
||||
bool (*emuReadState)(const u8 *, unsigned);
|
||||
// load state
|
||||
unsigned (*emuWriteState)(u8 *, unsigned);
|
||||
#else
|
||||
// load state
|
||||
bool (*emuReadState)(const char *);
|
||||
// save state
|
||||
bool (*emuWriteState)(const char *);
|
||||
// load state
|
||||
bool (*emuReadState)(const char *);
|
||||
// save state
|
||||
bool (*emuWriteState)(const char *);
|
||||
#endif
|
||||
// load memory state (rewind)
|
||||
bool (*emuReadMemState)(char *, int);
|
||||
// write memory state (rewind)
|
||||
bool (*emuWriteMemState)(char *, int, long&);
|
||||
// write PNG file
|
||||
bool (*emuWritePNG)(const char *);
|
||||
// write BMP file
|
||||
bool (*emuWriteBMP)(const char *);
|
||||
// emulator update CPSR (ARM only)
|
||||
void (*emuUpdateCPSR)();
|
||||
// emulator has debugger
|
||||
bool emuHasDebugger;
|
||||
// clock ticks to emulate
|
||||
int emuCount;
|
||||
// load memory state (rewind)
|
||||
bool (*emuReadMemState)(char *, int);
|
||||
// write memory state (rewind)
|
||||
bool (*emuWriteMemState)(char *, int, long &);
|
||||
// write PNG file
|
||||
bool (*emuWritePNG)(const char *);
|
||||
// write BMP file
|
||||
bool (*emuWriteBMP)(const char *);
|
||||
// emulator update CPSR (ARM only)
|
||||
void (*emuUpdateCPSR)();
|
||||
// emulator has debugger
|
||||
bool emuHasDebugger;
|
||||
// clock ticks to emulate
|
||||
int emuCount;
|
||||
};
|
||||
|
||||
extern void log(const char *,...);
|
||||
extern void log(const char *, ...);
|
||||
extern bool systemPauseOnFrame();
|
||||
extern void systemGbPrint(u8 *,int,int,int,int,int);
|
||||
extern void systemGbPrint(u8 *, int, int, int, int, int);
|
||||
extern void systemScreenCapture(int);
|
||||
extern void systemDrawScreen();
|
||||
// updates the joystick data
|
||||
|
@ -59,8 +59,8 @@ extern u32 systemReadJoypad(int);
|
|||
extern u32 systemGetClock();
|
||||
extern void systemMessage(int, const char *, ...);
|
||||
extern void systemSetTitle(const char *);
|
||||
extern SoundDriver * systemSoundInit();
|
||||
extern void systemOnWriteDataToSoundBuffer(const u16 * finalWave, int length);
|
||||
extern SoundDriver *systemSoundInit();
|
||||
extern void systemOnWriteDataToSoundBuffer(const u16 *finalWave, int length);
|
||||
extern void systemOnSoundShutdown();
|
||||
extern void systemScreenMessage(const char *);
|
||||
extern void systemUpdateMotionSensor();
|
||||
|
@ -81,7 +81,7 @@ extern bool Sm60FPS_CanSkipFrame();
|
|||
extern void Sm60FPS_Sleep();
|
||||
extern void DbgMsg(const char *msg, ...);
|
||||
extern void (*dbgOutput)(const char *s, u32 addr);
|
||||
extern void (*dbgSignal)(int sig,int number);
|
||||
extern void (*dbgSignal)(int sig, int number);
|
||||
extern u16 systemColorMap16[0x10000];
|
||||
extern u32 systemColorMap32[0x10000];
|
||||
extern u16 systemGbPalette[24];
|
||||
|
@ -95,4 +95,4 @@ extern int systemSaveUpdateCounter;
|
|||
extern int systemSpeed;
|
||||
#define SYSTEM_SAVE_UPDATED 30
|
||||
#define SYSTEM_SAVE_NOT_UPDATED 0
|
||||
#endif // SYSTEM_H
|
||||
#endif // SYSTEM_H
|
||||
|
|
1219
src/Util.cpp
1219
src/Util.cpp
File diff suppressed because it is too large
Load Diff
32
src/Util.h
32
src/Util.h
|
@ -3,21 +3,17 @@
|
|||
|
||||
#include "System.h"
|
||||
|
||||
enum IMAGE_TYPE {
|
||||
IMAGE_UNKNOWN = -1,
|
||||
IMAGE_GBA = 0,
|
||||
IMAGE_GB = 1
|
||||
};
|
||||
enum IMAGE_TYPE { IMAGE_UNKNOWN = -1, IMAGE_GBA = 0, IMAGE_GB = 1 };
|
||||
|
||||
// save game
|
||||
typedef struct {
|
||||
void *address;
|
||||
int size;
|
||||
void *address;
|
||||
int size;
|
||||
} variable_desc;
|
||||
|
||||
bool FileExists(const char *filename);
|
||||
|
||||
void utilReadScreenPixels(u8* dest, int w, int h);
|
||||
void utilReadScreenPixels(u8 *dest, int w, int h);
|
||||
bool utilWritePNGFile(const char *, int, int, u8 *);
|
||||
bool utilWriteBMPFile(const char *, int, int, u8 *);
|
||||
void utilApplyIPS(const char *ips, uint8_t **rom, int *size);
|
||||
|
@ -27,24 +23,23 @@ bool utilIsGzipFile(const char *);
|
|||
bool utilIsZipFile(const char *);
|
||||
void utilStripDoubleExtension(const char *, char *);
|
||||
IMAGE_TYPE utilFindType(const char *);
|
||||
uint8_t *utilLoad(const char *, bool (*)(const char*), uint8_t *, int &);
|
||||
void utilExtract(const char* filepath, const char* filename);
|
||||
uint8_t *utilLoad(const char *, bool (*)(const char *), uint8_t *, int &);
|
||||
void utilExtract(const char *filepath, const char *filename);
|
||||
|
||||
void utilPutDword(uint8_t *, uint32_t);
|
||||
void utilPutWord(uint8_t *, uint16_t);
|
||||
void utilGBAFindSave(const int);
|
||||
void utilUpdateSystemColorMaps(bool lcd = false);
|
||||
bool utilFileExists( const char *filename );
|
||||
|
||||
bool utilFileExists(const char *filename);
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
void utilWriteIntMem(uint8_t *& data, int);
|
||||
void utilWriteMem(uint8_t *& data, const void *in_data, unsigned size);
|
||||
void utilWriteDataMem(uint8_t *& data, variable_desc *);
|
||||
void utilWriteIntMem(uint8_t *&data, int);
|
||||
void utilWriteMem(uint8_t *&data, const void *in_data, unsigned size);
|
||||
void utilWriteDataMem(uint8_t *&data, variable_desc *);
|
||||
|
||||
int utilReadIntMem(const uint8_t *& data);
|
||||
void utilReadMem(void *buf, const uint8_t *& data, unsigned size);
|
||||
void utilReadDataMem(const uint8_t *& data, variable_desc *);
|
||||
int utilReadIntMem(const uint8_t *&data);
|
||||
void utilReadMem(void *buf, const uint8_t *&data, unsigned size);
|
||||
void utilReadDataMem(const uint8_t *&data, variable_desc *);
|
||||
#else
|
||||
gzFile utilGzOpen(const char *file, const char *mode);
|
||||
gzFile utilMemGzOpen(char *memory, int available, const char *mode);
|
||||
|
@ -60,5 +55,4 @@ int utilReadInt(gzFile);
|
|||
void utilWriteInt(gzFile, int);
|
||||
#endif
|
||||
|
||||
|
||||
#endif // UTIL_H
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,136 +8,154 @@
|
|||
|
||||
// See Simple_Effects_Buffer (below) for a simpler interface
|
||||
|
||||
class Effects_Buffer : public Multi_Buffer {
|
||||
public:
|
||||
// To reduce memory usage, fewer buffers can be used (with a best-fit
|
||||
// approach if there are too few), and maximum echo delay can be reduced
|
||||
Effects_Buffer( int max_bufs = 32, long echo_size = 24 * 1024L );
|
||||
class Effects_Buffer : public Multi_Buffer
|
||||
{
|
||||
public:
|
||||
// To reduce memory usage, fewer buffers can be used (with a best-fit
|
||||
// approach if there are too few), and maximum echo delay can be reduced
|
||||
Effects_Buffer(int max_bufs = 32, long echo_size = 24 * 1024L);
|
||||
|
||||
struct pan_vol_t
|
||||
{
|
||||
float vol; // 0.0 = silent, 0.5 = half volume, 1.0 = normal
|
||||
float pan; // -1.0 = left, 0.0 = center, +1.0 = right
|
||||
};
|
||||
struct pan_vol_t {
|
||||
float vol; // 0.0 = silent, 0.5 = half volume, 1.0 = normal
|
||||
float pan; // -1.0 = left, 0.0 = center, +1.0 = right
|
||||
};
|
||||
|
||||
// Global configuration
|
||||
struct config_t
|
||||
{
|
||||
bool enabled; // false = disable all effects
|
||||
// Global configuration
|
||||
struct config_t {
|
||||
bool enabled; // false = disable all effects
|
||||
|
||||
// Current sound is echoed at adjustable left/right delay,
|
||||
// with reduced treble and volume (feedback).
|
||||
float treble; // 1.0 = full treble, 0.1 = very little, 0.0 = silent
|
||||
int delay [2]; // left, right delays (msec)
|
||||
float feedback; // 0.0 = no echo, 0.5 = each echo half previous, 1.0 = cacophony
|
||||
pan_vol_t side_chans [2]; // left and right side channel volume and pan
|
||||
};
|
||||
config_t& config() { return config_; }
|
||||
// Current sound is echoed at adjustable left/right delay,
|
||||
// with reduced treble and volume (feedback).
|
||||
float treble; // 1.0 = full treble, 0.1 = very little, 0.0 = silent
|
||||
int delay[2]; // left, right delays (msec)
|
||||
float feedback; // 0.0 = no echo, 0.5 = each echo half previous, 1.0 = cacophony
|
||||
pan_vol_t side_chans[2]; // left and right side channel volume and pan
|
||||
};
|
||||
config_t &config()
|
||||
{
|
||||
return config_;
|
||||
}
|
||||
|
||||
// Limits of delay (msec)
|
||||
int min_delay() const;
|
||||
int max_delay() const;
|
||||
// Limits of delay (msec)
|
||||
int min_delay() const;
|
||||
int max_delay() const;
|
||||
|
||||
// Per-channel configuration. Two or more channels with matching parameters are
|
||||
// optimized to internally use the same buffer.
|
||||
struct chan_config_t : pan_vol_t
|
||||
{
|
||||
// (inherited from pan_vol_t)
|
||||
//float vol; // these only affect center channel
|
||||
//float pan;
|
||||
bool surround; // if true, negates left volume to put sound in back
|
||||
bool echo; // false = channel doesn't have any echo
|
||||
};
|
||||
chan_config_t& chan_config( int i ) { return chans [i + extra_chans].cfg; }
|
||||
// Per-channel configuration. Two or more channels with matching parameters are
|
||||
// optimized to internally use the same buffer.
|
||||
struct chan_config_t : pan_vol_t {
|
||||
// (inherited from pan_vol_t)
|
||||
// float vol; // these only affect center channel
|
||||
// float pan;
|
||||
bool surround; // if true, negates left volume to put sound in back
|
||||
bool echo; // false = channel doesn't have any echo
|
||||
};
|
||||
chan_config_t &chan_config(int i)
|
||||
{
|
||||
return chans[i + extra_chans].cfg;
|
||||
}
|
||||
|
||||
// Apply any changes made to config() and chan_config()
|
||||
virtual void apply_config();
|
||||
// Apply any changes made to config() and chan_config()
|
||||
virtual void apply_config();
|
||||
|
||||
public:
|
||||
~Effects_Buffer();
|
||||
blargg_err_t set_sample_rate( long samples_per_sec, int msec = blip_default_length );
|
||||
blargg_err_t set_channel_count( int, int const* = 0 );
|
||||
void clock_rate( long );
|
||||
void bass_freq( int );
|
||||
void clear();
|
||||
channel_t channel( int );
|
||||
void end_frame( blip_time_t );
|
||||
long read_samples( blip_sample_t*, long );
|
||||
long samples_avail() const { return (bufs [0].samples_avail() - mixer.samples_read) * 2; }
|
||||
enum { stereo = 2 };
|
||||
typedef blargg_long fixed_t;
|
||||
protected:
|
||||
enum { extra_chans = stereo * stereo };
|
||||
private:
|
||||
config_t config_;
|
||||
long clock_rate_;
|
||||
int bass_freq_;
|
||||
public:
|
||||
~Effects_Buffer();
|
||||
blargg_err_t set_sample_rate(long samples_per_sec, int msec = blip_default_length);
|
||||
blargg_err_t set_channel_count(int, int const * = 0);
|
||||
void clock_rate(long);
|
||||
void bass_freq(int);
|
||||
void clear();
|
||||
channel_t channel(int);
|
||||
void end_frame(blip_time_t);
|
||||
long read_samples(blip_sample_t *, long);
|
||||
long samples_avail() const
|
||||
{
|
||||
return (bufs[0].samples_avail() - mixer.samples_read) * 2;
|
||||
}
|
||||
enum { stereo = 2 };
|
||||
typedef blargg_long fixed_t;
|
||||
|
||||
blargg_long echo_size;
|
||||
protected:
|
||||
enum { extra_chans = stereo * stereo };
|
||||
|
||||
struct chan_t
|
||||
{
|
||||
fixed_t vol [stereo];
|
||||
chan_config_t cfg;
|
||||
channel_t channel;
|
||||
};
|
||||
blargg_vector<chan_t> chans;
|
||||
private:
|
||||
config_t config_;
|
||||
long clock_rate_;
|
||||
int bass_freq_;
|
||||
|
||||
struct buf_t : Tracked_Blip_Buffer
|
||||
{
|
||||
fixed_t vol [stereo];
|
||||
bool echo;
|
||||
blargg_long echo_size;
|
||||
|
||||
void* operator new ( size_t, void* p ) { return p; }
|
||||
void operator delete ( void* ) { }
|
||||
struct chan_t {
|
||||
fixed_t vol[stereo];
|
||||
chan_config_t cfg;
|
||||
channel_t channel;
|
||||
};
|
||||
blargg_vector<chan_t> chans;
|
||||
|
||||
~buf_t() { }
|
||||
};
|
||||
buf_t* bufs;
|
||||
int bufs_size;
|
||||
int bufs_max; // bufs_size <= bufs_max, to limit memory usage
|
||||
Stereo_Mixer mixer;
|
||||
struct buf_t : Tracked_Blip_Buffer {
|
||||
fixed_t vol[stereo];
|
||||
bool echo;
|
||||
|
||||
struct {
|
||||
long delay [stereo];
|
||||
fixed_t treble;
|
||||
fixed_t feedback;
|
||||
fixed_t low_pass [stereo];
|
||||
} s;
|
||||
void *operator new(size_t, void *p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
void operator delete(void *)
|
||||
{
|
||||
}
|
||||
|
||||
blargg_vector<fixed_t> echo;
|
||||
blargg_long echo_pos;
|
||||
~buf_t()
|
||||
{
|
||||
}
|
||||
};
|
||||
buf_t *bufs;
|
||||
int bufs_size;
|
||||
int bufs_max; // bufs_size <= bufs_max, to limit memory usage
|
||||
Stereo_Mixer mixer;
|
||||
|
||||
bool no_effects;
|
||||
bool no_echo;
|
||||
struct {
|
||||
long delay[stereo];
|
||||
fixed_t treble;
|
||||
fixed_t feedback;
|
||||
fixed_t low_pass[stereo];
|
||||
} s;
|
||||
|
||||
void assign_buffers();
|
||||
void clear_echo();
|
||||
void mix_effects( blip_sample_t* out, int pair_count );
|
||||
blargg_err_t new_bufs( int size );
|
||||
void delete_bufs();
|
||||
blargg_vector<fixed_t> echo;
|
||||
blargg_long echo_pos;
|
||||
|
||||
bool no_effects;
|
||||
bool no_echo;
|
||||
|
||||
void assign_buffers();
|
||||
void clear_echo();
|
||||
void mix_effects(blip_sample_t *out, int pair_count);
|
||||
blargg_err_t new_bufs(int size);
|
||||
void delete_bufs();
|
||||
};
|
||||
|
||||
// Simpler interface and lower memory usage
|
||||
class Simple_Effects_Buffer : public Effects_Buffer {
|
||||
public:
|
||||
struct config_t
|
||||
{
|
||||
bool enabled; // false = disable all effects
|
||||
float echo; // 0.0 = none, 1.0 = lots
|
||||
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
|
||||
bool surround; // true = put some channels in back
|
||||
};
|
||||
config_t& config() { return config_; }
|
||||
class Simple_Effects_Buffer : public Effects_Buffer
|
||||
{
|
||||
public:
|
||||
struct config_t {
|
||||
bool enabled; // false = disable all effects
|
||||
float echo; // 0.0 = none, 1.0 = lots
|
||||
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
|
||||
bool surround; // true = put some channels in back
|
||||
};
|
||||
config_t &config()
|
||||
{
|
||||
return config_;
|
||||
}
|
||||
|
||||
// Apply any changes made to config()
|
||||
void apply_config();
|
||||
// Apply any changes made to config()
|
||||
void apply_config();
|
||||
|
||||
public:
|
||||
Simple_Effects_Buffer();
|
||||
private:
|
||||
config_t config_;
|
||||
void chan_config(); // hide
|
||||
public:
|
||||
Simple_Effects_Buffer();
|
||||
|
||||
private:
|
||||
config_t config_;
|
||||
void chan_config(); // hide
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
270
src/apu/Gb_Apu.h
270
src/apu/Gb_Apu.h
|
@ -8,175 +8,185 @@
|
|||
|
||||
struct gb_apu_state_t;
|
||||
|
||||
class Gb_Apu {
|
||||
public:
|
||||
// Basics
|
||||
class Gb_Apu
|
||||
{
|
||||
public:
|
||||
// Basics
|
||||
|
||||
// Clock rate that sound hardware runs at.
|
||||
enum { clock_rate = 4194304 * GB_APU_OVERCLOCK };
|
||||
// Clock rate that sound hardware runs at.
|
||||
enum { clock_rate = 4194304 * GB_APU_OVERCLOCK };
|
||||
|
||||
// Sets buffer(s) to generate sound into. If left and right are NULL, output is mono.
|
||||
// If all are NULL, no output is generated but other emulation still runs.
|
||||
// If chan is specified, only that channel's output is changed, otherwise all are.
|
||||
enum { osc_count = 4 }; // 0: Square 1, 1: Square 2, 2: Wave, 3: Noise
|
||||
void set_output( Blip_Buffer* center, Blip_Buffer* left = NULL, Blip_Buffer* right = NULL,
|
||||
int chan = osc_count );
|
||||
// Sets buffer(s) to generate sound into. If left and right are NULL, output is mono.
|
||||
// If all are NULL, no output is generated but other emulation still runs.
|
||||
// If chan is specified, only that channel's output is changed, otherwise all are.
|
||||
enum { osc_count = 4 }; // 0: Square 1, 1: Square 2, 2: Wave, 3: Noise
|
||||
void set_output(Blip_Buffer *center, Blip_Buffer *left = NULL, Blip_Buffer *right = NULL,
|
||||
int chan = osc_count);
|
||||
|
||||
// Resets hardware to initial power on state BEFORE boot ROM runs. Mode selects
|
||||
// sound hardware. Additional AGB wave features are enabled separately.
|
||||
enum mode_t {
|
||||
mode_dmg, // Game Boy monochrome
|
||||
mode_cgb, // Game Boy Color
|
||||
mode_agb // Game Boy Advance
|
||||
};
|
||||
void reset( mode_t mode = mode_cgb, bool agb_wave = false );
|
||||
// Resets hardware to initial power on state BEFORE boot ROM runs. Mode selects
|
||||
// sound hardware. Additional AGB wave features are enabled separately.
|
||||
enum mode_t {
|
||||
mode_dmg, // Game Boy monochrome
|
||||
mode_cgb, // Game Boy Color
|
||||
mode_agb // Game Boy Advance
|
||||
};
|
||||
void reset(mode_t mode = mode_cgb, bool agb_wave = false);
|
||||
|
||||
// Reads and writes must be within the start_addr to end_addr range, inclusive.
|
||||
// Addresses outside this range are not mapped to the sound hardware.
|
||||
enum { start_addr = 0xFF10 };
|
||||
enum { end_addr = 0xFF3F };
|
||||
enum { register_count = end_addr - start_addr + 1 };
|
||||
// Reads and writes must be within the start_addr to end_addr range, inclusive.
|
||||
// Addresses outside this range are not mapped to the sound hardware.
|
||||
enum { start_addr = 0xFF10 };
|
||||
enum { end_addr = 0xFF3F };
|
||||
enum { register_count = end_addr - start_addr + 1 };
|
||||
|
||||
// Times are specified as the number of clocks since the beginning of the
|
||||
// current time frame.
|
||||
// Times are specified as the number of clocks since the beginning of the
|
||||
// current time frame.
|
||||
|
||||
// Emulates CPU write of data to addr at specified time.
|
||||
void write_register( blip_time_t time, unsigned addr, int data );
|
||||
// Emulates CPU write of data to addr at specified time.
|
||||
void write_register(blip_time_t time, unsigned addr, int data);
|
||||
|
||||
// Emulates CPU read from addr at specified time.
|
||||
int read_register( blip_time_t time, unsigned addr );
|
||||
// Emulates CPU read from addr at specified time.
|
||||
int read_register(blip_time_t time, unsigned addr);
|
||||
|
||||
// Emulates sound hardware up to specified time, ends current time frame, then
|
||||
// starts a new frame at time 0.
|
||||
void end_frame( blip_time_t frame_length );
|
||||
// Emulates sound hardware up to specified time, ends current time frame, then
|
||||
// starts a new frame at time 0.
|
||||
void end_frame(blip_time_t frame_length);
|
||||
|
||||
// Sound adjustments
|
||||
// Sound adjustments
|
||||
|
||||
// Sets overall volume, where 1.0 is normal.
|
||||
void volume( double );
|
||||
// Sets overall volume, where 1.0 is normal.
|
||||
void volume(double);
|
||||
|
||||
// If true, reduces clicking by disabling DAC biasing. Note that this reduces
|
||||
// emulation accuracy, since the clicks are authentic.
|
||||
void reduce_clicks( bool reduce = true );
|
||||
// If true, reduces clicking by disabling DAC biasing. Note that this reduces
|
||||
// emulation accuracy, since the clicks are authentic.
|
||||
void reduce_clicks(bool reduce = true);
|
||||
|
||||
// Sets treble equalization.
|
||||
void treble_eq( blip_eq_t const& );
|
||||
// Sets treble equalization.
|
||||
void treble_eq(blip_eq_t const &);
|
||||
|
||||
// Treble and bass values for various hardware.
|
||||
enum {
|
||||
speaker_treble = -47, // speaker on system
|
||||
speaker_bass = 2000,
|
||||
dmg_treble = 0, // headphones on each system
|
||||
dmg_bass = 30,
|
||||
cgb_treble = 0,
|
||||
cgb_bass = 300, // CGB has much less bass
|
||||
agb_treble = 0,
|
||||
agb_bass = 30
|
||||
};
|
||||
// Treble and bass values for various hardware.
|
||||
enum { speaker_treble = -47, // speaker on system
|
||||
speaker_bass = 2000,
|
||||
dmg_treble = 0, // headphones on each system
|
||||
dmg_bass = 30,
|
||||
cgb_treble = 0,
|
||||
cgb_bass = 300, // CGB has much less bass
|
||||
agb_treble = 0,
|
||||
agb_bass = 30 };
|
||||
|
||||
// Sets frame sequencer rate, where 1.0 is normal. Meant for adjusting the
|
||||
// tempo in a game music player.
|
||||
void set_tempo( double );
|
||||
// Sets frame sequencer rate, where 1.0 is normal. Meant for adjusting the
|
||||
// tempo in a game music player.
|
||||
void set_tempo(double);
|
||||
|
||||
// Save states
|
||||
// Save states
|
||||
|
||||
// Saves full emulation state to state_out. Data format is portable and
|
||||
// includes some extra space to avoid expansion in case more state needs
|
||||
// to be stored in the future.
|
||||
void save_state( gb_apu_state_t* state_out );
|
||||
// Saves full emulation state to state_out. Data format is portable and
|
||||
// includes some extra space to avoid expansion in case more state needs
|
||||
// to be stored in the future.
|
||||
void save_state(gb_apu_state_t *state_out);
|
||||
|
||||
// Loads state. You should call reset() BEFORE this.
|
||||
blargg_err_t load_state( gb_apu_state_t const& in );
|
||||
// Loads state. You should call reset() BEFORE this.
|
||||
blargg_err_t load_state(gb_apu_state_t const &in);
|
||||
|
||||
public:
|
||||
Gb_Apu();
|
||||
public:
|
||||
Gb_Apu();
|
||||
|
||||
// Use set_output() in place of these
|
||||
BLARGG_DEPRECATED void output ( Blip_Buffer* c ) { set_output( c, c, c ); }
|
||||
BLARGG_DEPRECATED void output ( Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r ); }
|
||||
BLARGG_DEPRECATED void osc_output( int i, Blip_Buffer* c ) { set_output( c, c, c, i ); }
|
||||
BLARGG_DEPRECATED void osc_output( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r, i ); }
|
||||
// Use set_output() in place of these
|
||||
BLARGG_DEPRECATED void output(Blip_Buffer *c)
|
||||
{
|
||||
set_output(c, c, c);
|
||||
}
|
||||
BLARGG_DEPRECATED void output(Blip_Buffer *c, Blip_Buffer *l, Blip_Buffer *r)
|
||||
{
|
||||
set_output(c, l, r);
|
||||
}
|
||||
BLARGG_DEPRECATED void osc_output(int i, Blip_Buffer *c)
|
||||
{
|
||||
set_output(c, c, c, i);
|
||||
}
|
||||
BLARGG_DEPRECATED void osc_output(int i, Blip_Buffer *c, Blip_Buffer *l, Blip_Buffer *r)
|
||||
{
|
||||
set_output(c, l, r, i);
|
||||
}
|
||||
|
||||
private:
|
||||
// noncopyable
|
||||
Gb_Apu( const Gb_Apu& );
|
||||
Gb_Apu& operator = ( const Gb_Apu& );
|
||||
private:
|
||||
// noncopyable
|
||||
Gb_Apu(const Gb_Apu &);
|
||||
Gb_Apu &operator=(const Gb_Apu &);
|
||||
|
||||
Gb_Osc* oscs [osc_count];
|
||||
blip_time_t last_time; // time sound emulator has been run to
|
||||
blip_time_t frame_period; // clocks between each frame sequencer step
|
||||
double volume_;
|
||||
bool reduce_clicks_;
|
||||
Gb_Osc *oscs[osc_count];
|
||||
blip_time_t last_time; // time sound emulator has been run to
|
||||
blip_time_t frame_period; // clocks between each frame sequencer step
|
||||
double volume_;
|
||||
bool reduce_clicks_;
|
||||
|
||||
Gb_Sweep_Square square1;
|
||||
Gb_Square square2;
|
||||
Gb_Wave wave;
|
||||
Gb_Noise noise;
|
||||
blip_time_t frame_time; // time of next frame sequencer action
|
||||
int frame_phase; // phase of next frame sequencer step
|
||||
enum { regs_size = register_count + 0x10 };
|
||||
BOOST::uint8_t regs [regs_size];// last values written to registers
|
||||
Gb_Sweep_Square square1;
|
||||
Gb_Square square2;
|
||||
Gb_Wave wave;
|
||||
Gb_Noise noise;
|
||||
blip_time_t frame_time; // time of next frame sequencer action
|
||||
int frame_phase; // phase of next frame sequencer step
|
||||
enum { regs_size = register_count + 0x10 };
|
||||
BOOST::uint8_t regs[regs_size]; // last values written to registers
|
||||
|
||||
// large objects after everything else
|
||||
Gb_Osc::Good_Synth good_synth;
|
||||
Gb_Osc::Med_Synth med_synth;
|
||||
// large objects after everything else
|
||||
Gb_Osc::Good_Synth good_synth;
|
||||
Gb_Osc::Med_Synth med_synth;
|
||||
|
||||
void reset_lengths();
|
||||
void reset_regs();
|
||||
int calc_output( int osc ) const;
|
||||
void apply_stereo();
|
||||
void apply_volume();
|
||||
void synth_volume( int );
|
||||
void run_until_( blip_time_t );
|
||||
void run_until( blip_time_t );
|
||||
void silence_osc( Gb_Osc& );
|
||||
void write_osc( int index, int reg, int old_data, int data );
|
||||
const char* save_load( gb_apu_state_t*, bool save );
|
||||
void save_load2( gb_apu_state_t*, bool save );
|
||||
friend class Gb_Apu_Tester;
|
||||
void reset_lengths();
|
||||
void reset_regs();
|
||||
int calc_output(int osc) const;
|
||||
void apply_stereo();
|
||||
void apply_volume();
|
||||
void synth_volume(int);
|
||||
void run_until_(blip_time_t);
|
||||
void run_until(blip_time_t);
|
||||
void silence_osc(Gb_Osc &);
|
||||
void write_osc(int index, int reg, int old_data, int data);
|
||||
const char *save_load(gb_apu_state_t *, bool save);
|
||||
void save_load2(gb_apu_state_t *, bool save);
|
||||
friend class Gb_Apu_Tester;
|
||||
};
|
||||
|
||||
// Format of save state. Should be stable across versions of the library,
|
||||
// with earlier versions properly opening later save states. Includes some
|
||||
// room for expansion so the state size shouldn't increase.
|
||||
struct gb_apu_state_t
|
||||
{
|
||||
struct gb_apu_state_t {
|
||||
#if GB_APU_CUSTOM_STATE
|
||||
// Values stored as plain int so your code can read/write them easily.
|
||||
// Structure can NOT be written to disk, since format is not portable.
|
||||
typedef int val_t;
|
||||
// Values stored as plain int so your code can read/write them easily.
|
||||
// Structure can NOT be written to disk, since format is not portable.
|
||||
typedef int val_t;
|
||||
#else
|
||||
// Values written in portable little-endian format, allowing structure
|
||||
// to be written directly to disk.
|
||||
typedef unsigned char val_t [4];
|
||||
// Values written in portable little-endian format, allowing structure
|
||||
// to be written directly to disk.
|
||||
typedef unsigned char val_t[4];
|
||||
#endif
|
||||
|
||||
enum { format0 = 0x50414247 };
|
||||
enum { format0 = 0x50414247 };
|
||||
|
||||
val_t format; // format of all following data
|
||||
val_t version; // later versions just add fields to end
|
||||
val_t format; // format of all following data
|
||||
val_t version; // later versions just add fields to end
|
||||
|
||||
unsigned char regs [0x40];
|
||||
val_t frame_time;
|
||||
val_t frame_phase;
|
||||
unsigned char regs[0x40];
|
||||
val_t frame_time;
|
||||
val_t frame_phase;
|
||||
|
||||
val_t sweep_freq;
|
||||
val_t sweep_delay;
|
||||
val_t sweep_enabled;
|
||||
val_t sweep_neg;
|
||||
val_t noise_divider;
|
||||
val_t wave_buf;
|
||||
val_t sweep_freq;
|
||||
val_t sweep_delay;
|
||||
val_t sweep_enabled;
|
||||
val_t sweep_neg;
|
||||
val_t noise_divider;
|
||||
val_t wave_buf;
|
||||
|
||||
val_t delay [4];
|
||||
val_t length_ctr [4];
|
||||
val_t phase [4];
|
||||
val_t enabled [4];
|
||||
val_t delay[4];
|
||||
val_t length_ctr[4];
|
||||
val_t phase[4];
|
||||
val_t enabled[4];
|
||||
|
||||
val_t env_delay [3];
|
||||
val_t env_volume [3];
|
||||
val_t env_enabled [3];
|
||||
val_t env_delay[3];
|
||||
val_t env_volume[3];
|
||||
val_t env_enabled[3];
|
||||
|
||||
val_t unused [13]; // for future expansion
|
||||
val_t unused[13]; // for future expansion
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,188 +4,228 @@
|
|||
#ifndef GB_OSCS_H
|
||||
#define GB_OSCS_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "Blip_Buffer.h"
|
||||
#include "blargg_common.h"
|
||||
|
||||
#ifndef GB_APU_OVERCLOCK
|
||||
#define GB_APU_OVERCLOCK 1
|
||||
#define GB_APU_OVERCLOCK 1
|
||||
#endif
|
||||
|
||||
#if GB_APU_OVERCLOCK & (GB_APU_OVERCLOCK - 1)
|
||||
#error "GB_APU_OVERCLOCK must be a power of 2"
|
||||
#error "GB_APU_OVERCLOCK must be a power of 2"
|
||||
#endif
|
||||
|
||||
class Gb_Osc {
|
||||
protected:
|
||||
|
||||
// 11-bit frequency in NRx3 and NRx4
|
||||
int frequency() const { return (regs [4] & 7) * 0x100 + regs [3]; }
|
||||
|
||||
void update_amp( blip_time_t, int new_amp );
|
||||
int write_trig( int frame_phase, int max_len, int old_data );
|
||||
public:
|
||||
|
||||
enum { clk_mul = GB_APU_OVERCLOCK };
|
||||
enum { dac_bias = 7 };
|
||||
|
||||
Blip_Buffer* outputs [4];// NULL, right, left, center
|
||||
Blip_Buffer* output; // where to output sound
|
||||
BOOST::uint8_t* regs; // osc's 5 registers
|
||||
int mode; // mode_dmg, mode_cgb, mode_agb
|
||||
int dac_off_amp;// amplitude when DAC is off
|
||||
int last_amp; // current amplitude in Blip_Buffer
|
||||
typedef Blip_Synth<blip_good_quality,1> Good_Synth;
|
||||
typedef Blip_Synth<blip_med_quality ,1> Med_Synth;
|
||||
Good_Synth const* good_synth;
|
||||
Med_Synth const* med_synth;
|
||||
|
||||
int delay; // clocks until frequency timer expires
|
||||
int length_ctr; // length counter
|
||||
unsigned phase; // waveform phase (or equivalent)
|
||||
bool enabled; // internal enabled flag
|
||||
|
||||
void clock_length();
|
||||
void reset();
|
||||
};
|
||||
|
||||
class Gb_Env : public Gb_Osc {
|
||||
public:
|
||||
Gb_Env() : env_enabled(false), env_delay(0) {}
|
||||
int env_delay;
|
||||
int volume;
|
||||
bool env_enabled;
|
||||
|
||||
void clock_envelope();
|
||||
bool write_register( int frame_phase, int reg, int old_data, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
env_delay = 0;
|
||||
volume = 0;
|
||||
Gb_Osc::reset();
|
||||
}
|
||||
protected:
|
||||
// Non-zero if DAC is enabled
|
||||
int dac_enabled() const { return regs [2] & 0xF8; }
|
||||
private:
|
||||
void zombie_volume( int old, int data );
|
||||
int reload_env_timer();
|
||||
};
|
||||
|
||||
class Gb_Square : public Gb_Env {
|
||||
public:
|
||||
bool write_register( int frame_phase, int reg, int old_data, int data );
|
||||
void run( blip_time_t, blip_time_t );
|
||||
|
||||
void reset()
|
||||
{
|
||||
Gb_Env::reset();
|
||||
delay = 0x40000000; // TODO: something less hacky (never clocked until first trigger)
|
||||
}
|
||||
private:
|
||||
// Frequency timer period
|
||||
int period() const { return (2048 - frequency()) * (4 * clk_mul); }
|
||||
};
|
||||
|
||||
class Gb_Sweep_Square : public Gb_Square {
|
||||
public:
|
||||
int sweep_freq;
|
||||
int sweep_delay;
|
||||
bool sweep_enabled;
|
||||
bool sweep_neg;
|
||||
|
||||
void clock_sweep();
|
||||
void write_register( int frame_phase, int reg, int old_data, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
sweep_freq = 0;
|
||||
sweep_delay = 0;
|
||||
sweep_enabled = false;
|
||||
sweep_neg = false;
|
||||
Gb_Square::reset();
|
||||
}
|
||||
private:
|
||||
enum { period_mask = 0x70 };
|
||||
enum { shift_mask = 0x07 };
|
||||
|
||||
void calc_sweep( bool update );
|
||||
void reload_sweep_timer();
|
||||
};
|
||||
|
||||
class Gb_Noise : public Gb_Env {
|
||||
public:
|
||||
|
||||
int divider; // noise has more complex frequency divider setup
|
||||
|
||||
void run( blip_time_t, blip_time_t );
|
||||
void write_register( int frame_phase, int reg, int old_data, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
divider = 0;
|
||||
Gb_Env::reset();
|
||||
delay = 4 * clk_mul; // TODO: remove?
|
||||
}
|
||||
private:
|
||||
enum { period2_mask = 0x1FFFF };
|
||||
|
||||
int period2_index() const { return regs [3] >> 4; }
|
||||
int period2( int base = 8 ) const { return base << period2_index(); }
|
||||
unsigned lfsr_mask() const { return (regs [3] & 0x08) ? ~0x4040 : ~0x4000; }
|
||||
};
|
||||
|
||||
class Gb_Wave : public Gb_Osc {
|
||||
public:
|
||||
int sample_buf; // last wave RAM byte read (hardware has this as well)
|
||||
|
||||
void write_register( int frame_phase, int reg, int old_data, int data );
|
||||
void run( blip_time_t, blip_time_t );
|
||||
|
||||
// Reads/writes wave RAM
|
||||
int read( unsigned addr ) const;
|
||||
void write( unsigned addr, int data );
|
||||
|
||||
void reset()
|
||||
{
|
||||
sample_buf = 0;
|
||||
Gb_Osc::reset();
|
||||
}
|
||||
|
||||
private:
|
||||
enum { bank40_mask = 0x40 };
|
||||
enum { bank_size = 32 };
|
||||
|
||||
int agb_mask; // 0xFF if AGB features enabled, 0 otherwise
|
||||
BOOST::uint8_t* wave_ram; // 32 bytes (64 nybbles), stored in APU
|
||||
|
||||
friend class Gb_Apu;
|
||||
|
||||
// Frequency timer period
|
||||
int period() const { return (2048 - frequency()) * (2 * clk_mul); }
|
||||
|
||||
// Non-zero if DAC is enabled
|
||||
int dac_enabled() const { return regs [0] & 0x80; }
|
||||
|
||||
void corrupt_wave();
|
||||
|
||||
BOOST::uint8_t* wave_bank() const { return &wave_ram [(~regs [0] & bank40_mask) >> 2 & agb_mask]; }
|
||||
|
||||
// Wave index that would be accessed, or -1 if no access would occur
|
||||
int access( unsigned addr ) const;
|
||||
};
|
||||
|
||||
inline int Gb_Wave::read( unsigned addr ) const
|
||||
class Gb_Osc
|
||||
{
|
||||
int index = access( addr );
|
||||
return (index < 0 ? 0xFF : wave_bank() [index]);
|
||||
protected:
|
||||
// 11-bit frequency in NRx3 and NRx4
|
||||
int frequency() const
|
||||
{
|
||||
return (regs[4] & 7) * 0x100 + regs[3];
|
||||
}
|
||||
|
||||
void update_amp(blip_time_t, int new_amp);
|
||||
int write_trig(int frame_phase, int max_len, int old_data);
|
||||
|
||||
public:
|
||||
enum { clk_mul = GB_APU_OVERCLOCK };
|
||||
enum { dac_bias = 7 };
|
||||
|
||||
Blip_Buffer *outputs[4]; // NULL, right, left, center
|
||||
Blip_Buffer *output; // where to output sound
|
||||
BOOST::uint8_t *regs; // osc's 5 registers
|
||||
int mode; // mode_dmg, mode_cgb, mode_agb
|
||||
int dac_off_amp; // amplitude when DAC is off
|
||||
int last_amp; // current amplitude in Blip_Buffer
|
||||
typedef Blip_Synth<blip_good_quality, 1> Good_Synth;
|
||||
typedef Blip_Synth<blip_med_quality, 1> Med_Synth;
|
||||
Good_Synth const *good_synth;
|
||||
Med_Synth const *med_synth;
|
||||
|
||||
int delay; // clocks until frequency timer expires
|
||||
int length_ctr; // length counter
|
||||
unsigned phase; // waveform phase (or equivalent)
|
||||
bool enabled; // internal enabled flag
|
||||
|
||||
void clock_length();
|
||||
void reset();
|
||||
};
|
||||
|
||||
class Gb_Env : public Gb_Osc
|
||||
{
|
||||
public:
|
||||
Gb_Env() : env_enabled(false), env_delay(0)
|
||||
{
|
||||
}
|
||||
int env_delay;
|
||||
int volume;
|
||||
bool env_enabled;
|
||||
|
||||
void clock_envelope();
|
||||
bool write_register(int frame_phase, int reg, int old_data, int data);
|
||||
|
||||
void reset()
|
||||
{
|
||||
env_delay = 0;
|
||||
volume = 0;
|
||||
Gb_Osc::reset();
|
||||
}
|
||||
|
||||
protected:
|
||||
// Non-zero if DAC is enabled
|
||||
int dac_enabled() const
|
||||
{
|
||||
return regs[2] & 0xF8;
|
||||
}
|
||||
|
||||
private:
|
||||
void zombie_volume(int old, int data);
|
||||
int reload_env_timer();
|
||||
};
|
||||
|
||||
class Gb_Square : public Gb_Env
|
||||
{
|
||||
public:
|
||||
bool write_register(int frame_phase, int reg, int old_data, int data);
|
||||
void run(blip_time_t, blip_time_t);
|
||||
|
||||
void reset()
|
||||
{
|
||||
Gb_Env::reset();
|
||||
delay = 0x40000000; // TODO: something less hacky (never clocked until first
|
||||
// trigger)
|
||||
}
|
||||
|
||||
private:
|
||||
// Frequency timer period
|
||||
int period() const
|
||||
{
|
||||
return (2048 - frequency()) * (4 * clk_mul);
|
||||
}
|
||||
};
|
||||
|
||||
class Gb_Sweep_Square : public Gb_Square
|
||||
{
|
||||
public:
|
||||
int sweep_freq;
|
||||
int sweep_delay;
|
||||
bool sweep_enabled;
|
||||
bool sweep_neg;
|
||||
|
||||
void clock_sweep();
|
||||
void write_register(int frame_phase, int reg, int old_data, int data);
|
||||
|
||||
void reset()
|
||||
{
|
||||
sweep_freq = 0;
|
||||
sweep_delay = 0;
|
||||
sweep_enabled = false;
|
||||
sweep_neg = false;
|
||||
Gb_Square::reset();
|
||||
}
|
||||
|
||||
private:
|
||||
enum { period_mask = 0x70 };
|
||||
enum { shift_mask = 0x07 };
|
||||
|
||||
void calc_sweep(bool update);
|
||||
void reload_sweep_timer();
|
||||
};
|
||||
|
||||
class Gb_Noise : public Gb_Env
|
||||
{
|
||||
public:
|
||||
int divider; // noise has more complex frequency divider setup
|
||||
|
||||
void run(blip_time_t, blip_time_t);
|
||||
void write_register(int frame_phase, int reg, int old_data, int data);
|
||||
|
||||
void reset()
|
||||
{
|
||||
divider = 0;
|
||||
Gb_Env::reset();
|
||||
delay = 4 * clk_mul; // TODO: remove?
|
||||
}
|
||||
|
||||
private:
|
||||
enum { period2_mask = 0x1FFFF };
|
||||
|
||||
int period2_index() const
|
||||
{
|
||||
return regs[3] >> 4;
|
||||
}
|
||||
int period2(int base = 8) const
|
||||
{
|
||||
return base << period2_index();
|
||||
}
|
||||
unsigned lfsr_mask() const
|
||||
{
|
||||
return (regs[3] & 0x08) ? ~0x4040 : ~0x4000;
|
||||
}
|
||||
};
|
||||
|
||||
class Gb_Wave : public Gb_Osc
|
||||
{
|
||||
public:
|
||||
int sample_buf; // last wave RAM byte read (hardware has this as well)
|
||||
|
||||
void write_register(int frame_phase, int reg, int old_data, int data);
|
||||
void run(blip_time_t, blip_time_t);
|
||||
|
||||
// Reads/writes wave RAM
|
||||
int read(unsigned addr) const;
|
||||
void write(unsigned addr, int data);
|
||||
|
||||
void reset()
|
||||
{
|
||||
sample_buf = 0;
|
||||
Gb_Osc::reset();
|
||||
}
|
||||
|
||||
private:
|
||||
enum { bank40_mask = 0x40 };
|
||||
enum { bank_size = 32 };
|
||||
|
||||
int agb_mask; // 0xFF if AGB features enabled, 0 otherwise
|
||||
BOOST::uint8_t *wave_ram; // 32 bytes (64 nybbles), stored in APU
|
||||
|
||||
friend class Gb_Apu;
|
||||
|
||||
// Frequency timer period
|
||||
int period() const
|
||||
{
|
||||
return (2048 - frequency()) * (2 * clk_mul);
|
||||
}
|
||||
|
||||
// Non-zero if DAC is enabled
|
||||
int dac_enabled() const
|
||||
{
|
||||
return regs[0] & 0x80;
|
||||
}
|
||||
|
||||
void corrupt_wave();
|
||||
|
||||
BOOST::uint8_t *wave_bank() const
|
||||
{
|
||||
return &wave_ram[(~regs[0] & bank40_mask) >> 2 & agb_mask];
|
||||
}
|
||||
|
||||
// Wave index that would be accessed, or -1 if no access would occur
|
||||
int access(unsigned addr) const;
|
||||
};
|
||||
|
||||
inline int Gb_Wave::read(unsigned addr) const
|
||||
{
|
||||
int index = access(addr);
|
||||
return (index < 0 ? 0xFF : wave_bank()[index]);
|
||||
}
|
||||
|
||||
inline void Gb_Wave::write( unsigned addr, int data )
|
||||
inline void Gb_Wave::write(unsigned addr, int data)
|
||||
{
|
||||
int index = access( addr );
|
||||
if ( index >= 0 )
|
||||
wave_bank() [index] = data;;
|
||||
int index = access(addr);
|
||||
if (index >= 0)
|
||||
wave_bank()[index] = data;
|
||||
;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,202 +4,296 @@
|
|||
#ifndef MULTI_BUFFER_H
|
||||
#define MULTI_BUFFER_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "Blip_Buffer.h"
|
||||
#include "blargg_common.h"
|
||||
|
||||
// Interface to one or more Blip_Buffers mapped to one or more channels
|
||||
// consisting of left, center, and right buffers.
|
||||
class Multi_Buffer {
|
||||
public:
|
||||
Multi_Buffer( int samples_per_frame );
|
||||
virtual ~Multi_Buffer() { }
|
||||
class Multi_Buffer
|
||||
{
|
||||
public:
|
||||
Multi_Buffer(int samples_per_frame);
|
||||
virtual ~Multi_Buffer()
|
||||
{
|
||||
}
|
||||
|
||||
// Sets the number of channels available and optionally their types
|
||||
// (type information used by Effects_Buffer)
|
||||
enum { type_index_mask = 0xFF };
|
||||
enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type };
|
||||
virtual blargg_err_t set_channel_count( int, int const* types = 0 );
|
||||
int channel_count() const { return channel_count_; }
|
||||
// Sets the number of channels available and optionally their types
|
||||
// (type information used by Effects_Buffer)
|
||||
enum { type_index_mask = 0xFF };
|
||||
enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type };
|
||||
virtual blargg_err_t set_channel_count(int, int const *types = 0);
|
||||
int channel_count() const
|
||||
{
|
||||
return channel_count_;
|
||||
}
|
||||
|
||||
// Gets indexed channel, from 0 to channel count - 1
|
||||
struct channel_t {
|
||||
Blip_Buffer* center;
|
||||
Blip_Buffer* left;
|
||||
Blip_Buffer* right;
|
||||
};
|
||||
virtual channel_t channel( int index ) BLARGG_PURE( ; )
|
||||
// Gets indexed channel, from 0 to channel count - 1
|
||||
struct channel_t {
|
||||
Blip_Buffer *center;
|
||||
Blip_Buffer *left;
|
||||
Blip_Buffer *right;
|
||||
};
|
||||
virtual channel_t channel(int index) BLARGG_PURE(;)
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual blargg_err_t set_sample_rate( long rate, int msec = blip_default_length ) BLARGG_PURE( ; )
|
||||
virtual void clock_rate( long ) BLARGG_PURE( { } )
|
||||
virtual void bass_freq( int ) BLARGG_PURE( { } )
|
||||
virtual void clear() BLARGG_PURE( { } )
|
||||
long sample_rate() const;
|
||||
// See Blip_Buffer.h
|
||||
virtual blargg_err_t set_sample_rate(long rate, int msec = blip_default_length)
|
||||
BLARGG_PURE(;) virtual void clock_rate(long)
|
||||
BLARGG_PURE({}) virtual void bass_freq(int) BLARGG_PURE({}) virtual void clear()
|
||||
BLARGG_PURE({}) long sample_rate() const;
|
||||
|
||||
// Length of buffer, in milliseconds
|
||||
int length() const;
|
||||
// Length of buffer, in milliseconds
|
||||
int length() const;
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual void end_frame( blip_time_t ) BLARGG_PURE( { } )
|
||||
// See Blip_Buffer.h
|
||||
virtual void end_frame(blip_time_t) BLARGG_PURE({})
|
||||
|
||||
// Number of samples per output frame (1 = mono, 2 = stereo)
|
||||
int samples_per_frame() const;
|
||||
// Number of samples per output frame (1 = mono, 2 = stereo)
|
||||
int samples_per_frame() const;
|
||||
|
||||
// Count of changes to channel configuration. Incremented whenever
|
||||
// a change is made to any of the Blip_Buffers for any channel.
|
||||
unsigned channels_changed_count() { return channels_changed_count_; }
|
||||
// Count of changes to channel configuration. Incremented whenever
|
||||
// a change is made to any of the Blip_Buffers for any channel.
|
||||
unsigned channels_changed_count()
|
||||
{
|
||||
return channels_changed_count_;
|
||||
}
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual long read_samples( blip_sample_t*, long ) BLARGG_PURE( { return 0; } )
|
||||
virtual long samples_avail() const BLARGG_PURE( { return 0; } )
|
||||
// See Blip_Buffer.h
|
||||
virtual long read_samples(blip_sample_t *, long)
|
||||
BLARGG_PURE({ return 0; }) virtual long samples_avail() const BLARGG_PURE({ return 0; })
|
||||
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
void disable_immediate_removal() { immediate_removal_ = false; }
|
||||
protected:
|
||||
bool immediate_removal() const { return immediate_removal_; }
|
||||
int const* channel_types() const { return channel_types_; }
|
||||
void channels_changed() { channels_changed_count_++; }
|
||||
private:
|
||||
// noncopyable
|
||||
Multi_Buffer( const Multi_Buffer& );
|
||||
Multi_Buffer& operator = ( const Multi_Buffer& );
|
||||
public : BLARGG_DISABLE_NOTHROW void disable_immediate_removal()
|
||||
{
|
||||
immediate_removal_ = false;
|
||||
}
|
||||
|
||||
unsigned channels_changed_count_;
|
||||
long sample_rate_;
|
||||
int length_;
|
||||
int channel_count_;
|
||||
int const samples_per_frame_;
|
||||
int const* channel_types_;
|
||||
bool immediate_removal_;
|
||||
protected:
|
||||
bool immediate_removal() const
|
||||
{
|
||||
return immediate_removal_;
|
||||
}
|
||||
int const *channel_types() const
|
||||
{
|
||||
return channel_types_;
|
||||
}
|
||||
void channels_changed()
|
||||
{
|
||||
channels_changed_count_++;
|
||||
}
|
||||
|
||||
private:
|
||||
// noncopyable
|
||||
Multi_Buffer(const Multi_Buffer &);
|
||||
Multi_Buffer &operator=(const Multi_Buffer &);
|
||||
|
||||
unsigned channels_changed_count_;
|
||||
long sample_rate_;
|
||||
int length_;
|
||||
int channel_count_;
|
||||
int const samples_per_frame_;
|
||||
int const *channel_types_;
|
||||
bool immediate_removal_;
|
||||
};
|
||||
|
||||
// Uses a single buffer and outputs mono samples.
|
||||
class Mono_Buffer : public Multi_Buffer {
|
||||
Blip_Buffer buf;
|
||||
channel_t chan;
|
||||
public:
|
||||
// Buffer used for all channels
|
||||
Blip_Buffer* center() { return &buf; }
|
||||
class Mono_Buffer : public Multi_Buffer
|
||||
{
|
||||
Blip_Buffer buf;
|
||||
channel_t chan;
|
||||
|
||||
public:
|
||||
Mono_Buffer();
|
||||
~Mono_Buffer();
|
||||
blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
|
||||
void clock_rate( long rate ) { buf.clock_rate( rate ); }
|
||||
void bass_freq( int freq ) { buf.bass_freq( freq ); }
|
||||
void clear() { buf.clear(); }
|
||||
long samples_avail() const { return buf.samples_avail(); }
|
||||
long read_samples( blip_sample_t* p, long s ) { return buf.read_samples( p, s ); }
|
||||
channel_t channel( int ) { return chan; }
|
||||
void end_frame( blip_time_t t ) { buf.end_frame( t ); }
|
||||
public:
|
||||
// Buffer used for all channels
|
||||
Blip_Buffer *center()
|
||||
{
|
||||
return &buf;
|
||||
}
|
||||
|
||||
public:
|
||||
Mono_Buffer();
|
||||
~Mono_Buffer();
|
||||
blargg_err_t set_sample_rate(long rate, int msec = blip_default_length);
|
||||
void clock_rate(long rate)
|
||||
{
|
||||
buf.clock_rate(rate);
|
||||
}
|
||||
void bass_freq(int freq)
|
||||
{
|
||||
buf.bass_freq(freq);
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
buf.clear();
|
||||
}
|
||||
long samples_avail() const
|
||||
{
|
||||
return buf.samples_avail();
|
||||
}
|
||||
long read_samples(blip_sample_t *p, long s)
|
||||
{
|
||||
return buf.read_samples(p, s);
|
||||
}
|
||||
channel_t channel(int)
|
||||
{
|
||||
return chan;
|
||||
}
|
||||
void end_frame(blip_time_t t)
|
||||
{
|
||||
buf.end_frame(t);
|
||||
}
|
||||
};
|
||||
|
||||
class Tracked_Blip_Buffer : public Blip_Buffer {
|
||||
public:
|
||||
// Non-zero if buffer still has non-silent samples in it. Requires that you call
|
||||
// set_modified() appropriately.
|
||||
blip_ulong non_silent() const;
|
||||
class Tracked_Blip_Buffer : public Blip_Buffer
|
||||
{
|
||||
public:
|
||||
// Non-zero if buffer still has non-silent samples in it. Requires that you call
|
||||
// set_modified() appropriately.
|
||||
blip_ulong non_silent() const;
|
||||
|
||||
// remove_samples( samples_avail() )
|
||||
void remove_all_samples();
|
||||
// remove_samples( samples_avail() )
|
||||
void remove_all_samples();
|
||||
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
|
||||
long read_samples( blip_sample_t*, long );
|
||||
void remove_silence( long );
|
||||
void remove_samples( long );
|
||||
Tracked_Blip_Buffer();
|
||||
void clear();
|
||||
void end_frame( blip_time_t );
|
||||
private:
|
||||
blip_long last_non_silence;
|
||||
void remove_( long );
|
||||
};
|
||||
long read_samples(blip_sample_t *, long);
|
||||
void remove_silence(long);
|
||||
void remove_samples(long);
|
||||
Tracked_Blip_Buffer();
|
||||
void clear();
|
||||
void end_frame(blip_time_t);
|
||||
|
||||
class Stereo_Mixer {
|
||||
public:
|
||||
Tracked_Blip_Buffer* bufs [3];
|
||||
blargg_long samples_read;
|
||||
private:
|
||||
blip_long last_non_silence;
|
||||
void remove_(long);
|
||||
};
|
||||
|
||||
Stereo_Mixer() : samples_read( 0 ) { }
|
||||
void read_pairs( blip_sample_t* out, int count );
|
||||
private:
|
||||
void mix_mono ( blip_sample_t* out, int pair_count );
|
||||
void mix_stereo( blip_sample_t* out, int pair_count );
|
||||
};
|
||||
class Stereo_Mixer
|
||||
{
|
||||
public:
|
||||
Tracked_Blip_Buffer *bufs[3];
|
||||
blargg_long samples_read;
|
||||
|
||||
Stereo_Mixer() : samples_read(0)
|
||||
{
|
||||
}
|
||||
void read_pairs(blip_sample_t *out, int count);
|
||||
|
||||
private:
|
||||
void mix_mono(blip_sample_t *out, int pair_count);
|
||||
void mix_stereo(blip_sample_t *out, int pair_count);
|
||||
};
|
||||
|
||||
// Uses three buffers (one for center) and outputs stereo sample pairs.
|
||||
class Stereo_Buffer : public Multi_Buffer {
|
||||
public:
|
||||
class Stereo_Buffer : public Multi_Buffer
|
||||
{
|
||||
public:
|
||||
// Buffers used for all channels
|
||||
Blip_Buffer *center()
|
||||
{
|
||||
return &bufs[2];
|
||||
}
|
||||
Blip_Buffer *left()
|
||||
{
|
||||
return &bufs[0];
|
||||
}
|
||||
Blip_Buffer *right()
|
||||
{
|
||||
return &bufs[1];
|
||||
}
|
||||
|
||||
// Buffers used for all channels
|
||||
Blip_Buffer* center() { return &bufs [2]; }
|
||||
Blip_Buffer* left() { return &bufs [0]; }
|
||||
Blip_Buffer* right() { return &bufs [1]; }
|
||||
public:
|
||||
Stereo_Buffer();
|
||||
~Stereo_Buffer();
|
||||
blargg_err_t set_sample_rate(long, int msec = blip_default_length);
|
||||
void clock_rate(long);
|
||||
void bass_freq(int);
|
||||
void clear();
|
||||
channel_t channel(int)
|
||||
{
|
||||
return chan;
|
||||
}
|
||||
void end_frame(blip_time_t);
|
||||
|
||||
public:
|
||||
Stereo_Buffer();
|
||||
~Stereo_Buffer();
|
||||
blargg_err_t set_sample_rate( long, int msec = blip_default_length );
|
||||
void clock_rate( long );
|
||||
void bass_freq( int );
|
||||
void clear();
|
||||
channel_t channel( int ) { return chan; }
|
||||
void end_frame( blip_time_t );
|
||||
long samples_avail() const
|
||||
{
|
||||
return (bufs[0].samples_avail() - mixer.samples_read) * 2;
|
||||
}
|
||||
long read_samples(blip_sample_t *, long);
|
||||
|
||||
long samples_avail() const { return (bufs [0].samples_avail() - mixer.samples_read) * 2; }
|
||||
long read_samples( blip_sample_t*, long );
|
||||
|
||||
private:
|
||||
enum { bufs_size = 3 };
|
||||
typedef Tracked_Blip_Buffer buf_t;
|
||||
buf_t bufs [bufs_size];
|
||||
Stereo_Mixer mixer;
|
||||
channel_t chan;
|
||||
long samples_avail_;
|
||||
private:
|
||||
enum { bufs_size = 3 };
|
||||
typedef Tracked_Blip_Buffer buf_t;
|
||||
buf_t bufs[bufs_size];
|
||||
Stereo_Mixer mixer;
|
||||
channel_t chan;
|
||||
long samples_avail_;
|
||||
};
|
||||
|
||||
// Silent_Buffer generates no samples, useful where no sound is wanted
|
||||
class Silent_Buffer : public Multi_Buffer {
|
||||
channel_t chan;
|
||||
public:
|
||||
Silent_Buffer();
|
||||
blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
|
||||
void clock_rate( long ) { }
|
||||
void bass_freq( int ) { }
|
||||
void clear() { }
|
||||
channel_t channel( int ) { return chan; }
|
||||
void end_frame( blip_time_t ) { }
|
||||
long samples_avail() const { return 0; }
|
||||
long read_samples( blip_sample_t*, long ) { return 0; }
|
||||
class Silent_Buffer : public Multi_Buffer
|
||||
{
|
||||
channel_t chan;
|
||||
|
||||
public:
|
||||
Silent_Buffer();
|
||||
blargg_err_t set_sample_rate(long rate, int msec = blip_default_length);
|
||||
void clock_rate(long)
|
||||
{
|
||||
}
|
||||
void bass_freq(int)
|
||||
{
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
}
|
||||
channel_t channel(int)
|
||||
{
|
||||
return chan;
|
||||
}
|
||||
void end_frame(blip_time_t)
|
||||
{
|
||||
}
|
||||
long samples_avail() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
long read_samples(blip_sample_t *, long)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline blargg_err_t Multi_Buffer::set_sample_rate( long rate, int msec )
|
||||
inline blargg_err_t Multi_Buffer::set_sample_rate(long rate, int msec)
|
||||
{
|
||||
sample_rate_ = rate;
|
||||
length_ = msec;
|
||||
return 0;
|
||||
sample_rate_ = rate;
|
||||
length_ = msec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline blargg_err_t Silent_Buffer::set_sample_rate( long rate, int msec )
|
||||
inline blargg_err_t Silent_Buffer::set_sample_rate(long rate, int msec)
|
||||
{
|
||||
return Multi_Buffer::set_sample_rate( rate, msec );
|
||||
return Multi_Buffer::set_sample_rate(rate, msec);
|
||||
}
|
||||
|
||||
inline int Multi_Buffer::samples_per_frame() const { return samples_per_frame_; }
|
||||
|
||||
inline long Multi_Buffer::sample_rate() const { return sample_rate_; }
|
||||
|
||||
inline int Multi_Buffer::length() const { return length_; }
|
||||
|
||||
inline blargg_err_t Multi_Buffer::set_channel_count( int n, int const* types )
|
||||
inline int Multi_Buffer::samples_per_frame() const
|
||||
{
|
||||
channel_count_ = n;
|
||||
channel_types_ = types;
|
||||
return 0;
|
||||
return samples_per_frame_;
|
||||
}
|
||||
|
||||
inline long Multi_Buffer::sample_rate() const
|
||||
{
|
||||
return sample_rate_;
|
||||
}
|
||||
|
||||
inline int Multi_Buffer::length() const
|
||||
{
|
||||
return length_;
|
||||
}
|
||||
|
||||
inline blargg_err_t Multi_Buffer::set_channel_count(int n, int const *types)
|
||||
{
|
||||
channel_count_ = n;
|
||||
channel_types_ = types;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
#ifndef BLARGG_COMMON_H
|
||||
#define BLARGG_COMMON_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#undef BLARGG_COMMON_H
|
||||
// allow blargg_config.h to #include blargg_common.h
|
||||
|
@ -18,188 +18,212 @@
|
|||
|
||||
// BLARGG_RESTRICT: equivalent to restrict, where supported
|
||||
#if __GNUC__ >= 3 || _MSC_VER >= 1100
|
||||
#define BLARGG_RESTRICT __restrict
|
||||
#define BLARGG_RESTRICT __restrict
|
||||
#else
|
||||
#define BLARGG_RESTRICT
|
||||
#define BLARGG_RESTRICT
|
||||
#endif
|
||||
|
||||
// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
|
||||
// CONST_CAST( T,expr): Used in place of const_cast<T> (expr)
|
||||
#ifndef STATIC_CAST
|
||||
#if __GNUC__ >= 4
|
||||
#define STATIC_CAST(T,expr) static_cast<T> (expr)
|
||||
#define CONST_CAST( T,expr) const_cast<T> (expr)
|
||||
#else
|
||||
#define STATIC_CAST(T,expr) ((T) (expr))
|
||||
#define CONST_CAST( T,expr) ((T) (expr))
|
||||
#endif
|
||||
#if __GNUC__ >= 4
|
||||
#define STATIC_CAST(T, expr) static_cast<T>(expr)
|
||||
#define CONST_CAST(T, expr) const_cast<T>(expr)
|
||||
#else
|
||||
#define STATIC_CAST(T, expr) ((T)(expr))
|
||||
#define CONST_CAST(T, expr) ((T)(expr))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// blargg_err_t (0 on success, otherwise error string)
|
||||
#ifndef blargg_err_t
|
||||
typedef const char* blargg_err_t;
|
||||
typedef const char *blargg_err_t;
|
||||
#endif
|
||||
|
||||
// blargg_vector - very lightweight vector of POD types (no constructor/destructor)
|
||||
template<class T>
|
||||
class blargg_vector {
|
||||
T* begin_;
|
||||
size_t size_;
|
||||
public:
|
||||
blargg_vector() : begin_( 0 ), size_( 0 ) { }
|
||||
~blargg_vector() { free( begin_ ); }
|
||||
size_t size() const { return size_; }
|
||||
T* begin() const { return begin_; }
|
||||
T* end() const { return begin_ + size_; }
|
||||
blargg_err_t resize( size_t n )
|
||||
{
|
||||
// TODO: blargg_common.cpp to hold this as an outline function, ugh
|
||||
void* p = realloc( begin_, n * sizeof (T) );
|
||||
if ( p )
|
||||
begin_ = (T*) p;
|
||||
else if ( n > size_ ) // realloc failure only a problem if expanding
|
||||
return "Out of memory";
|
||||
size_ = n;
|
||||
return 0;
|
||||
}
|
||||
void clear() { void* p = begin_; begin_ = 0; size_ = 0; free( p ); }
|
||||
T& operator [] ( size_t n ) const
|
||||
{
|
||||
assert( n <= size_ ); // <= to allow past-the-end value
|
||||
return begin_ [n];
|
||||
}
|
||||
template <class T> class blargg_vector
|
||||
{
|
||||
T *begin_;
|
||||
size_t size_;
|
||||
|
||||
public:
|
||||
blargg_vector() : begin_(0), size_(0)
|
||||
{
|
||||
}
|
||||
~blargg_vector()
|
||||
{
|
||||
free(begin_);
|
||||
}
|
||||
size_t size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
T *begin() const
|
||||
{
|
||||
return begin_;
|
||||
}
|
||||
T *end() const
|
||||
{
|
||||
return begin_ + size_;
|
||||
}
|
||||
blargg_err_t resize(size_t n)
|
||||
{
|
||||
// TODO: blargg_common.cpp to hold this as an outline function, ugh
|
||||
void *p = realloc(begin_, n * sizeof(T));
|
||||
if (p)
|
||||
begin_ = (T *)p;
|
||||
else if (n > size_) // realloc failure only a problem if expanding
|
||||
return "Out of memory";
|
||||
size_ = n;
|
||||
return 0;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
void *p = begin_;
|
||||
begin_ = 0;
|
||||
size_ = 0;
|
||||
free(p);
|
||||
}
|
||||
T &operator[](size_t n) const
|
||||
{
|
||||
assert(n <= size_); // <= to allow past-the-end value
|
||||
return begin_[n];
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BLARGG_DISABLE_NOTHROW
|
||||
// throw spec mandatory in ISO C++ if operator new can return NULL
|
||||
#if __cplusplus >= 199711 || __GNUC__ >= 3
|
||||
#define BLARGG_THROWS( spec ) throw spec
|
||||
#else
|
||||
#define BLARGG_THROWS( spec )
|
||||
#endif
|
||||
#define BLARGG_DISABLE_NOTHROW \
|
||||
void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
|
||||
void operator delete ( void* p ) { free( p ); }
|
||||
#define BLARGG_NEW new
|
||||
// throw spec mandatory in ISO C++ if operator new can return NULL
|
||||
#if __cplusplus >= 199711 || __GNUC__ >= 3
|
||||
#define BLARGG_THROWS(spec) throw spec
|
||||
#else
|
||||
#include <new>
|
||||
#define BLARGG_NEW new (std::nothrow)
|
||||
#define BLARGG_THROWS(spec)
|
||||
#endif
|
||||
#define BLARGG_DISABLE_NOTHROW \
|
||||
void *operator new(size_t s) BLARGG_THROWS(()) \
|
||||
{ \
|
||||
return malloc(s); \
|
||||
} \
|
||||
void operator delete(void *p) \
|
||||
{ \
|
||||
free(p); \
|
||||
}
|
||||
#define BLARGG_NEW new
|
||||
#else
|
||||
#include <new>
|
||||
#define BLARGG_NEW new (std::nothrow)
|
||||
#endif
|
||||
|
||||
// BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant)
|
||||
#define BLARGG_4CHAR( a, b, c, d ) \
|
||||
((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF))
|
||||
#define BLARGG_4CHAR(a, b, c, d) \
|
||||
((a & 0xFF) * 0x1000000 + (b & 0xFF) * 0x10000 + (c & 0xFF) * 0x100 + (d & 0xFF))
|
||||
|
||||
// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
|
||||
#ifndef BOOST_STATIC_ASSERT
|
||||
#ifdef _MSC_VER
|
||||
// MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified
|
||||
#define BOOST_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
|
||||
#else
|
||||
// Some other compilers fail when declaring same function multiple times in class,
|
||||
// so differentiate them by line
|
||||
#define BOOST_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
// MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified
|
||||
#define BOOST_STATIC_ASSERT(expr) void blargg_failed_(int(*arg)[2 / (int)!!(expr)-1])
|
||||
#else
|
||||
// Some other compilers fail when declaring same function multiple times in class,
|
||||
// so differentiate them by line
|
||||
#define BOOST_STATIC_ASSERT(expr) void blargg_failed_(int(*arg)[2 / !!(expr)-1][__LINE__])
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// BLARGG_COMPILER_HAS_BOOL: If 0, provides bool support for old compiler. If 1,
|
||||
// compiler is assumed to support bool. If undefined, availability is determined.
|
||||
#ifndef BLARGG_COMPILER_HAS_BOOL
|
||||
#if defined (__MWERKS__)
|
||||
#if !__option(bool)
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#elif defined (_MSC_VER)
|
||||
#if _MSC_VER < 1100
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#elif defined (__GNUC__)
|
||||
// supports bool
|
||||
#elif __cplusplus < 199711
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#if defined(__MWERKS__)
|
||||
#if !__option(bool)
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#if defined (BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL
|
||||
// If you get errors here, modify your blargg_config.h file
|
||||
typedef int bool;
|
||||
const bool true = 1;
|
||||
const bool false = 0;
|
||||
#elif defined(_MSC_VER)
|
||||
#if _MSC_VER < 1100
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
// supports bool
|
||||
#elif __cplusplus < 199711
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#endif
|
||||
#if defined(BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL
|
||||
// If you get errors here, modify your blargg_config.h file
|
||||
typedef int bool;
|
||||
const bool true = 1;
|
||||
const bool false = 0;
|
||||
#endif
|
||||
|
||||
// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
|
||||
|
||||
#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF
|
||||
typedef long blargg_long;
|
||||
typedef long blargg_long;
|
||||
#else
|
||||
typedef int blargg_long;
|
||||
typedef int blargg_long;
|
||||
#endif
|
||||
|
||||
#if UINT_MAX < 0xFFFFFFFF || ULONG_MAX == 0xFFFFFFFF
|
||||
typedef unsigned long blargg_ulong;
|
||||
typedef unsigned long blargg_ulong;
|
||||
#else
|
||||
typedef unsigned blargg_ulong;
|
||||
typedef unsigned blargg_ulong;
|
||||
#endif
|
||||
|
||||
// BOOST::int8_t etc.
|
||||
|
||||
// HAVE_STDINT_H: If defined, use <stdint.h> for int8_t etc.
|
||||
#if defined (HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#define BOOST
|
||||
#if defined(HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#define BOOST
|
||||
|
||||
// HAVE_INTTYPES_H: If defined, use <stdint.h> for int8_t etc.
|
||||
#elif defined (HAVE_INTTYPES_H)
|
||||
#include <inttypes.h>
|
||||
#define BOOST
|
||||
#elif defined(HAVE_INTTYPES_H)
|
||||
#include <inttypes.h>
|
||||
#define BOOST
|
||||
|
||||
#else
|
||||
struct BOOST
|
||||
{
|
||||
#if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
#else
|
||||
// No suitable 8-bit type available
|
||||
typedef struct see_blargg_common_h int8_t;
|
||||
typedef struct see_blargg_common_h uint8_t;
|
||||
#endif
|
||||
struct BOOST {
|
||||
#if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
#else
|
||||
// No suitable 8-bit type available
|
||||
typedef struct see_blargg_common_h int8_t;
|
||||
typedef struct see_blargg_common_h uint8_t;
|
||||
#endif
|
||||
|
||||
#if USHRT_MAX == 0xFFFF
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
#else
|
||||
// No suitable 16-bit type available
|
||||
typedef struct see_blargg_common_h int16_t;
|
||||
typedef struct see_blargg_common_h uint16_t;
|
||||
#endif
|
||||
#if USHRT_MAX == 0xFFFF
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
#else
|
||||
// No suitable 16-bit type available
|
||||
typedef struct see_blargg_common_h int16_t;
|
||||
typedef struct see_blargg_common_h uint16_t;
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX == 0xFFFFFFFF
|
||||
typedef long int32_t;
|
||||
typedef unsigned long uint32_t;
|
||||
#elif UINT_MAX == 0xFFFFFFFF
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
// No suitable 32-bit type available
|
||||
typedef struct see_blargg_common_h int32_t;
|
||||
typedef struct see_blargg_common_h uint32_t;
|
||||
#endif
|
||||
};
|
||||
#if ULONG_MAX == 0xFFFFFFFF
|
||||
typedef long int32_t;
|
||||
typedef unsigned long uint32_t;
|
||||
#elif UINT_MAX == 0xFFFFFFFF
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
// No suitable 32-bit type available
|
||||
typedef struct see_blargg_common_h int32_t;
|
||||
typedef struct see_blargg_common_h uint32_t;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#define BLARGG_DEPRECATED __attribute__ ((deprecated))
|
||||
#define BLARGG_DEPRECATED __attribute__((deprecated))
|
||||
#else
|
||||
#define BLARGG_DEPRECATED
|
||||
#define BLARGG_DEPRECATED
|
||||
#endif
|
||||
|
||||
// Use in place of "= 0;" for a pure virtual, since these cause calls to std C++ lib.
|
||||
// During development, BLARGG_PURE( x ) expands to = 0;
|
||||
// virtual int func() BLARGG_PURE( { return 0; } )
|
||||
#ifndef BLARGG_PURE
|
||||
#define BLARGG_PURE( def ) def
|
||||
#define BLARGG_PURE(def) def
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
// Use standard config.h if present
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,60 +24,78 @@ unprefixed names. */
|
|||
// of the module. A failed requirement probably indicates a bug in YOUR code.
|
||||
//
|
||||
// void require( bool expr );
|
||||
#undef require
|
||||
#define require( expr ) assert( expr )
|
||||
#undef require
|
||||
#define require(expr) assert(expr)
|
||||
|
||||
// Like printf() except output goes to debugging console/file.
|
||||
//
|
||||
// void dprintf( const char* format, ... );
|
||||
static inline void blargg_dprintf_( const char*, ... ) { }
|
||||
#undef dprintf
|
||||
#define dprintf (1) ? (void) 0 : blargg_dprintf_
|
||||
static inline void blargg_dprintf_(const char *, ...)
|
||||
{
|
||||
}
|
||||
#undef dprintf
|
||||
#define dprintf (1) ? (void)0 : blargg_dprintf_
|
||||
|
||||
// If expr is false, prints file and line number to debug console/log, then
|
||||
// continues execution normally. Meant for flagging potential problems or things
|
||||
// that should be looked into, but that aren't serious problems.
|
||||
//
|
||||
// void check( bool expr );
|
||||
#undef check
|
||||
#define check( expr ) ((void) 0)
|
||||
#undef check
|
||||
#define check(expr) ((void)0)
|
||||
|
||||
// If expr yields non-NULL error string, returns it from current function,
|
||||
// otherwise continues normally.
|
||||
#undef RETURN_ERR
|
||||
#define RETURN_ERR( expr ) do { \
|
||||
blargg_err_t blargg_return_err_ = (expr); \
|
||||
if ( blargg_return_err_ ) return blargg_return_err_; \
|
||||
} while ( 0 )
|
||||
#undef RETURN_ERR
|
||||
#define RETURN_ERR(expr) \
|
||||
do { \
|
||||
blargg_err_t blargg_return_err_ = (expr); \
|
||||
if (blargg_return_err_) \
|
||||
return blargg_return_err_; \
|
||||
} while (0)
|
||||
|
||||
// If ptr is NULL, returns "Out of memory" error string, otherwise continues normally.
|
||||
#undef CHECK_ALLOC
|
||||
#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
|
||||
#undef CHECK_ALLOC
|
||||
#define CHECK_ALLOC(ptr) \
|
||||
do { \
|
||||
if ((ptr) == 0) \
|
||||
return "Out of memory"; \
|
||||
} while (0)
|
||||
|
||||
// The usual min/max functions for built-in types.
|
||||
//
|
||||
// template<typename T> T min( T x, T y ) { return x < y ? x : y; }
|
||||
// template<typename T> T max( T x, T y ) { return x > y ? x : y; }
|
||||
#define BLARGG_DEF_MIN_MAX( type ) \
|
||||
static inline type blargg_min( type x, type y ) { if ( y < x ) x = y; return x; }\
|
||||
static inline type blargg_max( type x, type y ) { if ( x < y ) x = y; return x; }
|
||||
#define BLARGG_DEF_MIN_MAX(type) \
|
||||
static inline type blargg_min(type x, type y) \
|
||||
{ \
|
||||
if (y < x) \
|
||||
x = y; \
|
||||
return x; \
|
||||
} \
|
||||
static inline type blargg_max(type x, type y) \
|
||||
{ \
|
||||
if (x < y) \
|
||||
x = y; \
|
||||
return x; \
|
||||
}
|
||||
|
||||
BLARGG_DEF_MIN_MAX( int )
|
||||
BLARGG_DEF_MIN_MAX( unsigned )
|
||||
BLARGG_DEF_MIN_MAX( long )
|
||||
BLARGG_DEF_MIN_MAX( unsigned long )
|
||||
BLARGG_DEF_MIN_MAX( float )
|
||||
BLARGG_DEF_MIN_MAX( double )
|
||||
BLARGG_DEF_MIN_MAX(int)
|
||||
BLARGG_DEF_MIN_MAX(unsigned)
|
||||
BLARGG_DEF_MIN_MAX(long)
|
||||
BLARGG_DEF_MIN_MAX(unsigned long)
|
||||
BLARGG_DEF_MIN_MAX(float)
|
||||
BLARGG_DEF_MIN_MAX(double)
|
||||
|
||||
#undef min
|
||||
#undef min
|
||||
#define min blargg_min
|
||||
|
||||
#undef max
|
||||
#undef max
|
||||
#define max blargg_max
|
||||
|
||||
// typedef unsigned char byte;
|
||||
typedef unsigned char blargg_byte;
|
||||
#undef byte
|
||||
#undef byte
|
||||
#define byte blargg_byte
|
||||
|
||||
// deprecated
|
||||
|
@ -86,7 +104,7 @@ typedef unsigned char blargg_byte;
|
|||
|
||||
// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf and check
|
||||
#ifdef BLARGG_SOURCE_BEGIN
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
#define _CONFIGMANAGER_H
|
||||
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include "../sdl/filters.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef __GNUC__
|
||||
# define HAVE_DECL_GETOPT 0
|
||||
# define __STDC__ 1
|
||||
# include "getopt.h"
|
||||
#define HAVE_DECL_GETOPT 0
|
||||
#define __STDC__ 1
|
||||
#include "getopt.h"
|
||||
#else // ! __GNUC__
|
||||
# define HAVE_DECL_GETOPT 1
|
||||
# include <getopt.h>
|
||||
#define HAVE_DECL_GETOPT 1
|
||||
#include <getopt.h>
|
||||
#endif // ! __GNUC__
|
||||
|
||||
#define MAX_CHEATS 16384
|
||||
|
@ -21,20 +21,20 @@ extern bool mirroringEnable;
|
|||
extern bool parseDebug;
|
||||
extern bool speedHack;
|
||||
extern bool speedup;
|
||||
extern char* rewindMemory;
|
||||
extern const char* aviRecordDir;
|
||||
extern const char* biosFileNameGB;
|
||||
extern const char* biosFileNameGBA;
|
||||
extern const char* biosFileNameGBC;
|
||||
extern const char* loadDotCodeFile;
|
||||
extern const char* saveDotCodeFile;
|
||||
extern const char* linkHostAddr;
|
||||
extern const char* movieRecordDir;
|
||||
extern const char* romDirGB;
|
||||
extern const char* romDirGBA;
|
||||
extern const char* romDirGBC;
|
||||
extern const char* soundRecordDir;
|
||||
extern int* rewindSerials;
|
||||
extern char *rewindMemory;
|
||||
extern const char *aviRecordDir;
|
||||
extern const char *biosFileNameGB;
|
||||
extern const char *biosFileNameGBA;
|
||||
extern const char *biosFileNameGBC;
|
||||
extern const char *loadDotCodeFile;
|
||||
extern const char *saveDotCodeFile;
|
||||
extern const char *linkHostAddr;
|
||||
extern const char *movieRecordDir;
|
||||
extern const char *romDirGB;
|
||||
extern const char *romDirGBA;
|
||||
extern const char *romDirGBC;
|
||||
extern const char *soundRecordDir;
|
||||
extern int *rewindSerials;
|
||||
extern int active;
|
||||
extern int agbPrint;
|
||||
extern int autoFire;
|
||||
|
@ -100,7 +100,7 @@ extern int rewindPos;
|
|||
extern int rewindSaveNeeded;
|
||||
extern int rewindTimer;
|
||||
extern int rewindTopPos;
|
||||
//extern int romSize;
|
||||
// extern int romSize;
|
||||
extern int rtcEnabled;
|
||||
extern int saveType;
|
||||
extern int screenMessage;
|
||||
|
@ -140,8 +140,7 @@ extern u32 movieNextJoypad;
|
|||
extern int throttle;
|
||||
|
||||
extern int preparedCheats;
|
||||
extern const char* preparedCheatCodes[MAX_CHEATS];
|
||||
|
||||
extern const char *preparedCheatCodes[MAX_CHEATS];
|
||||
|
||||
// allow up to 100 IPS/UPS/PPF patches given on commandline
|
||||
#define PATCH_MAX_NUM 100
|
||||
|
@ -153,11 +152,10 @@ extern int mouseCounter;
|
|||
extern FilterFunc filterFunction;
|
||||
extern IFBFilterFunc ifbFunction;
|
||||
|
||||
|
||||
extern char* homeDir;
|
||||
extern const char* screenShotDir;
|
||||
extern const char* saveDir;
|
||||
extern const char* batteryDir;
|
||||
extern char *homeDir;
|
||||
extern const char *screenShotDir;
|
||||
extern const char *saveDir;
|
||||
extern const char *batteryDir;
|
||||
|
||||
// Directory within homedir to use for default save location.
|
||||
#define DOT_DIR ".vbam"
|
||||
|
@ -165,13 +163,13 @@ extern const char* batteryDir;
|
|||
void SetHome(char *_arg0);
|
||||
void SaveConfigFile();
|
||||
void CloseConfig();
|
||||
u32 ReadPrefHex(const char* pref_key, int default_value);
|
||||
u32 ReadPrefHex(const char* pref_key);
|
||||
u32 ReadPref(const char* pref_key, int default_value);
|
||||
u32 ReadPref(const char* pref_key);
|
||||
const char* ReadPrefString(const char* pref_key, const char* default_value);
|
||||
const char* ReadPrefString(const char* pref_key);
|
||||
void LoadConfigFile(int argc, char ** argv);
|
||||
u32 ReadPrefHex(const char *pref_key, int default_value);
|
||||
u32 ReadPrefHex(const char *pref_key);
|
||||
u32 ReadPref(const char *pref_key, int default_value);
|
||||
u32 ReadPref(const char *pref_key);
|
||||
const char *ReadPrefString(const char *pref_key, const char *default_value);
|
||||
const char *ReadPrefString(const char *pref_key);
|
||||
void LoadConfigFile(int argc, char **argv);
|
||||
void LoadConfig();
|
||||
int ReadOpts(int argc, char ** argv);
|
||||
int ReadOpts(int argc, char **argv);
|
||||
#endif
|
||||
|
|
|
@ -16,53 +16,47 @@
|
|||
// swaps a 16-bit value
|
||||
static inline u16 swap16(u16 v)
|
||||
{
|
||||
return (v<<8)|(v>>8);
|
||||
return (v << 8) | (v >> 8);
|
||||
}
|
||||
|
||||
// swaps a 32-bit value
|
||||
static inline u32 swap32(u32 v)
|
||||
{
|
||||
return (v<<24)|((v<<8)&0xff0000)|((v>>8)&0xff00)|(v>>24);
|
||||
return (v << 24) | ((v << 8) & 0xff0000) | ((v >> 8) & 0xff00) | (v >> 24);
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if defined(__GNUC__) && defined(__ppc__)
|
||||
|
||||
#define READ16LE(base) \
|
||||
({ unsigned short lhbrxResult; \
|
||||
__asm__ ("lhbrx %0, 0, %1" : "=r" (lhbrxResult) : "r" (base) : "memory"); \
|
||||
lhbrxResult; })
|
||||
#define READ16LE(base) \
|
||||
({ \
|
||||
unsigned short lhbrxResult; \
|
||||
__asm__("lhbrx %0, 0, %1" : "=r"(lhbrxResult) : "r"(base) : "memory"); \
|
||||
lhbrxResult; \
|
||||
})
|
||||
|
||||
#define READ32LE(base) \
|
||||
({ unsigned long lwbrxResult; \
|
||||
__asm__ ("lwbrx %0, 0, %1" : "=r" (lwbrxResult) : "r" (base) : "memory"); \
|
||||
lwbrxResult; })
|
||||
#define READ32LE(base) \
|
||||
({ \
|
||||
unsigned long lwbrxResult; \
|
||||
__asm__("lwbrx %0, 0, %1" : "=r"(lwbrxResult) : "r"(base) : "memory"); \
|
||||
lwbrxResult; \
|
||||
})
|
||||
|
||||
#define WRITE16LE(base, value) \
|
||||
__asm__ ("sthbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
|
||||
#define WRITE16LE(base, value) __asm__("sthbrx %0, 0, %1" : : "r"(value), "r"(base) : "memory")
|
||||
|
||||
#define WRITE32LE(base, value) \
|
||||
__asm__ ("stwbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
|
||||
#define WRITE32LE(base, value) __asm__("stwbrx %0, 0, %1" : : "r"(value), "r"(base) : "memory")
|
||||
|
||||
#else
|
||||
#define READ16LE(x) \
|
||||
swap16(*((u16 *)(x)))
|
||||
#define READ32LE(x) \
|
||||
swap32(*((u32 *)(x)))
|
||||
#define WRITE16LE(x,v) \
|
||||
*((u16 *)x) = swap16((v))
|
||||
#define WRITE32LE(x,v) \
|
||||
*((u32 *)x) = swap32((v))
|
||||
#define READ16LE(x) swap16(*((u16 *)(x)))
|
||||
#define READ32LE(x) swap32(*((u32 *)(x)))
|
||||
#define WRITE16LE(x, v) *((u16 *)x) = swap16((v))
|
||||
#define WRITE32LE(x, v) *((u32 *)x) = swap32((v))
|
||||
#endif
|
||||
#else
|
||||
#define READ16LE(x) \
|
||||
*((u16 *)x)
|
||||
#define READ32LE(x) \
|
||||
*((u32 *)x)
|
||||
#define WRITE16LE(x,v) \
|
||||
*((u16 *)x) = (v)
|
||||
#define WRITE32LE(x,v) \
|
||||
*((u32 *)x) = (v)
|
||||
#define READ16LE(x) *((u16 *)x)
|
||||
#define READ32LE(x) *((u32 *)x)
|
||||
#define WRITE16LE(x, v) *((u16 *)x) = (v)
|
||||
#define WRITE32LE(x, v) *((u32 *)x) = (v)
|
||||
#endif
|
||||
|
||||
#endif // PORT_H
|
||||
|
|
|
@ -20,93 +20,100 @@
|
|||
#define RINGBUFFER_H
|
||||
|
||||
#include "array.h"
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
template<typename T>
|
||||
class RingBuffer {
|
||||
Array<T> buf;
|
||||
std::size_t sz;
|
||||
std::size_t rpos;
|
||||
std::size_t wpos;
|
||||
template <typename T> class RingBuffer
|
||||
{
|
||||
Array<T> buf;
|
||||
std::size_t sz;
|
||||
std::size_t rpos;
|
||||
std::size_t wpos;
|
||||
|
||||
public:
|
||||
RingBuffer(const std::size_t sz_in = 0) : sz(0), rpos(0), wpos(0) { reset(sz_in); }
|
||||
public:
|
||||
RingBuffer(const std::size_t sz_in = 0) : sz(0), rpos(0), wpos(0)
|
||||
{
|
||||
reset(sz_in);
|
||||
}
|
||||
|
||||
std::size_t avail() const {
|
||||
return (wpos < rpos ? 0 : sz) + rpos - wpos - 1;
|
||||
}
|
||||
std::size_t avail() const
|
||||
{
|
||||
return (wpos < rpos ? 0 : sz) + rpos - wpos - 1;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
wpos = rpos = 0;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
wpos = rpos = 0;
|
||||
}
|
||||
|
||||
void fill(T value);
|
||||
void fill(T value);
|
||||
|
||||
void read(T *out, std::size_t num);
|
||||
void read(T *out, std::size_t num);
|
||||
|
||||
void reset(std::size_t sz_in);
|
||||
void reset(std::size_t sz_in);
|
||||
|
||||
std::size_t size() const {
|
||||
return sz - 1;
|
||||
}
|
||||
std::size_t size() const
|
||||
{
|
||||
return sz - 1;
|
||||
}
|
||||
|
||||
std::size_t used() const {
|
||||
return (wpos < rpos ? sz : 0) + wpos - rpos;
|
||||
}
|
||||
std::size_t used() const
|
||||
{
|
||||
return (wpos < rpos ? sz : 0) + wpos - rpos;
|
||||
}
|
||||
|
||||
void write(const T *in, std::size_t num);
|
||||
void write(const T *in, std::size_t num);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void RingBuffer<T>::fill(const T value) {
|
||||
std::fill(buf + 0, buf + sz, value);
|
||||
rpos = 0;
|
||||
wpos = sz - 1;
|
||||
template <typename T> void RingBuffer<T>::fill(const T value)
|
||||
{
|
||||
std::fill(buf + 0, buf + sz, value);
|
||||
rpos = 0;
|
||||
wpos = sz - 1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RingBuffer<T>::read(T *out, std::size_t num) {
|
||||
if (rpos + num > sz) {
|
||||
const std::size_t n = sz - rpos;
|
||||
template <typename T> void RingBuffer<T>::read(T *out, std::size_t num)
|
||||
{
|
||||
if (rpos + num > sz) {
|
||||
const std::size_t n = sz - rpos;
|
||||
|
||||
std::memcpy(out, buf + rpos, n * sizeof(T));
|
||||
std::memcpy(out, buf + rpos, n * sizeof(T));
|
||||
|
||||
rpos = 0;
|
||||
num -= n;
|
||||
out += n;
|
||||
}
|
||||
rpos = 0;
|
||||
num -= n;
|
||||
out += n;
|
||||
}
|
||||
|
||||
std::memcpy(out, buf + rpos, num * sizeof(T));
|
||||
std::memcpy(out, buf + rpos, num * sizeof(T));
|
||||
|
||||
if ((rpos += num) == sz)
|
||||
rpos = 0;
|
||||
if ((rpos += num) == sz)
|
||||
rpos = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RingBuffer<T>::reset(const std::size_t sz_in) {
|
||||
sz = sz_in + 1;
|
||||
rpos = wpos = 0;
|
||||
buf.reset(sz_in ? sz : 0);
|
||||
template <typename T> void RingBuffer<T>::reset(const std::size_t sz_in)
|
||||
{
|
||||
sz = sz_in + 1;
|
||||
rpos = wpos = 0;
|
||||
buf.reset(sz_in ? sz : 0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RingBuffer<T>::write(const T *in, std::size_t num) {
|
||||
if (wpos + num > sz) {
|
||||
const std::size_t n = sz - wpos;
|
||||
template <typename T> void RingBuffer<T>::write(const T *in, std::size_t num)
|
||||
{
|
||||
if (wpos + num > sz) {
|
||||
const std::size_t n = sz - wpos;
|
||||
|
||||
std::memcpy(buf + wpos, in, n * sizeof(T));
|
||||
std::memcpy(buf + wpos, in, n * sizeof(T));
|
||||
|
||||
wpos = 0;
|
||||
num -= n;
|
||||
in += n;
|
||||
}
|
||||
wpos = 0;
|
||||
num -= n;
|
||||
in += n;
|
||||
}
|
||||
|
||||
std::memcpy(buf + wpos, in, num * sizeof(T));
|
||||
std::memcpy(buf + wpos, in, num * sizeof(T));
|
||||
|
||||
if ((wpos += num) == sz)
|
||||
wpos = 0;
|
||||
if ((wpos += num) == sz)
|
||||
wpos = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,40 +26,39 @@
|
|||
*/
|
||||
class SoundDriver
|
||||
{
|
||||
public:
|
||||
public:
|
||||
/**
|
||||
* Destructor. Free the resources allocated by the sound driver.
|
||||
*/
|
||||
virtual ~SoundDriver(){};
|
||||
|
||||
/**
|
||||
* Destructor. Free the resources allocated by the sound driver.
|
||||
*/
|
||||
virtual ~SoundDriver() { };
|
||||
/**
|
||||
* Initialize the sound driver.
|
||||
* @param sampleRate In Hertz
|
||||
*/
|
||||
virtual bool init(long sampleRate) = 0;
|
||||
|
||||
/**
|
||||
* Initialize the sound driver.
|
||||
* @param sampleRate In Hertz
|
||||
*/
|
||||
virtual bool init(long sampleRate) = 0;
|
||||
/**
|
||||
* Tell the driver that the sound stream has paused
|
||||
*/
|
||||
virtual void pause() = 0;
|
||||
|
||||
/**
|
||||
* Tell the driver that the sound stream has paused
|
||||
*/
|
||||
virtual void pause() = 0;
|
||||
/**
|
||||
* Reset the sound driver
|
||||
*/
|
||||
virtual void reset() = 0;
|
||||
|
||||
/**
|
||||
* Reset the sound driver
|
||||
*/
|
||||
virtual void reset() = 0;
|
||||
/**
|
||||
* Tell the driver that the sound stream has resumed
|
||||
*/
|
||||
virtual void resume() = 0;
|
||||
|
||||
/**
|
||||
* Tell the driver that the sound stream has resumed
|
||||
*/
|
||||
virtual void resume() = 0;
|
||||
/**
|
||||
* Write length bytes of data from the finalWave buffer to the driver output buffer.
|
||||
*/
|
||||
virtual void write(u16 *finalWave, int length) = 0;
|
||||
|
||||
/**
|
||||
* Write length bytes of data from the finalWave buffer to the driver output buffer.
|
||||
*/
|
||||
virtual void write(u16 * finalWave, int length) = 0;
|
||||
|
||||
virtual void setThrottle(unsigned short throttle) { };
|
||||
virtual void setThrottle(unsigned short throttle){};
|
||||
};
|
||||
|
||||
#endif // __VBA_SOUND_DRIVER_H__
|
||||
|
|
|
@ -18,40 +18,40 @@
|
|||
#ifndef __VBA_SOUND_SDL_H__
|
||||
#define __VBA_SOUND_SDL_H__
|
||||
|
||||
#include "SoundDriver.h"
|
||||
#include "RingBuffer.h"
|
||||
#include "SoundDriver.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
class SoundSDL: public SoundDriver
|
||||
class SoundSDL : public SoundDriver
|
||||
{
|
||||
public:
|
||||
SoundSDL();
|
||||
virtual ~SoundSDL();
|
||||
public:
|
||||
SoundSDL();
|
||||
virtual ~SoundSDL();
|
||||
|
||||
virtual bool init(long sampleRate);
|
||||
virtual void pause();
|
||||
virtual void reset();
|
||||
virtual void resume();
|
||||
virtual void write(u16 * finalWave, int length);
|
||||
virtual bool init(long sampleRate);
|
||||
virtual void pause();
|
||||
virtual void reset();
|
||||
virtual void resume();
|
||||
virtual void write(u16 *finalWave, int length);
|
||||
|
||||
private:
|
||||
RingBuffer<u16> _rbuf;
|
||||
private:
|
||||
RingBuffer<u16> _rbuf;
|
||||
|
||||
SDL_mutex * _mutex;
|
||||
SDL_sem *_semBufferFull;
|
||||
SDL_sem *_semBufferEmpty;
|
||||
SDL_AudioDeviceID _dev;
|
||||
SDL_mutex *_mutex;
|
||||
SDL_sem *_semBufferFull;
|
||||
SDL_sem *_semBufferEmpty;
|
||||
SDL_AudioDeviceID _dev;
|
||||
|
||||
int current_rate;
|
||||
int current_rate;
|
||||
|
||||
bool _initialized;
|
||||
bool _initialized;
|
||||
|
||||
// Defines what delay in seconds we keep in the sound buffer
|
||||
static const float _delay;
|
||||
// Defines what delay in seconds we keep in the sound buffer
|
||||
static const float _delay;
|
||||
|
||||
static void soundCallback(void *data, u8 *stream, int length);
|
||||
virtual void read(u16 * stream, int length);
|
||||
static void soundCallback(void *data, u8 *stream, int length);
|
||||
virtual void read(u16 *stream, int length);
|
||||
};
|
||||
|
||||
#endif // __VBA_SOUND_SDL_H__
|
||||
|
|
|
@ -1,45 +1,54 @@
|
|||
#ifndef ARRAY_H
|
||||
#define ARRAY_H
|
||||
|
||||
#include <iterator>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
template<typename T>
|
||||
class Array
|
||||
template <typename T> class Array
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T &reference;
|
||||
typedef const T &const_reference;
|
||||
typedef T *pointer;
|
||||
typedef const T *const_pointer;
|
||||
typedef T *iterator;
|
||||
typedef const T *const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T &reference;
|
||||
typedef const T &const_reference;
|
||||
typedef T *pointer;
|
||||
typedef const T *const_pointer;
|
||||
typedef T *iterator;
|
||||
typedef const T *const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
private:
|
||||
pointer m_p;
|
||||
size_type m_size;
|
||||
private:
|
||||
pointer m_p;
|
||||
size_type m_size;
|
||||
|
||||
public:
|
||||
public:
|
||||
Array(size_type size = 0) : m_p(size ? new value_type[size] : 0), m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
Array(size_type size = 0) : m_p(size ? new value_type[size] : 0), m_size(size) {}
|
||||
void reset(size_t size)
|
||||
{
|
||||
delete[] this->m_p;
|
||||
this->m_p = size ? new value_type[size] : 0;
|
||||
this->m_size = size;
|
||||
}
|
||||
|
||||
void reset(size_t size)
|
||||
{
|
||||
delete[] this->m_p;
|
||||
this->m_p = size ? new value_type[size] : 0;
|
||||
this->m_size = size;
|
||||
}
|
||||
size_type size() const
|
||||
{
|
||||
return (this->m_size);
|
||||
}
|
||||
|
||||
size_type size() const { return(this->m_size); }
|
||||
operator pointer()
|
||||
{
|
||||
return (this->m_p);
|
||||
}
|
||||
operator const_pointer() const
|
||||
{
|
||||
return (this->m_p);
|
||||
}
|
||||
|
||||
operator pointer() { return(this->m_p); }
|
||||
operator const_pointer() const { return(this->m_p); }
|
||||
|
||||
///TODO: Add more functions from here: http://en.cppreference.com/w/cpp/container/array
|
||||
/// TODO: Add more functions from here: http://en.cppreference.com/w/cpp/container/array
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
//#include <unistd.h>
|
||||
|
||||
/** Maximum value size for integers and doubles. */
|
||||
#define MAXVALSZ 1024
|
||||
#define MAXVALSZ 1024
|
||||
|
||||
/** Minimal allocated number of entries in a dictionary */
|
||||
#define DICTMINSZ 128
|
||||
#define DICTMINSZ 128
|
||||
|
||||
/** Invalid key token */
|
||||
#define DICT_INVALID_KEY ((char*)-1)
|
||||
#define DICT_INVALID_KEY ((char *)-1)
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private functions
|
||||
|
@ -35,17 +35,17 @@
|
|||
|
||||
/* Doubles the allocated size associated to a pointer */
|
||||
/* 'size' is the current allocated size. */
|
||||
static void * mem_double(void * ptr, int size)
|
||||
static void *mem_double(void *ptr, int size)
|
||||
{
|
||||
void * newptr ;
|
||||
|
||||
newptr = calloc(2*size, 1);
|
||||
if (newptr==NULL) {
|
||||
return NULL ;
|
||||
}
|
||||
memcpy(newptr, ptr, size);
|
||||
free(ptr);
|
||||
return newptr ;
|
||||
void *newptr;
|
||||
|
||||
newptr = calloc(2 * size, 1);
|
||||
if (newptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(newptr, ptr, size);
|
||||
free(ptr);
|
||||
return newptr;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -58,16 +58,16 @@ static void * mem_double(void * ptr, int size)
|
|||
for systems that do not have it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static char * xstrdup(const char * s)
|
||||
static char *xstrdup(const char *s)
|
||||
{
|
||||
char * t ;
|
||||
if (!s)
|
||||
return NULL ;
|
||||
t = (char*)malloc(strlen(s)+1) ;
|
||||
if (t) {
|
||||
strcpy(t,s);
|
||||
}
|
||||
return t ;
|
||||
char *t;
|
||||
if (!s)
|
||||
return NULL;
|
||||
t = (char *)malloc(strlen(s) + 1);
|
||||
if (t) {
|
||||
strcpy(t, s);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
|
@ -85,22 +85,22 @@ static char * xstrdup(const char * s)
|
|||
by comparing the key itself in last resort.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
unsigned dictionary_hash(const char * key)
|
||||
unsigned dictionary_hash(const char *key)
|
||||
{
|
||||
int len ;
|
||||
unsigned hash ;
|
||||
int i ;
|
||||
int len;
|
||||
unsigned hash;
|
||||
int i;
|
||||
|
||||
len = strlen(key);
|
||||
for (hash=0, i=0 ; i<len ; i++) {
|
||||
hash += (unsigned)key[i] ;
|
||||
hash += (hash<<10);
|
||||
hash ^= (hash>>6) ;
|
||||
}
|
||||
hash += (hash <<3);
|
||||
hash ^= (hash >>11);
|
||||
hash += (hash <<15);
|
||||
return hash ;
|
||||
len = strlen(key);
|
||||
for (hash = 0, i = 0; i < len; i++) {
|
||||
hash += (unsigned)key[i];
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -114,21 +114,22 @@ unsigned dictionary_hash(const char * key)
|
|||
dictionary, give size=0.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
dictionary * dictionary_new(int size)
|
||||
dictionary *dictionary_new(int size)
|
||||
{
|
||||
dictionary * d ;
|
||||
dictionary *d;
|
||||
|
||||
/* If no size was specified, allocate space for DICTMINSZ */
|
||||
if (size<DICTMINSZ) size=DICTMINSZ ;
|
||||
/* If no size was specified, allocate space for DICTMINSZ */
|
||||
if (size < DICTMINSZ)
|
||||
size = DICTMINSZ;
|
||||
|
||||
if (!(d = (dictionary *)calloc(1, sizeof(dictionary)))) {
|
||||
return NULL;
|
||||
}
|
||||
d->size = size ;
|
||||
d->val = (char **)calloc(size, sizeof(char*));
|
||||
d->key = (char **)calloc(size, sizeof(char*));
|
||||
d->hash = (unsigned int *)calloc(size, sizeof(unsigned));
|
||||
return d ;
|
||||
if (!(d = (dictionary *)calloc(1, sizeof(dictionary)))) {
|
||||
return NULL;
|
||||
}
|
||||
d->size = size;
|
||||
d->val = (char **)calloc(size, sizeof(char *));
|
||||
d->key = (char **)calloc(size, sizeof(char *));
|
||||
d->hash = (unsigned int *)calloc(size, sizeof(unsigned));
|
||||
return d;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -140,22 +141,23 @@ dictionary * dictionary_new(int size)
|
|||
Deallocate a dictionary object and all memory associated to it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_del(dictionary * d)
|
||||
void dictionary_del(dictionary *d)
|
||||
{
|
||||
int i ;
|
||||
int i;
|
||||
|
||||
if (d==NULL) return ;
|
||||
for (i=0 ; i<d->size ; i++) {
|
||||
if (d->key[i]!=NULL)
|
||||
free(d->key[i]);
|
||||
if (d->val[i]!=NULL)
|
||||
free(d->val[i]);
|
||||
}
|
||||
free(d->val);
|
||||
free(d->key);
|
||||
free(d->hash);
|
||||
free(d);
|
||||
return ;
|
||||
if (d == NULL)
|
||||
return;
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] != NULL)
|
||||
free(d->key[i]);
|
||||
if (d->val[i] != NULL)
|
||||
free(d->val[i]);
|
||||
}
|
||||
free(d->val);
|
||||
free(d->key);
|
||||
free(d->hash);
|
||||
free(d);
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -172,24 +174,24 @@ void dictionary_del(dictionary * d)
|
|||
dictionary object, you should not try to free it or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char * dictionary_get(dictionary * d, const char * key, const char * def)
|
||||
const char *dictionary_get(dictionary *d, const char *key, const char *def)
|
||||
{
|
||||
unsigned hash ;
|
||||
int i ;
|
||||
unsigned hash;
|
||||
int i;
|
||||
|
||||
hash = dictionary_hash(key);
|
||||
for (i=0 ; i<d->size ; i++) {
|
||||
if (d->key[i]==NULL)
|
||||
continue ;
|
||||
/* Compare hash */
|
||||
if (hash==d->hash[i]) {
|
||||
/* Compare string, to avoid hash collisions */
|
||||
if (!strcmp(key, d->key[i])) {
|
||||
return d->val[i] ;
|
||||
}
|
||||
hash = dictionary_hash(key);
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
/* Compare hash */
|
||||
if (hash == d->hash[i]) {
|
||||
/* Compare string, to avoid hash collisions */
|
||||
if (!strcmp(key, d->key[i])) {
|
||||
return d->val[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return def ;
|
||||
return def;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -218,60 +220,61 @@ const char * dictionary_get(dictionary * d, const char * key, const char * def)
|
|||
This function returns non-zero in case of failure.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int dictionary_set(dictionary * d, const char * key, const char * val)
|
||||
int dictionary_set(dictionary *d, const char *key, const char *val)
|
||||
{
|
||||
int i ;
|
||||
unsigned hash ;
|
||||
int i;
|
||||
unsigned hash;
|
||||
|
||||
if (d==NULL || key==NULL) return -1 ;
|
||||
|
||||
/* Compute hash for this key */
|
||||
hash = dictionary_hash(key) ;
|
||||
/* Find if value is already in dictionary */
|
||||
if (d->n>0) {
|
||||
for (i=0 ; i<d->size ; i++) {
|
||||
if (d->key[i]==NULL)
|
||||
continue ;
|
||||
if (hash==d->hash[i]) { /* Same hash value */
|
||||
if (!strcmp(key, d->key[i])) { /* Same key */
|
||||
/* Found a value: modify and return */
|
||||
if (d->val[i]!=NULL)
|
||||
free(d->val[i]);
|
||||
d->val[i] = val ? xstrdup(val) : NULL ;
|
||||
/* Value has been modified: return */
|
||||
return 0 ;
|
||||
if (d == NULL || key == NULL)
|
||||
return -1;
|
||||
|
||||
/* Compute hash for this key */
|
||||
hash = dictionary_hash(key);
|
||||
/* Find if value is already in dictionary */
|
||||
if (d->n > 0) {
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
if (hash == d->hash[i]) { /* Same hash value */
|
||||
if (!strcmp(key, d->key[i])) { /* Same key */
|
||||
/* Found a value: modify and return */
|
||||
if (d->val[i] != NULL)
|
||||
free(d->val[i]);
|
||||
d->val[i] = val ? xstrdup(val) : NULL;
|
||||
/* Value has been modified: return */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Add a new value */
|
||||
/* See if dictionary needs to grow */
|
||||
if (d->n==d->size) {
|
||||
|
||||
/* Reached maximum size: reallocate dictionary */
|
||||
d->val = (char **)mem_double(d->val, d->size * sizeof(char*)) ;
|
||||
d->key = (char **)mem_double(d->key, d->size * sizeof(char*)) ;
|
||||
d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ;
|
||||
if ((d->val==NULL) || (d->key==NULL) || (d->hash==NULL)) {
|
||||
/* Cannot grow dictionary */
|
||||
return -1 ;
|
||||
/* Add a new value */
|
||||
/* See if dictionary needs to grow */
|
||||
if (d->n == d->size) {
|
||||
/* Reached maximum size: reallocate dictionary */
|
||||
d->val = (char **)mem_double(d->val, d->size * sizeof(char *));
|
||||
d->key = (char **)mem_double(d->key, d->size * sizeof(char *));
|
||||
d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned));
|
||||
if ((d->val == NULL) || (d->key == NULL) || (d->hash == NULL)) {
|
||||
/* Cannot grow dictionary */
|
||||
return -1;
|
||||
}
|
||||
/* Double size */
|
||||
d->size *= 2;
|
||||
}
|
||||
/* Double size */
|
||||
d->size *= 2 ;
|
||||
}
|
||||
|
||||
/* Insert key in the first empty slot. Start at d->n and wrap at
|
||||
d->size. Because d->n < d->size this will necessarily
|
||||
terminate. */
|
||||
for (i=d->n ; d->key[i] ; ) {
|
||||
if(++i == d->size) i = 0;
|
||||
}
|
||||
/* Copy key */
|
||||
d->key[i] = xstrdup(key);
|
||||
d->val[i] = val ? xstrdup(val) : NULL ;
|
||||
d->hash[i] = hash;
|
||||
d->n ++ ;
|
||||
return 0 ;
|
||||
/* Insert key in the first empty slot. Start at d->n and wrap at
|
||||
d->size. Because d->n < d->size this will necessarily
|
||||
terminate. */
|
||||
for (i = d->n; d->key[i];) {
|
||||
if (++i == d->size)
|
||||
i = 0;
|
||||
}
|
||||
/* Copy key */
|
||||
d->key[i] = xstrdup(key);
|
||||
d->val[i] = val ? xstrdup(val) : NULL;
|
||||
d->hash[i] = hash;
|
||||
d->n++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -285,41 +288,41 @@ int dictionary_set(dictionary * d, const char * key, const char * val)
|
|||
key cannot be found.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_unset(dictionary * d, const char * key)
|
||||
void dictionary_unset(dictionary *d, const char *key)
|
||||
{
|
||||
unsigned hash ;
|
||||
int i ;
|
||||
unsigned hash;
|
||||
int i;
|
||||
|
||||
if (key == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
hash = dictionary_hash(key);
|
||||
for (i=0 ; i<d->size ; i++) {
|
||||
if (d->key[i]==NULL)
|
||||
continue ;
|
||||
/* Compare hash */
|
||||
if (hash==d->hash[i]) {
|
||||
/* Compare string, to avoid hash collisions */
|
||||
if (!strcmp(key, d->key[i])) {
|
||||
/* Found key */
|
||||
break ;
|
||||
}
|
||||
if (key == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (i>=d->size)
|
||||
/* Key not found */
|
||||
return ;
|
||||
|
||||
free(d->key[i]);
|
||||
d->key[i] = NULL ;
|
||||
if (d->val[i]!=NULL) {
|
||||
free(d->val[i]);
|
||||
d->val[i] = NULL ;
|
||||
}
|
||||
d->hash[i] = 0 ;
|
||||
d->n -- ;
|
||||
return ;
|
||||
hash = dictionary_hash(key);
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
/* Compare hash */
|
||||
if (hash == d->hash[i]) {
|
||||
/* Compare string, to avoid hash collisions */
|
||||
if (!strcmp(key, d->key[i])) {
|
||||
/* Found key */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i >= d->size)
|
||||
/* Key not found */
|
||||
return;
|
||||
|
||||
free(d->key[i]);
|
||||
d->key[i] = NULL;
|
||||
if (d->val[i] != NULL) {
|
||||
free(d->val[i]);
|
||||
d->val[i] = NULL;
|
||||
}
|
||||
d->hash[i] = 0;
|
||||
d->n--;
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -334,65 +337,63 @@ void dictionary_unset(dictionary * d, const char * key)
|
|||
output file pointers.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_dump(dictionary * d, FILE * out)
|
||||
void dictionary_dump(dictionary *d, FILE *out)
|
||||
{
|
||||
int i ;
|
||||
int i;
|
||||
|
||||
if (d==NULL || out==NULL) return ;
|
||||
if (d->n<1) {
|
||||
fprintf(out, "empty dictionary\n");
|
||||
return ;
|
||||
}
|
||||
for (i=0 ; i<d->size ; i++) {
|
||||
if (d->key[i]) {
|
||||
fprintf(out, "%20s\t[%s]\n",
|
||||
d->key[i],
|
||||
d->val[i] ? d->val[i] : "UNDEF");
|
||||
if (d == NULL || out == NULL)
|
||||
return;
|
||||
if (d->n < 1) {
|
||||
fprintf(out, "empty dictionary\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
return ;
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i]) {
|
||||
fprintf(out, "%20s\t[%s]\n", d->key[i], d->val[i] ? d->val[i] : "UNDEF");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Test code */
|
||||
#ifdef TESTDIC
|
||||
#define NVALS 20000
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
dictionary * d ;
|
||||
char * val ;
|
||||
int i ;
|
||||
char cval[90] ;
|
||||
dictionary *d;
|
||||
char *val;
|
||||
int i;
|
||||
char cval[90];
|
||||
|
||||
/* Allocate dictionary */
|
||||
printf("allocating...\n");
|
||||
d = dictionary_new(0);
|
||||
|
||||
/* Set values in dictionary */
|
||||
printf("setting %d values...\n", NVALS);
|
||||
for (i=0 ; i<NVALS ; i++) {
|
||||
sprintf(cval, "%04d", i);
|
||||
dictionary_set(d, cval, "salut");
|
||||
}
|
||||
printf("getting %d values...\n", NVALS);
|
||||
for (i=0 ; i<NVALS ; i++) {
|
||||
sprintf(cval, "%04d", i);
|
||||
val = dictionary_get(d, cval, DICT_INVALID_KEY);
|
||||
if (val==DICT_INVALID_KEY) {
|
||||
printf("cannot get value for key [%s]\n", cval);
|
||||
/* Allocate dictionary */
|
||||
printf("allocating...\n");
|
||||
d = dictionary_new(0);
|
||||
|
||||
/* Set values in dictionary */
|
||||
printf("setting %d values...\n", NVALS);
|
||||
for (i = 0; i < NVALS; i++) {
|
||||
sprintf(cval, "%04d", i);
|
||||
dictionary_set(d, cval, "salut");
|
||||
}
|
||||
}
|
||||
printf("unsetting %d values...\n", NVALS);
|
||||
for (i=0 ; i<NVALS ; i++) {
|
||||
sprintf(cval, "%04d", i);
|
||||
dictionary_unset(d, cval);
|
||||
}
|
||||
if (d->n != 0) {
|
||||
printf("error deleting values\n");
|
||||
}
|
||||
printf("deallocating...\n");
|
||||
dictionary_del(d);
|
||||
return 0 ;
|
||||
printf("getting %d values...\n", NVALS);
|
||||
for (i = 0; i < NVALS; i++) {
|
||||
sprintf(cval, "%04d", i);
|
||||
val = dictionary_get(d, cval, DICT_INVALID_KEY);
|
||||
if (val == DICT_INVALID_KEY) {
|
||||
printf("cannot get value for key [%s]\n", cval);
|
||||
}
|
||||
}
|
||||
printf("unsetting %d values...\n", NVALS);
|
||||
for (i = 0; i < NVALS; i++) {
|
||||
sprintf(cval, "%04d", i);
|
||||
dictionary_unset(d, cval);
|
||||
}
|
||||
if (d->n != 0) {
|
||||
printf("error deleting values\n");
|
||||
}
|
||||
printf("deallocating...\n");
|
||||
dictionary_del(d);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
New types
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
@brief Dictionary object
|
||||
|
@ -39,13 +38,12 @@
|
|||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
typedef struct _dictionary_ {
|
||||
int n ; /** Number of entries in dictionary */
|
||||
int size ; /** Storage size */
|
||||
char ** val ; /** List of string values */
|
||||
char ** key ; /** List of string keys */
|
||||
unsigned * hash ; /** List of hash values for keys */
|
||||
} dictionary ;
|
||||
|
||||
int n; /** Number of entries in dictionary */
|
||||
int size; /** Storage size */
|
||||
char **val; /** List of string values */
|
||||
char **key; /** List of string keys */
|
||||
unsigned *hash; /** List of hash values for keys */
|
||||
} dictionary;
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Function prototypes
|
||||
|
@ -63,7 +61,7 @@ typedef struct _dictionary_ {
|
|||
by comparing the key itself in last resort.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
unsigned dictionary_hash(const char * key);
|
||||
unsigned dictionary_hash(const char *key);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -76,7 +74,7 @@ unsigned dictionary_hash(const char * key);
|
|||
dictionary, give size=0.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
dictionary * dictionary_new(int size);
|
||||
dictionary *dictionary_new(int size);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -87,7 +85,7 @@ dictionary * dictionary_new(int size);
|
|||
Deallocate a dictionary object and all memory associated to it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_del(dictionary * vd);
|
||||
void dictionary_del(dictionary *vd);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -103,8 +101,7 @@ void dictionary_del(dictionary * vd);
|
|||
dictionary object, you should not try to free it or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char * dictionary_get(dictionary * d, const char * key, const char * def);
|
||||
|
||||
const char *dictionary_get(dictionary *d, const char *key, const char *def);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -132,7 +129,7 @@ const char * dictionary_get(dictionary * d, const char * key, const char * def);
|
|||
This function returns non-zero in case of failure.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int dictionary_set(dictionary * vd, const char * key, const char * val);
|
||||
int dictionary_set(dictionary *vd, const char *key, const char *val);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -145,8 +142,7 @@ int dictionary_set(dictionary * vd, const char * key, const char * val);
|
|||
key cannot be found.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_unset(dictionary * d, const char * key);
|
||||
|
||||
void dictionary_unset(dictionary *d, const char *key);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -160,6 +156,6 @@ void dictionary_unset(dictionary * d, const char * key);
|
|||
output file pointers.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void dictionary_dump(dictionary * d, FILE * out);
|
||||
void dictionary_dump(dictionary *d, FILE *out);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,40 +19,43 @@
|
|||
// return codes
|
||||
// probably ought to put in own namespace, but this is good enough
|
||||
enum MediaRet {
|
||||
MRET_OK, // no errors
|
||||
MRET_ERR_NOMEM, // error allocating buffers or structures
|
||||
MRET_ERR_NOCODEC, // error opening codec
|
||||
MRET_ERR_FERR, // error writing output file
|
||||
MRET_ERR_RECORDING, // attempt to start recording when already doing it
|
||||
MRET_ERR_FMTGUESS, // can't guess format from file name
|
||||
MRET_ERR_BUFSIZE // buffer overflow (fatal)
|
||||
MRET_OK, // no errors
|
||||
MRET_ERR_NOMEM, // error allocating buffers or structures
|
||||
MRET_ERR_NOCODEC, // error opening codec
|
||||
MRET_ERR_FERR, // error writing output file
|
||||
MRET_ERR_RECORDING, // attempt to start recording when already doing it
|
||||
MRET_ERR_FMTGUESS, // can't guess format from file name
|
||||
MRET_ERR_BUFSIZE // buffer overflow (fatal)
|
||||
};
|
||||
|
||||
class MediaRecorder
|
||||
{
|
||||
public:
|
||||
MediaRecorder();
|
||||
virtual ~MediaRecorder();
|
||||
public:
|
||||
MediaRecorder();
|
||||
virtual ~MediaRecorder();
|
||||
|
||||
// start audio+video (also video-only codecs)
|
||||
MediaRet Record(const char *fname, int width, int height, int depth);
|
||||
// start audio only
|
||||
MediaRet Record(const char *fname);
|
||||
// stop both
|
||||
void Stop();
|
||||
bool IsRecording() { return oc != NULL; }
|
||||
// add a frame of video; width+height+depth already given
|
||||
// assumes a 1-pixel border on top & right
|
||||
// always assumes being passed 1/60th of a second of video
|
||||
MediaRet AddFrame(const u8 *vid);
|
||||
// add a frame of audio; uses current sample rate to know length
|
||||
// always assumes being passed 1/60th of a second of audio.
|
||||
MediaRet AddFrame(const u16 *aud);
|
||||
// start audio+video (also video-only codecs)
|
||||
MediaRet Record(const char *fname, int width, int height, int depth);
|
||||
// start audio only
|
||||
MediaRet Record(const char *fname);
|
||||
// stop both
|
||||
void Stop();
|
||||
bool IsRecording()
|
||||
{
|
||||
return oc != NULL;
|
||||
}
|
||||
// add a frame of video; width+height+depth already given
|
||||
// assumes a 1-pixel border on top & right
|
||||
// always assumes being passed 1/60th of a second of video
|
||||
MediaRet AddFrame(const u8 *vid);
|
||||
// add a frame of audio; uses current sample rate to know length
|
||||
// always assumes being passed 1/60th of a second of audio.
|
||||
MediaRet AddFrame(const u16 *aud);
|
||||
|
||||
private:
|
||||
static bool did_init;
|
||||
private:
|
||||
static bool did_init;
|
||||
|
||||
// these are to avoid polluting things with avcodec includes
|
||||
// these are to avoid polluting things with avcodec includes
|
||||
#ifndef priv_AVFormatContext
|
||||
#define priv_AVFormatContext void
|
||||
#define priv_AVStream void
|
||||
|
@ -61,19 +64,19 @@ private:
|
|||
#define priv_SwsContext void
|
||||
#define priv_PixelFormat int
|
||||
#endif
|
||||
priv_AVFormatContext *oc;
|
||||
priv_AVStream *vid_st, *aud_st;
|
||||
u8 *audio_buf, *video_buf;
|
||||
u16 *audio_buf2;
|
||||
int frame_len, sample_len, in_audio_buf2;
|
||||
int linesize, pixsize;
|
||||
priv_PixelFormat pixfmt;
|
||||
priv_AVFrame *pic, *convpic;
|
||||
priv_SwsContext *converter;
|
||||
|
||||
MediaRet setup_sound_stream(const char *fname, priv_AVOutputFormat *fmt);
|
||||
MediaRet setup_video_stream(const char *fname, int w, int h, int d);
|
||||
MediaRet finish_setup(const char *fname);
|
||||
priv_AVFormatContext *oc;
|
||||
priv_AVStream *vid_st, *aud_st;
|
||||
u8 *audio_buf, *video_buf;
|
||||
u16 *audio_buf2;
|
||||
int frame_len, sample_len, in_audio_buf2;
|
||||
int linesize, pixsize;
|
||||
priv_PixelFormat pixfmt;
|
||||
priv_AVFrame *pic, *convpic;
|
||||
priv_SwsContext *converter;
|
||||
|
||||
MediaRet setup_sound_stream(const char *fname, priv_AVOutputFormat *fmt);
|
||||
MediaRet setup_video_stream(const char *fname, int w, int h, int d);
|
||||
MediaRet finish_setup(const char *fname);
|
||||
};
|
||||
|
||||
#endif /* WX_FFMPEG_H */
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/*---------------------------- Includes ------------------------------------*/
|
||||
#include <ctype.h>
|
||||
#include "iniparser.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/*---------------------------- Defines -------------------------------------*/
|
||||
#define ASCIILINESZ (1024)
|
||||
#define INI_INVALID_KEY ((char*)-1)
|
||||
#define ASCIILINESZ (1024)
|
||||
#define INI_INVALID_KEY ((char *)-1)
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Private to this module
|
||||
|
@ -21,13 +21,13 @@
|
|||
* This enum stores the status for each parsed line (internal use only).
|
||||
*/
|
||||
typedef enum _line_status_ {
|
||||
LINE_UNPROCESSED,
|
||||
LINE_ERROR,
|
||||
LINE_EMPTY,
|
||||
LINE_COMMENT,
|
||||
LINE_SECTION,
|
||||
LINE_VALUE
|
||||
} line_status ;
|
||||
LINE_UNPROCESSED,
|
||||
LINE_ERROR,
|
||||
LINE_EMPTY,
|
||||
LINE_COMMENT,
|
||||
LINE_SECTION,
|
||||
LINE_VALUE
|
||||
} line_status;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -41,21 +41,22 @@ typedef enum _line_status_ {
|
|||
allocated, it will be modified at each function call (not re-entrant).
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static char * strlwc(const char * s)
|
||||
static char *strlwc(const char *s)
|
||||
{
|
||||
static char l[ASCIILINESZ+1];
|
||||
int i ;
|
||||
static char l[ASCIILINESZ + 1];
|
||||
int i;
|
||||
|
||||
if (s==NULL) return NULL ;
|
||||
memset(l, 0, ASCIILINESZ+1);
|
||||
i=0 ;
|
||||
while (s[i] && i<ASCIILINESZ) {
|
||||
//l[i] = (char)tolower((int)s[i]);
|
||||
l[i] = (char)((int)s[i]);
|
||||
i++ ;
|
||||
}
|
||||
l[ASCIILINESZ]=(char)0;
|
||||
return l ;
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
memset(l, 0, ASCIILINESZ + 1);
|
||||
i = 0;
|
||||
while (s[i] && i < ASCIILINESZ) {
|
||||
// l[i] = (char)tolower((int)s[i]);
|
||||
l[i] = (char)((int)s[i]);
|
||||
i++;
|
||||
}
|
||||
l[ASCIILINESZ] = (char)0;
|
||||
return l;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -72,24 +73,26 @@ static char * strlwc(const char * s)
|
|||
(not re-entrant).
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static char * strstrip(const char * s)
|
||||
static char *strstrip(const char *s)
|
||||
{
|
||||
static char l[ASCIILINESZ+1];
|
||||
char * last ;
|
||||
|
||||
if (s==NULL) return NULL ;
|
||||
|
||||
while (isspace((int)*s) && *s) s++;
|
||||
memset(l, 0, ASCIILINESZ+1);
|
||||
strcpy(l, s);
|
||||
last = l + strlen(l);
|
||||
while (last > l) {
|
||||
if (!isspace((int)*(last-1)))
|
||||
break ;
|
||||
last -- ;
|
||||
}
|
||||
*last = (char)0;
|
||||
return (char*)l ;
|
||||
static char l[ASCIILINESZ + 1];
|
||||
char *last;
|
||||
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
while (isspace((int)*s) && *s)
|
||||
s++;
|
||||
memset(l, 0, ASCIILINESZ + 1);
|
||||
strcpy(l, s);
|
||||
last = l + strlen(l);
|
||||
while (last > l) {
|
||||
if (!isspace((int)*(last - 1)))
|
||||
break;
|
||||
last--;
|
||||
}
|
||||
*last = (char)0;
|
||||
return (char *)l;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -110,21 +113,22 @@ static char * strstrip(const char * s)
|
|||
This function returns -1 in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getnsec(dictionary * d)
|
||||
int iniparser_getnsec(dictionary *d)
|
||||
{
|
||||
int i ;
|
||||
int nsec ;
|
||||
int i;
|
||||
int nsec;
|
||||
|
||||
if (d==NULL) return -1 ;
|
||||
nsec=0 ;
|
||||
for (i=0 ; i<d->size ; i++) {
|
||||
if (d->key[i]==NULL)
|
||||
continue ;
|
||||
if (strchr(d->key[i], ':')==NULL) {
|
||||
nsec ++ ;
|
||||
if (d == NULL)
|
||||
return -1;
|
||||
nsec = 0;
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
if (strchr(d->key[i], ':') == NULL) {
|
||||
nsec++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nsec ;
|
||||
return nsec;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -141,26 +145,27 @@ int iniparser_getnsec(dictionary * d)
|
|||
This function returns NULL in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char * iniparser_getsecname(dictionary * d, int n)
|
||||
char *iniparser_getsecname(dictionary *d, int n)
|
||||
{
|
||||
int i ;
|
||||
int foundsec ;
|
||||
int i;
|
||||
int foundsec;
|
||||
|
||||
if (d==NULL || n<0) return NULL ;
|
||||
foundsec=0 ;
|
||||
for (i=0 ; i<d->size ; i++) {
|
||||
if (d->key[i]==NULL)
|
||||
continue ;
|
||||
if (strchr(d->key[i], ':')==NULL) {
|
||||
foundsec++ ;
|
||||
if (foundsec>n)
|
||||
break ;
|
||||
if (d == NULL || n < 0)
|
||||
return NULL;
|
||||
foundsec = 0;
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
if (strchr(d->key[i], ':') == NULL) {
|
||||
foundsec++;
|
||||
if (foundsec > n)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (foundsec<=n) {
|
||||
return NULL ;
|
||||
}
|
||||
return d->key[i] ;
|
||||
if (foundsec <= n) {
|
||||
return NULL;
|
||||
}
|
||||
return d->key[i];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -176,21 +181,22 @@ char * iniparser_getsecname(dictionary * d, int n)
|
|||
purposes mostly.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_dump(dictionary * d, FILE * f)
|
||||
void iniparser_dump(dictionary *d, FILE *f)
|
||||
{
|
||||
int i ;
|
||||
int i;
|
||||
|
||||
if (d==NULL || f==NULL) return ;
|
||||
for (i=0 ; i<d->size ; i++) {
|
||||
if (d->key[i]==NULL)
|
||||
continue ;
|
||||
if (d->val[i]!=NULL) {
|
||||
fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);
|
||||
} else {
|
||||
fprintf(f, "[%s]=UNDEF\n", d->key[i]);
|
||||
if (d == NULL || f == NULL)
|
||||
return;
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
if (d->val[i] != NULL) {
|
||||
fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);
|
||||
} else {
|
||||
fprintf(f, "[%s]=UNDEF\n", d->key[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -204,36 +210,36 @@ void iniparser_dump(dictionary * d, FILE * f)
|
|||
It is Ok to specify @c stderr or @c stdout as output files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_dump_ini(dictionary * d, FILE * f)
|
||||
void iniparser_dump_ini(dictionary *d, FILE *f)
|
||||
{
|
||||
int i ;
|
||||
int nsec ;
|
||||
char * secname ;
|
||||
int i;
|
||||
int nsec;
|
||||
char *secname;
|
||||
|
||||
if (d==NULL || f==NULL) return ;
|
||||
if (d == NULL || f == NULL)
|
||||
return;
|
||||
|
||||
nsec = iniparser_getnsec(d);
|
||||
if (nsec<1) {
|
||||
/* No section in file: dump all keys as they are */
|
||||
fprintf(f, "[preferences]\n");
|
||||
for (i=0 ; i<d->size ; i++) {
|
||||
if (d->key[i]==NULL)
|
||||
continue ;
|
||||
if (!strncmp(d->key[i], "preferences:", strlen("preferences:"))) {
|
||||
fprintf(f,
|
||||
"%s=%s\n",
|
||||
d->key[i]+strlen("preferences:"),
|
||||
d->val[i] ? d->val[i] : "");
|
||||
|
||||
}
|
||||
nsec = iniparser_getnsec(d);
|
||||
if (nsec < 1) {
|
||||
/* No section in file: dump all keys as they are */
|
||||
fprintf(f, "[preferences]\n");
|
||||
for (i = 0; i < d->size; i++) {
|
||||
if (d->key[i] == NULL)
|
||||
continue;
|
||||
if (!strncmp(d->key[i], "preferences:", strlen("preferences:"))) {
|
||||
fprintf(f,
|
||||
"%s=%s\n",
|
||||
d->key[i] + strlen("preferences:"),
|
||||
d->val[i] ? d->val[i] : "");
|
||||
}
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
return;
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
return ;
|
||||
for (i = 0; i < nsec; i++) {
|
||||
secname = iniparser_getsecname(d, i);
|
||||
iniparser_dumpsection_ini(d, secname, f);
|
||||
}
|
||||
for (i=0 ; i<nsec ; i++) {
|
||||
secname = iniparser_getsecname(d, i) ;
|
||||
iniparser_dumpsection_ini(d, secname, f) ;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -248,31 +254,30 @@ void iniparser_dump_ini(dictionary * d, FILE * f)
|
|||
file. It is Ok to specify @c stderr or @c stdout as output files.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f)
|
||||
void iniparser_dumpsection_ini(dictionary *d, char *s, FILE *f)
|
||||
{
|
||||
int j ;
|
||||
char keym[ASCIILINESZ+1];
|
||||
int seclen ;
|
||||
int j;
|
||||
char keym[ASCIILINESZ + 1];
|
||||
int seclen;
|
||||
|
||||
if (d==NULL || f==NULL) return ;
|
||||
if (! iniparser_find_entry(d, s)) return ;
|
||||
if (d == NULL || f == NULL)
|
||||
return;
|
||||
if (!iniparser_find_entry(d, s))
|
||||
return;
|
||||
|
||||
seclen = (int)strlen(s);
|
||||
//fprintf(f, "\n[%s]\n", s);
|
||||
fprintf(f, "[%s]\n", s);
|
||||
sprintf(keym, "%s:", s);
|
||||
for (j=0 ; j<d->size ; j++) {
|
||||
if (d->key[j]==NULL)
|
||||
continue ;
|
||||
if (!strncmp(d->key[j], keym, seclen+1)) {
|
||||
fprintf(f,
|
||||
"%s=%s\n",
|
||||
d->key[j]+seclen+1,
|
||||
d->val[j] ? d->val[j] : "");
|
||||
seclen = (int)strlen(s);
|
||||
// fprintf(f, "\n[%s]\n", s);
|
||||
fprintf(f, "[%s]\n", s);
|
||||
sprintf(keym, "%s:", s);
|
||||
for (j = 0; j < d->size; j++) {
|
||||
if (d->key[j] == NULL)
|
||||
continue;
|
||||
if (!strncmp(d->key[j], keym, seclen + 1)) {
|
||||
fprintf(f, "%s=%s\n", d->key[j] + seclen + 1, d->val[j] ? d->val[j] : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
return ;
|
||||
fprintf(f, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -283,29 +288,30 @@ void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f)
|
|||
@return Number of keys in section
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getsecnkeys(dictionary * d, char * s)
|
||||
int iniparser_getsecnkeys(dictionary *d, char *s)
|
||||
{
|
||||
int seclen, nkeys ;
|
||||
char keym[ASCIILINESZ+1];
|
||||
int j ;
|
||||
int seclen, nkeys;
|
||||
char keym[ASCIILINESZ + 1];
|
||||
int j;
|
||||
|
||||
nkeys = 0;
|
||||
nkeys = 0;
|
||||
|
||||
if (d==NULL) return nkeys;
|
||||
if (! iniparser_find_entry(d, s)) return nkeys;
|
||||
if (d == NULL)
|
||||
return nkeys;
|
||||
if (!iniparser_find_entry(d, s))
|
||||
return nkeys;
|
||||
|
||||
seclen = (int)strlen(s);
|
||||
sprintf(keym, "%s:", s);
|
||||
seclen = (int)strlen(s);
|
||||
sprintf(keym, "%s:", s);
|
||||
|
||||
for (j=0 ; j<d->size ; j++) {
|
||||
if (d->key[j]==NULL)
|
||||
continue ;
|
||||
if (!strncmp(d->key[j], keym, seclen+1))
|
||||
nkeys++;
|
||||
}
|
||||
|
||||
return nkeys;
|
||||
for (j = 0; j < d->size; j++) {
|
||||
if (d->key[j] == NULL)
|
||||
continue;
|
||||
if (!strncmp(d->key[j], keym, seclen + 1))
|
||||
nkeys++;
|
||||
}
|
||||
|
||||
return nkeys;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -318,44 +324,44 @@ int iniparser_getsecnkeys(dictionary * d, char * s)
|
|||
This function queries a dictionary and finds all keys in a given section.
|
||||
Each pointer in the returned char pointer-to-pointer is pointing to
|
||||
a string allocated in the dictionary; do not free or modify them.
|
||||
|
||||
|
||||
This function returns NULL in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char ** iniparser_getseckeys(dictionary * d, char * s)
|
||||
char **iniparser_getseckeys(dictionary *d, char *s)
|
||||
{
|
||||
char **keys;
|
||||
|
||||
char **keys;
|
||||
int i, j;
|
||||
char keym[ASCIILINESZ + 1];
|
||||
int seclen, nkeys;
|
||||
|
||||
int i, j ;
|
||||
char keym[ASCIILINESZ+1];
|
||||
int seclen, nkeys ;
|
||||
keys = NULL;
|
||||
|
||||
keys = NULL;
|
||||
if (d == NULL)
|
||||
return keys;
|
||||
if (!iniparser_find_entry(d, s))
|
||||
return keys;
|
||||
|
||||
if (d==NULL) return keys;
|
||||
if (! iniparser_find_entry(d, s)) return keys;
|
||||
nkeys = iniparser_getsecnkeys(d, s);
|
||||
|
||||
nkeys = iniparser_getsecnkeys(d, s);
|
||||
keys = (char **)malloc(nkeys * sizeof(char *));
|
||||
|
||||
keys = (char**) malloc(nkeys*sizeof(char*));
|
||||
seclen = (int)strlen(s);
|
||||
sprintf(keym, "%s:", s);
|
||||
|
||||
seclen = (int)strlen(s);
|
||||
sprintf(keym, "%s:", s);
|
||||
|
||||
i = 0;
|
||||
i = 0;
|
||||
|
||||
for (j=0 ; j<d->size ; j++) {
|
||||
if (d->key[j]==NULL)
|
||||
continue ;
|
||||
if (!strncmp(d->key[j], keym, seclen+1)) {
|
||||
keys[i] = d->key[j];
|
||||
i++;
|
||||
for (j = 0; j < d->size; j++) {
|
||||
if (d->key[j] == NULL)
|
||||
continue;
|
||||
if (!strncmp(d->key[j], keym, seclen + 1)) {
|
||||
keys[i] = d->key[j];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -373,17 +379,17 @@ char ** iniparser_getseckeys(dictionary * d, char * s)
|
|||
the dictionary, do not free or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char * iniparser_getstring(dictionary * d, const char * key, const char * def)
|
||||
const char *iniparser_getstring(dictionary *d, const char *key, const char *def)
|
||||
{
|
||||
char * lc_key ;
|
||||
const char * sval ;
|
||||
char *lc_key;
|
||||
const char *sval;
|
||||
|
||||
if (d==NULL || key==NULL)
|
||||
return def ;
|
||||
if (d == NULL || key == NULL)
|
||||
return def;
|
||||
|
||||
lc_key = strlwc(key);
|
||||
sval = dictionary_get(d, lc_key, def);
|
||||
return sval ;
|
||||
lc_key = strlwc(key);
|
||||
sval = dictionary_get(d, lc_key, def);
|
||||
return sval;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -413,13 +419,14 @@ const char * iniparser_getstring(dictionary * d, const char * key, const char *
|
|||
Credits: Thanks to A. Becker for suggesting strtol()
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getint(dictionary * d, const char * key, int notfound)
|
||||
int iniparser_getint(dictionary *d, const char *key, int notfound)
|
||||
{
|
||||
const char *str;
|
||||
const char *str;
|
||||
|
||||
str = iniparser_getstring(d, key, INI_INVALID_KEY);
|
||||
if (str==INI_INVALID_KEY) return notfound ;
|
||||
return (int)strtol(str, NULL, 0);
|
||||
str = iniparser_getstring(d, key, INI_INVALID_KEY);
|
||||
if (str == INI_INVALID_KEY)
|
||||
return notfound;
|
||||
return (int)strtol(str, NULL, 0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -435,13 +442,14 @@ int iniparser_getint(dictionary * d, const char * key, int notfound)
|
|||
the notfound value is returned.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
double iniparser_getdouble(dictionary * d, const char * key, double notfound)
|
||||
double iniparser_getdouble(dictionary *d, const char *key, double notfound)
|
||||
{
|
||||
const char *str;
|
||||
const char *str;
|
||||
|
||||
str = iniparser_getstring(d, key, INI_INVALID_KEY);
|
||||
if (str==INI_INVALID_KEY) return notfound ;
|
||||
return atof(str);
|
||||
str = iniparser_getstring(d, key, INI_INVALID_KEY);
|
||||
if (str == INI_INVALID_KEY)
|
||||
return notfound;
|
||||
return atof(str);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -476,21 +484,22 @@ double iniparser_getdouble(dictionary * d, const char * key, double notfound)
|
|||
necessarily have to be 0 or 1.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getboolean(dictionary * d, const char * key, int notfound)
|
||||
int iniparser_getboolean(dictionary *d, const char *key, int notfound)
|
||||
{
|
||||
const char * c;
|
||||
int ret ;
|
||||
const char *c;
|
||||
int ret;
|
||||
|
||||
c = iniparser_getstring(d, key, INI_INVALID_KEY);
|
||||
if (c==INI_INVALID_KEY) return notfound ;
|
||||
if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') {
|
||||
ret = 1 ;
|
||||
} else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') {
|
||||
ret = 0 ;
|
||||
} else {
|
||||
ret = notfound ;
|
||||
}
|
||||
return ret;
|
||||
c = iniparser_getstring(d, key, INI_INVALID_KEY);
|
||||
if (c == INI_INVALID_KEY)
|
||||
return notfound;
|
||||
if (c[0] == 'y' || c[0] == 'Y' || c[0] == '1' || c[0] == 't' || c[0] == 'T') {
|
||||
ret = 1;
|
||||
} else if (c[0] == 'n' || c[0] == 'N' || c[0] == '0' || c[0] == 'f' || c[0] == 'F') {
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = notfound;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -505,16 +514,13 @@ int iniparser_getboolean(dictionary * d, const char * key, int notfound)
|
|||
of querying for the presence of sections in a dictionary.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_find_entry(
|
||||
dictionary * ini,
|
||||
const char * entry
|
||||
)
|
||||
int iniparser_find_entry(dictionary *ini, const char *entry)
|
||||
{
|
||||
int found=0 ;
|
||||
if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) {
|
||||
found = 1 ;
|
||||
}
|
||||
return found ;
|
||||
int found = 0;
|
||||
if (iniparser_getstring(ini, entry, INI_INVALID_KEY) != INI_INVALID_KEY) {
|
||||
found = 1;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -530,9 +536,9 @@ int iniparser_find_entry(
|
|||
It is Ok to set val to NULL.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_set(dictionary * ini, const char * entry, const char * val)
|
||||
int iniparser_set(dictionary *ini, const char *entry, const char *val)
|
||||
{
|
||||
return dictionary_set(ini, strlwc(entry), val) ;
|
||||
return dictionary_set(ini, strlwc(entry), val);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -545,9 +551,9 @@ int iniparser_set(dictionary * ini, const char * entry, const char * val)
|
|||
If the given entry can be found, it is deleted from the dictionary.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_unset(dictionary * ini, const char * entry)
|
||||
void iniparser_unset(dictionary *ini, const char *entry)
|
||||
{
|
||||
dictionary_unset(ini, strlwc(entry));
|
||||
dictionary_unset(ini, strlwc(entry));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -560,64 +566,60 @@ void iniparser_unset(dictionary * ini, const char * entry)
|
|||
@return line_status value
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static line_status iniparser_line(
|
||||
const char * input_line,
|
||||
char * section,
|
||||
char * key,
|
||||
char * value)
|
||||
{
|
||||
line_status sta ;
|
||||
char line[ASCIILINESZ+1];
|
||||
int len ;
|
||||
static line_status iniparser_line(const char *input_line, char *section, char *key, char *value)
|
||||
{
|
||||
line_status sta;
|
||||
char line[ASCIILINESZ + 1];
|
||||
int len;
|
||||
|
||||
strcpy(line, strstrip(input_line));
|
||||
len = (int)strlen(line);
|
||||
strcpy(line, strstrip(input_line));
|
||||
len = (int)strlen(line);
|
||||
|
||||
sta = LINE_UNPROCESSED ;
|
||||
if (len<1) {
|
||||
/* Empty line */
|
||||
sta = LINE_EMPTY ;
|
||||
} else if (line[0]=='#' || line[0]==';') {
|
||||
/* Comment line */
|
||||
sta = LINE_COMMENT ;
|
||||
} else if (line[0]=='[' && line[len-1]==']') {
|
||||
/* Section name */
|
||||
sscanf(line, "[%[^]]", section);
|
||||
strcpy(section, strstrip(section));
|
||||
strcpy(section, strlwc(section));
|
||||
sta = LINE_SECTION ;
|
||||
} else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2
|
||||
|| sscanf (line, "%[^=] = '%[^\']'", key, value) == 2
|
||||
|| sscanf (line, "%[^=] = %[^;#]", key, value) == 2) {
|
||||
/* Usual key=value, with or without comments */
|
||||
strcpy(key, strstrip(key));
|
||||
strcpy(key, strlwc(key));
|
||||
strcpy(value, strstrip(value));
|
||||
/*
|
||||
* sscanf cannot handle '' or "" as empty values
|
||||
* this is done here
|
||||
*/
|
||||
if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) {
|
||||
value[0]=0 ;
|
||||
sta = LINE_UNPROCESSED;
|
||||
if (len < 1) {
|
||||
/* Empty line */
|
||||
sta = LINE_EMPTY;
|
||||
} else if (line[0] == '#' || line[0] == ';') {
|
||||
/* Comment line */
|
||||
sta = LINE_COMMENT;
|
||||
} else if (line[0] == '[' && line[len - 1] == ']') {
|
||||
/* Section name */
|
||||
sscanf(line, "[%[^]]", section);
|
||||
strcpy(section, strstrip(section));
|
||||
strcpy(section, strlwc(section));
|
||||
sta = LINE_SECTION;
|
||||
} else if (sscanf(line, "%[^=] = \"%[^\"]\"", key, value) == 2 ||
|
||||
sscanf(line, "%[^=] = '%[^\']'", key, value) == 2 ||
|
||||
sscanf(line, "%[^=] = %[^;#]", key, value) == 2) {
|
||||
/* Usual key=value, with or without comments */
|
||||
strcpy(key, strstrip(key));
|
||||
strcpy(key, strlwc(key));
|
||||
strcpy(value, strstrip(value));
|
||||
/*
|
||||
* sscanf cannot handle '' or "" as empty values
|
||||
* this is done here
|
||||
*/
|
||||
if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) {
|
||||
value[0] = 0;
|
||||
}
|
||||
sta = LINE_VALUE;
|
||||
} else if (sscanf(line, "%[^=] = %[;#]", key, value) == 2 ||
|
||||
sscanf(line, "%[^=] %[=]", key, value) == 2) {
|
||||
/*
|
||||
* Special cases:
|
||||
* key=
|
||||
* key=;
|
||||
* key=#
|
||||
*/
|
||||
strcpy(key, strstrip(key));
|
||||
strcpy(key, strlwc(key));
|
||||
value[0] = 0;
|
||||
sta = LINE_VALUE;
|
||||
} else {
|
||||
/* Generate syntax error */
|
||||
sta = LINE_ERROR;
|
||||
}
|
||||
sta = LINE_VALUE ;
|
||||
} else if (sscanf(line, "%[^=] = %[;#]", key, value)==2
|
||||
|| sscanf(line, "%[^=] %[=]", key, value) == 2) {
|
||||
/*
|
||||
* Special cases:
|
||||
* key=
|
||||
* key=;
|
||||
* key=#
|
||||
*/
|
||||
strcpy(key, strstrip(key));
|
||||
strcpy(key, strlwc(key));
|
||||
value[0]=0 ;
|
||||
sta = LINE_VALUE ;
|
||||
} else {
|
||||
/* Generate syntax error */
|
||||
sta = LINE_ERROR ;
|
||||
}
|
||||
return sta ;
|
||||
return sta;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -634,110 +636,107 @@ static line_status iniparser_line(
|
|||
The returned dictionary must be freed using iniparser_freedict().
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
dictionary * iniparser_load(const char * ininame)
|
||||
dictionary *iniparser_load(const char *ininame)
|
||||
{
|
||||
FILE * in ;
|
||||
FILE *in;
|
||||
|
||||
char line [ASCIILINESZ+1] ;
|
||||
char section [ASCIILINESZ+1] ;
|
||||
char key [ASCIILINESZ+1] ;
|
||||
char tmp [ASCIILINESZ+1] ;
|
||||
char val [ASCIILINESZ+1] ;
|
||||
char line[ASCIILINESZ + 1];
|
||||
char section[ASCIILINESZ + 1];
|
||||
char key[ASCIILINESZ + 1];
|
||||
char tmp[ASCIILINESZ + 1];
|
||||
char val[ASCIILINESZ + 1];
|
||||
|
||||
int last=0 ;
|
||||
int len ;
|
||||
int lineno=0 ;
|
||||
int errs=0;
|
||||
int last = 0;
|
||||
int len;
|
||||
int lineno = 0;
|
||||
int errs = 0;
|
||||
|
||||
dictionary * dict ;
|
||||
dictionary *dict;
|
||||
|
||||
if ((in=fopen(ininame, "r"))==NULL) {
|
||||
fprintf(stderr, "iniparser: cannot open %s\n", ininame);
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
dict = dictionary_new(0) ;
|
||||
if (!dict) {
|
||||
fclose(in);
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
memset(line, 0, ASCIILINESZ);
|
||||
memset(section, 0, ASCIILINESZ);
|
||||
memset(key, 0, ASCIILINESZ);
|
||||
memset(val, 0, ASCIILINESZ);
|
||||
last=0 ;
|
||||
|
||||
while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) {
|
||||
lineno++ ;
|
||||
len = (int)strlen(line)-1;
|
||||
if (len==0)
|
||||
continue;
|
||||
/* Safety check against buffer overflows */
|
||||
if (line[len]!='\n') {
|
||||
fprintf(stderr,
|
||||
"iniparser: input line too long in %s (%d)\n",
|
||||
ininame,
|
||||
lineno);
|
||||
dictionary_del(dict);
|
||||
fclose(in);
|
||||
return NULL ;
|
||||
if ((in = fopen(ininame, "r")) == NULL) {
|
||||
fprintf(stderr, "iniparser: cannot open %s\n", ininame);
|
||||
return NULL;
|
||||
}
|
||||
/* Get rid of \n and spaces at end of line */
|
||||
while ((len>=0) &&
|
||||
((line[len]=='\n') || (isspace(line[len])))) {
|
||||
line[len]=0 ;
|
||||
len-- ;
|
||||
|
||||
dict = dictionary_new(0);
|
||||
if (!dict) {
|
||||
fclose(in);
|
||||
return NULL;
|
||||
}
|
||||
/* Detect multi-line */
|
||||
if (line[len]=='\\') {
|
||||
/* Multi-line value */
|
||||
last=len ;
|
||||
continue ;
|
||||
} else {
|
||||
last=0 ;
|
||||
}
|
||||
switch (iniparser_line(line, section, key, val)) {
|
||||
case LINE_EMPTY:
|
||||
case LINE_COMMENT:
|
||||
break ;
|
||||
|
||||
case LINE_SECTION:
|
||||
errs = dictionary_set(dict, section, NULL);
|
||||
break ;
|
||||
|
||||
case LINE_VALUE:
|
||||
if (strlen(section))
|
||||
sprintf(tmp, "%s:%s", section, key);
|
||||
else
|
||||
sprintf(tmp, "preferences:%s", key);
|
||||
errs = dictionary_set(dict, tmp, val) ;
|
||||
break ;
|
||||
|
||||
case LINE_ERROR:
|
||||
fprintf(stderr, "iniparser: syntax error in %s (%d):\n",
|
||||
ininame,
|
||||
lineno);
|
||||
fprintf(stderr, "-> %s\n", line);
|
||||
errs++ ;
|
||||
break;
|
||||
|
||||
default:
|
||||
break ;
|
||||
}
|
||||
memset(line, 0, ASCIILINESZ);
|
||||
last=0;
|
||||
if (errs<0) {
|
||||
fprintf(stderr, "iniparser: memory allocation failure\n");
|
||||
break ;
|
||||
memset(section, 0, ASCIILINESZ);
|
||||
memset(key, 0, ASCIILINESZ);
|
||||
memset(val, 0, ASCIILINESZ);
|
||||
last = 0;
|
||||
|
||||
while (fgets(line + last, ASCIILINESZ - last, in) != NULL) {
|
||||
lineno++;
|
||||
len = (int)strlen(line) - 1;
|
||||
if (len == 0)
|
||||
continue;
|
||||
/* Safety check against buffer overflows */
|
||||
if (line[len] != '\n') {
|
||||
fprintf(stderr,
|
||||
"iniparser: input line too long in %s (%d)\n",
|
||||
ininame,
|
||||
lineno);
|
||||
dictionary_del(dict);
|
||||
fclose(in);
|
||||
return NULL;
|
||||
}
|
||||
/* Get rid of \n and spaces at end of line */
|
||||
while ((len >= 0) && ((line[len] == '\n') || (isspace(line[len])))) {
|
||||
line[len] = 0;
|
||||
len--;
|
||||
}
|
||||
/* Detect multi-line */
|
||||
if (line[len] == '\\') {
|
||||
/* Multi-line value */
|
||||
last = len;
|
||||
continue;
|
||||
} else {
|
||||
last = 0;
|
||||
}
|
||||
switch (iniparser_line(line, section, key, val)) {
|
||||
case LINE_EMPTY:
|
||||
case LINE_COMMENT:
|
||||
break;
|
||||
|
||||
case LINE_SECTION:
|
||||
errs = dictionary_set(dict, section, NULL);
|
||||
break;
|
||||
|
||||
case LINE_VALUE:
|
||||
if (strlen(section))
|
||||
sprintf(tmp, "%s:%s", section, key);
|
||||
else
|
||||
sprintf(tmp, "preferences:%s", key);
|
||||
errs = dictionary_set(dict, tmp, val);
|
||||
break;
|
||||
|
||||
case LINE_ERROR:
|
||||
fprintf(stderr, "iniparser: syntax error in %s (%d):\n", ininame, lineno);
|
||||
fprintf(stderr, "-> %s\n", line);
|
||||
errs++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
memset(line, 0, ASCIILINESZ);
|
||||
last = 0;
|
||||
if (errs < 0) {
|
||||
fprintf(stderr, "iniparser: memory allocation failure\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errs) {
|
||||
dictionary_del(dict);
|
||||
dict = NULL ;
|
||||
}
|
||||
fclose(in);
|
||||
return dict ;
|
||||
if (errs) {
|
||||
dictionary_del(dict);
|
||||
dict = NULL;
|
||||
}
|
||||
fclose(in);
|
||||
return dict;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -751,9 +750,9 @@ dictionary * iniparser_load(const char * ininame)
|
|||
gets out of the current context.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_freedict(dictionary * d)
|
||||
void iniparser_freedict(dictionary *d)
|
||||
{
|
||||
dictionary_del(d);
|
||||
dictionary_del(d);
|
||||
}
|
||||
|
||||
/* vim: set ts=4 et sw=4 tw=75 */
|
||||
|
|
|
@ -46,8 +46,7 @@
|
|||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
int iniparser_getnsec(dictionary * d);
|
||||
|
||||
int iniparser_getnsec(dictionary *d);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -64,8 +63,7 @@ int iniparser_getnsec(dictionary * d);
|
|||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
char * iniparser_getsecname(dictionary * d, int n);
|
||||
|
||||
char *iniparser_getsecname(dictionary *d, int n);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -79,7 +77,7 @@ char * iniparser_getsecname(dictionary * d, int n);
|
|||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void iniparser_dump_ini(dictionary * d, FILE * f);
|
||||
void iniparser_dump_ini(dictionary *d, FILE *f);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -94,7 +92,7 @@ void iniparser_dump_ini(dictionary * d, FILE * f);
|
|||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f);
|
||||
void iniparser_dumpsection_ini(dictionary *d, char *s, FILE *f);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -109,7 +107,7 @@ void iniparser_dumpsection_ini(dictionary * d, char * s, FILE * f);
|
|||
purposes mostly.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_dump(dictionary * d, FILE * f);
|
||||
void iniparser_dump(dictionary *d, FILE *f);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -119,7 +117,7 @@ void iniparser_dump(dictionary * d, FILE * f);
|
|||
@return Number of keys in section
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getsecnkeys(dictionary * d, char * s);
|
||||
int iniparser_getsecnkeys(dictionary *d, char *s);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -135,7 +133,7 @@ int iniparser_getsecnkeys(dictionary * d, char * s);
|
|||
This function returns NULL in case of error.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
char ** iniparser_getseckeys(dictionary * d, char * s);
|
||||
char **iniparser_getseckeys(dictionary *d, char *s);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -152,7 +150,7 @@ char ** iniparser_getseckeys(dictionary * d, char * s);
|
|||
the dictionary, do not free or modify it.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
const char * iniparser_getstring(dictionary * d, const char * key, const char * def);
|
||||
const char *iniparser_getstring(dictionary *d, const char *key, const char *def);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -181,7 +179,7 @@ const char * iniparser_getstring(dictionary * d, const char * key, const char *
|
|||
Credits: Thanks to A. Becker for suggesting strtol()
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getint(dictionary * d, const char * key, int notfound);
|
||||
int iniparser_getint(dictionary *d, const char *key, int notfound);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -196,7 +194,7 @@ int iniparser_getint(dictionary * d, const char * key, int notfound);
|
|||
the notfound value is returned.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
double iniparser_getdouble(dictionary * d, const char * key, double notfound);
|
||||
double iniparser_getdouble(dictionary *d, const char *key, double notfound);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -230,8 +228,7 @@ double iniparser_getdouble(dictionary * d, const char * key, double notfound);
|
|||
necessarily have to be 0 or 1.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_getboolean(dictionary * d, const char * key, int notfound);
|
||||
|
||||
int iniparser_getboolean(dictionary *d, const char *key, int notfound);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -246,8 +243,7 @@ int iniparser_getboolean(dictionary * d, const char * key, int notfound);
|
|||
It is Ok to set val to NULL.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_set(dictionary * ini, const char * entry, const char * val);
|
||||
|
||||
int iniparser_set(dictionary *ini, const char *entry, const char *val);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -259,7 +255,7 @@ int iniparser_set(dictionary * ini, const char * entry, const char * val);
|
|||
If the given entry can be found, it is deleted from the dictionary.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_unset(dictionary * ini, const char * entry);
|
||||
void iniparser_unset(dictionary *ini, const char *entry);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -273,7 +269,7 @@ void iniparser_unset(dictionary * ini, const char * entry);
|
|||
of querying for the presence of sections in a dictionary.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int iniparser_find_entry(dictionary * ini, const char * entry) ;
|
||||
int iniparser_find_entry(dictionary *ini, const char *entry);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -289,7 +285,7 @@ int iniparser_find_entry(dictionary * ini, const char * entry) ;
|
|||
The returned dictionary must be freed using iniparser_freedict().
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
dictionary * iniparser_load(const char * ininame);
|
||||
dictionary *iniparser_load(const char *ininame);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
@ -302,6 +298,6 @@ dictionary * iniparser_load(const char * ininame);
|
|||
gets out of the current context.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void iniparser_freedict(dictionary * d);
|
||||
void iniparser_freedict(dictionary *d);
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -18,289 +18,339 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
hq filter by Maxim Stepin ( http://hiend3d.com )
|
||||
hq filter by Maxim Stepin ( http://hiend3d.com )
|
||||
*/
|
||||
|
||||
|
||||
#ifdef _16BIT
|
||||
#ifdef _32BIT
|
||||
#error _16BIT and _32BIT defined at the same time!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _16BIT
|
||||
#define SIZE_PIXEL 2 // 16bit = 2 bytes
|
||||
#define COLORTYPE unsigned short
|
||||
#define RGBtoYUV RGBtoYUV_16
|
||||
#define Interp1 Interp1_16
|
||||
#define Interp2 Interp2_16
|
||||
#define Interp3 Interp3_16
|
||||
#define Interp4 Interp4_16
|
||||
#define Interp5 Interp5_16
|
||||
#define Interp6 Interp6_16
|
||||
#define Interp7 Interp7_16
|
||||
#define Interp8 Interp8_16
|
||||
#define SIZE_PIXEL 2 // 16bit = 2 bytes
|
||||
#define COLORTYPE unsigned short
|
||||
#define RGBtoYUV RGBtoYUV_16
|
||||
#define Interp1 Interp1_16
|
||||
#define Interp2 Interp2_16
|
||||
#define Interp3 Interp3_16
|
||||
#define Interp4 Interp4_16
|
||||
#define Interp5 Interp5_16
|
||||
#define Interp6 Interp6_16
|
||||
#define Interp7 Interp7_16
|
||||
#define Interp8 Interp8_16
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _32BIT
|
||||
#define SIZE_PIXEL 4 // 32bit = 4 bytes
|
||||
#define COLORTYPE unsigned int
|
||||
#define RGBtoYUV RGBtoYUV_32
|
||||
#define Interp1 Interp1_32
|
||||
#define Interp2 Interp2_32
|
||||
#define Interp3 Interp3_32
|
||||
#define Interp4 Interp4_32
|
||||
#define Interp5 Interp5_32
|
||||
#define Interp6 Interp6_32
|
||||
#define Interp7 Interp7_32
|
||||
#define Interp8 Interp8_32
|
||||
#define SIZE_PIXEL 4 // 32bit = 4 bytes
|
||||
#define COLORTYPE unsigned int
|
||||
#define RGBtoYUV RGBtoYUV_32
|
||||
#define Interp1 Interp1_32
|
||||
#define Interp2 Interp2_32
|
||||
#define Interp3 Interp3_32
|
||||
#define Interp4 Interp4_32
|
||||
#define Interp5 Interp5_32
|
||||
#define Interp6 Interp6_32
|
||||
#define Interp7 Interp7_32
|
||||
#define Interp8 Interp8_32
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _HQ3X
|
||||
|
||||
#define _MAGNIFICATION 3
|
||||
|
||||
#define PIXEL00_1M Interp1( pOut, c[5], c[1] );
|
||||
#define PIXEL00_1U Interp1( pOut, c[5], c[2] );
|
||||
#define PIXEL00_1L Interp1( pOut, c[5], c[4] );
|
||||
#define PIXEL00_2 Interp2( pOut, c[5], c[4], c[2] );
|
||||
#define PIXEL00_4 Interp4( pOut, c[5], c[4], c[2] );
|
||||
#define PIXEL00_5 Interp5( pOut, c[4], c[2] );
|
||||
#define PIXEL00_C *((COLORTYPE*)(pOut)) = c[5];
|
||||
#define PIXEL00_1M Interp1(pOut, c[5], c[1]);
|
||||
#define PIXEL00_1U Interp1(pOut, c[5], c[2]);
|
||||
#define PIXEL00_1L Interp1(pOut, c[5], c[4]);
|
||||
#define PIXEL00_2 Interp2(pOut, c[5], c[4], c[2]);
|
||||
#define PIXEL00_4 Interp4(pOut, c[5], c[4], c[2]);
|
||||
#define PIXEL00_5 Interp5(pOut, c[4], c[2]);
|
||||
#define PIXEL00_C *((COLORTYPE *)(pOut)) = c[5];
|
||||
|
||||
#define PIXEL01_1 Interp1( pOut+SIZE_PIXEL, c[5], c[2] );
|
||||
#define PIXEL01_3 Interp3( pOut+SIZE_PIXEL, c[5], c[2] );
|
||||
#define PIXEL01_6 Interp1( pOut+SIZE_PIXEL, c[2], c[5] );
|
||||
#define PIXEL01_C *((COLORTYPE*)(pOut+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL01_1 Interp1(pOut + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL01_3 Interp3(pOut + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL01_6 Interp1(pOut + SIZE_PIXEL, c[2], c[5]);
|
||||
#define PIXEL01_C *((COLORTYPE *)(pOut + SIZE_PIXEL)) = c[5];
|
||||
|
||||
#define PIXEL02_1M Interp1( pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[3] );
|
||||
#define PIXEL02_1U Interp1( pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2] );
|
||||
#define PIXEL02_1R Interp1( pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6] );
|
||||
#define PIXEL02_2 Interp2( pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2], c[6] );
|
||||
#define PIXEL02_4 Interp4( pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2], c[6] );
|
||||
#define PIXEL02_5 Interp5( pOut+SIZE_PIXEL+SIZE_PIXEL, c[2], c[6] );
|
||||
#define PIXEL02_C *((COLORTYPE*)(pOut+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL02_1M Interp1(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[3]);
|
||||
#define PIXEL02_1U Interp1(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL02_1R Interp1(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL02_2 Interp2(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2], c[6]);
|
||||
#define PIXEL02_4 Interp4(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2], c[6]);
|
||||
#define PIXEL02_5 Interp5(pOut + SIZE_PIXEL + SIZE_PIXEL, c[2], c[6]);
|
||||
#define PIXEL02_C *((COLORTYPE *)(pOut + SIZE_PIXEL + SIZE_PIXEL)) = c[5];
|
||||
|
||||
#define PIXEL10_1 Interp1( pOut+dstPitch, c[5], c[4] );
|
||||
#define PIXEL10_3 Interp3( pOut+dstPitch, c[5], c[4] );
|
||||
#define PIXEL10_6 Interp1( pOut+dstPitch, c[4], c[5] );
|
||||
#define PIXEL10_C *((COLORTYPE*)(pOut+dstPitch)) = c[5];
|
||||
#define PIXEL10_1 Interp1(pOut + dstPitch, c[5], c[4]);
|
||||
#define PIXEL10_3 Interp3(pOut + dstPitch, c[5], c[4]);
|
||||
#define PIXEL10_6 Interp1(pOut + dstPitch, c[4], c[5]);
|
||||
#define PIXEL10_C *((COLORTYPE *)(pOut + dstPitch)) = c[5];
|
||||
|
||||
#define PIXEL11 *((COLORTYPE*)(pOut+dstPitch+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL11 *((COLORTYPE *)(pOut + dstPitch + SIZE_PIXEL)) = c[5];
|
||||
|
||||
#define PIXEL12_1 Interp1( pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6] );
|
||||
#define PIXEL12_3 Interp3( pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6] );
|
||||
#define PIXEL12_6 Interp1( pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[6], c[5] );
|
||||
#define PIXEL12_C *((COLORTYPE*)(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL12_1 Interp1(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL12_3 Interp3(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL12_6 Interp1(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[6], c[5]);
|
||||
#define PIXEL12_C *((COLORTYPE *)(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL)) = c[5];
|
||||
|
||||
#define PIXEL20_1M Interp1( pOut+dstPitch+dstPitch, c[5], c[7] );
|
||||
#define PIXEL20_1D Interp1( pOut+dstPitch+dstPitch, c[5], c[8] );
|
||||
#define PIXEL20_1L Interp1( pOut+dstPitch+dstPitch, c[5], c[4] );
|
||||
#define PIXEL20_2 Interp2( pOut+dstPitch+dstPitch, c[5], c[8], c[4] );
|
||||
#define PIXEL20_4 Interp4( pOut+dstPitch+dstPitch, c[5], c[8], c[4] );
|
||||
#define PIXEL20_5 Interp5( pOut+dstPitch+dstPitch, c[8], c[4] );
|
||||
#define PIXEL20_C *((COLORTYPE*)(pOut+dstPitch+dstPitch)) = c[5];
|
||||
#define PIXEL20_1M Interp1(pOut + dstPitch + dstPitch, c[5], c[7]);
|
||||
#define PIXEL20_1D Interp1(pOut + dstPitch + dstPitch, c[5], c[8]);
|
||||
#define PIXEL20_1L Interp1(pOut + dstPitch + dstPitch, c[5], c[4]);
|
||||
#define PIXEL20_2 Interp2(pOut + dstPitch + dstPitch, c[5], c[8], c[4]);
|
||||
#define PIXEL20_4 Interp4(pOut + dstPitch + dstPitch, c[5], c[8], c[4]);
|
||||
#define PIXEL20_5 Interp5(pOut + dstPitch + dstPitch, c[8], c[4]);
|
||||
#define PIXEL20_C *((COLORTYPE *)(pOut + dstPitch + dstPitch)) = c[5];
|
||||
|
||||
#define PIXEL21_1 Interp1( pOut+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[8] );
|
||||
#define PIXEL21_3 Interp3( pOut+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[8] );
|
||||
#define PIXEL21_6 Interp1( pOut+dstPitch+dstPitch+SIZE_PIXEL, c[8], c[5] );
|
||||
#define PIXEL21_C *((COLORTYPE*)(pOut+dstPitch+dstPitch+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL21_1 Interp1(pOut + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL21_3 Interp3(pOut + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL21_6 Interp1(pOut + dstPitch + dstPitch + SIZE_PIXEL, c[8], c[5]);
|
||||
#define PIXEL21_C *((COLORTYPE *)(pOut + dstPitch + dstPitch + SIZE_PIXEL)) = c[5];
|
||||
|
||||
#define PIXEL22_1M Interp1( pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[9] );
|
||||
#define PIXEL22_1D Interp1( pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[8] );
|
||||
#define PIXEL22_1R Interp1( pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6] );
|
||||
#define PIXEL22_2 Interp2( pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6], c[8] );
|
||||
#define PIXEL22_4 Interp4( pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6], c[8] );
|
||||
#define PIXEL22_5 Interp5( pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[6], c[8] );
|
||||
#define PIXEL22_C *((COLORTYPE*)(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL22_1M Interp1(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[9]);
|
||||
#define PIXEL22_1D Interp1(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL22_1R Interp1(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL22_2 Interp2(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6], c[8]);
|
||||
#define PIXEL22_4 Interp4(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6], c[8]);
|
||||
#define PIXEL22_5 Interp5(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[6], c[8]);
|
||||
#define PIXEL22_C *((COLORTYPE *)(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL)) = c[5];
|
||||
|
||||
#endif // #ifdef _HQ3X
|
||||
|
||||
|
||||
|
||||
#ifdef _HQ4X
|
||||
|
||||
#define _MAGNIFICATION 4
|
||||
|
||||
#define PIXEL00_0 *((COLORTYPE*)(pOut)) = c[5];
|
||||
#define PIXEL00_11 Interp1(pOut, c[5], c[4]);
|
||||
#define PIXEL00_12 Interp1(pOut, c[5], c[2]);
|
||||
#define PIXEL00_20 Interp2(pOut, c[5], c[2], c[4]);
|
||||
#define PIXEL00_50 Interp5(pOut, c[2], c[4]);
|
||||
#define PIXEL00_80 Interp8(pOut, c[5], c[1]);
|
||||
#define PIXEL00_81 Interp8(pOut, c[5], c[4]);
|
||||
#define PIXEL00_82 Interp8(pOut, c[5], c[2]);
|
||||
#define PIXEL00_0 *((COLORTYPE *)(pOut)) = c[5];
|
||||
#define PIXEL00_11 Interp1(pOut, c[5], c[4]);
|
||||
#define PIXEL00_12 Interp1(pOut, c[5], c[2]);
|
||||
#define PIXEL00_20 Interp2(pOut, c[5], c[2], c[4]);
|
||||
#define PIXEL00_50 Interp5(pOut, c[2], c[4]);
|
||||
#define PIXEL00_80 Interp8(pOut, c[5], c[1]);
|
||||
#define PIXEL00_81 Interp8(pOut, c[5], c[4]);
|
||||
#define PIXEL00_82 Interp8(pOut, c[5], c[2]);
|
||||
|
||||
#define PIXEL01_0 *((COLORTYPE*)(pOut+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL01_10 Interp1(pOut+SIZE_PIXEL, c[5], c[1]);
|
||||
#define PIXEL01_12 Interp1(pOut+SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL01_14 Interp1(pOut+SIZE_PIXEL, c[2], c[5]);
|
||||
#define PIXEL01_21 Interp2(pOut+SIZE_PIXEL, c[2], c[5], c[4]);
|
||||
#define PIXEL01_31 Interp3(pOut+SIZE_PIXEL, c[5], c[4]);
|
||||
#define PIXEL01_50 Interp5(pOut+SIZE_PIXEL, c[2], c[5]);
|
||||
#define PIXEL01_60 Interp6(pOut+SIZE_PIXEL, c[5], c[2], c[4]);
|
||||
#define PIXEL01_61 Interp6(pOut+SIZE_PIXEL, c[5], c[2], c[1]);
|
||||
#define PIXEL01_82 Interp8(pOut+SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL01_83 Interp8(pOut+SIZE_PIXEL, c[2], c[4]);
|
||||
#define PIXEL01_0 *((COLORTYPE *)(pOut + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL01_10 Interp1(pOut + SIZE_PIXEL, c[5], c[1]);
|
||||
#define PIXEL01_12 Interp1(pOut + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL01_14 Interp1(pOut + SIZE_PIXEL, c[2], c[5]);
|
||||
#define PIXEL01_21 Interp2(pOut + SIZE_PIXEL, c[2], c[5], c[4]);
|
||||
#define PIXEL01_31 Interp3(pOut + SIZE_PIXEL, c[5], c[4]);
|
||||
#define PIXEL01_50 Interp5(pOut + SIZE_PIXEL, c[2], c[5]);
|
||||
#define PIXEL01_60 Interp6(pOut + SIZE_PIXEL, c[5], c[2], c[4]);
|
||||
#define PIXEL01_61 Interp6(pOut + SIZE_PIXEL, c[5], c[2], c[1]);
|
||||
#define PIXEL01_82 Interp8(pOut + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL01_83 Interp8(pOut + SIZE_PIXEL, c[2], c[4]);
|
||||
|
||||
#define PIXEL02_0 *((COLORTYPE*)(pOut+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL02_10 Interp1(pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[3]);
|
||||
#define PIXEL02_11 Interp1(pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL02_13 Interp1(pOut+SIZE_PIXEL+SIZE_PIXEL, c[2], c[5]);
|
||||
#define PIXEL02_21 Interp2(pOut+SIZE_PIXEL+SIZE_PIXEL, c[2], c[5], c[6]);
|
||||
#define PIXEL02_32 Interp3(pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL02_50 Interp5(pOut+SIZE_PIXEL+SIZE_PIXEL, c[2], c[5]);
|
||||
#define PIXEL02_60 Interp6(pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2], c[6]);
|
||||
#define PIXEL02_61 Interp6(pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2], c[3]);
|
||||
#define PIXEL02_81 Interp8(pOut+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL02_83 Interp8(pOut+SIZE_PIXEL+SIZE_PIXEL, c[2], c[6]);
|
||||
#define PIXEL02_0 *((COLORTYPE *)(pOut + SIZE_PIXEL + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL02_10 Interp1(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[3]);
|
||||
#define PIXEL02_11 Interp1(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL02_13 Interp1(pOut + SIZE_PIXEL + SIZE_PIXEL, c[2], c[5]);
|
||||
#define PIXEL02_21 Interp2(pOut + SIZE_PIXEL + SIZE_PIXEL, c[2], c[5], c[6]);
|
||||
#define PIXEL02_32 Interp3(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL02_50 Interp5(pOut + SIZE_PIXEL + SIZE_PIXEL, c[2], c[5]);
|
||||
#define PIXEL02_60 Interp6(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2], c[6]);
|
||||
#define PIXEL02_61 Interp6(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2], c[3]);
|
||||
#define PIXEL02_81 Interp8(pOut + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL02_83 Interp8(pOut + SIZE_PIXEL + SIZE_PIXEL, c[2], c[6]);
|
||||
|
||||
#define PIXEL03_0 *((COLORTYPE*)(pOut+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL03_11 Interp1(pOut+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL03_12 Interp1(pOut+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL03_20 Interp2(pOut+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2], c[6]);
|
||||
#define PIXEL03_50 Interp5(pOut+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[2], c[6]);
|
||||
#define PIXEL03_80 Interp8(pOut+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[3]);
|
||||
#define PIXEL03_81 Interp8(pOut+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL03_82 Interp8(pOut+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL03_0 *((COLORTYPE *)(pOut + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL03_11 Interp1(pOut + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL03_12 Interp1(pOut + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL03_20 Interp2(pOut + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2], c[6]);
|
||||
#define PIXEL03_50 Interp5(pOut + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[2], c[6]);
|
||||
#define PIXEL03_80 Interp8(pOut + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[3]);
|
||||
#define PIXEL03_81 Interp8(pOut + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL03_82 Interp8(pOut + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
|
||||
#define PIXEL10_0 *((COLORTYPE*)(pOut+dstPitch)) = c[5];
|
||||
#define PIXEL10_10 Interp1(pOut+dstPitch, c[5], c[1]);
|
||||
#define PIXEL10_11 Interp1(pOut+dstPitch, c[5], c[4]);
|
||||
#define PIXEL10_13 Interp1(pOut+dstPitch, c[4], c[5]);
|
||||
#define PIXEL10_21 Interp2(pOut+dstPitch, c[4], c[5], c[2]);
|
||||
#define PIXEL10_32 Interp3(pOut+dstPitch, c[5], c[2]);
|
||||
#define PIXEL10_50 Interp5(pOut+dstPitch, c[4], c[5]);
|
||||
#define PIXEL10_60 Interp6(pOut+dstPitch, c[5], c[4], c[2]);
|
||||
#define PIXEL10_61 Interp6(pOut+dstPitch, c[5], c[4], c[1]);
|
||||
#define PIXEL10_81 Interp8(pOut+dstPitch, c[5], c[4]);
|
||||
#define PIXEL10_83 Interp8(pOut+dstPitch, c[4], c[2]);
|
||||
#define PIXEL10_0 *((COLORTYPE *)(pOut + dstPitch)) = c[5];
|
||||
#define PIXEL10_10 Interp1(pOut + dstPitch, c[5], c[1]);
|
||||
#define PIXEL10_11 Interp1(pOut + dstPitch, c[5], c[4]);
|
||||
#define PIXEL10_13 Interp1(pOut + dstPitch, c[4], c[5]);
|
||||
#define PIXEL10_21 Interp2(pOut + dstPitch, c[4], c[5], c[2]);
|
||||
#define PIXEL10_32 Interp3(pOut + dstPitch, c[5], c[2]);
|
||||
#define PIXEL10_50 Interp5(pOut + dstPitch, c[4], c[5]);
|
||||
#define PIXEL10_60 Interp6(pOut + dstPitch, c[5], c[4], c[2]);
|
||||
#define PIXEL10_61 Interp6(pOut + dstPitch, c[5], c[4], c[1]);
|
||||
#define PIXEL10_81 Interp8(pOut + dstPitch, c[5], c[4]);
|
||||
#define PIXEL10_83 Interp8(pOut + dstPitch, c[4], c[2]);
|
||||
|
||||
#define PIXEL11_0 *((COLORTYPE*)(pOut+dstPitch+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL11_30 Interp3(pOut+dstPitch+SIZE_PIXEL, c[5], c[1]);
|
||||
#define PIXEL11_31 Interp3(pOut+dstPitch+SIZE_PIXEL, c[5], c[4]);
|
||||
#define PIXEL11_32 Interp3(pOut+dstPitch+SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL11_70 Interp7(pOut+dstPitch+SIZE_PIXEL, c[5], c[4], c[2]);
|
||||
#define PIXEL11_0 *((COLORTYPE *)(pOut + dstPitch + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL11_30 Interp3(pOut + dstPitch + SIZE_PIXEL, c[5], c[1]);
|
||||
#define PIXEL11_31 Interp3(pOut + dstPitch + SIZE_PIXEL, c[5], c[4]);
|
||||
#define PIXEL11_32 Interp3(pOut + dstPitch + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL11_70 Interp7(pOut + dstPitch + SIZE_PIXEL, c[5], c[4], c[2]);
|
||||
|
||||
#define PIXEL12_0 *((COLORTYPE*)(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL12_30 Interp3(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[3]);
|
||||
#define PIXEL12_31 Interp3(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL12_32 Interp3(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL12_70 Interp7(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6], c[2]);
|
||||
#define PIXEL12_0 *((COLORTYPE *)(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL12_30 Interp3(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[3]);
|
||||
#define PIXEL12_31 Interp3(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL12_32 Interp3(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL12_70 Interp7(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6], c[2]);
|
||||
|
||||
#define PIXEL13_0 *((COLORTYPE*)(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL13_10 Interp1(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[3]);
|
||||
#define PIXEL13_12 Interp1(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL13_14 Interp1(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[6], c[5]);
|
||||
#define PIXEL13_21 Interp2(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[6], c[5], c[2]);
|
||||
#define PIXEL13_31 Interp3(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL13_50 Interp5(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[6], c[5]);
|
||||
#define PIXEL13_60 Interp6(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6], c[2]);
|
||||
#define PIXEL13_61 Interp6(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6], c[3]);
|
||||
#define PIXEL13_82 Interp8(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL13_83 Interp8(pOut+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[6], c[2]);
|
||||
#define PIXEL13_0 *((COLORTYPE *)(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL13_10 Interp1(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[3]);
|
||||
#define PIXEL13_12 Interp1(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL13_14 Interp1(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[6], c[5]);
|
||||
#define PIXEL13_21 \
|
||||
Interp2(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[6], c[5], c[2]);
|
||||
#define PIXEL13_31 Interp3(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[2]);
|
||||
#define PIXEL13_50 Interp5(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[6], c[5]);
|
||||
#define PIXEL13_60 \
|
||||
Interp6(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6], c[2]);
|
||||
#define PIXEL13_61 \
|
||||
Interp6(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6], c[3]);
|
||||
#define PIXEL13_82 Interp8(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL13_83 Interp8(pOut + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[6], c[2]);
|
||||
|
||||
#define PIXEL20_0 *((COLORTYPE*)(pOut+dstPitch+dstPitch)) = c[5];
|
||||
#define PIXEL20_10 Interp1(pOut+dstPitch+dstPitch, c[5], c[7]);
|
||||
#define PIXEL20_12 Interp1(pOut+dstPitch+dstPitch, c[5], c[4]);
|
||||
#define PIXEL20_14 Interp1(pOut+dstPitch+dstPitch, c[4], c[5]);
|
||||
#define PIXEL20_21 Interp2(pOut+dstPitch+dstPitch, c[4], c[5], c[8]);
|
||||
#define PIXEL20_31 Interp3(pOut+dstPitch+dstPitch, c[5], c[8]);
|
||||
#define PIXEL20_50 Interp5(pOut+dstPitch+dstPitch, c[4], c[5]);
|
||||
#define PIXEL20_60 Interp6(pOut+dstPitch+dstPitch, c[5], c[4], c[8]);
|
||||
#define PIXEL20_61 Interp6(pOut+dstPitch+dstPitch, c[5], c[4], c[7]);
|
||||
#define PIXEL20_82 Interp8(pOut+dstPitch+dstPitch, c[5], c[4]);
|
||||
#define PIXEL20_83 Interp8(pOut+dstPitch+dstPitch, c[4], c[8]);
|
||||
#define PIXEL20_0 *((COLORTYPE *)(pOut + dstPitch + dstPitch)) = c[5];
|
||||
#define PIXEL20_10 Interp1(pOut + dstPitch + dstPitch, c[5], c[7]);
|
||||
#define PIXEL20_12 Interp1(pOut + dstPitch + dstPitch, c[5], c[4]);
|
||||
#define PIXEL20_14 Interp1(pOut + dstPitch + dstPitch, c[4], c[5]);
|
||||
#define PIXEL20_21 Interp2(pOut + dstPitch + dstPitch, c[4], c[5], c[8]);
|
||||
#define PIXEL20_31 Interp3(pOut + dstPitch + dstPitch, c[5], c[8]);
|
||||
#define PIXEL20_50 Interp5(pOut + dstPitch + dstPitch, c[4], c[5]);
|
||||
#define PIXEL20_60 Interp6(pOut + dstPitch + dstPitch, c[5], c[4], c[8]);
|
||||
#define PIXEL20_61 Interp6(pOut + dstPitch + dstPitch, c[5], c[4], c[7]);
|
||||
#define PIXEL20_82 Interp8(pOut + dstPitch + dstPitch, c[5], c[4]);
|
||||
#define PIXEL20_83 Interp8(pOut + dstPitch + dstPitch, c[4], c[8]);
|
||||
|
||||
#define PIXEL21_0 *((COLORTYPE*)(pOut+dstPitch+dstPitch+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL21_30 Interp3(pOut+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[7]);
|
||||
#define PIXEL21_31 Interp3(pOut+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL21_32 Interp3(pOut+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[4]);
|
||||
#define PIXEL21_70 Interp7(pOut+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[4], c[8]);
|
||||
#define PIXEL22_0 *((COLORTYPE*)(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL22_30 Interp3(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[9]);
|
||||
#define PIXEL22_31 Interp3(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL22_32 Interp3(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL22_70 Interp7(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6], c[8]);
|
||||
#define PIXEL21_0 *((COLORTYPE *)(pOut + dstPitch + dstPitch + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL21_30 Interp3(pOut + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[7]);
|
||||
#define PIXEL21_31 Interp3(pOut + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL21_32 Interp3(pOut + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[4]);
|
||||
#define PIXEL21_70 Interp7(pOut + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[4], c[8]);
|
||||
#define PIXEL22_0 *((COLORTYPE *)(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL22_30 Interp3(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[9]);
|
||||
#define PIXEL22_31 Interp3(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL22_32 Interp3(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL22_70 Interp7(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6], c[8]);
|
||||
|
||||
#define PIXEL23_0 *((COLORTYPE*)(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL23_10 Interp1(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[9]);
|
||||
#define PIXEL23_11 Interp1(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL23_13 Interp1(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[6], c[5]);
|
||||
#define PIXEL23_21 Interp2(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[6], c[5], c[8]);
|
||||
#define PIXEL23_32 Interp3(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL23_50 Interp5(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[6], c[5]);
|
||||
#define PIXEL23_60 Interp6(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6], c[8]);
|
||||
#define PIXEL23_61 Interp6(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6], c[9]);
|
||||
#define PIXEL23_81 Interp8(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL23_83 Interp8(pOut+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[6], c[8]);
|
||||
#define PIXEL23_0 \
|
||||
*((COLORTYPE *)(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL23_10 \
|
||||
Interp1(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[9]);
|
||||
#define PIXEL23_11 \
|
||||
Interp1(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL23_13 \
|
||||
Interp1(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[6], c[5]);
|
||||
#define PIXEL23_21 \
|
||||
Interp2(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, \
|
||||
c[6], \
|
||||
c[5], \
|
||||
c[8]);
|
||||
#define PIXEL23_32 \
|
||||
Interp3(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL23_50 \
|
||||
Interp5(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[6], c[5]);
|
||||
#define PIXEL23_60 \
|
||||
Interp6(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, \
|
||||
c[5], \
|
||||
c[6], \
|
||||
c[8]);
|
||||
#define PIXEL23_61 \
|
||||
Interp6(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, \
|
||||
c[5], \
|
||||
c[6], \
|
||||
c[9]);
|
||||
#define PIXEL23_81 \
|
||||
Interp8(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL23_83 \
|
||||
Interp8(pOut + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, c[6], c[8]);
|
||||
|
||||
#define PIXEL30_0 *((COLORTYPE*)(pOut+dstPitch+dstPitch+dstPitch)) = c[5];
|
||||
#define PIXEL30_11 Interp1(pOut+dstPitch+dstPitch+dstPitch, c[5], c[8]);
|
||||
#define PIXEL30_12 Interp1(pOut+dstPitch+dstPitch+dstPitch, c[5], c[4]);
|
||||
#define PIXEL30_20 Interp2(pOut+dstPitch+dstPitch+dstPitch, c[5], c[8], c[4]);
|
||||
#define PIXEL30_50 Interp5(pOut+dstPitch+dstPitch+dstPitch, c[8], c[4]);
|
||||
#define PIXEL30_80 Interp8(pOut+dstPitch+dstPitch+dstPitch, c[5], c[7]);
|
||||
#define PIXEL30_81 Interp8(pOut+dstPitch+dstPitch+dstPitch, c[5], c[8]);
|
||||
#define PIXEL30_82 Interp8(pOut+dstPitch+dstPitch+dstPitch, c[5], c[4]);
|
||||
#define PIXEL30_0 *((COLORTYPE *)(pOut + dstPitch + dstPitch + dstPitch)) = c[5];
|
||||
#define PIXEL30_11 Interp1(pOut + dstPitch + dstPitch + dstPitch, c[5], c[8]);
|
||||
#define PIXEL30_12 Interp1(pOut + dstPitch + dstPitch + dstPitch, c[5], c[4]);
|
||||
#define PIXEL30_20 Interp2(pOut + dstPitch + dstPitch + dstPitch, c[5], c[8], c[4]);
|
||||
#define PIXEL30_50 Interp5(pOut + dstPitch + dstPitch + dstPitch, c[8], c[4]);
|
||||
#define PIXEL30_80 Interp8(pOut + dstPitch + dstPitch + dstPitch, c[5], c[7]);
|
||||
#define PIXEL30_81 Interp8(pOut + dstPitch + dstPitch + dstPitch, c[5], c[8]);
|
||||
#define PIXEL30_82 Interp8(pOut + dstPitch + dstPitch + dstPitch, c[5], c[4]);
|
||||
|
||||
#define PIXEL31_0 *((COLORTYPE*)(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL31_10 Interp1(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[7]);
|
||||
#define PIXEL31_11 Interp1(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL31_13 Interp1(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL, c[8], c[5]);
|
||||
#define PIXEL31_21 Interp2(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL, c[8], c[5], c[4]);
|
||||
#define PIXEL31_32 Interp3(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[4]);
|
||||
#define PIXEL31_50 Interp5(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL, c[8], c[5]);
|
||||
#define PIXEL31_60 Interp6(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[8], c[4]);
|
||||
#define PIXEL31_61 Interp6(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[8], c[7]);
|
||||
#define PIXEL31_81 Interp8(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL31_83 Interp8(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL, c[8], c[4]);
|
||||
#define PIXEL31_0 *((COLORTYPE *)(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL31_10 Interp1(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[7]);
|
||||
#define PIXEL31_11 Interp1(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL31_13 Interp1(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL, c[8], c[5]);
|
||||
#define PIXEL31_21 Interp2(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL, c[8], c[5], c[4]);
|
||||
#define PIXEL31_32 Interp3(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[4]);
|
||||
#define PIXEL31_50 Interp5(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL, c[8], c[5]);
|
||||
#define PIXEL31_60 Interp6(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[8], c[4]);
|
||||
#define PIXEL31_61 Interp6(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[8], c[7]);
|
||||
#define PIXEL31_81 Interp8(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL31_83 Interp8(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL, c[8], c[4]);
|
||||
|
||||
#define PIXEL32_0 *((COLORTYPE*)(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL32_10 Interp1(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[9]);
|
||||
#define PIXEL32_12 Interp1(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL32_14 Interp1(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[8], c[5]);
|
||||
#define PIXEL32_21 Interp2(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[8], c[5], c[6]);
|
||||
#define PIXEL32_31 Interp3(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL32_50 Interp5(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[8], c[5]);
|
||||
#define PIXEL32_60 Interp6(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[8], c[6]);
|
||||
#define PIXEL32_61 Interp6(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[8], c[9]);
|
||||
#define PIXEL32_82 Interp8(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL32_83 Interp8(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL, c[8], c[6]);
|
||||
#define PIXEL32_0 \
|
||||
*((COLORTYPE *)(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL32_10 \
|
||||
Interp1(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[9]);
|
||||
#define PIXEL32_12 \
|
||||
Interp1(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL32_14 \
|
||||
Interp1(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[8], c[5]);
|
||||
#define PIXEL32_21 \
|
||||
Interp2(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[8], c[5], c[6]);
|
||||
#define PIXEL32_31 \
|
||||
Interp3(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL32_50 \
|
||||
Interp5(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[8], c[5]);
|
||||
#define PIXEL32_60 \
|
||||
Interp6(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[8], c[6]);
|
||||
#define PIXEL32_61 \
|
||||
Interp6(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[8], c[9]);
|
||||
#define PIXEL32_82 \
|
||||
Interp8(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL32_83 \
|
||||
Interp8(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL, c[8], c[6]);
|
||||
|
||||
#define PIXEL33_0 *((COLORTYPE*)(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL33_11 Interp1(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL33_12 Interp1(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL33_20 Interp2(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[8], c[6]);
|
||||
#define PIXEL33_50 Interp5(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[8], c[6]);
|
||||
#define PIXEL33_80 Interp8(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[9]);
|
||||
#define PIXEL33_81 Interp8(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[6]);
|
||||
#define PIXEL33_82 Interp8(pOut+dstPitch+dstPitch+dstPitch+SIZE_PIXEL+SIZE_PIXEL+SIZE_PIXEL, c[5], c[8]);
|
||||
#define PIXEL33_0 \
|
||||
*((COLORTYPE *)(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + \
|
||||
SIZE_PIXEL)) = c[5];
|
||||
#define PIXEL33_11 \
|
||||
Interp1(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, \
|
||||
c[5], \
|
||||
c[6]);
|
||||
#define PIXEL33_12 \
|
||||
Interp1(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, \
|
||||
c[5], \
|
||||
c[8]);
|
||||
#define PIXEL33_20 \
|
||||
Interp2(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, \
|
||||
c[5], \
|
||||
c[8], \
|
||||
c[6]);
|
||||
#define PIXEL33_50 \
|
||||
Interp5(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, \
|
||||
c[8], \
|
||||
c[6]);
|
||||
#define PIXEL33_80 \
|
||||
Interp8(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, \
|
||||
c[5], \
|
||||
c[9]);
|
||||
#define PIXEL33_81 \
|
||||
Interp8(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, \
|
||||
c[5], \
|
||||
c[6]);
|
||||
#define PIXEL33_82 \
|
||||
Interp8(pOut + dstPitch + dstPitch + dstPitch + SIZE_PIXEL + SIZE_PIXEL + SIZE_PIXEL, \
|
||||
c[5], \
|
||||
c[8]);
|
||||
|
||||
#endif // #ifdef _HQ4X
|
||||
|
||||
|
||||
|
||||
// function header
|
||||
#ifdef _16BIT
|
||||
#ifdef _HQ3X
|
||||
void hq3x16(
|
||||
#endif
|
||||
#ifdef _HQ4X
|
||||
#ifdef _HQ3X
|
||||
void hq3x16(
|
||||
#endif
|
||||
#ifdef _HQ4X
|
||||
void hq4x16(
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _32BIT
|
||||
#ifdef _HQ3X
|
||||
#ifdef _HQ3X
|
||||
void hq3x32(
|
||||
#endif
|
||||
#ifdef _HQ4X
|
||||
#endif
|
||||
#ifdef _HQ4X
|
||||
void hq4x32(
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
unsigned char *pIn, unsigned int srcPitch,
|
||||
|
@ -308,100 +358,93 @@ unsigned char *,
|
|||
unsigned char *pOut, unsigned int dstPitch,
|
||||
int Xres, int Yres )
|
||||
{
|
||||
unsigned int yuv[10] = {0}; // yuv[0] not used
|
||||
// yuv[1-9] allows reusage of calculated YUV values
|
||||
int x, y;
|
||||
unsigned int linePlus, lineMinus;
|
||||
unsigned int yuv[10] = { 0 }; // yuv[0] not used
|
||||
// yuv[1-9] allows reusage of calculated YUV values
|
||||
int x, y;
|
||||
unsigned int linePlus, lineMinus;
|
||||
|
||||
COLORTYPE c[10]; // c[0] not used
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | c1 | c2 | c3 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | c4 | c5 | c6 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | c7 | c8 | c9 |
|
||||
// +----+----+----+
|
||||
COLORTYPE c[10]; // c[0] not used
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | c1 | c2 | c3 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | c4 | c5 | c6 |
|
||||
// +----+----+----+
|
||||
// | | | |
|
||||
// | c7 | c8 | c9 |
|
||||
// +----+----+----+
|
||||
|
||||
for (y=0; y<Yres; y++)
|
||||
{
|
||||
if( y == 0 ) {
|
||||
linePlus = srcPitch;
|
||||
lineMinus = 0;
|
||||
} else if( y == ( Yres - 1 ) ) {
|
||||
linePlus = 0;
|
||||
lineMinus = srcPitch;
|
||||
} else {
|
||||
linePlus = srcPitch;
|
||||
lineMinus = srcPitch;
|
||||
}
|
||||
for (y = 0; y < Yres; y++) {
|
||||
if (y == 0) {
|
||||
linePlus = srcPitch;
|
||||
lineMinus = 0;
|
||||
} else if (y == (Yres - 1)) {
|
||||
linePlus = 0;
|
||||
lineMinus = srcPitch;
|
||||
} else {
|
||||
linePlus = srcPitch;
|
||||
lineMinus = srcPitch;
|
||||
}
|
||||
|
||||
for (x=0; x<Xres; x++)
|
||||
{
|
||||
c[2] = *((COLORTYPE*)(pIn - lineMinus));
|
||||
c[5] = *((COLORTYPE*)(pIn ));
|
||||
c[8] = *((COLORTYPE*)(pIn + linePlus ));
|
||||
for (x = 0; x < Xres; x++) {
|
||||
c[2] = *((COLORTYPE *)(pIn - lineMinus));
|
||||
c[5] = *((COLORTYPE *)(pIn));
|
||||
c[8] = *((COLORTYPE *)(pIn + linePlus));
|
||||
|
||||
if (x>0)
|
||||
{
|
||||
// upper border possible:
|
||||
c[1] = *((COLORTYPE*)(pIn - lineMinus - SIZE_PIXEL));
|
||||
if (x > 0) {
|
||||
// upper border possible:
|
||||
c[1] = *((COLORTYPE *)(pIn - lineMinus - SIZE_PIXEL));
|
||||
|
||||
c[4] = *((COLORTYPE*)(pIn - SIZE_PIXEL));
|
||||
c[4] = *((COLORTYPE *)(pIn - SIZE_PIXEL));
|
||||
|
||||
// lower border possible:
|
||||
c[7] = *((COLORTYPE*)(pIn + linePlus - SIZE_PIXEL));
|
||||
}
|
||||
else
|
||||
{ // left border
|
||||
c[1] = c[2];
|
||||
c[4] = c[5];
|
||||
c[7] = c[8];
|
||||
}
|
||||
// lower border possible:
|
||||
c[7] = *((COLORTYPE *)(pIn + linePlus - SIZE_PIXEL));
|
||||
} else { // left border
|
||||
c[1] = c[2];
|
||||
c[4] = c[5];
|
||||
c[7] = c[8];
|
||||
}
|
||||
|
||||
if (x<Xres-1)
|
||||
{
|
||||
// upper border possible:
|
||||
c[3] = *((COLORTYPE*)(pIn - lineMinus + SIZE_PIXEL));
|
||||
if (x < Xres - 1) {
|
||||
// upper border possible:
|
||||
c[3] = *((COLORTYPE *)(pIn - lineMinus + SIZE_PIXEL));
|
||||
|
||||
c[6] = *((COLORTYPE*)(pIn + SIZE_PIXEL));
|
||||
c[6] = *((COLORTYPE *)(pIn + SIZE_PIXEL));
|
||||
|
||||
// lower border possible:
|
||||
c[9] = *((COLORTYPE*)(pIn + linePlus + SIZE_PIXEL));
|
||||
}
|
||||
else
|
||||
{ // right border
|
||||
c[3] = c[2];
|
||||
c[6] = c[5];
|
||||
c[9] = c[8];
|
||||
}
|
||||
// lower border possible:
|
||||
c[9] = *((COLORTYPE *)(pIn + linePlus + SIZE_PIXEL));
|
||||
} else { // right border
|
||||
c[3] = c[2];
|
||||
c[6] = c[5];
|
||||
c[9] = c[8];
|
||||
}
|
||||
|
||||
unsigned int pattern = 0;
|
||||
unsigned int flag = 1;
|
||||
unsigned int pattern = 0;
|
||||
unsigned int flag = 1;
|
||||
|
||||
yuv[5] = RGBtoYUV( c[5] );
|
||||
yuv[5] = RGBtoYUV(c[5]);
|
||||
|
||||
for( unsigned char k = 1; k <= 9; k++)
|
||||
{
|
||||
if( k == 5 ) continue;
|
||||
for (unsigned char k = 1; k <= 9; k++) {
|
||||
if (k == 5)
|
||||
continue;
|
||||
|
||||
if( c[k] != c[5] )
|
||||
{
|
||||
// pre-calculating the YUV-values for every pixel does
|
||||
// not speed up the process
|
||||
yuv[k] = RGBtoYUV( c[k] );
|
||||
if (c[k] != c[5]) {
|
||||
// pre-calculating the YUV-values for every pixel does
|
||||
// not speed up the process
|
||||
yuv[k] = RGBtoYUV(c[k]);
|
||||
|
||||
if( ( abs_32((yuv[5] & 0x00FF0000) - (yuv[k] & 0x00FF0000)) > 0x00300000 ) ||
|
||||
( abs_32((yuv[5] & 0x0000FF00) - (yuv[k] & 0x0000FF00)) > 0x00000700 ) ||
|
||||
( abs_32((yuv[5] & 0x000000FF) - (yuv[k] & 0x000000FF)) > 0x00000006 )
|
||||
) {
|
||||
pattern |= flag;
|
||||
}
|
||||
}
|
||||
flag <<= 1;
|
||||
}
|
||||
if ((abs_32((yuv[5] & 0x00FF0000) - (yuv[k] & 0x00FF0000)) >
|
||||
0x00300000) ||
|
||||
(abs_32((yuv[5] & 0x0000FF00) - (yuv[k] & 0x0000FF00)) >
|
||||
0x00000700) ||
|
||||
(abs_32((yuv[5] & 0x000000FF) - (yuv[k] & 0x000000FF)) >
|
||||
0x00000006)) {
|
||||
pattern |= flag;
|
||||
}
|
||||
}
|
||||
flag <<= 1;
|
||||
}
|
||||
|
||||
#ifdef _HQ3X
|
||||
#include "hq3x_pattern.h"
|
||||
|
@ -411,28 +454,28 @@ int Xres, int Yres )
|
|||
#include "hq4x_pattern.h"
|
||||
#endif
|
||||
|
||||
pIn += SIZE_PIXEL;
|
||||
pOut += _MAGNIFICATION * SIZE_PIXEL;
|
||||
}
|
||||
pIn += srcPitch - ( Xres * SIZE_PIXEL );
|
||||
pOut += dstPitch - ( _MAGNIFICATION * Xres * SIZE_PIXEL );
|
||||
pOut += ( _MAGNIFICATION - 1 ) * dstPitch;
|
||||
}
|
||||
pIn += SIZE_PIXEL;
|
||||
pOut += _MAGNIFICATION * SIZE_PIXEL;
|
||||
}
|
||||
pIn += srcPitch - (Xres * SIZE_PIXEL);
|
||||
pOut += dstPitch - (_MAGNIFICATION * Xres * SIZE_PIXEL);
|
||||
pOut += (_MAGNIFICATION - 1) * dstPitch;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _32BIT
|
||||
#ifdef _HQ3X
|
||||
#ifdef _HQ3X
|
||||
void hq3x32_32(unsigned char *pIn, unsigned int srcPitch, unsigned char *, unsigned char *pOut, unsigned int dstPitch, int Xres, int Yres)
|
||||
{
|
||||
hq3x32(pIn, srcPitch, 0, pOut, dstPitch, Xres, Yres);
|
||||
hq3x32(pIn, srcPitch, 0, pOut, dstPitch, Xres, Yres);
|
||||
}
|
||||
#endif
|
||||
#ifdef _HQ4X
|
||||
#endif
|
||||
#ifdef _HQ4X
|
||||
void hq4x32_32(unsigned char *pIn, unsigned int srcPitch, unsigned char *, unsigned char *pOut, unsigned int dstPitch, int Xres, int Yres)
|
||||
{
|
||||
hq4x32(pIn, srcPitch, 0, pOut, dstPitch, Xres, Yres);
|
||||
hq4x32(pIn, srcPitch, 0, pOut, dstPitch, Xres, Yres);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef SIZE_PIXEL
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
hq filter by Maxim Stepin ( http://hiend3d.com )
|
||||
hq filter by Maxim Stepin ( http://hiend3d.com )
|
||||
*/
|
||||
|
||||
#ifdef RGB555
|
||||
|
@ -52,394 +52,218 @@
|
|||
#define RBSHIFT4MASK 0x000F81F0
|
||||
#endif
|
||||
|
||||
|
||||
// we only need the 32bit version because our YUV format has 32bits
|
||||
#define abs_32( value ) ( ( value ) & 0x7FFFFFFF )
|
||||
#define abs_32(value) ((value)&0x7FFFFFFF)
|
||||
|
||||
|
||||
inline bool Diff( unsigned int YUV1, unsigned int YUV2 )
|
||||
inline bool Diff(unsigned int YUV1, unsigned int YUV2)
|
||||
{
|
||||
if( YUV1 == YUV2 ) return false; // Save some processing power
|
||||
if (YUV1 == YUV2)
|
||||
return false; // Save some processing power
|
||||
|
||||
return
|
||||
( abs_32((YUV1 & 0x00FF0000) - (YUV2 & 0x00FF0000)) > 0x00300000 ) ||
|
||||
( abs_32((YUV1 & 0x0000FF00) - (YUV2 & 0x0000FF00)) > 0x00000700 ) ||
|
||||
( abs_32((YUV1 & 0x000000FF) - (YUV2 & 0x000000FF)) > 0x00000006 );
|
||||
return (abs_32((YUV1 & 0x00FF0000) - (YUV2 & 0x00FF0000)) > 0x00300000) ||
|
||||
(abs_32((YUV1 & 0x0000FF00) - (YUV2 & 0x0000FF00)) > 0x00000700) ||
|
||||
(abs_32((YUV1 & 0x000000FF) - (YUV2 & 0x000000FF)) > 0x00000006);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ===============
|
||||
// 32bit routines:
|
||||
// ===============
|
||||
|
||||
// ( c1*3 + c2 ) / 4
|
||||
// hq3x, hq4x
|
||||
#define Interp1_32( pc, c1, c2 ) \
|
||||
( \
|
||||
*( (unsigned int *)(pc) ) = \
|
||||
( (c1) == (c2) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & 0x00FF00 ) * 3 ) + \
|
||||
( (c2) & 0x00FF00 ) \
|
||||
) & 0x0003FC00 ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & 0xFF00FF ) * 3 ) + \
|
||||
( (c2) & 0xFF00FF ) \
|
||||
) & 0x03FC03FC ) \
|
||||
) >> 2 \
|
||||
)
|
||||
|
||||
#define Interp1_32(pc, c1, c2) \
|
||||
(*((unsigned int *)(pc)) = \
|
||||
((c1) == (c2)) ? c1 : ((((((c1)&0x00FF00) * 3) + ((c2)&0x00FF00)) & 0x0003FC00) + \
|
||||
(((((c1)&0xFF00FF) * 3) + ((c2)&0xFF00FF)) & 0x03FC03FC)) >> \
|
||||
2)
|
||||
|
||||
// ( c1*2 + c2 + c3 ) / 4
|
||||
// hq3x, hq4x
|
||||
#define Interp2_32( pc, c1, c2, c3 ) \
|
||||
( \
|
||||
*( (unsigned int *)(pc) ) = \
|
||||
( ( (c1) == (c2) ) == (c3) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & 0x00FF00 ) * 2 ) + \
|
||||
( (c2) & 0x00FF00 ) + \
|
||||
( (c3) & 0x00FF00 ) \
|
||||
) & 0x0003FC00 ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & 0xFF00FF ) * 2 ) + \
|
||||
( (c2) & 0xFF00FF ) + \
|
||||
( (c3) & 0xFF00FF ) \
|
||||
) & 0x03FC03FC ) \
|
||||
) >> 2 \
|
||||
)
|
||||
|
||||
#define Interp2_32(pc, c1, c2, c3) \
|
||||
(*((unsigned int *)(pc)) = \
|
||||
(((c1) == (c2)) == (c3)) \
|
||||
? c1 \
|
||||
: ((((((c1)&0x00FF00) * 2) + ((c2)&0x00FF00) + ((c3)&0x00FF00)) & 0x0003FC00) + \
|
||||
(((((c1)&0xFF00FF) * 2) + ((c2)&0xFF00FF) + ((c3)&0xFF00FF)) & 0x03FC03FC)) >> \
|
||||
2)
|
||||
|
||||
// ( c1*7 + c2 ) / 8
|
||||
// hq3x, hq4x
|
||||
#define Interp3_32( pc, c1, c2 ) \
|
||||
( \
|
||||
*( (unsigned int *)(pc) ) = \
|
||||
( (c1) == (c2) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & 0x00FF00 ) * 7 ) + \
|
||||
( (c2) & 0x00FF00 ) \
|
||||
) & 0x0007F800 ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & 0xFF00FF ) * 7 ) + \
|
||||
( (c2) & 0xFF00FF ) \
|
||||
) & 0x07F807F8 ) \
|
||||
) >> 3 \
|
||||
)
|
||||
|
||||
#define Interp3_32(pc, c1, c2) \
|
||||
(*((unsigned int *)(pc)) = \
|
||||
((c1) == (c2)) ? c1 : ((((((c1)&0x00FF00) * 7) + ((c2)&0x00FF00)) & 0x0007F800) + \
|
||||
(((((c1)&0xFF00FF) * 7) + ((c2)&0xFF00FF)) & 0x07F807F8)) >> \
|
||||
3)
|
||||
|
||||
// ( c1*2 + (c2+c3)*7 ) / 16
|
||||
// hq3x, not used by hq4x
|
||||
#define Interp4_32( pc, c1, c2, c3 ) \
|
||||
( \
|
||||
*( (unsigned int *)(pc) ) = \
|
||||
( ( (c1) == (c2) ) == (c3) ) ? c1 : \
|
||||
( \
|
||||
( ( ( ( (c1) & 0x00FF00 ) * 2 ) + ( ( ( (c2) & 0x00FF00 ) + ( (c3) & 0x00FF00 ) ) * 7 ) ) & 0x000FF000 ) + \
|
||||
( ( ( ( (c1) & 0xFF00FF ) * 2 ) + ( ( ( (c2) & 0xFF00FF ) + ( (c3) & 0xFF00FF ) ) * 7 ) ) & 0x0FF00FF0 ) \
|
||||
) >> 4 \
|
||||
)
|
||||
|
||||
#define Interp4_32(pc, c1, c2, c3) \
|
||||
(*((unsigned int *)(pc)) = \
|
||||
(((c1) == (c2)) == (c3)) \
|
||||
? c1 \
|
||||
: ((((((c1)&0x00FF00) * 2) + ((((c2)&0x00FF00) + ((c3)&0x00FF00)) * 7)) & \
|
||||
0x000FF000) + \
|
||||
(((((c1)&0xFF00FF) * 2) + ((((c2)&0xFF00FF) + ((c3)&0xFF00FF)) * 7)) & \
|
||||
0x0FF00FF0)) >> \
|
||||
4)
|
||||
|
||||
// ( c1 + c2 ) / 2
|
||||
// hq3x, hq4x
|
||||
#define Interp5_32( pc, c1, c2 ) \
|
||||
( \
|
||||
*( (unsigned int *)(pc) ) = \
|
||||
( (c1) == (c2) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( (c1) & 0x00FF00 ) + \
|
||||
( (c2) & 0x00FF00 ) \
|
||||
) & 0x0001FE00 ) \
|
||||
+ \
|
||||
( ( \
|
||||
( (c1) & 0xFF00FF ) + \
|
||||
( (c2) & 0xFF00FF ) \
|
||||
) & 0x01FE01FE ) \
|
||||
) >> 1 \
|
||||
)
|
||||
|
||||
#define Interp5_32(pc, c1, c2) \
|
||||
(*((unsigned int *)(pc)) = \
|
||||
((c1) == (c2)) ? c1 : (((((c1)&0x00FF00) + ((c2)&0x00FF00)) & 0x0001FE00) + \
|
||||
((((c1)&0xFF00FF) + ((c2)&0xFF00FF)) & 0x01FE01FE)) >> \
|
||||
1)
|
||||
|
||||
// ( c1*5 + c2*2 + c3 ) / 8
|
||||
// hq4x
|
||||
#define Interp6_32( pc, c1, c2, c3 ) \
|
||||
( \
|
||||
*( (unsigned int *)(pc) ) = \
|
||||
( ( (c1) == (c2) ) == (c3) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & 0x00FF00 ) * 5 ) + \
|
||||
( ( (c2) & 0x00FF00 ) * 2 ) + \
|
||||
( (c3) & 0x00FF00 ) \
|
||||
) & 0x0007F800 ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & 0xFF00FF ) * 5 ) + \
|
||||
( ( (c2) & 0xFF00FF ) * 2 ) + \
|
||||
( (c3) & 0xFF00FF ) \
|
||||
) & 0x07F807F8 ) \
|
||||
) >> 3 \
|
||||
)
|
||||
|
||||
#define Interp6_32(pc, c1, c2, c3) \
|
||||
(*((unsigned int *)(pc)) = \
|
||||
(((c1) == (c2)) == (c3)) \
|
||||
? c1 \
|
||||
: ((((((c1)&0x00FF00) * 5) + (((c2)&0x00FF00) * 2) + ((c3)&0x00FF00)) & \
|
||||
0x0007F800) + \
|
||||
(((((c1)&0xFF00FF) * 5) + (((c2)&0xFF00FF) * 2) + ((c3)&0xFF00FF)) & \
|
||||
0x07F807F8)) >> \
|
||||
3)
|
||||
|
||||
// ( c1*6 + c2 + c3 ) / 8
|
||||
// hq4x
|
||||
#define Interp7_32( pc, c1, c2, c3 ) \
|
||||
( \
|
||||
*( (unsigned int *)(pc) ) = \
|
||||
( ( (c1) == (c2) ) == (c3) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & 0x00FF00 ) * 6 ) + \
|
||||
( (c2) & 0x00FF00 ) + \
|
||||
( (c3) & 0x00FF00 ) \
|
||||
) & 0x0007F800 ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & 0xFF00FF ) * 6 ) + \
|
||||
( (c2) & 0xFF00FF ) + \
|
||||
( (c3) & 0xFF00FF ) \
|
||||
) & 0x07F807F8 ) \
|
||||
) >> 3 \
|
||||
)
|
||||
|
||||
#define Interp7_32(pc, c1, c2, c3) \
|
||||
(*((unsigned int *)(pc)) = \
|
||||
(((c1) == (c2)) == (c3)) \
|
||||
? c1 \
|
||||
: ((((((c1)&0x00FF00) * 6) + ((c2)&0x00FF00) + ((c3)&0x00FF00)) & 0x0007F800) + \
|
||||
(((((c1)&0xFF00FF) * 6) + ((c2)&0xFF00FF) + ((c3)&0xFF00FF)) & 0x07F807F8)) >> \
|
||||
3)
|
||||
|
||||
// ( c1*5 + c2*3 ) / 8
|
||||
// hq4x
|
||||
#define Interp8_32( pc, c1, c2 ) \
|
||||
( \
|
||||
*( (unsigned int *)(pc) ) = \
|
||||
( (c1) == (c2) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & 0x00FF00 ) * 5 ) + \
|
||||
( ( (c2) & 0x00FF00 ) * 3 ) \
|
||||
) & 0x0007F800 ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & 0xFF00FF ) * 5 ) + \
|
||||
( ( (c2) & 0xFF00FF ) * 3 ) \
|
||||
) & 0x07F807F8 ) \
|
||||
) >> 3 \
|
||||
)
|
||||
|
||||
#define Interp8_32(pc, c1, c2) \
|
||||
(*((unsigned int *)(pc)) = \
|
||||
((c1) == (c2)) ? c1 \
|
||||
: ((((((c1)&0x00FF00) * 5) + (((c2)&0x00FF00) * 3)) & 0x0007F800) + \
|
||||
(((((c1)&0xFF00FF) * 5) + (((c2)&0xFF00FF) * 3)) & 0x07F807F8)) >> \
|
||||
3)
|
||||
|
||||
// 32 bit input color
|
||||
// 0x00YYUUVV return value
|
||||
inline unsigned int RGBtoYUV_32( unsigned int c )
|
||||
inline unsigned int RGBtoYUV_32(unsigned int c)
|
||||
{
|
||||
// Division through 3 slows down the emulation about 10% !!!
|
||||
// Division through 3 slows down the emulation about 10% !!!
|
||||
|
||||
register unsigned char r, g, b;
|
||||
b = c & 0x0000FF;
|
||||
g = ( c & 0x00FF00 ) >> 8;
|
||||
r = c >> 16;
|
||||
return ( (r + g + b) << 14 ) +
|
||||
( ( r - b + 512 ) << 4 ) +
|
||||
( ( 2*g - r - b ) >> 3 ) + 128;
|
||||
register unsigned char r, g, b;
|
||||
b = c & 0x0000FF;
|
||||
g = (c & 0x00FF00) >> 8;
|
||||
r = c >> 16;
|
||||
return ((r + g + b) << 14) + ((r - b + 512) << 4) + ((2 * g - r - b) >> 3) + 128;
|
||||
|
||||
// unoptimized:
|
||||
//unsigned char r, g, b, Y, u, v;
|
||||
//b = (c & 0x000000FF);
|
||||
//g = (c & 0x0000FF00) >> 8;
|
||||
//r = (c & 0x00FF0000) >> 16;
|
||||
//Y = (r + g + b) >> 2;
|
||||
//u = 128 + ((r - b) >> 2);
|
||||
//v = 128 + ((-r + 2*g -b)>>3);
|
||||
//return (Y<<16) + (u<<8) + v;
|
||||
// unoptimized:
|
||||
// unsigned char r, g, b, Y, u, v;
|
||||
// b = (c & 0x000000FF);
|
||||
// g = (c & 0x0000FF00) >> 8;
|
||||
// r = (c & 0x00FF0000) >> 16;
|
||||
// Y = (r + g + b) >> 2;
|
||||
// u = 128 + ((r - b) >> 2);
|
||||
// v = 128 + ((-r + 2*g -b)>>3);
|
||||
// return (Y<<16) + (u<<8) + v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ===============
|
||||
// 16bit routines:
|
||||
// ===============
|
||||
|
||||
// ( c1*3 + c2 ) / 4
|
||||
// hq3x, hq4x
|
||||
#define Interp1_16( pc, c1, c2 ) \
|
||||
( \
|
||||
*( (unsigned short *)(pc) ) = \
|
||||
( (c1) == (c2) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & GMASK ) * 3 ) + \
|
||||
( (c2) & GMASK ) \
|
||||
) & GSHIFT2MASK ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & RBMASK ) * 3 ) + \
|
||||
( (c2) & RBMASK ) \
|
||||
) & RBSHIFT2MASK ) \
|
||||
) >> 2 \
|
||||
)
|
||||
|
||||
#define Interp1_16(pc, c1, c2) \
|
||||
(*((unsigned short *)(pc)) = \
|
||||
((c1) == (c2)) ? c1 : ((((((c1)&GMASK) * 3) + ((c2)&GMASK)) & GSHIFT2MASK) + \
|
||||
(((((c1)&RBMASK) * 3) + ((c2)&RBMASK)) & RBSHIFT2MASK)) >> \
|
||||
2)
|
||||
|
||||
// ( c1*2 + c2 + c3 ) / 4
|
||||
// hq3x, hq4x
|
||||
#define Interp2_16( pc, c1, c2, c3 ) \
|
||||
( \
|
||||
*( (unsigned short *)(pc) ) = \
|
||||
( ( (c1) == (c2) ) == (c3) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & GMASK ) * 2 ) + \
|
||||
( (c2) & GMASK ) + \
|
||||
( (c3) & GMASK ) \
|
||||
) & GSHIFT2MASK ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & RBMASK ) * 2 ) + \
|
||||
( (c2) & RBMASK ) + \
|
||||
( (c3) & RBMASK ) \
|
||||
) & RBSHIFT2MASK ) \
|
||||
) >> 2 \
|
||||
)
|
||||
|
||||
#define Interp2_16(pc, c1, c2, c3) \
|
||||
(*((unsigned short *)(pc)) = \
|
||||
(((c1) == (c2)) == (c3)) \
|
||||
? c1 \
|
||||
: ((((((c1)&GMASK) * 2) + ((c2)&GMASK) + ((c3)&GMASK)) & GSHIFT2MASK) + \
|
||||
(((((c1)&RBMASK) * 2) + ((c2)&RBMASK) + ((c3)&RBMASK)) & RBSHIFT2MASK)) >> \
|
||||
2)
|
||||
|
||||
// ( c1*7 + c2 ) / 8
|
||||
// hq3x, hq4x
|
||||
#define Interp3_16( pc, c1, c2 ) \
|
||||
( \
|
||||
*( (unsigned short *)(pc) ) = \
|
||||
( (c1) == (c2) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & GMASK ) * 7 ) + \
|
||||
( (c2) & GMASK ) \
|
||||
) & GSHIFT3MASK ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & RBMASK ) * 7 ) + \
|
||||
( (c2) & RBMASK ) \
|
||||
) & RBSHIFT3MASK ) \
|
||||
) >> 3 \
|
||||
)
|
||||
|
||||
#define Interp3_16(pc, c1, c2) \
|
||||
(*((unsigned short *)(pc)) = \
|
||||
((c1) == (c2)) ? c1 : ((((((c1)&GMASK) * 7) + ((c2)&GMASK)) & GSHIFT3MASK) + \
|
||||
(((((c1)&RBMASK) * 7) + ((c2)&RBMASK)) & RBSHIFT3MASK)) >> \
|
||||
3)
|
||||
|
||||
// ( c1*2 + (c2+c3)*7 ) / 16
|
||||
// hq3x, not used by hq4x
|
||||
#define Interp4_16( pc, c1, c2, c3 ) \
|
||||
( \
|
||||
*( (unsigned short *)(pc) ) = \
|
||||
( ( (c1) == (c2) ) == (c3) ) ? c1 : \
|
||||
( \
|
||||
( ( ( ( (c1) & GMASK ) * 2 ) + ( ( ( (c2) & GMASK ) + ( (c3) & GMASK ) ) * 7 ) ) & GSHIFT4MASK ) + \
|
||||
( ( ( ( (c1) & RBMASK ) * 2 ) + ( ( ( (c2) & RBMASK ) + ( (c3) & RBMASK ) ) * 7 ) ) & RBSHIFT4MASK ) \
|
||||
) >> 4 \
|
||||
)
|
||||
|
||||
#define Interp4_16(pc, c1, c2, c3) \
|
||||
(*((unsigned short *)(pc)) = \
|
||||
(((c1) == (c2)) == (c3)) \
|
||||
? c1 \
|
||||
: ((((((c1)&GMASK) * 2) + ((((c2)&GMASK) + ((c3)&GMASK)) * 7)) & GSHIFT4MASK) + \
|
||||
(((((c1)&RBMASK) * 2) + ((((c2)&RBMASK) + ((c3)&RBMASK)) * 7)) & \
|
||||
RBSHIFT4MASK)) >> \
|
||||
4)
|
||||
|
||||
// ( c1 + c2 ) / 2
|
||||
// hq3x, hq4x
|
||||
#define Interp5_16( pc, c1, c2 ) \
|
||||
( \
|
||||
*( (unsigned short *)(pc) ) = \
|
||||
( (c1) == (c2) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( (c1) & GMASK ) + \
|
||||
( (c2) & GMASK ) \
|
||||
) & GSHIFT1MASK ) \
|
||||
+ \
|
||||
( ( \
|
||||
( (c1) & RBMASK ) + \
|
||||
( (c2) & RBMASK ) \
|
||||
) & RBSHIFT1MASK ) \
|
||||
) >> 1 \
|
||||
)
|
||||
|
||||
#define Interp5_16(pc, c1, c2) \
|
||||
(*((unsigned short *)(pc)) = \
|
||||
((c1) == (c2)) ? c1 : (((((c1)&GMASK) + ((c2)&GMASK)) & GSHIFT1MASK) + \
|
||||
((((c1)&RBMASK) + ((c2)&RBMASK)) & RBSHIFT1MASK)) >> \
|
||||
1)
|
||||
|
||||
// ( c1*5 + c2*2 + c3 ) / 8
|
||||
// hq4x
|
||||
#define Interp6_16( pc, c1, c2, c3 ) \
|
||||
( \
|
||||
*( (unsigned short *)(pc) ) = \
|
||||
( ( (c1) == (c2) ) == (c3) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & GMASK ) * 5 ) + \
|
||||
( ( (c2) & GMASK ) * 2 ) + \
|
||||
( (c3) & GMASK ) \
|
||||
) & GSHIFT3MASK ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & RBMASK ) * 5 ) + \
|
||||
( ( (c2) & RBMASK ) * 2 ) + \
|
||||
( (c3) & RBMASK ) \
|
||||
) & RBSHIFT3MASK ) \
|
||||
) >> 3 \
|
||||
)
|
||||
|
||||
#define Interp6_16(pc, c1, c2, c3) \
|
||||
(*((unsigned short *)(pc)) = \
|
||||
(((c1) == (c2)) == (c3)) \
|
||||
? c1 \
|
||||
: ((((((c1)&GMASK) * 5) + (((c2)&GMASK) * 2) + ((c3)&GMASK)) & GSHIFT3MASK) + \
|
||||
(((((c1)&RBMASK) * 5) + (((c2)&RBMASK) * 2) + ((c3)&RBMASK)) & \
|
||||
RBSHIFT3MASK)) >> \
|
||||
3)
|
||||
|
||||
// ( c1*6 + c2 + c3 ) / 8
|
||||
// hq4x
|
||||
#define Interp7_16( pc, c1, c2, c3 ) \
|
||||
( \
|
||||
*( (unsigned short *)(pc) ) = \
|
||||
( ( (c1) == (c2) ) == (c3) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & GMASK ) * 6 ) + \
|
||||
( (c2) & GMASK ) + \
|
||||
( (c3) & GMASK ) \
|
||||
) & GSHIFT3MASK ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & RBMASK ) * 6 ) + \
|
||||
( (c2) & RBMASK ) + \
|
||||
( (c3) & RBMASK ) \
|
||||
) & RBSHIFT3MASK ) \
|
||||
) >> 3 \
|
||||
)
|
||||
|
||||
#define Interp7_16(pc, c1, c2, c3) \
|
||||
(*((unsigned short *)(pc)) = \
|
||||
(((c1) == (c2)) == (c3)) \
|
||||
? c1 \
|
||||
: ((((((c1)&GMASK) * 6) + ((c2)&GMASK) + ((c3)&GMASK)) & GSHIFT3MASK) + \
|
||||
(((((c1)&RBMASK) * 6) + ((c2)&RBMASK) + ((c3)&RBMASK)) & RBSHIFT3MASK)) >> \
|
||||
3)
|
||||
|
||||
// ( c1*5 + c2*3 ) / 8
|
||||
// hq4x
|
||||
#define Interp8_16( pc, c1, c2 ) \
|
||||
( \
|
||||
*( (unsigned short *)(pc) ) = \
|
||||
( (c1) == (c2) ) ? c1 : \
|
||||
( \
|
||||
( ( \
|
||||
( ( (c1) & GMASK ) * 5 ) + \
|
||||
( ( (c2) & GMASK ) * 3 ) \
|
||||
) & GSHIFT3MASK ) \
|
||||
+ \
|
||||
( ( \
|
||||
( ( (c1) & RBMASK ) * 5 ) + \
|
||||
( ( (c2) & RBMASK ) * 3 ) \
|
||||
) & RBSHIFT3MASK ) \
|
||||
) >> 3 \
|
||||
)
|
||||
|
||||
#define Interp8_16(pc, c1, c2) \
|
||||
(*((unsigned short *)(pc)) = \
|
||||
((c1) == (c2)) ? c1 \
|
||||
: ((((((c1)&GMASK) * 5) + (((c2)&GMASK) * 3)) & GSHIFT3MASK) + \
|
||||
(((((c1)&RBMASK) * 5) + (((c2)&RBMASK) * 3)) & RBSHIFT3MASK)) >> \
|
||||
3)
|
||||
|
||||
// 16 bit input color
|
||||
// 0x00YYUUVV return value
|
||||
inline unsigned int RGBtoYUV_16( unsigned short c )
|
||||
inline unsigned int RGBtoYUV_16(unsigned short c)
|
||||
{
|
||||
// Division through 3 slows down the emulation about 10% !!!
|
||||
// Division through 3 slows down the emulation about 10% !!!
|
||||
|
||||
register unsigned char r, g, b;
|
||||
register unsigned char r, g, b;
|
||||
#ifdef RGB555
|
||||
r = ( c & 0x7C00 ) >> 7;
|
||||
g = ( c & 0x03E0 ) >> 2;
|
||||
b = ( c & 0x001F ) << 3;
|
||||
r = (c & 0x7C00) >> 7;
|
||||
g = (c & 0x03E0) >> 2;
|
||||
b = (c & 0x001F) << 3;
|
||||
#else
|
||||
r = ( c & 0xF800 ) >> 8;
|
||||
g = ( c & 0x07E0 ) >> 3;
|
||||
b = ( c & 0x001F ) << 3;
|
||||
r = (c & 0xF800) >> 8;
|
||||
g = (c & 0x07E0) >> 3;
|
||||
b = (c & 0x001F) << 3;
|
||||
#endif
|
||||
|
||||
return ( (r + g + b) << 14 ) +
|
||||
( ( r - b + 512 ) << 4 ) +
|
||||
( ( 2*g - r - b ) >> 3 ) + 128;
|
||||
return ((r + g + b) << 14) + ((r - b + 512) << 4) + ((2 * g - r - b) >> 3) + 128;
|
||||
}
|
||||
|
|
3498
src/filters/hq2x.h
3498
src/filters/hq2x.h
File diff suppressed because it is too large
Load Diff
|
@ -35,7 +35,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef uint16_t interp_uint16;
|
||||
typedef uint32_t interp_uint32;
|
||||
|
||||
|
@ -53,80 +52,102 @@ static unsigned interp_bits_per_pixel;
|
|||
|
||||
static inline u16 interp_16_521(u16 p1, u16 p2, u16 p3)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*2 + INTERP_16_MASK_1(p3)*1) / 8)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*2 + INTERP_16_MASK_2(p3)*1) / 8);
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) * 5 + INTERP_16_MASK_1(p2) * 2 +
|
||||
INTERP_16_MASK_1(p3) * 1) /
|
||||
8) |
|
||||
INTERP_16_MASK_2((INTERP_16_MASK_2(p1) * 5 + INTERP_16_MASK_2(p2) * 2 +
|
||||
INTERP_16_MASK_2(p3) * 1) /
|
||||
8);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_332(u16 p1, u16 p2, u16 p3)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)*2) / 8)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)*2) / 8);
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) * 3 + INTERP_16_MASK_1(p2) * 3 +
|
||||
INTERP_16_MASK_1(p3) * 2) /
|
||||
8) |
|
||||
INTERP_16_MASK_2((INTERP_16_MASK_2(p1) * 3 + INTERP_16_MASK_2(p2) * 3 +
|
||||
INTERP_16_MASK_2(p3) * 2) /
|
||||
8);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_611(u16 p1, u16 p2, u16 p3)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*6 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 8)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*6 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 8);
|
||||
return INTERP_16_MASK_1(
|
||||
(INTERP_16_MASK_1(p1) * 6 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 8) |
|
||||
INTERP_16_MASK_2(
|
||||
(INTERP_16_MASK_2(p1) * 6 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 8);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_71(u16 p1, u16 p2)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*7 + INTERP_16_MASK_1(p2)) / 8)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*7 + INTERP_16_MASK_2(p2)) / 8);
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) * 7 + INTERP_16_MASK_1(p2)) / 8) |
|
||||
INTERP_16_MASK_2((INTERP_16_MASK_2(p1) * 7 + INTERP_16_MASK_2(p2)) / 8);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_211(u16 p1, u16 p2, u16 p3)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*2 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 4)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*2 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 4);
|
||||
return INTERP_16_MASK_1(
|
||||
(INTERP_16_MASK_1(p1) * 2 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 4) |
|
||||
INTERP_16_MASK_2(
|
||||
(INTERP_16_MASK_2(p1) * 2 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 4);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_772(u16 p1, u16 p2, u16 p3)
|
||||
{
|
||||
return INTERP_16_MASK_1(((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2))*7 + INTERP_16_MASK_1(p3)*2) / 16)
|
||||
| INTERP_16_MASK_2(((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2))*7 + INTERP_16_MASK_2(p3)*2) / 16);
|
||||
return INTERP_16_MASK_1(
|
||||
((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2)) * 7 + INTERP_16_MASK_1(p3) * 2) /
|
||||
16) |
|
||||
INTERP_16_MASK_2(
|
||||
((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2)) * 7 + INTERP_16_MASK_2(p3) * 2) /
|
||||
16);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_11(u16 p1, u16 p2)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2)) / 2)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2)) / 2);
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2)) / 2) |
|
||||
INTERP_16_MASK_2((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2)) / 2);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_31(u16 p1, u16 p2)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)) / 4)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)) / 4);
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) * 3 + INTERP_16_MASK_1(p2)) / 4) |
|
||||
INTERP_16_MASK_2((INTERP_16_MASK_2(p1) * 3 + INTERP_16_MASK_2(p2)) / 4);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_1411(u16 p1, u16 p2, u16 p3)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*14 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 16)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*14 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 16);
|
||||
return INTERP_16_MASK_1(
|
||||
(INTERP_16_MASK_1(p1) * 14 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 16) |
|
||||
INTERP_16_MASK_2(
|
||||
(INTERP_16_MASK_2(p1) * 14 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 16);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_431(u16 p1, u16 p2, u16 p3)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*4 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)) / 8)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*4 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)) / 8);
|
||||
return INTERP_16_MASK_1(
|
||||
(INTERP_16_MASK_1(p1) * 4 + INTERP_16_MASK_1(p2) * 3 + INTERP_16_MASK_1(p3)) /
|
||||
8) |
|
||||
INTERP_16_MASK_2(
|
||||
(INTERP_16_MASK_2(p1) * 4 + INTERP_16_MASK_2(p2) * 3 + INTERP_16_MASK_2(p3)) /
|
||||
8);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_53(u16 p1, u16 p2)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*3) / 8)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*3) / 8);
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) * 5 + INTERP_16_MASK_1(p2) * 3) / 8) |
|
||||
INTERP_16_MASK_2((INTERP_16_MASK_2(p1) * 5 + INTERP_16_MASK_2(p2) * 3) / 8);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_151(u16 p1, u16 p2)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*15 + INTERP_16_MASK_1(p2)) / 16)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*15 + INTERP_16_MASK_2(p2)) / 16);
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) * 15 + INTERP_16_MASK_1(p2)) / 16) |
|
||||
INTERP_16_MASK_2((INTERP_16_MASK_2(p1) * 15 + INTERP_16_MASK_2(p2)) / 16);
|
||||
}
|
||||
|
||||
static inline u16 interp_16_97(u16 p1, u16 p2)
|
||||
{
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*9 + INTERP_16_MASK_1(p2)*7) / 16)
|
||||
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*9 + INTERP_16_MASK_2(p2)*7) / 16);
|
||||
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) * 9 + INTERP_16_MASK_1(p2) * 7) / 16) |
|
||||
INTERP_16_MASK_2((INTERP_16_MASK_2(p1) * 9 + INTERP_16_MASK_2(p2) * 7) / 16);
|
||||
}
|
||||
|
||||
#define INTERP_32_MASK_1(v) (v & 0xFF00FF)
|
||||
|
@ -134,169 +155,191 @@ static inline u16 interp_16_97(u16 p1, u16 p2)
|
|||
|
||||
static inline u32 interp_32_521(u32 p1, u32 p2, u32 p3)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*2 + INTERP_32_MASK_1(p3)*1) / 8)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*2 + INTERP_32_MASK_2(p3)*1) / 8);
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) * 5 + INTERP_32_MASK_1(p2) * 2 +
|
||||
INTERP_32_MASK_1(p3) * 1) /
|
||||
8) |
|
||||
INTERP_32_MASK_2((INTERP_32_MASK_2(p1) * 5 + INTERP_32_MASK_2(p2) * 2 +
|
||||
INTERP_32_MASK_2(p3) * 1) /
|
||||
8);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_332(u32 p1, u32 p2, u32 p3)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)*2) / 8)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)*2) / 8);
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) * 3 + INTERP_32_MASK_1(p2) * 3 +
|
||||
INTERP_32_MASK_1(p3) * 2) /
|
||||
8) |
|
||||
INTERP_32_MASK_2((INTERP_32_MASK_2(p1) * 3 + INTERP_32_MASK_2(p2) * 3 +
|
||||
INTERP_32_MASK_2(p3) * 2) /
|
||||
8);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_211(u32 p1, u32 p2, u32 p3)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*2 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 4)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*2 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 4);
|
||||
return INTERP_32_MASK_1(
|
||||
(INTERP_32_MASK_1(p1) * 2 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 4) |
|
||||
INTERP_32_MASK_2(
|
||||
(INTERP_32_MASK_2(p1) * 2 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 4);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_611(u32 p1, u32 p2, u32 p3)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*6 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 8)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*6 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 8);
|
||||
return INTERP_32_MASK_1(
|
||||
(INTERP_32_MASK_1(p1) * 6 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 8) |
|
||||
INTERP_32_MASK_2(
|
||||
(INTERP_32_MASK_2(p1) * 6 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 8);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_71(u32 p1, u32 p2)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*7 + INTERP_32_MASK_1(p2)) / 8)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*7 + INTERP_32_MASK_2(p2)) / 8);
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) * 7 + INTERP_32_MASK_1(p2)) / 8) |
|
||||
INTERP_32_MASK_2((INTERP_32_MASK_2(p1) * 7 + INTERP_32_MASK_2(p2)) / 8);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_772(u32 p1, u32 p2, u32 p3)
|
||||
{
|
||||
return INTERP_32_MASK_1(((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2))*7 + INTERP_32_MASK_1(p3)*2) / 16)
|
||||
| INTERP_32_MASK_2(((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2))*7 + INTERP_32_MASK_2(p3)*2) / 16);
|
||||
return INTERP_32_MASK_1(
|
||||
((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2)) * 7 + INTERP_32_MASK_1(p3) * 2) /
|
||||
16) |
|
||||
INTERP_32_MASK_2(
|
||||
((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2)) * 7 + INTERP_32_MASK_2(p3) * 2) /
|
||||
16);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_11(u32 p1, u32 p2)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2)) / 2)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2)) / 2);
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2)) / 2) |
|
||||
INTERP_32_MASK_2((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2)) / 2);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_31(u32 p1, u32 p2)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)) / 4)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)) / 4);
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) * 3 + INTERP_32_MASK_1(p2)) / 4) |
|
||||
INTERP_32_MASK_2((INTERP_32_MASK_2(p1) * 3 + INTERP_32_MASK_2(p2)) / 4);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_1411(u32 p1, u32 p2, u32 p3)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*14 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 16)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*14 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 16);
|
||||
return INTERP_32_MASK_1(
|
||||
(INTERP_32_MASK_1(p1) * 14 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 16) |
|
||||
INTERP_32_MASK_2(
|
||||
(INTERP_32_MASK_2(p1) * 14 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 16);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_431(u32 p1, u32 p2, u32 p3)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*4 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)) / 8)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*4 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)) / 8);
|
||||
return INTERP_32_MASK_1(
|
||||
(INTERP_32_MASK_1(p1) * 4 + INTERP_32_MASK_1(p2) * 3 + INTERP_32_MASK_1(p3)) /
|
||||
8) |
|
||||
INTERP_32_MASK_2(
|
||||
(INTERP_32_MASK_2(p1) * 4 + INTERP_32_MASK_2(p2) * 3 + INTERP_32_MASK_2(p3)) /
|
||||
8);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_53(u32 p1, u32 p2)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*3) / 8)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*3) / 8);
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) * 5 + INTERP_32_MASK_1(p2) * 3) / 8) |
|
||||
INTERP_32_MASK_2((INTERP_32_MASK_2(p1) * 5 + INTERP_32_MASK_2(p2) * 3) / 8);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_151(u32 p1, u32 p2)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*15 + INTERP_32_MASK_1(p2)) / 16)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*15 + INTERP_32_MASK_2(p2)) / 16);
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) * 15 + INTERP_32_MASK_1(p2)) / 16) |
|
||||
INTERP_32_MASK_2((INTERP_32_MASK_2(p1) * 15 + INTERP_32_MASK_2(p2)) / 16);
|
||||
}
|
||||
|
||||
static inline u32 interp_32_97(u32 p1, u32 p2)
|
||||
{
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*9 + INTERP_32_MASK_1(p2)*7) / 16)
|
||||
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*9 + INTERP_32_MASK_2(p2)*7) / 16);
|
||||
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) * 9 + INTERP_32_MASK_1(p2) * 7) / 16) |
|
||||
INTERP_32_MASK_2((INTERP_32_MASK_2(p1) * 9 + INTERP_32_MASK_2(p2) * 7) / 16);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* diff */
|
||||
|
||||
#define INTERP_Y_LIMIT (0x30*4)
|
||||
#define INTERP_U_LIMIT (0x07*4)
|
||||
#define INTERP_V_LIMIT (0x06*8)
|
||||
#define INTERP_Y_LIMIT (0x30 * 4)
|
||||
#define INTERP_U_LIMIT (0x07 * 4)
|
||||
#define INTERP_V_LIMIT (0x06 * 8)
|
||||
|
||||
static int interp_16_diff(u16 p1, u16 p2)
|
||||
{
|
||||
int r, g, b;
|
||||
int y, u, v;
|
||||
int r, g, b;
|
||||
int y, u, v;
|
||||
|
||||
if (p1 == p2)
|
||||
return 0;
|
||||
if (p1 == p2)
|
||||
return 0;
|
||||
|
||||
if (interp_bits_per_pixel == 16) {
|
||||
b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
|
||||
g = (int)((p1 & 0x7E0) - (p2 & 0x7E0)) >> 3;
|
||||
r = (int)((p1 & 0xF800) - (p2 & 0xF800)) >> 8;
|
||||
} else {
|
||||
b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
|
||||
g = (int)((p1 & 0x3E0) - (p2 & 0x3E0)) >> 2;
|
||||
r = (int)((p1 & 0x7C00) - (p2 & 0x7C00)) >> 7;
|
||||
}
|
||||
if (interp_bits_per_pixel == 16) {
|
||||
b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
|
||||
g = (int)((p1 & 0x7E0) - (p2 & 0x7E0)) >> 3;
|
||||
r = (int)((p1 & 0xF800) - (p2 & 0xF800)) >> 8;
|
||||
} else {
|
||||
b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
|
||||
g = (int)((p1 & 0x3E0) - (p2 & 0x3E0)) >> 2;
|
||||
r = (int)((p1 & 0x7C00) - (p2 & 0x7C00)) >> 7;
|
||||
}
|
||||
|
||||
y = r + g + b;
|
||||
u = r - b;
|
||||
v = -r + 2*g - b;
|
||||
y = r + g + b;
|
||||
u = r - b;
|
||||
v = -r + 2 * g - b;
|
||||
|
||||
if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
|
||||
return 1;
|
||||
if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
|
||||
return 1;
|
||||
|
||||
if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
|
||||
return 1;
|
||||
if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
|
||||
return 1;
|
||||
|
||||
if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
|
||||
return 1;
|
||||
if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int interp_32_diff(u32 p1, u32 p2)
|
||||
{
|
||||
int r, g, b;
|
||||
int y, u, v;
|
||||
int r, g, b;
|
||||
int y, u, v;
|
||||
|
||||
if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8))
|
||||
return 0;
|
||||
if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8))
|
||||
return 0;
|
||||
|
||||
b = (int)((p1 & 0xFF) - (p2 & 0xFF));
|
||||
g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8;
|
||||
r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16;
|
||||
b = (int)((p1 & 0xFF) - (p2 & 0xFF));
|
||||
g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8;
|
||||
r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16;
|
||||
|
||||
y = r + g + b;
|
||||
u = r - b;
|
||||
v = -r + 2*g - b;
|
||||
y = r + g + b;
|
||||
u = r - b;
|
||||
v = -r + 2 * g - b;
|
||||
|
||||
if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
|
||||
return 1;
|
||||
if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
|
||||
return 1;
|
||||
|
||||
if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
|
||||
return 1;
|
||||
if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
|
||||
return 1;
|
||||
|
||||
if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
|
||||
return 1;
|
||||
if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void interp_set(unsigned bits_per_pixel)
|
||||
{
|
||||
interp_bits_per_pixel = bits_per_pixel;
|
||||
interp_bits_per_pixel = bits_per_pixel;
|
||||
|
||||
switch (bits_per_pixel) {
|
||||
case 15 :
|
||||
interp_mask[0] = 0x7C1F;
|
||||
interp_mask[1] = 0x03E0;
|
||||
break;
|
||||
case 16 :
|
||||
interp_mask[0] = 0xF81F;
|
||||
interp_mask[1] = 0x07E0;
|
||||
break;
|
||||
case 32 :
|
||||
interp_mask[0] = 0xFF00FF;
|
||||
interp_mask[1] = 0x00FF00;
|
||||
break;
|
||||
}
|
||||
switch (bits_per_pixel) {
|
||||
case 15:
|
||||
interp_mask[0] = 0x7C1F;
|
||||
interp_mask[1] = 0x03E0;
|
||||
break;
|
||||
case 16:
|
||||
interp_mask[0] = 0xF81F;
|
||||
interp_mask[1] = 0x07E0;
|
||||
break;
|
||||
case 32:
|
||||
interp_mask[0] = 0xFF00FF;
|
||||
interp_mask[1] = 0x00FF00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
2487
src/filters/lq2x.h
2487
src/filters/lq2x.h
File diff suppressed because it is too large
Load Diff
|
@ -16,25 +16,23 @@
|
|||
#ifndef XBRZ_CONFIG_HEADER_284578425345
|
||||
#define XBRZ_CONFIG_HEADER_284578425345
|
||||
|
||||
//do NOT include any headers here! used by xBRZ_dll!!!
|
||||
// do NOT include any headers here! used by xBRZ_dll!!!
|
||||
|
||||
namespace xbrz
|
||||
{
|
||||
struct ScalerCfg
|
||||
{
|
||||
ScalerCfg() :
|
||||
luminanceWeight(1),
|
||||
equalColorTolerance(30),
|
||||
dominantDirectionThreshold(3.6),
|
||||
steepDirectionThreshold(2.2),
|
||||
newTestAttribute(0) {}
|
||||
struct ScalerCfg {
|
||||
ScalerCfg()
|
||||
: luminanceWeight(1), equalColorTolerance(30), dominantDirectionThreshold(3.6),
|
||||
steepDirectionThreshold(2.2), newTestAttribute(0)
|
||||
{
|
||||
}
|
||||
|
||||
double luminanceWeight;
|
||||
double equalColorTolerance;
|
||||
double dominantDirectionThreshold;
|
||||
double steepDirectionThreshold;
|
||||
double newTestAttribute; //unused; test new parameters
|
||||
double luminanceWeight;
|
||||
double equalColorTolerance;
|
||||
double dominantDirectionThreshold;
|
||||
double steepDirectionThreshold;
|
||||
double newTestAttribute; // unused; test new parameters
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -16,10 +16,10 @@
|
|||
#ifndef XBRZ_HEADER_3847894708239054
|
||||
#define XBRZ_HEADER_3847894708239054
|
||||
|
||||
#include <cstddef> //size_t
|
||||
#include <stdint.h> //uint32_t
|
||||
#include <limits>
|
||||
#include "config.h"
|
||||
#include <cstddef> //size_t
|
||||
#include <limits>
|
||||
#include <stdint.h> //uint32_t
|
||||
|
||||
namespace xbrz
|
||||
{
|
||||
|
@ -38,57 +38,64 @@ http://board.byuu.org/viewtopic.php?f=10&t=2248
|
|||
- support scaling up to 6xBRZ
|
||||
*/
|
||||
|
||||
enum ColorFormat //from high bits -> low bits, 8 bit per channel
|
||||
{
|
||||
RGB, //8 bit for each red, green, blue, upper 8 bits unused
|
||||
ARGB, //including alpha channel, BGRA byte order on little-endian machines
|
||||
enum ColorFormat // from high bits -> low bits, 8 bit per channel
|
||||
{ RGB, // 8 bit for each red, green, blue, upper 8 bits unused
|
||||
ARGB, // including alpha channel, BGRA byte order on little-endian machines
|
||||
};
|
||||
|
||||
/*
|
||||
-> map source (srcWidth * srcHeight) to target (scale * width x scale * height) image, optionally processing a half-open slice of rows [yFirst, yLast) only
|
||||
-> map source (srcWidth * srcHeight) to target (scale * width x scale * height) image, optionally
|
||||
processing a half-open slice of rows [yFirst, yLast) only
|
||||
-> support for source/target pitch in bytes!
|
||||
-> if your emulator changes only a few image slices during each cycle (e.g. DOSBox) then there's no need to run xBRZ on the complete image:
|
||||
Just make sure you enlarge the source image slice by 2 rows on top and 2 on bottom (this is the additional range the xBRZ algorithm is using during analysis)
|
||||
Caveat: If there are multiple changed slices, make sure they do not overlap after adding these additional rows in order to avoid a memory race condition
|
||||
-> if your emulator changes only a few image slices during each cycle (e.g. DOSBox) then there's no
|
||||
need to run xBRZ on the complete image:
|
||||
Just make sure you enlarge the source image slice by 2 rows on top and 2 on bottom (this is the
|
||||
additional range the xBRZ algorithm is using during analysis)
|
||||
Caveat: If there are multiple changed slices, make sure they do not overlap after adding these
|
||||
additional rows in order to avoid a memory race condition
|
||||
in the target image data if you are using multiple threads for processing each enlarged slice!
|
||||
|
||||
THREAD-SAFETY: - parts of the same image may be scaled by multiple threads as long as the [yFirst, yLast) ranges do not overlap!
|
||||
- there is a minor inefficiency for the first row of a slice, so avoid processing single rows only; suggestion: process 8-16 rows at least
|
||||
THREAD-SAFETY: - parts of the same image may be scaled by multiple threads as long as the [yFirst,
|
||||
yLast) ranges do not overlap!
|
||||
- there is a minor inefficiency for the first row of a slice, so avoid processing
|
||||
single rows only; suggestion: process 8-16 rows at least
|
||||
*/
|
||||
void scale(size_t factor, //valid range: 2 - 6
|
||||
const uint32_t* src, int srcWidth, int srcHeight, int srcPitch,
|
||||
uint32_t* trg, int trgPitch,
|
||||
ColorFormat colFmt,
|
||||
const ScalerCfg& cfg = ScalerCfg(),
|
||||
int yFirst = 0, int yLast = std::numeric_limits<int>::max()); //slice of source image
|
||||
void scale(size_t factor, // valid range: 2 - 6
|
||||
const uint32_t *src, int srcWidth, int srcHeight, int srcPitch, uint32_t *trg,
|
||||
int trgPitch, ColorFormat colFmt, const ScalerCfg &cfg = ScalerCfg(), int yFirst = 0,
|
||||
int yLast = std::numeric_limits<int>::max()); // slice of source image
|
||||
|
||||
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight,
|
||||
uint32_t* trg, int trgWidth, int trgHeight);
|
||||
void nearestNeighborScale(const uint32_t *src, int srcWidth, int srcHeight, uint32_t *trg,
|
||||
int trgWidth, int trgHeight);
|
||||
|
||||
enum SliceType
|
||||
{
|
||||
NN_SCALE_SLICE_SOURCE,
|
||||
NN_SCALE_SLICE_TARGET,
|
||||
enum SliceType {
|
||||
NN_SCALE_SLICE_SOURCE,
|
||||
NN_SCALE_SLICE_TARGET,
|
||||
};
|
||||
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight, int srcPitch, //pitch in bytes!
|
||||
uint32_t* trg, int trgWidth, int trgHeight, int trgPitch,
|
||||
SliceType st, int yFirst, int yLast);
|
||||
|
||||
//parameter tuning
|
||||
bool equalColorTest(uint32_t col1, uint32_t col2, ColorFormat colFmt, double luminanceWeight, double equalColorTolerance);
|
||||
|
||||
|
||||
|
||||
void nearestNeighborScale(const uint32_t *src, int srcWidth, int srcHeight,
|
||||
int srcPitch, // pitch in bytes!
|
||||
uint32_t *trg, int trgWidth, int trgHeight, int trgPitch, SliceType st,
|
||||
int yFirst, int yLast);
|
||||
|
||||
// parameter tuning
|
||||
bool equalColorTest(uint32_t col1, uint32_t col2, ColorFormat colFmt, double luminanceWeight,
|
||||
double equalColorTolerance);
|
||||
|
||||
//########################### implementation ###########################
|
||||
inline
|
||||
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight,
|
||||
uint32_t* trg, int trgWidth, int trgHeight)
|
||||
inline void nearestNeighborScale(const uint32_t *src, int srcWidth, int srcHeight, uint32_t *trg,
|
||||
int trgWidth, int trgHeight)
|
||||
{
|
||||
nearestNeighborScale(src, srcWidth, srcHeight, srcWidth * sizeof(uint32_t),
|
||||
trg, trgWidth, trgHeight, trgWidth * sizeof(uint32_t),
|
||||
NN_SCALE_SLICE_TARGET, 0, trgHeight);
|
||||
nearestNeighborScale(src,
|
||||
srcWidth,
|
||||
srcHeight,
|
||||
srcWidth * sizeof(uint32_t),
|
||||
trg,
|
||||
trgWidth,
|
||||
trgHeight,
|
||||
trgWidth * sizeof(uint32_t),
|
||||
NN_SCALE_SLICE_TARGET,
|
||||
0,
|
||||
trgHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
14
src/gb/gb.h
14
src/gb/gb.h
|
@ -7,14 +7,14 @@
|
|||
#define Z_FLAG 0x80
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u8 B1, B0;
|
||||
u8 B1, B0;
|
||||
#else
|
||||
u8 B0,B1;
|
||||
u8 B0, B1;
|
||||
#endif
|
||||
} B;
|
||||
u16 W;
|
||||
} B;
|
||||
u16 W;
|
||||
} gbRegister;
|
||||
|
||||
extern gbRegister AF, BC, DE, HL, SP, PC;
|
||||
|
@ -30,12 +30,12 @@ bool gbIsGameboyRom(const char *);
|
|||
void gbGetHardwareType();
|
||||
void gbReset();
|
||||
void gbCleanUp();
|
||||
void gbCPUInit(const char *,bool);
|
||||
void gbCPUInit(const char *, bool);
|
||||
bool gbWriteBatteryFile(const char *);
|
||||
bool gbWriteBatteryFile(const char *, bool);
|
||||
bool gbReadBatteryFile(const char *);
|
||||
bool gbWriteSaveState(const char *);
|
||||
bool gbWriteMemSaveState(char *, int, long&);
|
||||
bool gbWriteMemSaveState(char *, int, long &);
|
||||
bool gbReadSaveState(const char *);
|
||||
bool gbReadMemSaveState(char *, int);
|
||||
void gbSgbRenderBorder();
|
||||
|
|
|
@ -5,18 +5,18 @@
|
|||
#include "../common/ConfigManager.h"
|
||||
|
||||
struct gbXxCheat {
|
||||
char cheatDesc[100];
|
||||
char cheatCode[20];
|
||||
char cheatDesc[100];
|
||||
char cheatCode[20];
|
||||
};
|
||||
|
||||
struct gbCheat {
|
||||
char cheatCode[20];
|
||||
char cheatDesc[32];
|
||||
u16 address;
|
||||
int code;
|
||||
u8 compare;
|
||||
u8 value;
|
||||
bool enabled;
|
||||
char cheatCode[20];
|
||||
char cheatDesc[32];
|
||||
u16 address;
|
||||
int code;
|
||||
u8 compare;
|
||||
u8 value;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
void gbCheatsSaveGame(gzFile);
|
||||
|
@ -26,8 +26,8 @@ void gbCheatsSaveCheatList(const char *);
|
|||
bool gbCheatsLoadCheatList(const char *);
|
||||
bool gbCheatReadGSCodeFile(const char *);
|
||||
|
||||
bool gbAddGsCheat(const char *, const char*);
|
||||
bool gbAddGgCheat(const char *, const char*);
|
||||
bool gbAddGsCheat(const char *, const char *);
|
||||
bool gbAddGgCheat(const char *, const char *);
|
||||
void gbCheatRemove(int);
|
||||
void gbCheatRemoveAll();
|
||||
void gbCheatEnable(int);
|
||||
|
@ -37,7 +37,6 @@ void gbCheatWrite(bool);
|
|||
bool gbVerifyGsCode(const char *code);
|
||||
bool gbVerifyGgCode(const char *code);
|
||||
|
||||
|
||||
extern int gbCheatNumber;
|
||||
extern gbCheat gbCheatList[MAX_CHEATS];
|
||||
extern bool gbCheatMap[0x10000];
|
||||
|
|
2839
src/gb/gbCodes.h
2839
src/gb/gbCodes.h
File diff suppressed because it is too large
Load Diff
2542
src/gb/gbCodesCB.h
2542
src/gb/gbCodesCB.h
File diff suppressed because it is too large
Load Diff
|
@ -43,8 +43,8 @@ extern u8 gbSCXLine[300];
|
|||
// gbBgpLine is used for the emulation of the
|
||||
// Prehistorik Man's title screen scroller.
|
||||
extern u8 gbBgpLine[300];
|
||||
extern u8 gbObp0Line [300];
|
||||
extern u8 gbObp1Line [300];
|
||||
extern u8 gbObp0Line[300];
|
||||
extern u8 gbObp1Line[300];
|
||||
// gbSpritesTicks is used for the emulation of Parodius' Laser Beam.
|
||||
extern u8 gbSpritesTicks[300];
|
||||
|
||||
|
|
|
@ -4,134 +4,134 @@
|
|||
#include <time.h>
|
||||
|
||||
struct mapperMBC1 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int mapperRomBank0Remapping;
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int mapperRomBank0Remapping;
|
||||
};
|
||||
|
||||
struct mapperMBC2 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
};
|
||||
|
||||
struct mapperMBC3 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperClockLatch;
|
||||
int mapperClockRegister;
|
||||
int mapperSeconds;
|
||||
int mapperMinutes;
|
||||
int mapperHours;
|
||||
int mapperDays;
|
||||
int mapperControl;
|
||||
int mapperLSeconds;
|
||||
int mapperLMinutes;
|
||||
int mapperLHours;
|
||||
int mapperLDays;
|
||||
int mapperLControl;
|
||||
time_t mapperLastTime;
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperClockLatch;
|
||||
int mapperClockRegister;
|
||||
int mapperSeconds;
|
||||
int mapperMinutes;
|
||||
int mapperHours;
|
||||
int mapperDays;
|
||||
int mapperControl;
|
||||
int mapperLSeconds;
|
||||
int mapperLMinutes;
|
||||
int mapperLHours;
|
||||
int mapperLDays;
|
||||
int mapperLControl;
|
||||
time_t mapperLastTime;
|
||||
};
|
||||
|
||||
struct mapperMBC5 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int isRumbleCartridge;
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int isRumbleCartridge;
|
||||
};
|
||||
|
||||
struct mapperMBC7 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int cs;
|
||||
int sk;
|
||||
int state;
|
||||
int buffer;
|
||||
int idle;
|
||||
int count;
|
||||
int code;
|
||||
int address;
|
||||
int writeEnable;
|
||||
int value;
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int cs;
|
||||
int sk;
|
||||
int state;
|
||||
int buffer;
|
||||
int idle;
|
||||
int count;
|
||||
int code;
|
||||
int address;
|
||||
int writeEnable;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct mapperHuC1 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
};
|
||||
|
||||
struct mapperHuC3 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperAddress;
|
||||
int mapperRAMFlag;
|
||||
int mapperRAMValue;
|
||||
int mapperRegister1;
|
||||
int mapperRegister2;
|
||||
int mapperRegister3;
|
||||
int mapperRegister4;
|
||||
int mapperRegister5;
|
||||
int mapperRegister6;
|
||||
int mapperRegister7;
|
||||
int mapperRegister8;
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperAddress;
|
||||
int mapperRAMFlag;
|
||||
int mapperRAMValue;
|
||||
int mapperRegister1;
|
||||
int mapperRegister2;
|
||||
int mapperRegister3;
|
||||
int mapperRegister4;
|
||||
int mapperRegister5;
|
||||
int mapperRegister6;
|
||||
int mapperRegister7;
|
||||
int mapperRegister8;
|
||||
};
|
||||
|
||||
struct mapperTAMA5 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperRamByteSelect;
|
||||
int mapperCommandNumber;
|
||||
int mapperLastCommandNumber;
|
||||
int mapperCommands[0x10];
|
||||
int mapperRegister;
|
||||
int mapperClockLatch;
|
||||
int mapperClockRegister;
|
||||
int mapperSeconds;
|
||||
int mapperMinutes;
|
||||
int mapperHours;
|
||||
int mapperDays;
|
||||
int mapperMonths;
|
||||
int mapperYears;
|
||||
int mapperControl;
|
||||
int mapperLSeconds;
|
||||
int mapperLMinutes;
|
||||
int mapperLHours;
|
||||
int mapperLDays;
|
||||
int mapperLMonths;
|
||||
int mapperLYears;
|
||||
int mapperLControl;
|
||||
time_t mapperLastTime;
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperRAMAddress;
|
||||
int mapperRamByteSelect;
|
||||
int mapperCommandNumber;
|
||||
int mapperLastCommandNumber;
|
||||
int mapperCommands[0x10];
|
||||
int mapperRegister;
|
||||
int mapperClockLatch;
|
||||
int mapperClockRegister;
|
||||
int mapperSeconds;
|
||||
int mapperMinutes;
|
||||
int mapperHours;
|
||||
int mapperDays;
|
||||
int mapperMonths;
|
||||
int mapperYears;
|
||||
int mapperControl;
|
||||
int mapperLSeconds;
|
||||
int mapperLMinutes;
|
||||
int mapperLHours;
|
||||
int mapperLDays;
|
||||
int mapperLMonths;
|
||||
int mapperLYears;
|
||||
int mapperLControl;
|
||||
time_t mapperLastTime;
|
||||
};
|
||||
|
||||
struct mapperMMM01 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int mapperRomBank0Remapping;
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
int mapperRAMBank;
|
||||
int mapperMemoryModel;
|
||||
int mapperROMHighAddress;
|
||||
int mapperRAMAddress;
|
||||
int mapperRomBank0Remapping;
|
||||
};
|
||||
|
||||
struct mapperGS3 {
|
||||
int mapperROMBank;
|
||||
int mapperROMBank;
|
||||
};
|
||||
|
||||
extern mapperMBC1 gbDataMBC1;
|
||||
|
@ -144,35 +144,35 @@ extern mapperTAMA5 gbDataTAMA5;
|
|||
extern mapperMMM01 gbDataMMM01;
|
||||
extern mapperGS3 gbDataGS3;
|
||||
|
||||
void mapperMBC1ROM(u16,u8);
|
||||
void mapperMBC1RAM(u16,u8);
|
||||
void mapperMBC1ROM(u16, u8);
|
||||
void mapperMBC1RAM(u16, u8);
|
||||
u8 mapperMBC1ReadRAM(u16);
|
||||
void mapperMBC2ROM(u16,u8);
|
||||
void mapperMBC2RAM(u16,u8);
|
||||
void mapperMBC3ROM(u16,u8);
|
||||
void mapperMBC3RAM(u16,u8);
|
||||
void mapperMBC2ROM(u16, u8);
|
||||
void mapperMBC2RAM(u16, u8);
|
||||
void mapperMBC3ROM(u16, u8);
|
||||
void mapperMBC3RAM(u16, u8);
|
||||
u8 mapperMBC3ReadRAM(u16);
|
||||
void mapperMBC5ROM(u16,u8);
|
||||
void mapperMBC5RAM(u16,u8);
|
||||
void mapperMBC5ROM(u16, u8);
|
||||
void mapperMBC5RAM(u16, u8);
|
||||
u8 mapperMBC5ReadRAM(u16);
|
||||
void mapperMBC7ROM(u16,u8);
|
||||
void mapperMBC7RAM(u16,u8);
|
||||
void mapperMBC7ROM(u16, u8);
|
||||
void mapperMBC7RAM(u16, u8);
|
||||
u8 mapperMBC7ReadRAM(u16);
|
||||
void mapperHuC1ROM(u16,u8);
|
||||
void mapperHuC1RAM(u16,u8);
|
||||
void mapperHuC3ROM(u16,u8);
|
||||
void mapperHuC3RAM(u16,u8);
|
||||
void mapperHuC1ROM(u16, u8);
|
||||
void mapperHuC1RAM(u16, u8);
|
||||
void mapperHuC3ROM(u16, u8);
|
||||
void mapperHuC3RAM(u16, u8);
|
||||
u8 mapperHuC3ReadRAM(u16);
|
||||
void mapperTAMA5RAM(u16,u8);
|
||||
void mapperTAMA5RAM(u16, u8);
|
||||
u8 mapperTAMA5ReadRAM(u16);
|
||||
void memoryUpdateTAMA5Clock();
|
||||
void mapperMMM01ROM(u16,u8);
|
||||
void mapperMMM01RAM(u16,u8);
|
||||
void mapperGGROM(u16,u8);
|
||||
void mapperGS3ROM(u16,u8);
|
||||
//extern void (*mapper)(u16,u8);
|
||||
//extern void (*mapperRAM)(u16,u8);
|
||||
//extern u8 (*mapperReadRAM)(u16);
|
||||
void mapperMMM01ROM(u16, u8);
|
||||
void mapperMMM01RAM(u16, u8);
|
||||
void mapperGGROM(u16, u8);
|
||||
void mapperGS3ROM(u16, u8);
|
||||
// extern void (*mapper)(u16,u8);
|
||||
// extern void (*mapperRAM)(u16,u8);
|
||||
// extern u8 (*mapperReadRAM)(u16);
|
||||
|
||||
extern void memoryUpdateMapMBC1();
|
||||
extern void memoryUpdateMapMBC2();
|
||||
|
|
|
@ -11,13 +11,13 @@ void gbSgbSaveGame(gzFile);
|
|||
void gbSgbReadGame(gzFile, int version);
|
||||
void gbSgbRenderBorder();
|
||||
|
||||
extern u8 gbSgbATF[20*18];
|
||||
extern u8 gbSgbATF[20 * 18];
|
||||
extern int gbSgbMode;
|
||||
extern int gbSgbMask;
|
||||
extern int gbSgbMultiplayer;
|
||||
extern u8 gbSgbNextController;
|
||||
extern u8 gbSgbNextController;
|
||||
extern int gbSgbPacketTimeout;
|
||||
extern u8 gbSgbReadingController;
|
||||
extern u8 gbSgbReadingController;
|
||||
extern int gbSgbFourPlayers;
|
||||
|
||||
#endif // GBSGB_H
|
||||
|
|
|
@ -7,28 +7,26 @@
|
|||
|
||||
//// GB sound options
|
||||
|
||||
void gbSoundSetSampleRate( long sampleRate );
|
||||
void gbSoundSetSampleRate(long sampleRate);
|
||||
|
||||
// Manages declicking mode. When enabled, clicks are reduced. Note that clicks
|
||||
// are normal for GB and GBC sound hardware.
|
||||
void gbSoundSetDeclicking( bool enable );
|
||||
void gbSoundSetDeclicking(bool enable);
|
||||
bool gbSoundGetDeclicking();
|
||||
|
||||
// Effects configuration
|
||||
struct gb_effects_config_t
|
||||
{
|
||||
bool enabled; // false = disable all effects
|
||||
struct gb_effects_config_t {
|
||||
bool enabled; // false = disable all effects
|
||||
|
||||
float echo; // 0.0 = none, 1.0 = lots
|
||||
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
|
||||
bool surround; // true = put some channels in back
|
||||
float echo; // 0.0 = none, 1.0 = lots
|
||||
float stereo; // 0.0 = channels in center, 1.0 = channels on left/right
|
||||
bool surround; // true = put some channels in back
|
||||
};
|
||||
|
||||
// Changes effects configuration
|
||||
void gbSoundConfigEffects( gb_effects_config_t const& );
|
||||
void gbSoundConfigEffects(gb_effects_config_t const &);
|
||||
extern gb_effects_config_t gb_effects_config; // current configuration
|
||||
|
||||
|
||||
//// GB sound emulation
|
||||
|
||||
// GB sound registers
|
||||
|
@ -58,19 +56,19 @@ extern gb_effects_config_t gb_effects_config; // current configuration
|
|||
void gbSoundReset();
|
||||
|
||||
// Emulates write to sound hardware
|
||||
void gbSoundEvent( u16 address, int data );
|
||||
void gbSoundEvent(u16 address, int data);
|
||||
#define SOUND_EVENT gbSoundEvent
|
||||
|
||||
// Emulates read from sound hardware
|
||||
u8 gbSoundRead( u16 address );
|
||||
u8 gbSoundRead(u16 address);
|
||||
|
||||
// Notifies emulator that SOUND_CLOCK_TICKS clocks have passed
|
||||
void gbSoundTick();
|
||||
extern int SOUND_CLOCK_TICKS; // Number of 16.8 MHz clocks between calls to gbSoundTick()
|
||||
extern int soundTicks; // Number of 16.8 MHz clocks until gbSoundTick() will be called
|
||||
extern int SOUND_CLOCK_TICKS; // Number of 16.8 MHz clocks between calls to gbSoundTick()
|
||||
extern int soundTicks; // Number of 16.8 MHz clocks until gbSoundTick() will be called
|
||||
|
||||
// Saves/loads emulator state
|
||||
void gbSoundSaveGame( gzFile out );
|
||||
void gbSoundReadGame( int version, gzFile in );
|
||||
void gbSoundSaveGame(gzFile out);
|
||||
void gbSoundReadGame(int version, gzFile in);
|
||||
|
||||
#endif // GBSOUND_H
|
||||
|
|
|
@ -3,71 +3,68 @@
|
|||
|
||||
#include "../common/Types.h"
|
||||
|
||||
#define readWord(addr) \
|
||||
((map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])+\
|
||||
((map[(addr+1)>>24].address[(addr+1) & map[(addr+1)>>24].mask])<<8)+\
|
||||
((map[(addr+2)>>24].address[(addr+2) & map[(addr+2)>>24].mask])<<16)+\
|
||||
((map[(addr+3)>>24].address[(addr+3) & map[(addr+3)>>24].mask])<<24))
|
||||
#define readWord(addr) \
|
||||
((map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + \
|
||||
((map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8) + \
|
||||
((map[(addr + 2) >> 24].address[(addr + 2) & map[(addr + 2) >> 24].mask]) << 16) + \
|
||||
((map[(addr + 3) >> 24].address[(addr + 3) & map[(addr + 3) >> 24].mask]) << 24))
|
||||
|
||||
#define readHalfWord(addr) \
|
||||
((&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])+\
|
||||
((&map[(addr+1)>>24].address[(addr+1) & map[(addr+1)>>24].mask])<<8))
|
||||
#define readHalfWord(addr) \
|
||||
((&map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]) + \
|
||||
((&map[(addr + 1) >> 24].address[(addr + 1) & map[(addr + 1) >> 24].mask]) << 8))
|
||||
|
||||
#define readByte(addr) \
|
||||
map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
|
||||
#define readByte(addr) map[(addr) >> 24].address[(addr)&map[(addr) >> 24].mask]
|
||||
|
||||
|
||||
struct ConditionalBreakNode{
|
||||
char* address;
|
||||
char* value;
|
||||
u8 cond_flags;
|
||||
u8 exp_type_flags;
|
||||
struct ConditionalBreakNode* next;
|
||||
struct ConditionalBreakNode {
|
||||
char *address;
|
||||
char *value;
|
||||
u8 cond_flags;
|
||||
u8 exp_type_flags;
|
||||
struct ConditionalBreakNode *next;
|
||||
};
|
||||
|
||||
struct ConditionalBreak{
|
||||
u32 break_address;
|
||||
u8 type_flags;
|
||||
struct ConditionalBreakNode* firstCond;
|
||||
struct ConditionalBreak* next;
|
||||
struct ConditionalBreak {
|
||||
u32 break_address;
|
||||
u8 type_flags;
|
||||
struct ConditionalBreakNode *firstCond;
|
||||
struct ConditionalBreak *next;
|
||||
};
|
||||
|
||||
extern struct ConditionalBreak* conditionals[16];
|
||||
extern struct ConditionalBreak *conditionals[16];
|
||||
|
||||
//conditional break manipulators
|
||||
//case '*': flag = 0xf; break;
|
||||
//case 't': flag = 0x8; break; // thumb
|
||||
//case 'a': flag = 0x4; break; // arm
|
||||
//case 'x': flag = 0xC; break;
|
||||
//case 'r': flag = 0x2; break; // mem read
|
||||
//case 'w': flag = 0x1; break; // mem write
|
||||
//case 'i': flag = 0x3; break;
|
||||
struct ConditionalBreak* addConditionalBreak(u32 address, u8 flag);
|
||||
// conditional break manipulators
|
||||
// case '*': flag = 0xf; break;
|
||||
// case 't': flag = 0x8; break; // thumb
|
||||
// case 'a': flag = 0x4; break; // arm
|
||||
// case 'x': flag = 0xC; break;
|
||||
// case 'r': flag = 0x2; break; // mem read
|
||||
// case 'w': flag = 0x1; break; // mem write
|
||||
// case 'i': flag = 0x3; break;
|
||||
struct ConditionalBreak *addConditionalBreak(u32 address, u8 flag);
|
||||
|
||||
int removeConditionalBreakNo(u32 address, u8 number);
|
||||
int removeFlagFromConditionalBreakNo(u32 address, u8 number, u8 flag);
|
||||
int removeConditionalWithAddress(u32 address);
|
||||
int removeConditionalWithFlag(u8 flag, bool orMode);
|
||||
int removeConditionalWithAddressAndFlag(u32 address, u8 flag, bool orMode);
|
||||
//void freeConditionalBreak(struct ConditionalBreak* toFree);
|
||||
// void freeConditionalBreak(struct ConditionalBreak* toFree);
|
||||
|
||||
void addCondition(struct ConditionalBreak* base, struct ConditionalBreakNode* toAdd);
|
||||
//bool removeCondition(struct ConditionalBreak* base, struct ConditionalBreakNode* toDel);
|
||||
//bool removeCondition(u32 address, u8 flags, u8 num);
|
||||
void addCondition(struct ConditionalBreak *base, struct ConditionalBreakNode *toAdd);
|
||||
// bool removeCondition(struct ConditionalBreak* base, struct ConditionalBreakNode* toDel);
|
||||
// bool removeCondition(u32 address, u8 flags, u8 num);
|
||||
|
||||
void freeConditionalNode(struct ConditionalBreakNode* toDel);
|
||||
void freeConditionalNode(struct ConditionalBreakNode *toDel);
|
||||
|
||||
void parseAndCreateConditionalBreaks(u32 address, u8 flags, char **exp, int n);
|
||||
|
||||
void parseAndCreateConditionalBreaks(u32 address, u8 flags, char** exp, int n);
|
||||
|
||||
bool isCorrectBreak(struct ConditionalBreak* toTest, u8 accessType);
|
||||
bool isCorrectBreak(struct ConditionalBreak *toTest, u8 accessType);
|
||||
bool doesBreak(u32 address, u8 allowedFlags);
|
||||
bool doBreak(struct ConditionalBreak* toTest);
|
||||
bool doBreak(struct ConditionalBreak *toTest);
|
||||
|
||||
//printing the structure(AKA list Breaks)
|
||||
//void printConditionalBreak(struct ConditionalBreak* toPrint, bool printAddress);
|
||||
//void printAllConditionals();
|
||||
//u8 printConditionalsFromAddress(u32 address);
|
||||
//void printAllFlagConditionals(u8 flag, bool orMode);
|
||||
//void printAllFlagConditionalsWithAddress(u32 address, u8 flag, bool orMode);
|
||||
// printing the structure(AKA list Breaks)
|
||||
// void printConditionalBreak(struct ConditionalBreak* toPrint, bool printAddress);
|
||||
// void printAllConditionals();
|
||||
// u8 printConditionalsFromAddress(u32 address);
|
||||
// void printAllFlagConditionals(u8 flag, bool orMode);
|
||||
// void printAllFlagConditionalsWithAddress(u32 address, u8 flag, bool orMode);
|
||||
#endif
|
|
@ -4,41 +4,27 @@
|
|||
#include "../System.h"
|
||||
|
||||
struct CheatSearchBlock {
|
||||
int size;
|
||||
u32 offset;
|
||||
u8 *bits;
|
||||
u8 *data;
|
||||
u8 *saved;
|
||||
int size;
|
||||
u32 offset;
|
||||
u8 *bits;
|
||||
u8 *data;
|
||||
u8 *saved;
|
||||
};
|
||||
|
||||
struct CheatSearchData {
|
||||
int count;
|
||||
CheatSearchBlock *blocks;
|
||||
int count;
|
||||
CheatSearchBlock *blocks;
|
||||
};
|
||||
|
||||
enum {
|
||||
SEARCH_EQ,
|
||||
SEARCH_NE,
|
||||
SEARCH_LT,
|
||||
SEARCH_LE,
|
||||
SEARCH_GT,
|
||||
SEARCH_GE
|
||||
};
|
||||
enum { SEARCH_EQ, SEARCH_NE, SEARCH_LT, SEARCH_LE, SEARCH_GT, SEARCH_GE };
|
||||
|
||||
enum {
|
||||
BITS_8,
|
||||
BITS_16,
|
||||
BITS_32
|
||||
};
|
||||
enum { BITS_8, BITS_16, BITS_32 };
|
||||
|
||||
#define SET_BIT(bits,off) \
|
||||
(bits)[(off) >> 3] |= (1 << ((off) & 7))
|
||||
#define SET_BIT(bits, off) (bits)[(off) >> 3] |= (1 << ((off)&7))
|
||||
|
||||
#define CLEAR_BIT(bits, off) \
|
||||
(bits)[(off) >> 3] &= ~(1 << ((off) & 7))
|
||||
#define CLEAR_BIT(bits, off) (bits)[(off) >> 3] &= ~(1 << ((off)&7))
|
||||
|
||||
#define IS_BIT_SET(bits, off) \
|
||||
(bits)[(off) >> 3] & (1 << ((off) & 7))
|
||||
#define IS_BIT_SET(bits, off) (bits)[(off) >> 3] & (1 << ((off)&7))
|
||||
|
||||
extern CheatSearchData cheatSearchData;
|
||||
|
||||
|
|
|
@ -4,19 +4,20 @@
|
|||
#include "../common/ConfigManager.h"
|
||||
|
||||
struct CheatsData {
|
||||
int code;
|
||||
int size;
|
||||
int status;
|
||||
bool enabled;
|
||||
u32 rawaddress;
|
||||
u32 address;
|
||||
u32 value;
|
||||
u32 oldValue;
|
||||
char codestring[20];
|
||||
char desc[32];
|
||||
int code;
|
||||
int size;
|
||||
int status;
|
||||
bool enabled;
|
||||
u32 rawaddress;
|
||||
u32 address;
|
||||
u32 value;
|
||||
u32 oldValue;
|
||||
char codestring[20];
|
||||
char desc[32];
|
||||
};
|
||||
|
||||
void cheatsAdd(const char *codeStr, const char *desc, u32 rawaddress, u32 address, u32 value, int code, int size);
|
||||
void cheatsAdd(const char *codeStr, const char *desc, u32 rawaddress, u32 address, u32 value,
|
||||
int code, int size);
|
||||
void cheatsAddCheatCode(const char *code, const char *desc);
|
||||
void cheatsAddGSACode(const char *code, const char *desc, bool v3);
|
||||
void cheatsAddCBACode(const char *code, const char *desc);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define EEPROM_H
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
extern void eepromSaveGame(u8* &data);
|
||||
extern void eepromSaveGame(u8 *&data);
|
||||
extern void eepromReadGame(const u8 *&data, int version);
|
||||
#else
|
||||
extern void eepromSaveGame(gzFile _gzFile);
|
||||
|
@ -21,10 +21,10 @@ extern u8 eepromData[0x2000];
|
|||
extern bool eepromInUse;
|
||||
extern int eepromSize;
|
||||
|
||||
#define EEPROM_IDLE 0
|
||||
#define EEPROM_READADDRESS 1
|
||||
#define EEPROM_READDATA 2
|
||||
#define EEPROM_READDATA2 3
|
||||
#define EEPROM_WRITEDATA 4
|
||||
#define EEPROM_IDLE 0
|
||||
#define EEPROM_READADDRESS 1
|
||||
#define EEPROM_READDATA 2
|
||||
#define EEPROM_READDATA2 3
|
||||
#define EEPROM_WRITEDATA 4
|
||||
|
||||
#endif // EEPROM_H
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#define FLASH_128K_SZ 0x20000
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
extern void flashSaveGame(u8 *& data);
|
||||
extern void flashReadGame(const u8 *& data, int);
|
||||
extern void flashSaveGame(u8 *&data);
|
||||
extern void flashReadGame(const u8 *&data, int);
|
||||
#else
|
||||
extern void flashSaveGame(gzFile _gzFile);
|
||||
extern void flashReadGame(gzFile _gzFile, int version);
|
||||
|
|
102
src/gba/GBA.h
102
src/gba/GBA.h
|
@ -15,46 +15,46 @@ const u64 TICKS_PER_SECOND = 16777216;
|
|||
#define SAVE_GAME_VERSION_8 8
|
||||
#define SAVE_GAME_VERSION_9 9
|
||||
#define SAVE_GAME_VERSION_10 10
|
||||
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
|
||||
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
|
||||
|
||||
typedef struct {
|
||||
u8 *address;
|
||||
u32 mask;
|
||||
u8 *address;
|
||||
u32 mask;
|
||||
#ifdef BKPT_SUPPORT
|
||||
u8 *breakPoints;
|
||||
u8 *searchMatch;
|
||||
u8* trace;
|
||||
u32 size;
|
||||
u8 *breakPoints;
|
||||
u8 *searchMatch;
|
||||
u8 *trace;
|
||||
u32 size;
|
||||
#endif
|
||||
} memoryMap;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u8 B3;
|
||||
u8 B2;
|
||||
u8 B1;
|
||||
u8 B0;
|
||||
u8 B3;
|
||||
u8 B2;
|
||||
u8 B1;
|
||||
u8 B0;
|
||||
#else
|
||||
u8 B0;
|
||||
u8 B1;
|
||||
u8 B2;
|
||||
u8 B3;
|
||||
u8 B0;
|
||||
u8 B1;
|
||||
u8 B2;
|
||||
u8 B3;
|
||||
#endif
|
||||
} B;
|
||||
struct {
|
||||
} B;
|
||||
struct {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
u16 W1;
|
||||
u16 W0;
|
||||
u16 W1;
|
||||
u16 W0;
|
||||
#else
|
||||
u16 W0;
|
||||
u16 W1;
|
||||
u16 W0;
|
||||
u16 W1;
|
||||
#endif
|
||||
} W;
|
||||
} W;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
volatile u32 I;
|
||||
volatile u32 I;
|
||||
#else
|
||||
u32 I;
|
||||
u32 I;
|
||||
#endif
|
||||
} reg_pair;
|
||||
|
||||
|
@ -64,7 +64,7 @@ extern memoryMap map[256];
|
|||
|
||||
extern u8 biosProtected[4];
|
||||
|
||||
extern void (*cpuSaveGameFunc)(u32,u8);
|
||||
extern void (*cpuSaveGameFunc)(u32, u8);
|
||||
|
||||
#ifdef BKPT_SUPPORT
|
||||
extern u8 freezeWorkRAM[0x40000];
|
||||
|
@ -73,7 +73,7 @@ extern u8 freezeVRAM[0x18000];
|
|||
extern u8 freezeOAM[0x400];
|
||||
extern u8 freezePRAM[0x400];
|
||||
extern bool debugger_last;
|
||||
extern int oldreg[18];
|
||||
extern int oldreg[18];
|
||||
extern char oldbuffer[10];
|
||||
extern bool debugger;
|
||||
#endif
|
||||
|
@ -93,7 +93,7 @@ extern void CPUUpdateRenderBuffers(bool);
|
|||
extern bool CPUReadMemState(char *, int);
|
||||
extern bool CPUWriteMemState(char *, int);
|
||||
#ifdef __LIBRETRO__
|
||||
extern bool CPUReadState(const u8*, unsigned);
|
||||
extern bool CPUReadState(const u8 *, unsigned);
|
||||
extern unsigned int CPUWriteState(u8 *data, unsigned int size);
|
||||
#else
|
||||
extern bool CPUReadState(const char *);
|
||||
|
@ -103,12 +103,12 @@ extern int CPULoadRom(const char *);
|
|||
extern int CPULoadRomData(const char *data, int size);
|
||||
extern void doMirroring(bool);
|
||||
extern void CPUUpdateRegister(u32, u16);
|
||||
extern void applyTimer ();
|
||||
extern void CPUInit(const char *,bool);
|
||||
extern void applyTimer();
|
||||
extern void CPUInit(const char *, bool);
|
||||
void SetSaveType(int st);
|
||||
extern void CPUReset();
|
||||
extern void CPULoop(int);
|
||||
extern void CPUCheckDMA(int,int);
|
||||
extern void CPUCheckDMA(int, int);
|
||||
extern bool CPUIsGBAImage(const char *);
|
||||
extern bool CPUIsZipFile(const char *);
|
||||
#ifdef PROFILING
|
||||
|
@ -117,39 +117,39 @@ extern void cpuProfil(profile_segment *seg);
|
|||
extern void cpuEnableProfiling(int hz);
|
||||
#endif
|
||||
|
||||
const char* GetLoadDotCodeFile();
|
||||
const char* GetSaveDotCodeFile();
|
||||
const char *GetLoadDotCodeFile();
|
||||
const char *GetSaveDotCodeFile();
|
||||
void SetLoadDotCodeFile(const char *szFile);
|
||||
void SetSaveDotCodeFile(const char *szFile);
|
||||
|
||||
extern struct EmulatedSystem GBASystem;
|
||||
|
||||
#define R13_IRQ 18
|
||||
#define R14_IRQ 19
|
||||
#define R13_IRQ 18
|
||||
#define R14_IRQ 19
|
||||
#define SPSR_IRQ 20
|
||||
#define R13_USR 26
|
||||
#define R14_USR 27
|
||||
#define R13_SVC 28
|
||||
#define R14_SVC 29
|
||||
#define R13_USR 26
|
||||
#define R14_USR 27
|
||||
#define R13_SVC 28
|
||||
#define R14_SVC 29
|
||||
#define SPSR_SVC 30
|
||||
#define R13_ABT 31
|
||||
#define R14_ABT 32
|
||||
#define R13_ABT 31
|
||||
#define R14_ABT 32
|
||||
#define SPSR_ABT 33
|
||||
#define R13_UND 34
|
||||
#define R14_UND 35
|
||||
#define R13_UND 34
|
||||
#define R14_UND 35
|
||||
#define SPSR_UND 36
|
||||
#define R8_FIQ 37
|
||||
#define R9_FIQ 38
|
||||
#define R10_FIQ 39
|
||||
#define R11_FIQ 40
|
||||
#define R12_FIQ 41
|
||||
#define R13_FIQ 42
|
||||
#define R14_FIQ 43
|
||||
#define R8_FIQ 37
|
||||
#define R9_FIQ 38
|
||||
#define R10_FIQ 39
|
||||
#define R11_FIQ 40
|
||||
#define R12_FIQ 41
|
||||
#define R13_FIQ 42
|
||||
#define R14_FIQ 43
|
||||
#define SPSR_FIQ 44
|
||||
|
||||
#include "Cheats.h"
|
||||
#include "Globals.h"
|
||||
#include "EEprom.h"
|
||||
#include "Flash.h"
|
||||
#include "Globals.h"
|
||||
|
||||
#endif // GBA_H
|
||||
|
|
2950
src/gba/GBAGfx.h
2950
src/gba/GBAGfx.h
File diff suppressed because it is too large
Load Diff
|
@ -4,28 +4,21 @@
|
|||
/**
|
||||
* Link modes to be passed to InitLink
|
||||
*/
|
||||
enum LinkMode
|
||||
{
|
||||
LINK_DISCONNECTED,
|
||||
LINK_CABLE_IPC,
|
||||
LINK_CABLE_SOCKET,
|
||||
LINK_RFU_IPC,
|
||||
LINK_RFU_SOCKET,
|
||||
LINK_GAMECUBE_DOLPHIN,
|
||||
LINK_GAMEBOY_IPC,
|
||||
LINK_GAMEBOY_SOCKET
|
||||
enum LinkMode {
|
||||
LINK_DISCONNECTED,
|
||||
LINK_CABLE_IPC,
|
||||
LINK_CABLE_SOCKET,
|
||||
LINK_RFU_IPC,
|
||||
LINK_RFU_SOCKET,
|
||||
LINK_GAMECUBE_DOLPHIN,
|
||||
LINK_GAMEBOY_IPC,
|
||||
LINK_GAMEBOY_SOCKET
|
||||
};
|
||||
|
||||
/**
|
||||
* State of the connection attempt
|
||||
*/
|
||||
enum ConnectionState
|
||||
{
|
||||
LINK_OK,
|
||||
LINK_ERROR,
|
||||
LINK_NEEDS_UPDATE,
|
||||
LINK_ABORT
|
||||
};
|
||||
enum ConnectionState { LINK_OK, LINK_ERROR, LINK_NEEDS_UPDATE, LINK_ABORT };
|
||||
|
||||
/**
|
||||
* Initialize GBA linking
|
||||
|
@ -41,7 +34,7 @@ extern ConnectionState InitLink(LinkMode mode);
|
|||
* @param message Information message
|
||||
* @param size Maximum message size
|
||||
*/
|
||||
extern ConnectionState ConnectLinkUpdate(char * const message, size_t size);
|
||||
extern ConnectionState ConnectLinkUpdate(char *const message, size_t size);
|
||||
|
||||
/**
|
||||
* Get the currently enabled link mode
|
||||
|
@ -80,7 +73,7 @@ extern bool SetLinkServerHost(const char *host);
|
|||
* If in gamecube mode, returns the IP adress of the dolphin host
|
||||
*
|
||||
*/
|
||||
extern void GetLinkServerHost(char * const host, size_t size);
|
||||
extern void GetLinkServerHost(char *const host, size_t size);
|
||||
|
||||
/**
|
||||
* Set the value in milliseconds of the timeout after which a connection is
|
||||
|
@ -141,56 +134,58 @@ extern void CleanLocalLink();
|
|||
extern const char *MakeInstanceFilename(const char *Input);
|
||||
|
||||
// register definitions
|
||||
#define COMM_SIODATA32_L 0x120 // Lower 16bit on Normal mode
|
||||
#define COMM_SIODATA32_H 0x122 // Higher 16bit on Normal mode
|
||||
#define COMM_SIOCNT 0x128
|
||||
#define COMM_SIODATA8 0x12a // 8bit on Normal/UART mode, (up to 4x8bit with FIFO)
|
||||
#define COMM_SIOMLT_SEND 0x12a // SIOMLT_SEND (16bit R/W) on MultiPlayer mode (local outgoing)
|
||||
#define COMM_SIOMULTI0 0x120 // SIOMULTI0 (16bit) on MultiPlayer mode (Parent/Master)
|
||||
#define COMM_SIOMULTI1 0x122 // SIOMULTI1 (16bit) on MultiPlayer mode (Child1/Slave1)
|
||||
#define COMM_SIOMULTI2 0x124 // SIOMULTI2 (16bit) on MultiPlayer mode (Child2/Slave2)
|
||||
#define COMM_SIOMULTI3 0x126 // SIOMULTI3 (16bit) on MultiPlayer mode (Child3/Slave3)
|
||||
#define COMM_RCNT 0x134 // SIO Mode (4bit data) on GeneralPurpose mode
|
||||
#define COMM_IR 0x136 // Infrared Register (16bit) 1bit data at a time(LED On/Off)?
|
||||
#define COMM_JOYCNT 0x140
|
||||
#define COMM_JOY_RECV_L 0x150 // Send/Receive 8bit Lower first then 8bit Higher
|
||||
#define COMM_JOY_RECV_H 0x152
|
||||
#define COMM_JOY_TRANS_L 0x154 // Send/Receive 8bit Lower first then 8bit Higher
|
||||
#define COMM_JOY_TRANS_H 0x156
|
||||
#define COMM_JOYSTAT 0x158 // Send/Receive 8bit lower only
|
||||
#define COMM_SIODATA32_L 0x120 // Lower 16bit on Normal mode
|
||||
#define COMM_SIODATA32_H 0x122 // Higher 16bit on Normal mode
|
||||
#define COMM_SIOCNT 0x128
|
||||
#define COMM_SIODATA8 0x12a // 8bit on Normal/UART mode, (up to 4x8bit with FIFO)
|
||||
#define COMM_SIOMLT_SEND 0x12a // SIOMLT_SEND (16bit R/W) on MultiPlayer mode (local outgoing)
|
||||
#define COMM_SIOMULTI0 0x120 // SIOMULTI0 (16bit) on MultiPlayer mode (Parent/Master)
|
||||
#define COMM_SIOMULTI1 0x122 // SIOMULTI1 (16bit) on MultiPlayer mode (Child1/Slave1)
|
||||
#define COMM_SIOMULTI2 0x124 // SIOMULTI2 (16bit) on MultiPlayer mode (Child2/Slave2)
|
||||
#define COMM_SIOMULTI3 0x126 // SIOMULTI3 (16bit) on MultiPlayer mode (Child3/Slave3)
|
||||
#define COMM_RCNT 0x134 // SIO Mode (4bit data) on GeneralPurpose mode
|
||||
#define COMM_IR 0x136 // Infrared Register (16bit) 1bit data at a time(LED On/Off)?
|
||||
#define COMM_JOYCNT 0x140
|
||||
#define COMM_JOY_RECV_L 0x150 // Send/Receive 8bit Lower first then 8bit Higher
|
||||
#define COMM_JOY_RECV_H 0x152
|
||||
#define COMM_JOY_TRANS_L 0x154 // Send/Receive 8bit Lower first then 8bit Higher
|
||||
#define COMM_JOY_TRANS_H 0x156
|
||||
#define COMM_JOYSTAT 0x158 // Send/Receive 8bit lower only
|
||||
|
||||
#define JOYSTAT_RECV 2
|
||||
#define JOYSTAT_SEND 8
|
||||
#define JOYSTAT_RECV 2
|
||||
#define JOYSTAT_SEND 8
|
||||
|
||||
#define JOYCNT_RESET 1
|
||||
#define JOYCNT_RECV_COMPLETE 2
|
||||
#define JOYCNT_SEND_COMPLETE 4
|
||||
#define JOYCNT_INT_ENABLE 0x40
|
||||
#define JOYCNT_RESET 1
|
||||
#define JOYCNT_RECV_COMPLETE 2
|
||||
#define JOYCNT_SEND_COMPLETE 4
|
||||
#define JOYCNT_INT_ENABLE 0x40
|
||||
|
||||
#define LINK_PARENTLOST 0x80
|
||||
#define LINK_PARENTLOST 0x80
|
||||
|
||||
#define UNSUPPORTED -1
|
||||
#define MULTIPLAYER 0
|
||||
#define NORMAL8 1
|
||||
#define NORMAL32 2 // wireless use normal32 also
|
||||
#define UART 3
|
||||
#define JOYBUS 4
|
||||
#define GP 5
|
||||
#define INFRARED 6 // Infrared Register at 4000136h
|
||||
#define UNSUPPORTED -1
|
||||
#define MULTIPLAYER 0
|
||||
#define NORMAL8 1
|
||||
#define NORMAL32 2 // wireless use normal32 also
|
||||
#define UART 3
|
||||
#define JOYBUS 4
|
||||
#define GP 5
|
||||
#define INFRARED 6 // Infrared Register at 4000136h
|
||||
|
||||
#define RFU_INIT 0
|
||||
#define RFU_COMM 1
|
||||
#define RFU_SEND 2
|
||||
#define RFU_RECV 3
|
||||
#define RFU_INIT 0
|
||||
#define RFU_COMM 1
|
||||
#define RFU_SEND 2
|
||||
#define RFU_RECV 3
|
||||
|
||||
#define RF_RECVCMD 0x278 // Unknown, Seems to be related to Wireless Adapter(RF_RCNT or armMode/CPSR or CMD sent by the adapter when RF_SIOCNT=0x83 or when RCNT=0x80aX?)
|
||||
#define RF_CNT 0x27a // Unknown, Seems to be related to Wireless Adapter(RF_SIOCNT?)
|
||||
#define RF_RECVCMD \
|
||||
0x278 // Unknown, Seems to be related to Wireless Adapter(RF_RCNT or armMode/CPSR or CMD
|
||||
// sent by the adapter when RF_SIOCNT=0x83 or when RCNT=0x80aX?)
|
||||
#define RF_CNT 0x27a // Unknown, Seems to be related to Wireless Adapter(RF_SIOCNT?)
|
||||
|
||||
typedef struct {
|
||||
u8 len; //data len in 32bit words
|
||||
u8 gbaid; //source id
|
||||
u32 time; //linktime
|
||||
u32 data[255];
|
||||
u8 len; // data len in 32bit words
|
||||
u8 gbaid; // source id
|
||||
u32 time; // linktime
|
||||
u32 data[255];
|
||||
} rfu_datarec;
|
||||
|
||||
extern u8 gbSIO_SC;
|
||||
|
@ -198,11 +193,11 @@ extern bool LinkIsWaiting;
|
|||
extern bool LinkFirstTime;
|
||||
extern bool EmuReseted;
|
||||
extern void gbInitLink();
|
||||
extern u8 gbStartLink(u8 b);
|
||||
extern u16 gbLinkUpdate(u8 b, int gbSerialOn);
|
||||
extern u8 gbStartLink(u8 b);
|
||||
extern u16 gbLinkUpdate(u8 b, int gbSerialOn);
|
||||
extern void gbInitLinkIPC();
|
||||
extern u8 gbStartLinkIPC(u8 b);
|
||||
extern u16 gbLinkUpdateIPC(u8 b, int gbSerialOn);
|
||||
extern u8 gbStartLinkIPC(u8 b);
|
||||
extern u16 gbLinkUpdateIPC(u8 b, int gbSerialOn);
|
||||
|
||||
extern void BootLink(int m_type, const char *host, int timeout, bool m_hacks, int m_numplayers);
|
||||
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <SFML/Network.hpp>
|
||||
#include "../common/Types.h"
|
||||
#include <SFML/Network.hpp>
|
||||
|
||||
class GBASockClient
|
||||
{
|
||||
public:
|
||||
GBASockClient(sf::IpAddress _server_addr);
|
||||
~GBASockClient();
|
||||
public:
|
||||
GBASockClient(sf::IpAddress _server_addr);
|
||||
~GBASockClient();
|
||||
|
||||
bool Connect(sf::IpAddress server_addr);
|
||||
void Send(std::vector<char> data);
|
||||
char ReceiveCmd(char* data_in, bool block);
|
||||
void ReceiveClock(bool block);
|
||||
bool Connect(sf::IpAddress server_addr);
|
||||
void Send(std::vector<char> data);
|
||||
char ReceiveCmd(char *data_in, bool block);
|
||||
void ReceiveClock(bool block);
|
||||
|
||||
void ClockSync(u32 ticks);
|
||||
void Disconnect();
|
||||
bool IsDisconnected();
|
||||
void ClockSync(u32 ticks);
|
||||
void Disconnect();
|
||||
bool IsDisconnected();
|
||||
|
||||
private:
|
||||
sf::IpAddress server_addr;
|
||||
sf::TcpSocket client;
|
||||
sf::TcpSocket clock_client;
|
||||
private:
|
||||
sf::IpAddress server_addr;
|
||||
sf::TcpSocket client;
|
||||
sf::TcpSocket clock_client;
|
||||
|
||||
s32 clock_sync;
|
||||
bool is_disconnected;
|
||||
s32 clock_sync;
|
||||
bool is_disconnected;
|
||||
};
|
||||
|
|
347
src/gba/GBAcpu.h
347
src/gba/GBAcpu.h
|
@ -6,41 +6,38 @@ extern int thumbExecute();
|
|||
|
||||
#ifdef __GNUC__
|
||||
#ifndef __APPLE__
|
||||
# define INSN_REGPARM __attribute__((regparm(1)))
|
||||
#define INSN_REGPARM __attribute__((regparm(1)))
|
||||
#else
|
||||
# define INSN_REGPARM /*nothing*/
|
||||
#define INSN_REGPARM /*nothing*/
|
||||
#endif
|
||||
# define LIKELY(x) __builtin_expect(!!(x),1)
|
||||
# define UNLIKELY(x) __builtin_expect(!!(x),0)
|
||||
#define LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
# define INSN_REGPARM /*nothing*/
|
||||
# define LIKELY(x) (x)
|
||||
# define UNLIKELY(x) (x)
|
||||
#define INSN_REGPARM /*nothing*/
|
||||
#define LIKELY(x) (x)
|
||||
#define UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
#define UPDATE_REG(address, value)\
|
||||
{\
|
||||
WRITE16LE(((u16 *)&ioMem[address]),value);\
|
||||
}\
|
||||
#define UPDATE_REG(address, value) \
|
||||
{ \
|
||||
WRITE16LE(((u16 *)&ioMem[address]), value); \
|
||||
}
|
||||
|
||||
#define ARM_PREFETCH \
|
||||
{\
|
||||
cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC);\
|
||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);\
|
||||
}
|
||||
#define ARM_PREFETCH \
|
||||
{ \
|
||||
cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC); \
|
||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4); \
|
||||
}
|
||||
|
||||
#define THUMB_PREFETCH \
|
||||
{\
|
||||
cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC);\
|
||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);\
|
||||
}
|
||||
#define THUMB_PREFETCH \
|
||||
{ \
|
||||
cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC); \
|
||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC + 2); \
|
||||
}
|
||||
|
||||
#define ARM_PREFETCH_NEXT \
|
||||
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);
|
||||
|
||||
#define THUMB_PREFETCH_NEXT\
|
||||
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);
|
||||
#define ARM_PREFETCH_NEXT cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC + 4);
|
||||
|
||||
#define THUMB_PREFETCH_NEXT cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC + 2);
|
||||
|
||||
extern int SWITicks;
|
||||
extern u32 mastercode;
|
||||
|
@ -66,222 +63,182 @@ extern void CPUUndefinedException();
|
|||
extern void CPUSoftwareInterrupt();
|
||||
extern void CPUSoftwareInterrupt(int comment);
|
||||
|
||||
|
||||
// Waitstates when accessing data
|
||||
inline int dataTicksAccess16(u32 address) // DATA 8/16bits NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWait[addr];
|
||||
int addr = (address >> 24) & 15;
|
||||
int value = memoryWait[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
if ((addr >= 0x08) || (addr < 0x02)) {
|
||||
busPrefetchCount = 0;
|
||||
busPrefetch = false;
|
||||
} else if (busPrefetch) {
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int dataTicksAccess32(u32 address) // DATA 32bits NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWait32[addr];
|
||||
int addr = (address >> 24) & 15;
|
||||
int value = memoryWait32[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
if ((addr >= 0x08) || (addr < 0x02)) {
|
||||
busPrefetchCount = 0;
|
||||
busPrefetch = false;
|
||||
} else if (busPrefetch) {
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int dataTicksAccessSeq16(u32 address)// DATA 8/16bits SEQ
|
||||
inline int dataTicksAccessSeq16(u32 address) // DATA 8/16bits SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWaitSeq[addr];
|
||||
int addr = (address >> 24) & 15;
|
||||
int value = memoryWaitSeq[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
if ((addr >= 0x08) || (addr < 0x02)) {
|
||||
busPrefetchCount = 0;
|
||||
busPrefetch = false;
|
||||
} else if (busPrefetch) {
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
inline int dataTicksAccessSeq32(u32 address)// DATA 32bits SEQ
|
||||
inline int dataTicksAccessSeq32(u32 address) // DATA 32bits SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int value = memoryWaitSeq32[addr];
|
||||
int addr = (address >> 24) & 15;
|
||||
int value = memoryWaitSeq32[addr];
|
||||
|
||||
if ((addr>=0x08) || (addr < 0x02))
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
busPrefetch=false;
|
||||
}
|
||||
else if (busPrefetch)
|
||||
{
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
|
||||
}
|
||||
if ((addr >= 0x08) || (addr < 0x02)) {
|
||||
busPrefetchCount = 0;
|
||||
busPrefetch = false;
|
||||
} else if (busPrefetch) {
|
||||
int waitState = value;
|
||||
if (!waitState)
|
||||
waitState = 1;
|
||||
busPrefetchCount = ((busPrefetchCount + 1) << waitState) - 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// Waitstates when executing opcode
|
||||
inline int codeTicksAccess16(u32 address) // THUMB NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int addr = (address >> 24) & 15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
if (busPrefetchCount&0x2)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return memoryWaitSeq[addr]-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
if ((addr >= 0x08) && (addr <= 0x0D)) {
|
||||
if (busPrefetchCount & 0x1) {
|
||||
if (busPrefetchCount & 0x2) {
|
||||
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) |
|
||||
(busPrefetchCount & 0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount =
|
||||
((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
|
||||
return memoryWaitSeq[addr] - 1;
|
||||
} else {
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
} else {
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
}
|
||||
|
||||
inline int codeTicksAccess32(u32 address) // ARM NON SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int addr = (address >> 24) & 15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
if (busPrefetchCount&0x2)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return memoryWaitSeq[addr] - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
if ((addr >= 0x08) && (addr <= 0x0D)) {
|
||||
if (busPrefetchCount & 0x1) {
|
||||
if (busPrefetchCount & 0x2) {
|
||||
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) |
|
||||
(busPrefetchCount & 0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount =
|
||||
((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
|
||||
return memoryWaitSeq[addr] - 1;
|
||||
} else {
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
} else {
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
}
|
||||
|
||||
inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int addr = (address >> 24) & 15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
if (busPrefetchCount>0xFF)
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
return memoryWait[addr];
|
||||
}
|
||||
else
|
||||
return memoryWaitSeq[addr];
|
||||
}
|
||||
else
|
||||
{
|
||||
busPrefetchCount = 0;
|
||||
return memoryWaitSeq[addr];
|
||||
}
|
||||
if ((addr >= 0x08) && (addr <= 0x0D)) {
|
||||
if (busPrefetchCount & 0x1) {
|
||||
busPrefetchCount =
|
||||
((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
|
||||
return 0;
|
||||
} else if (busPrefetchCount > 0xFF) {
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait[addr];
|
||||
} else
|
||||
return memoryWaitSeq[addr];
|
||||
} else {
|
||||
busPrefetchCount = 0;
|
||||
return memoryWaitSeq[addr];
|
||||
}
|
||||
}
|
||||
|
||||
inline int codeTicksAccessSeq32(u32 address) // ARM SEQ
|
||||
{
|
||||
int addr = (address>>24)&15;
|
||||
int addr = (address >> 24) & 15;
|
||||
|
||||
if ((addr>=0x08) && (addr<=0x0D))
|
||||
{
|
||||
if (busPrefetchCount&0x1)
|
||||
{
|
||||
if (busPrefetchCount&0x2)
|
||||
{
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
|
||||
return memoryWaitSeq[addr];
|
||||
}
|
||||
else
|
||||
if (busPrefetchCount>0xFF)
|
||||
{
|
||||
busPrefetchCount=0;
|
||||
return memoryWait32[addr];
|
||||
}
|
||||
else
|
||||
return memoryWaitSeq32[addr];
|
||||
}
|
||||
else
|
||||
{
|
||||
return memoryWaitSeq32[addr];
|
||||
}
|
||||
if ((addr >= 0x08) && (addr <= 0x0D)) {
|
||||
if (busPrefetchCount & 0x1) {
|
||||
if (busPrefetchCount & 0x2) {
|
||||
busPrefetchCount = ((busPrefetchCount & 0xFF) >> 2) |
|
||||
(busPrefetchCount & 0xFFFFFF00);
|
||||
return 0;
|
||||
}
|
||||
busPrefetchCount =
|
||||
((busPrefetchCount & 0xFF) >> 1) | (busPrefetchCount & 0xFFFFFF00);
|
||||
return memoryWaitSeq[addr];
|
||||
} else if (busPrefetchCount > 0xFF) {
|
||||
busPrefetchCount = 0;
|
||||
return memoryWait32[addr];
|
||||
} else
|
||||
return memoryWaitSeq32[addr];
|
||||
} else {
|
||||
return memoryWaitSeq32[addr];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Emulates the Cheat System (m) code
|
||||
inline void cpuMasterCodeCheck()
|
||||
{
|
||||
if((mastercode) && (mastercode == armNextPC))
|
||||
{
|
||||
u32 joy = 0;
|
||||
if(systemReadJoypads())
|
||||
joy = systemReadJoypad(-1);
|
||||
u32 ext = (joy >> 10);
|
||||
cpuTotalTicks += cheatsCheckKeys(P1^0x3FF, ext);
|
||||
}
|
||||
if ((mastercode) && (mastercode == armNextPC)) {
|
||||
u32 joy = 0;
|
||||
if (systemReadJoypads())
|
||||
joy = systemReadJoypad(-1);
|
||||
u32 ext = (joy >> 10);
|
||||
cpuTotalTicks += cheatsCheckKeys(P1 ^ 0x3FF, ext);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GBACPU_H
|
||||
|
|
1329
src/gba/GBAinline.h
1329
src/gba/GBAinline.h
File diff suppressed because it is too large
Load Diff
|
@ -4,17 +4,17 @@
|
|||
#include "../common/Types.h"
|
||||
#include "GBA.h"
|
||||
|
||||
#define VERBOSE_SWI 1
|
||||
#define VERBOSE_UNALIGNED_MEMORY 2
|
||||
#define VERBOSE_ILLEGAL_WRITE 4
|
||||
#define VERBOSE_ILLEGAL_READ 8
|
||||
#define VERBOSE_DMA0 16
|
||||
#define VERBOSE_DMA1 32
|
||||
#define VERBOSE_DMA2 64
|
||||
#define VERBOSE_DMA3 128
|
||||
#define VERBOSE_UNDEFINED 256
|
||||
#define VERBOSE_AGBPRINT 512
|
||||
#define VERBOSE_SOUNDOUTPUT 1024
|
||||
#define VERBOSE_SWI 1
|
||||
#define VERBOSE_UNALIGNED_MEMORY 2
|
||||
#define VERBOSE_ILLEGAL_WRITE 4
|
||||
#define VERBOSE_ILLEGAL_READ 8
|
||||
#define VERBOSE_DMA0 16
|
||||
#define VERBOSE_DMA1 32
|
||||
#define VERBOSE_DMA2 64
|
||||
#define VERBOSE_DMA3 128
|
||||
#define VERBOSE_UNDEFINED 256
|
||||
#define VERBOSE_AGBPRINT 512
|
||||
#define VERBOSE_SOUNDOUTPUT 1024
|
||||
|
||||
extern reg_pair reg[45];
|
||||
extern bool ioReadable[0x400];
|
||||
|
|
|
@ -15,7 +15,7 @@ bool soundInit();
|
|||
void soundSetThrottle(unsigned short throttle);
|
||||
|
||||
// Manages sound volume, where 1.0 is normal
|
||||
void soundSetVolume( float );
|
||||
void soundSetVolume(float);
|
||||
float soundGetVolume();
|
||||
|
||||
// Manages muting bitmask. The bits control the following channels:
|
||||
|
@ -25,8 +25,8 @@ float soundGetVolume();
|
|||
// 0x008 Noise
|
||||
// 0x100 PCM 1
|
||||
// 0x200 PCM 2
|
||||
void soundSetEnable( int mask );
|
||||
int soundGetEnable();
|
||||
void soundSetEnable(int mask);
|
||||
int soundGetEnable();
|
||||
|
||||
// Pauses/resumes system sound output
|
||||
void soundPause();
|
||||
|
@ -45,7 +45,6 @@ void soundSetSampleRate(long sampleRate);
|
|||
extern bool soundInterpolation; // 1 if PCM should have low-pass filtering
|
||||
extern float soundFiltering; // 0.0 = none, 1.0 = max
|
||||
|
||||
|
||||
//// GBA sound emulation
|
||||
|
||||
// GBA sound registers
|
||||
|
@ -59,31 +58,31 @@ extern float soundFiltering; // 0.0 = none, 1.0 = max
|
|||
void soundReset();
|
||||
|
||||
// Emulates write to sound hardware
|
||||
void soundEvent( u32 addr, u8 data );
|
||||
void soundEvent( u32 addr, u16 data ); // TODO: error-prone to overload like this
|
||||
void soundEvent(u32 addr, u8 data);
|
||||
void soundEvent(u32 addr, u16 data); // TODO: error-prone to overload like this
|
||||
|
||||
// Notifies emulator that a timer has overflowed
|
||||
void soundTimerOverflow( int which );
|
||||
void soundTimerOverflow(int which);
|
||||
|
||||
// Notifies emulator that PCM rate may have changed
|
||||
void interp_rate();
|
||||
|
||||
// Notifies emulator that SOUND_CLOCK_TICKS clocks have passed
|
||||
void psoundTickfn();
|
||||
extern int SOUND_CLOCK_TICKS; // Number of 16.8 MHz clocks between calls to soundTick()
|
||||
extern int soundTicks; // Number of 16.8 MHz clocks until soundTick() will be called
|
||||
extern int SOUND_CLOCK_TICKS; // Number of 16.8 MHz clocks between calls to soundTick()
|
||||
extern int soundTicks; // Number of 16.8 MHz clocks until soundTick() will be called
|
||||
|
||||
// Saves/loads emulator state
|
||||
#ifdef __LIBRETRO__
|
||||
void soundSaveGame( u8 *& );
|
||||
void soundReadGame(const u8*& in, int version );
|
||||
void soundSaveGame(u8 *&);
|
||||
void soundReadGame(const u8 *&in, int version);
|
||||
#else
|
||||
void soundSaveGame( gzFile );
|
||||
void soundReadGame( gzFile, int version );
|
||||
void soundSaveGame(gzFile);
|
||||
void soundReadGame(gzFile, int version);
|
||||
#endif
|
||||
|
||||
class Multi_Buffer;
|
||||
|
||||
void flush_samples(Multi_Buffer * buffer);
|
||||
void flush_samples(Multi_Buffer *buffer);
|
||||
|
||||
#endif // SOUND_H
|
||||
|
|
334
src/gba/elf.h
334
src/gba/elf.h
|
@ -1,256 +1,252 @@
|
|||
#ifndef ELF_H
|
||||
#define ELF_H
|
||||
|
||||
enum LocationType {
|
||||
LOCATION_register,
|
||||
LOCATION_memory,
|
||||
LOCATION_value
|
||||
};
|
||||
enum LocationType { LOCATION_register, LOCATION_memory, LOCATION_value };
|
||||
|
||||
#define DW_ATE_boolean 0x02
|
||||
#define DW_ATE_signed 0x05
|
||||
#define DW_ATE_unsigned 0x07
|
||||
#define DW_ATE_boolean 0x02
|
||||
#define DW_ATE_signed 0x05
|
||||
#define DW_ATE_unsigned 0x07
|
||||
#define DW_ATE_unsigned_char 0x08
|
||||
|
||||
struct ELFHeader {
|
||||
u32 magic;
|
||||
u8 clazz;
|
||||
u8 data;
|
||||
u8 version;
|
||||
u8 pad[9];
|
||||
u16 e_type;
|
||||
u16 e_machine;
|
||||
u32 e_version;
|
||||
u32 e_entry;
|
||||
u32 e_phoff;
|
||||
u32 e_shoff;
|
||||
u32 e_flags;
|
||||
u16 e_ehsize;
|
||||
u16 e_phentsize;
|
||||
u16 e_phnum;
|
||||
u16 e_shentsize;
|
||||
u16 e_shnum;
|
||||
u16 e_shstrndx;
|
||||
u32 magic;
|
||||
u8 clazz;
|
||||
u8 data;
|
||||
u8 version;
|
||||
u8 pad[9];
|
||||
u16 e_type;
|
||||
u16 e_machine;
|
||||
u32 e_version;
|
||||
u32 e_entry;
|
||||
u32 e_phoff;
|
||||
u32 e_shoff;
|
||||
u32 e_flags;
|
||||
u16 e_ehsize;
|
||||
u16 e_phentsize;
|
||||
u16 e_phnum;
|
||||
u16 e_shentsize;
|
||||
u16 e_shnum;
|
||||
u16 e_shstrndx;
|
||||
};
|
||||
|
||||
struct ELFProgramHeader {
|
||||
u32 type;
|
||||
u32 offset;
|
||||
u32 vaddr;
|
||||
u32 paddr;
|
||||
u32 filesz;
|
||||
u32 memsz;
|
||||
u32 flags;
|
||||
u32 align;
|
||||
u32 type;
|
||||
u32 offset;
|
||||
u32 vaddr;
|
||||
u32 paddr;
|
||||
u32 filesz;
|
||||
u32 memsz;
|
||||
u32 flags;
|
||||
u32 align;
|
||||
};
|
||||
|
||||
struct ELFSectionHeader {
|
||||
u32 name;
|
||||
u32 type;
|
||||
u32 flags;
|
||||
u32 addr;
|
||||
u32 offset;
|
||||
u32 size;
|
||||
u32 link;
|
||||
u32 info;
|
||||
u32 addralign;
|
||||
u32 entsize;
|
||||
u32 name;
|
||||
u32 type;
|
||||
u32 flags;
|
||||
u32 addr;
|
||||
u32 offset;
|
||||
u32 size;
|
||||
u32 link;
|
||||
u32 info;
|
||||
u32 addralign;
|
||||
u32 entsize;
|
||||
};
|
||||
|
||||
struct ELFSymbol {
|
||||
u32 name;
|
||||
u32 value;
|
||||
u32 size;
|
||||
u8 info;
|
||||
u8 other;
|
||||
u16 shndx;
|
||||
u32 name;
|
||||
u32 value;
|
||||
u32 size;
|
||||
u8 info;
|
||||
u8 other;
|
||||
u16 shndx;
|
||||
};
|
||||
|
||||
struct ELFBlock {
|
||||
int length;
|
||||
u8 *data;
|
||||
int length;
|
||||
u8 *data;
|
||||
};
|
||||
|
||||
struct ELFAttr {
|
||||
u32 name;
|
||||
u32 form;
|
||||
union {
|
||||
u32 value;
|
||||
char *string;
|
||||
u8 *data;
|
||||
bool flag;
|
||||
ELFBlock *block;
|
||||
};
|
||||
u32 name;
|
||||
u32 form;
|
||||
union {
|
||||
u32 value;
|
||||
char *string;
|
||||
u8 *data;
|
||||
bool flag;
|
||||
ELFBlock *block;
|
||||
};
|
||||
};
|
||||
|
||||
struct ELFAbbrev {
|
||||
u32 number;
|
||||
u32 tag;
|
||||
bool hasChildren;
|
||||
int numAttrs;
|
||||
ELFAttr *attrs;
|
||||
ELFAbbrev *next;
|
||||
u32 number;
|
||||
u32 tag;
|
||||
bool hasChildren;
|
||||
int numAttrs;
|
||||
ELFAttr *attrs;
|
||||
ELFAbbrev *next;
|
||||
};
|
||||
|
||||
enum TypeEnum {
|
||||
TYPE_base,
|
||||
TYPE_pointer,
|
||||
TYPE_function,
|
||||
TYPE_void,
|
||||
TYPE_array,
|
||||
TYPE_struct,
|
||||
TYPE_reference,
|
||||
TYPE_enum,
|
||||
TYPE_union
|
||||
TYPE_base,
|
||||
TYPE_pointer,
|
||||
TYPE_function,
|
||||
TYPE_void,
|
||||
TYPE_array,
|
||||
TYPE_struct,
|
||||
TYPE_reference,
|
||||
TYPE_enum,
|
||||
TYPE_union
|
||||
};
|
||||
|
||||
struct Type;
|
||||
struct Object;
|
||||
|
||||
struct FunctionType {
|
||||
Type *returnType;
|
||||
Object *args;
|
||||
Type *returnType;
|
||||
Object *args;
|
||||
};
|
||||
|
||||
struct Member {
|
||||
char *name;
|
||||
Type *type;
|
||||
int bitSize;
|
||||
int bitOffset;
|
||||
int byteSize;
|
||||
ELFBlock *location;
|
||||
char *name;
|
||||
Type *type;
|
||||
int bitSize;
|
||||
int bitOffset;
|
||||
int byteSize;
|
||||
ELFBlock *location;
|
||||
};
|
||||
|
||||
struct Struct {
|
||||
int memberCount;
|
||||
Member *members;
|
||||
int memberCount;
|
||||
Member *members;
|
||||
};
|
||||
|
||||
struct Array {
|
||||
Type *type;
|
||||
int maxBounds;
|
||||
int *bounds;
|
||||
Type *type;
|
||||
int maxBounds;
|
||||
int *bounds;
|
||||
};
|
||||
|
||||
struct EnumMember {
|
||||
char *name;
|
||||
u32 value;
|
||||
char *name;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
struct Enum {
|
||||
int count;
|
||||
EnumMember *members;
|
||||
int count;
|
||||
EnumMember *members;
|
||||
};
|
||||
|
||||
struct Type {
|
||||
u32 offset;
|
||||
TypeEnum type;
|
||||
const char *name;
|
||||
int encoding;
|
||||
int size;
|
||||
int bitSize;
|
||||
union {
|
||||
Type *pointer;
|
||||
FunctionType *function;
|
||||
Array *array;
|
||||
Struct *structure;
|
||||
Enum *enumeration;
|
||||
};
|
||||
Type *next;
|
||||
u32 offset;
|
||||
TypeEnum type;
|
||||
const char *name;
|
||||
int encoding;
|
||||
int size;
|
||||
int bitSize;
|
||||
union {
|
||||
Type *pointer;
|
||||
FunctionType *function;
|
||||
Array *array;
|
||||
Struct *structure;
|
||||
Enum *enumeration;
|
||||
};
|
||||
Type *next;
|
||||
};
|
||||
|
||||
struct Object {
|
||||
char *name;
|
||||
int file;
|
||||
int line;
|
||||
bool external;
|
||||
Type *type;
|
||||
ELFBlock *location;
|
||||
u32 startScope;
|
||||
u32 endScope;
|
||||
Object *next;
|
||||
char *name;
|
||||
int file;
|
||||
int line;
|
||||
bool external;
|
||||
Type *type;
|
||||
ELFBlock *location;
|
||||
u32 startScope;
|
||||
u32 endScope;
|
||||
Object *next;
|
||||
};
|
||||
|
||||
struct Function {
|
||||
char *name;
|
||||
u32 lowPC;
|
||||
u32 highPC;
|
||||
int file;
|
||||
int line;
|
||||
bool external;
|
||||
Type *returnType;
|
||||
Object *parameters;
|
||||
Object *variables;
|
||||
ELFBlock *frameBase;
|
||||
Function *next;
|
||||
char *name;
|
||||
u32 lowPC;
|
||||
u32 highPC;
|
||||
int file;
|
||||
int line;
|
||||
bool external;
|
||||
Type *returnType;
|
||||
Object *parameters;
|
||||
Object *variables;
|
||||
ELFBlock *frameBase;
|
||||
Function *next;
|
||||
};
|
||||
|
||||
struct LineInfoItem {
|
||||
u32 address;
|
||||
char *file;
|
||||
int line;
|
||||
u32 address;
|
||||
char *file;
|
||||
int line;
|
||||
};
|
||||
|
||||
struct LineInfo {
|
||||
int fileCount;
|
||||
char **files;
|
||||
int number;
|
||||
LineInfoItem *lines;
|
||||
int fileCount;
|
||||
char **files;
|
||||
int number;
|
||||
LineInfoItem *lines;
|
||||
};
|
||||
|
||||
struct ARange {
|
||||
u32 lowPC;
|
||||
u32 highPC;
|
||||
u32 lowPC;
|
||||
u32 highPC;
|
||||
};
|
||||
|
||||
struct ARanges {
|
||||
u32 offset;
|
||||
int count;
|
||||
ARange *ranges;
|
||||
u32 offset;
|
||||
int count;
|
||||
ARange *ranges;
|
||||
};
|
||||
|
||||
struct CompileUnit {
|
||||
u32 length;
|
||||
u8 *top;
|
||||
u32 offset;
|
||||
ELFAbbrev **abbrevs;
|
||||
ARanges *ranges;
|
||||
char *name;
|
||||
char *compdir;
|
||||
u32 lowPC;
|
||||
u32 highPC;
|
||||
bool hasLineInfo;
|
||||
u32 lineInfo;
|
||||
LineInfo *lineInfoTable;
|
||||
Function *functions;
|
||||
Function *lastFunction;
|
||||
Object *variables;
|
||||
Type *types;
|
||||
CompileUnit *next;
|
||||
u32 length;
|
||||
u8 *top;
|
||||
u32 offset;
|
||||
ELFAbbrev **abbrevs;
|
||||
ARanges *ranges;
|
||||
char *name;
|
||||
char *compdir;
|
||||
u32 lowPC;
|
||||
u32 highPC;
|
||||
bool hasLineInfo;
|
||||
u32 lineInfo;
|
||||
LineInfo *lineInfoTable;
|
||||
Function *functions;
|
||||
Function *lastFunction;
|
||||
Object *variables;
|
||||
Type *types;
|
||||
CompileUnit *next;
|
||||
};
|
||||
|
||||
struct DebugInfo {
|
||||
u8 *debugfile;
|
||||
u8 *abbrevdata;
|
||||
u8 *debugdata;
|
||||
u8 *infodata;
|
||||
int numRanges;
|
||||
ARanges *ranges;
|
||||
u8 *debugfile;
|
||||
u8 *abbrevdata;
|
||||
u8 *debugdata;
|
||||
u8 *infodata;
|
||||
int numRanges;
|
||||
ARanges *ranges;
|
||||
};
|
||||
|
||||
struct Symbol {
|
||||
const char *name;
|
||||
int type;
|
||||
int binding;
|
||||
u32 address;
|
||||
u32 value;
|
||||
u32 size;
|
||||
const char *name;
|
||||
int type;
|
||||
int binding;
|
||||
u32 address;
|
||||
u32 value;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
extern u32 elfReadLEB128(u8 *, int *);
|
||||
extern s32 elfReadSignedLEB128(u8 *, int *);
|
||||
extern bool elfRead(const char *, int &, FILE *f);
|
||||
extern bool elfGetSymbolAddress(const char *,u32 *, u32 *, int *);
|
||||
extern bool elfGetSymbolAddress(const char *, u32 *, u32 *, int *);
|
||||
extern const char *elfGetAddressSymbol(u32);
|
||||
extern const char *elfGetSymbol(int, u32 *, u32 *, int *);
|
||||
extern void elfCleanUp();
|
||||
|
|
|
@ -3,8 +3,7 @@ extern char filebuffer[];
|
|||
|
||||
int OpenDotCodeFile(void);
|
||||
int CheckEReaderRegion(void);
|
||||
int LoadDotCodeData(int size, u32* DCdata, unsigned long MEM1, unsigned long MEM2);
|
||||
int LoadDotCodeData(int size, u32 *DCdata, unsigned long MEM1, unsigned long MEM2);
|
||||
void EReaderWriteMemory(u32 address, u32 value);
|
||||
|
||||
void BIOS_EReader_ScanCard(int swi_num);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "../System.h"
|
||||
|
||||
void gbafilter_pal(u16 * buf, int count);
|
||||
void gbafilter_pal32(u32 * buf, int count);
|
||||
void gbafilter_pad(u8 * buf, int count);
|
||||
void gbafilter_pal(u16 *buf, int count);
|
||||
void gbafilter_pal32(u32 *buf, int count);
|
||||
void gbafilter_pad(u8 *buf, int count);
|
||||
|
|
|
@ -4,40 +4,33 @@
|
|||
#include "../common/Types.h"
|
||||
#include "GBA.h"
|
||||
|
||||
#define BitSet(array, bit) \
|
||||
((u8 *)(array))[(bit) >> 3] |= (1 << ((bit) & 7))
|
||||
#define BitSet(array, bit) ((u8 *)(array))[(bit) >> 3] |= (1 << ((bit)&7))
|
||||
|
||||
#define BitClear(array, bit) \
|
||||
((u8 *)(array))[(bit) >> 3] &= ~(1 << ((bit) & 7))
|
||||
#define BitClear(array, bit) ((u8 *)(array))[(bit) >> 3] &= ~(1 << ((bit)&7))
|
||||
|
||||
#define BitGet(array, bit) \
|
||||
((u8)((array)[(bit) >> 3]) & (u8)(1 <<((bit) & 7)))
|
||||
#define BitGet(array, bit) ((u8)((array)[(bit) >> 3]) & (u8)(1 << ((bit)&7)))
|
||||
|
||||
#define BreakSet(array, addr, flag) \
|
||||
((u8 *)(array))[(addr)>>1] |= ((addr&1) ? (flag<<4) : (flag&0xf))
|
||||
#define BreakSet(array, addr, flag) \
|
||||
((u8 *)(array))[(addr) >> 1] |= ((addr & 1) ? (flag << 4) : (flag & 0xf))
|
||||
|
||||
#define BreakClear(array, addr, flag) \
|
||||
((u8 *)(array))[(addr)>>1] &= ~((addr&1) ? (flag<<4) : (flag&0xf))
|
||||
#define BreakClear(array, addr, flag) \
|
||||
((u8 *)(array))[(addr) >> 1] &= ~((addr & 1) ? (flag << 4) : (flag & 0xf))
|
||||
|
||||
//check
|
||||
#define BreakThumbCheck(array, addr) \
|
||||
((u8 *)(array))[(addr)>>1] &((addr&1) ? 0x80 : 0x8 )
|
||||
// check
|
||||
#define BreakThumbCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x80 : 0x8)
|
||||
|
||||
#define BreakARMCheck(array, addr) \
|
||||
((u8 *)(array))[(addr)>>1] & ((addr&1) ? 0x40 : 0x4 )
|
||||
#define BreakARMCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x40 : 0x4)
|
||||
|
||||
#define BreakReadCheck(array, addr) \
|
||||
((u8 *)(array))[(addr)>>1] & ((addr&1) ? 0x20 : 0x2 )
|
||||
#define BreakReadCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x20 : 0x2)
|
||||
|
||||
#define BreakWriteCheck(array, addr) \
|
||||
((u8 *)(array))[(addr)>>1] & ((addr&1) ? 0x10 : 0x1 )
|
||||
#define BreakWriteCheck(array, addr) ((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? 0x10 : 0x1)
|
||||
|
||||
#define BreakCheck(array, addr, flag) \
|
||||
((u8 *)(array))[(addr)>>1] & ((addr&1) ? (flag<<4) : (flag&0xf))
|
||||
#define BreakCheck(array, addr, flag) \
|
||||
((u8 *)(array))[(addr) >> 1] & ((addr & 1) ? (flag << 4) : (flag & 0xf))
|
||||
|
||||
extern bool debugger;
|
||||
|
||||
extern bool dexp_eval(char *, u32*);
|
||||
extern bool dexp_eval(char *, u32 *);
|
||||
extern void dexp_setVar(char *, u32);
|
||||
extern void dexp_listVars();
|
||||
extern void dexp_saveVars(char *);
|
||||
|
@ -50,26 +43,26 @@ bool debuggerBreakOnWrite(u32 address, u32 value, int size);
|
|||
void debuggerBreakOnWrite(u32 address, u32 oldvalue, u32 value, int size, int t);
|
||||
bool debuggerBreakOnRead(u32 address, int size);
|
||||
|
||||
struct regBreak{
|
||||
//u8 regNum; /No longer needed
|
||||
// bit 0 = equal
|
||||
// bit 1 = greater
|
||||
// bit 2 = smaller
|
||||
// bit 3 = signed
|
||||
u8 flags;
|
||||
u32 intVal;
|
||||
struct regBreak* next;
|
||||
struct regBreak {
|
||||
// u8 regNum; /No longer needed
|
||||
// bit 0 = equal
|
||||
// bit 1 = greater
|
||||
// bit 2 = smaller
|
||||
// bit 3 = signed
|
||||
u8 flags;
|
||||
u32 intVal;
|
||||
struct regBreak *next;
|
||||
};
|
||||
extern u8 lowRegBreakCounter[4]; //(r0-r3)
|
||||
extern u8 medRegBreakCounter[4]; //(r4-r7)
|
||||
extern u8 highRegBreakCounter[4]; //(r8-r11)
|
||||
extern u8 lowRegBreakCounter[4]; //(r0-r3)
|
||||
extern u8 medRegBreakCounter[4]; //(r4-r7)
|
||||
extern u8 highRegBreakCounter[4]; //(r8-r11)
|
||||
extern u8 statusRegBreakCounter[4]; //(r12-r15)
|
||||
|
||||
extern bool enableRegBreak;
|
||||
extern regBreak* breakRegList[16];
|
||||
extern regBreak *breakRegList[16];
|
||||
extern void breakReg_check(int i);
|
||||
|
||||
struct regBreak* getFromBreakRegList(u8 regnum, int location);
|
||||
struct regBreak *getFromBreakRegList(u8 regnum, int location);
|
||||
|
||||
void clearBreakRegList();
|
||||
void clearParticularRegListBreaks(int reg);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue