updated standards to webkit standard

This commit is contained in:
Zach Bacon 2016-07-08 19:59:29 -04:00
parent 87bc6ca10a
commit 5bf44d19be
No known key found for this signature in database
GPG Key ID: 7D110798AFE84B3A
218 changed files with 38228 additions and 39733 deletions

View File

@ -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
...

View File

@ -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:

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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
}

View File

@ -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

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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
}

File diff suppressed because it is too large Load Diff

View File

@ -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
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -27,7 +27,7 @@
// Use standard config.h if present
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#endif

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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__

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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];

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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];

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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;
};

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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];

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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