dev_4VirtualNes #24

Merged
sin365 merged 2 commits from dev_4VirtualNes into master 2024-08-05 18:01:45 +08:00
1188 changed files with 130121 additions and 2426 deletions
Showing only changes of commit 8b39e9aa02 - Show all commits

View File

@ -91,7 +91,9 @@ Mapper支持越多通俗讲就是支持更多卡带。
我们的项目也必须支持上! 咱们也同步要进行一个补充
追加了特殊的失传Mapper 162,163,175,176,178,192,195,199,216 (from https://github.com/yamanyandakure/VirtuaNES097)
追加了特殊的失传Mapper 35,111,162,163,175,176,178,192,195,199,216 (from https://github.com/yamanyandakure/VirtuaNES097)
后续补充二次,修正 Mapper199 参照叶枫VirtuaNESex_src(20191105)

View File

@ -0,0 +1,203 @@
/* 7z.h -- 7z interface
2010-03-11 : Igor Pavlov : Public domain */
#ifndef __7Z_H
#define __7Z_H
#include "7zBuf.h"
EXTERN_C_BEGIN
#define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6
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
};
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;
} CSzBindPair;
typedef struct
{
CSzCoderInfo *Coders;
CSzBindPair *BindPairs;
UInt32 *PackStreams;
UInt64 *UnpackSizes;
UInt32 NumCoders;
UInt32 NumBindPairs;
UInt32 NumPackStreams;
int UnpackCRCDefined;
UInt32 UnpackCRC;
UInt32 NumUnpackStreams;
} CSzFolder;
void SzFolder_Init(CSzFolder *p);
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
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);
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;
} CSzFileItem;
void SzFile_Init(CSzFileItem *p);
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
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*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;
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);
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
/*
if dest == NULL, the return value specifies the required size of the buffer,
in 16-bit characters, including the null-terminating character.
if dest != NULL, the return value specifies the number of 16-bit characters that
are written to the dest, including the null-terminating character. */
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);
/*
SzArEx_Open Errors:
SZ_ERROR_NO_ARCHIVE
SZ_ERROR_ARCHIVE
SZ_ERROR_UNSUPPORTED
SZ_ERROR_MEM
SZ_ERROR_CRC
SZ_ERROR_INPUT_EOF
SZ_ERROR_FAIL
*/
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
EXTERN_C_END
#endif

View File

@ -0,0 +1,76 @@
/* 7zAlloc.c -- Allocation functions
2010-10-29 : Igor Pavlov : Public domain */
#include "7zAlloc.h"
/* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdio.h>
int g_allocCount = 0;
int g_allocCountTemp = 0;
#endif
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);
}
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);
}
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);
}
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);
}

View File

@ -0,0 +1,15 @@
/* 7zAlloc.h -- Allocation functions
2010-10-29 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H
#include <stdlib.h>
void *SzAlloc(void *p, size_t size);
void SzFree(void *p, void *address);
void *SzAllocTemp(void *p, size_t size);
void SzFreeTemp(void *p, void *address);
#endif

View File

@ -0,0 +1,36 @@
/* 7zBuf.c -- Byte Buffer
2008-03-28
Igor Pavlov
Public domain */
#include "7zBuf.h"
void Buf_Init(CBuf *p)
{
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;
}
void Buf_Free(CBuf *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->data);
p->data = 0;
p->size = 0;
}

View File

@ -0,0 +1,39 @@
/* 7zBuf.h -- Byte Buffer
2009-02-07 : Igor Pavlov : Public domain */
#ifndef __7Z_BUF_H
#define __7Z_BUF_H
#include "Types.h"
#ifdef __cplusplus
extern "C" {
#endif
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;
} CDynBuf;
void DynBuf_Construct(CDynBuf *p);
void DynBuf_SeekToBeg(CDynBuf *p);
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,74 @@
/* 7zCrc.c -- CRC32 calculation
2009-11-23 : Igor Pavlov : Public domain */
#include "7zCrc.h"
#include "CpuArch.h"
#define kCrcPoly 0xEDB88320
#ifdef MY_CPU_LE
#define CRC_NUM_TABLES 8
#else
#define CRC_NUM_TABLES 1
#endif
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];
#if CRC_NUM_TABLES == 1
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
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;
}
#else
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
{
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;
}
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
}

View File

@ -0,0 +1,25 @@
/* 7zCrc.h -- CRC32 calculation
2009-11-21 : Igor Pavlov : Public domain */
#ifndef __7Z_CRC_H
#define __7Z_CRC_H
#include "Types.h"
EXTERN_C_BEGIN
extern UInt32 g_CrcTable[];
/* Call CrcGenerateTable one time before other CRC functions */
void MY_FAST_CALL CrcGenerateTable(void);
#define CRC_INIT_VAL 0xFFFFFFFF
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
EXTERN_C_END
#endif

View File

@ -0,0 +1,34 @@
/* 7zCrcOpt.c -- CRC32 calculation : optimized version
2009-11-23 : Igor Pavlov : Public domain */
#include "CpuArch.h"
#ifdef MY_CPU_LE
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
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;
}
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
return CrcUpdateT4(v, data, size, table);
}
#endif

View File

@ -0,0 +1,470 @@
/* 7zDec.c -- Decoding from 7z folder
2010-11-02 : Igor Pavlov : Public domain */
#include <string.h>
/* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h"
#include "Bcj2.h"
#include "Bra.h"
#include "CpuArch.h"
#include "LzmaDec.h"
#include "Lzma2Dec.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_SPARC 0x03030805
#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;
} 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;
}
static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
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;
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;
}
#endif
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
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);
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;
}
}
LzmaDec_FreeProbs(&state, allocMain);
return res;
}
static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
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);
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;
}
}
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;
}
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;
}
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);
}
#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:
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;
}
#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[])
{
UInt32 ci;
SizeT tempSizes[3] = { 0, 0, 0};
SizeT tempSize3 = 0;
Byte *tempBuf3 = 0;
RINOK(CheckSupportedFolder(folder));
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;
}
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;
}
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;
}

View File

@ -0,0 +1,284 @@
/* 7zFile.c -- File IO
2009-11-24 : Igor Pavlov : Public domain */
#include "7zFile.h"
#ifndef USE_WINDOWS_FILE
#ifndef UNDER_CE
#include <errno.h>
#endif
#else
/*
ReadFile and WriteFile functions in Windows have BUG:
If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
(Insufficient system resources exist to complete the requested service).
Probably in some version of Windows there are problems with other sizes:
for 32 MB (maybe also for 16 MB).
And message can be "Network connection was lost"
*/
#define kChunkSizeMax (1 << 22)
#endif
void File_Construct(CSzFile *p)
{
#ifdef USE_WINDOWS_FILE
p->handle = INVALID_HANDLE_VALUE;
#else
p->file = NULL;
#endif
}
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
static WRes File_Open(CSzFile *p, const char *name, int writeMode)
{
#ifdef USE_WINDOWS_FILE
p->handle = CreateFileA(name,
writeMode ? GENERIC_WRITE : GENERIC_READ,
FILE_SHARE_READ, NULL,
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
#else
p->file = fopen(name, writeMode ? "wb+" : "rb");
return (p->file != 0) ? 0 :
#ifdef UNDER_CE
2; /* ENOENT */
#else
errno;
#endif
#endif
}
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
#endif
#ifdef USE_WINDOWS_FILE
static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
{
p->handle = CreateFileW(name,
writeMode ? GENERIC_WRITE : GENERIC_READ,
FILE_SHARE_READ, NULL,
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
}
WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
#endif
WRes File_Close(CSzFile *p)
{
#ifdef USE_WINDOWS_FILE
if (p->handle != INVALID_HANDLE_VALUE)
{
if (!CloseHandle(p->handle))
return GetLastError();
p->handle = INVALID_HANDLE_VALUE;
}
#else
if (p->file != NULL)
{
int res = fclose(p->file);
if (res != 0)
return res;
p->file = NULL;
}
#endif
return 0;
}
WRes File_Read(CSzFile *p, void *data, size_t *size)
{
size_t originalSize = *size;
if (originalSize == 0)
return 0;
#ifdef USE_WINDOWS_FILE
*size = 0;
do
{
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
DWORD processed = 0;
BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
data = (void *)((Byte *)data + processed);
originalSize -= processed;
*size += processed;
if (!res)
return GetLastError();
if (processed == 0)
break;
}
while (originalSize > 0);
return 0;
#else
*size = fread(data, 1, originalSize, p->file);
if (*size == originalSize)
return 0;
return ferror(p->file);
#endif
}
WRes File_Write(CSzFile *p, const void *data, size_t *size)
{
size_t originalSize = *size;
if (originalSize == 0)
return 0;
#ifdef USE_WINDOWS_FILE
*size = 0;
do
{
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
DWORD processed = 0;
BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
data = (void *)((Byte *)data + processed);
originalSize -= processed;
*size += processed;
if (!res)
return GetLastError();
if (processed == 0)
break;
}
while (originalSize > 0);
return 0;
#else
*size = fwrite(data, 1, originalSize, p->file);
if (*size == originalSize)
return 0;
return ferror(p->file);
#endif
}
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
{
#ifdef USE_WINDOWS_FILE
LARGE_INTEGER value;
DWORD moveMethod;
value.LowPart = (DWORD)*pos;
value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
switch (origin)
{
case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
case SZ_SEEK_END: moveMethod = FILE_END; break;
default: return ERROR_INVALID_PARAMETER;
}
value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
if (value.LowPart == 0xFFFFFFFF)
{
WRes res = GetLastError();
if (res != NO_ERROR)
return res;
}
*pos = ((Int64)value.HighPart << 32) | value.LowPart;
return 0;
#else
int moveMethod;
int res;
switch (origin)
{
case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
case SZ_SEEK_END: moveMethod = SEEK_END; break;
default: return 1;
}
res = fseek(p->file, (long)*pos, moveMethod);
*pos = ftell(p->file);
return res;
#endif
}
WRes File_GetLength(CSzFile *p, UInt64 *length)
{
#ifdef USE_WINDOWS_FILE
DWORD sizeHigh;
DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
if (sizeLow == 0xFFFFFFFF)
{
DWORD res = GetLastError();
if (res != NO_ERROR)
return res;
}
*length = (((UInt64)sizeHigh) << 32) + sizeLow;
return 0;
#else
long pos = ftell(p->file);
int res = fseek(p->file, 0, SEEK_END);
*length = ftell(p->file);
fseek(p->file, pos, SEEK_SET);
return res;
#endif
}
/* ---------- FileSeqInStream ---------- */
static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
{
CFileSeqInStream *p = (CFileSeqInStream *)pp;
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
}
void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
{
p->s.Read = FileSeqInStream_Read;
}
/* ---------- FileInStream ---------- */
static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
{
CFileInStream *p = (CFileInStream *)pp;
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
}
static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
{
CFileInStream *p = (CFileInStream *)pp;
return File_Seek(&p->file, pos, origin);
}
void FileInStream_CreateVTable(CFileInStream *p)
{
p->s.Read = FileInStream_Read;
p->s.Seek = FileInStream_Seek;
}
/* ---------- FileOutStream ---------- */
static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
{
CFileOutStream *p = (CFileOutStream *)pp;
File_Write(&p->file, data, &size);
return size;
}
void FileOutStream_CreateVTable(CFileOutStream *p)
{
p->s.Write = FileOutStream_Write;
}

View File

@ -0,0 +1,83 @@
/* 7zFile.h -- File IO
2009-11-24 : Igor Pavlov : Public domain */
#ifndef __7Z_FILE_H
#define __7Z_FILE_H
#ifdef _WIN32
#define USE_WINDOWS_FILE
#endif
#ifdef USE_WINDOWS_FILE
#include <windows.h>
#else
#include <stdio.h>
#endif
#include "Types.h"
EXTERN_C_BEGIN
/* ---------- File ---------- */
typedef struct
{
#ifdef USE_WINDOWS_FILE
HANDLE handle;
#else
FILE *file;
#endif
} CSzFile;
void File_Construct(CSzFile *p);
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
WRes InFile_Open(CSzFile *p, const char *name);
WRes OutFile_Open(CSzFile *p, const char *name);
#endif
#ifdef USE_WINDOWS_FILE
WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
#endif
WRes File_Close(CSzFile *p);
/* reads max(*size, remain file's size) bytes */
WRes File_Read(CSzFile *p, void *data, size_t *size);
/* writes *size bytes */
WRes File_Write(CSzFile *p, const void *data, size_t *size);
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
WRes File_GetLength(CSzFile *p, UInt64 *length);
/* ---------- FileInStream ---------- */
typedef struct
{
ISeqInStream s;
CSzFile file;
} CFileSeqInStream;
void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
typedef struct
{
ISeekInStream s;
CSzFile file;
} CFileInStream;
void FileInStream_CreateVTable(CFileInStream *p);
typedef struct
{
ISeqOutStream s;
CSzFile file;
} CFileOutStream;
void FileOutStream_CreateVTable(CFileOutStream *p);
EXTERN_C_END
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,438 @@
/* 7zMain.c - Test application for 7z Decoder
2010-10-28 : Igor Pavlov : Public domain */
#include <stdio.h>
#include <string.h>
#include "7z/7z.h"
#include "7z/7zAlloc.h"
#include "7z/7zCrc.h"
#include "7z/7zFile.h"
#include "7z/7zVersion.h"
/*
#ifndef UNICODE
#define UNICODE
#endif
*/
#ifndef USE_WINDOWS_FILE
/* for mkdir */
#ifdef _WIN32
#include <direct.h>
#else
#include <sys/stat.h>
#include <errno.h>
#endif
#endif
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
static int Buf_EnsureSize(CBuf *dest, size_t size)
{
if (dest->size >= size)
return 1;
Buf_Free(dest, &g_Alloc);
return Buf_Create(dest, size, &g_Alloc);
}
#ifndef _WIN32
static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen)
{
size_t destPos = 0, srcPos = 0;
for (;;)
{
unsigned numAdds;
UInt32 value;
if (srcPos == srcLen)
{
*destLen = destPos;
return True;
}
value = src[srcPos++];
if (value < 0x80)
{
if (dest)
dest[destPos] = (char)value;
destPos++;
continue;
}
if (value >= 0xD800 && value < 0xE000)
{
UInt32 c2;
if (value >= 0xDC00 || srcPos == srcLen)
break;
c2 = src[srcPos++];
if (c2 < 0xDC00 || c2 >= 0xE000)
break;
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
}
for (numAdds = 1; numAdds < 5; numAdds++)
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
break;
if (dest)
dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
destPos++;
do
{
numAdds--;
if (dest)
dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
destPos++;
}
while (numAdds != 0);
}
*destLen = destPos;
return False;
}
static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
{
size_t destLen = 0;
Bool res;
Utf16_To_Utf8(NULL, &destLen, src, srcLen);
destLen += 1;
if (!Buf_EnsureSize(dest, destLen))
return SZ_ERROR_MEM;
res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen);
dest->data[destLen] = 0;
return res ? SZ_OK : SZ_ERROR_FAIL;
}
#endif
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
{
int len = 0;
for (len = 0; s[len] != '\0'; len++);
#ifdef _WIN32
{
int size = len * 3 + 100;
if (!Buf_EnsureSize(buf, size))
return SZ_ERROR_MEM;
{
char defaultChar = '_';
BOOL defUsed;
int numChars = WideCharToMultiByte(fileMode ?
(
#ifdef UNDER_CE
CP_ACP
#else
AreFileApisANSI() ? CP_ACP : CP_OEMCP
#endif
) : CP_OEMCP,
0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
if (numChars == 0 || numChars >= size)
return SZ_ERROR_FAIL;
buf->data[numChars] = 0;
return SZ_OK;
}
}
#else
fileMode = fileMode;
return Utf16_To_Utf8Buf(buf, s, len);
#endif
}
static WRes MyCreateDir(const UInt16 *name)
{
#ifdef USE_WINDOWS_FILE
return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
#else
CBuf buf;
WRes res;
Buf_Init(&buf);
RINOK(Utf16_To_Char(&buf, name, 1));
res =
#ifdef _WIN32
_mkdir((const char *)buf.data)
#else
mkdir((const char *)buf.data, 0777)
#endif
== 0 ? 0 : errno;
Buf_Free(&buf, &g_Alloc);
return res;
#endif
}
static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
{
#ifdef USE_WINDOWS_FILE
return OutFile_OpenW(p, name);
#else
CBuf buf;
WRes res;
Buf_Init(&buf);
RINOK(Utf16_To_Char(&buf, name, 1));
res = OutFile_Open(p, (const char *)buf.data);
Buf_Free(&buf, &g_Alloc);
return res;
#endif
}
static SRes PrintString(const UInt16 *s)
{
CBuf buf;
SRes res;
Buf_Init(&buf);
res = Utf16_To_Char(&buf, s, 0);
if (res == SZ_OK)
fputs((const char *)buf.data, stdout);
Buf_Free(&buf, &g_Alloc);
return res;
}
static void UInt64ToStr(UInt64 value, char *s)
{
char temp[32];
int pos = 0;
do
{
temp[pos++] = (char)('0' + (unsigned)(value % 10));
value /= 10;
}
while (value != 0);
do
*s++ = temp[--pos];
while (pos);
*s = '\0';
}
static char *UIntToStr(char *s, unsigned value, int numDigits)
{
char temp[16];
int pos = 0;
do
temp[pos++] = (char)('0' + (value % 10));
while (value /= 10);
for (numDigits -= pos; numDigits > 0; numDigits--)
*s++ = '0';
do
*s++ = temp[--pos];
while (pos);
*s = '\0';
return s;
}
#define PERIOD_4 (4 * 365 + 1)
#define PERIOD_100 (PERIOD_4 * 25 - 1)
#define PERIOD_400 (PERIOD_100 * 4 + 1)
static void ConvertFileTimeToString(const CNtfsFileTime *ft, char *s)
{
unsigned year, mon, day, hour, min, sec;
UInt64 v64 = (ft->Low | ((UInt64)ft->High << 32)) / 10000000;
Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
unsigned t;
UInt32 v;
sec = (unsigned)(v64 % 60); v64 /= 60;
min = (unsigned)(v64 % 60); v64 /= 60;
hour = (unsigned)(v64 % 24); v64 /= 24;
v = (UInt32)v64;
year = (unsigned)(1601 + v / PERIOD_400 * 400);
v %= PERIOD_400;
t = v / PERIOD_100; if (t == 4) t = 3; year += t * 100; v -= t * PERIOD_100;
t = v / PERIOD_4; if (t == 25) t = 24; year += t * 4; v -= t * PERIOD_4;
t = v / 365; if (t == 4) t = 3; year += t; v -= t * 365;
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
ms[1] = 29;
for (mon = 1; mon <= 12; mon++)
{
unsigned s = ms[mon - 1];
if (v < s)
break;
v -= s;
}
day = (unsigned)v + 1;
s = UIntToStr(s, year, 4); *s++ = '-';
s = UIntToStr(s, mon, 2); *s++ = '-';
s = UIntToStr(s, day, 2); *s++ = ' ';
s = UIntToStr(s, hour, 2); *s++ = ':';
s = UIntToStr(s, min, 2); *s++ = ':';
s = UIntToStr(s, sec, 2);
}
void PrintError(char *sz)
{
printf("\nERROR: %s\n", sz);
}
#ifdef USE_WINDOWS_FILE
#define kEmptyAttribChar '.'
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
{
s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar);
s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar);
s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar);
s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar);
s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar);
s[5] = '\0';
}
#else
static void GetAttribString(UInt32, Bool, char *s)
{
s[0] = '\0';
}
#endif
int SevenZipUnCompress( char *fname, unsigned char ** ppBuf,size_t * lpdwSize)
{
CFileInStream archiveStream;
CLookToRead lookStream;
CSzArEx db;
SRes res;
ISzAlloc allocImp;
ISzAlloc allocTempImp;
UInt16 *temp = NULL;
size_t tempSize = 0;
int bHasRomFile = 0;
int bExtractRomOK = 0;
//枚举文件找到NES或者UNF文件找不到直接返回
allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree;
allocTempImp.Alloc = SzAllocTemp;
allocTempImp.Free = SzFreeTemp;
if (InFile_Open(&archiveStream.file, fname))
{
return FALSE;
}
FileInStream_CreateVTable(&archiveStream);
LookToRead_CreateVTable(&lookStream, False);
lookStream.realStream = &archiveStream.s;
LookToRead_Init(&lookStream);
CrcGenerateTable();
SzArEx_Init(&db);
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
if (res == SZ_OK)
{
UInt32 i;
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
for (i = 0; i < db.db.NumFiles; i++)
{
size_t offset = 0;
size_t outSizeProcessed = 0;
const CSzFileItem *f = db.db.Files + i;
size_t len;
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
if (len > tempSize)
{
SzFree(NULL, temp);
tempSize = len;
temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
if (temp == 0)
{
res = SZ_ERROR_MEM;
break;
}
}
SzArEx_GetFileNameUtf16(&db, i, temp);
//获取文件信息
{
char attr[8];
GetAttribString(f->AttribDefined ? f->Attrib : 0, f->IsDir, attr);// f->IsDir 文件是否是目录
//UInt64ToStr(f->Size, s);//f->Size 文件大小
if(f->IsDir!=1)
{
//检测扩展名
if(len>5)
{
//"*.nes",
//"*.unf",
//"*.fds",
//"*.nsf",
if(wcsicmp(L".nes",&temp[len-5])==0)
{
bHasRomFile =1;
}
else if(wcsicmp(L".unf",&temp[len-5])==0)
{
bHasRomFile =1;
}
else if(wcsicmp(L".fds",&temp[len-5])==0)
{
bHasRomFile =1;
}
else if(wcsicmp(L".nsf",&temp[len-5])==0)
{
bHasRomFile =1;
}
}
//if( (f->Size>16000)&&(f->Size<10000000) )
//bHasRomFile =1;
}
if(bHasRomFile==0)
continue;
}
if (bHasRomFile)
{
res = SzArEx_Extract(&db, &lookStream.s, i,&blockIndex, ppBuf, lpdwSize,&offset, &outSizeProcessed,&allocImp, &allocTempImp);
if (res != SZ_OK)
continue;
else
{
bExtractRomOK = 1;
if(offset!=0)
{//重组
void *pRom = malloc(f->Size);
memcpy(pRom,*ppBuf+offset,f->Size);
*lpdwSize = f->Size;
free(*ppBuf);
*ppBuf = pRom;
}
}
}
if(bExtractRomOK)
break;
}//结束文件枚举循环
IAlloc_Free(&allocImp, outBuffer);
}
SzArEx_Free(&db, &allocImp);
SzFree(NULL, temp);
File_Close(&archiveStream.file);
/*if (res == SZ_OK)
{
printf("\nEverything is Ok\n");
return 0;
}*/
return bExtractRomOK;
}
/*
int MY_CDECL main(int c, char *v[])
{
unsigned char *pBuf = 0;
size_t fileLen;
int i = SevenZipUnCompress(v[1],&pBuf,&fileLen);
free(pBuf); pBuf = 0;
printf("%d",i);
}
*/

View File

@ -0,0 +1,169 @@
/* 7zStream.c -- 7z Stream functions
2010-03-11 : Igor Pavlov : Public domain */
#include <string.h>
#include "Types.h"
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;
}
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
{
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;
}
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
{
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);
}
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;
}
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
{
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;
}
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;
}
static SRes LookToRead_Skip(void *pp, size_t offset)
{
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;
}
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);
}
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;
}
void LookToRead_Init(CLookToRead *p)
{
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);
}
void SecToLook_CreateVTable(CSecToLook *p)
{
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);
}
void SecToRead_CreateVTable(CSecToRead *p)
{
p->s.Read = SecToRead_Read;
}

View File

@ -0,0 +1,7 @@
#define MY_VER_MAJOR 9
#define MY_VER_MINOR 20
#define MY_VER_BUILD 0
#define MY_VERSION "9.20"
#define MY_DATE "2010-11-18"
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE

View File

@ -0,0 +1,132 @@
/* Bcj2.c -- Converter for x86 code (BCJ2)
2008-10-04 : Igor Pavlov : Public domain */
#include "Bcj2.h"
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb UInt16
#endif
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#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 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;
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;
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;
buffer = buf3;
bufferLim = buffer + size3;
RC_INIT2
if (outSize == 0)
return SZ_OK;
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--;
}
if (limit == 0 || outPos == outSize)
break;
b = buf0[inPos++];
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;
}

View File

@ -0,0 +1,38 @@
/* Bcj2.h -- Converter for x86 code (BCJ2)
2009-02-07 : Igor Pavlov : Public domain */
#ifndef __BCJ2_H
#define __BCJ2_H
#include "Types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
Conditions:
outSize <= FullOutputSize,
where FullOutputSize is full size of output stream of x86_2 filter.
If buf0 overlaps outBuf, there are two required conditions:
1) (buf0 >= outBuf)
2) (buf0 + size0 >= outBuf + FullOutputSize).
Returns:
SZ_OK
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);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,133 @@
/* Bra.c -- Converters for RISC code
2010-04-16 : Igor Pavlov : Public domain */
#include "Bra.h"
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 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 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 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;
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

@ -0,0 +1,68 @@
/* Bra.h -- Branch converters for executables
2009-02-07 : Igor Pavlov : Public domain */
#ifndef __BRA_H
#define __BRA_H
#include "Types.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
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
PPC big 4 0
SPARC big 4 0
IA64 little 16 0
size must be >= Alignment + LookAhead, if it's not last block.
If (size < Alignment + LookAhead), converter returns 0.
Example:
UInt32 ip = 0;
for ()
{
; size must be >= Alignment + LookAhead, if it's not last block
SizeT processed = Convert(data, size, ip, 1);
data += processed;
size -= processed;
ip += processed;
}
*/
#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);
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,85 @@
/* Bra86.c -- Converter for x86 code (BCJ)
2008-10-04 : Igor Pavlov : Public domain */
#include "Bra.h"
#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};
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;
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 - prevPosT;
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
return bufferPos;
}

View File

@ -0,0 +1,168 @@
/* CpuArch.c -- CPU specific code
2010-10-26: Igor Pavlov : Public domain */
#include "CpuArch.h"
#ifdef MY_CPU_X86_OR_AMD64
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
#define USE_ASM
#endif
#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;
}
#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 _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;
*a = a2;
*b = b2;
*c = c2;
*d = d2;
#else
__asm__ __volatile__ (
"cpuid"
: "=a" (*a) ,
"=b" (*b) ,
"=c" (*c) ,
"=d" (*d)
: "0" (function)) ;
#endif
#else
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;
}
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;
}
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;
}
#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);
}
#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;
}
#endif

View File

@ -0,0 +1,155 @@
/* CpuArch.h -- CPU specific code
2010-10-26: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
#include "Types.h"
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).
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.
*/
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
#define MY_CPU_AMD64
#endif
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
#define MY_CPU_64BIT
#endif
#if defined(_M_IX86) || defined(__i386__)
#define MY_CPU_X86
#endif
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64
#endif
#if defined(MY_CPU_X86) || defined(_M_ARM)
#define MY_CPU_32BIT
#endif
#if defined(_WIN32) && defined(_M_ARM)
#define MY_CPU_ARM_LE
#endif
#if defined(_WIN32) && defined(_M_IA64)
#define MY_CPU_IA64_LE
#endif
#if defined(MY_CPU_X86_OR_AMD64)
#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__)
#define MY_CPU_LE
#endif
#if defined(__BIG_ENDIAN__)
#define MY_CPU_BE
#endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian
#endif
#ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(p))
#define GetUi32(p) (*(const UInt32 *)(p))
#define GetUi64(p) (*(const UInt64 *)(p))
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
#else
#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 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 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)); }
#endif
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
#pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64)
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
#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 GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
#endif
#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;
} Cx86cpuid;
enum
{
CPU_FIRM_INTEL,
CPU_FIRM_AMD,
CPU_FIRM_VIA
};
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
int x86cpuid_GetFirm(const Cx86cpuid *p);
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
Bool CPU_Is_InOrder();
Bool CPU_Is_Aes_Supported();
#endif
EXTERN_C_END
#endif

View File

@ -0,0 +1,356 @@
/* Lzma2Dec.c -- LZMA2 Decoder
2009-05-03 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
#ifdef SHOW_DEBUG_INFO
#include <stdio.h>
#endif
#include <string.h>
#include "Lzma2Dec.h"
/*
00000000 - EOS
00000001 U U - Uncompressed Reset Dic
00000010 U U - Uncompressed No Reset
100uuuuu U U P P - LZMA no reset
101uuuuu U U P P - LZMA reset state
110uuuuu U U P P S - LZMA reset state + new prop
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
u, U - Unpack Size
P - Pack Size
S - Props
*/
#define LZMA2_CONTROL_LZMA (1 << 7)
#define LZMA2_CONTROL_COPY_NO_RESET 2
#define LZMA2_CONTROL_COPY_RESET_DIC 1
#define LZMA2_CONTROL_EOF 0
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
#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))
#ifdef SHOW_DEBUG_INFO
#define PRF(x) x
#else
#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
} 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;
}
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);
}
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);
}
void Lzma2Dec_Init(CLzma2Dec *p)
{
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;
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;
}
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;
}
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)
{
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;
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;
}
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;
}

View File

@ -0,0 +1,84 @@
/* Lzma2Dec.h -- LZMA2 Decoder
2009-05-03 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H
#include "LzmaDec.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ---------- State Interface ---------- */
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)
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
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).
LZMA_FINISH_ANY - use smallest number of input bytes
LZMA_FINISH_END - read EndOfStream marker after decoding
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
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);
/* ---------- One Call Interface ---------- */
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - use smallest number of input bytes
LZMA_FINISH_END - read EndOfStream marker after decoding
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
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);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,999 @@
/* LzmaDec.c -- LZMA Decoder
2009-09-20 : Igor Pavlov : Public domain */
#include "LzmaDec.h"
#include <string.h>
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
#define RC_INIT_SIZE 5
#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
{ UPDATE_0(p); i = (i + i); A0; } else \
{ UPDATE_1(p); i = (i + i) + 1; A1; }
#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
#define TREE_DECODE(probs, limit, i) \
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
/* #define _LZMA_SIZE_OPT */
#ifdef _LZMA_SIZE_OPT
#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
#else
#define TREE_6_DECODE(probs, i) \
{ i = 1; \
TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \
TREE_GET_BIT(probs, i); \
i -= 0x40; }
#endif
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
#define UPDATE_0_CHECK range = bound;
#define UPDATE_1_CHECK range -= bound; code -= bound;
#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
{ UPDATE_0_CHECK; i = (i + i); A0; } else \
{ UPDATE_1_CHECK; i = (i + i) + 1; A1; }
#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
#define TREE_DECODE_CHECK(probs, limit, i) \
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
#define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded.
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
Out:
Result:
SZ_OK - OK
SZ_ERROR_DATA - Error
p->remainLen:
< kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : Flush marker
= kMatchSpecLenStart + 2 : State Init Marker
*/
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{
CLzmaProb *probs = p->probs;
unsigned state = p->state;
UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
unsigned lc = p->prop.lc;
Byte *dic = p->dic;
SizeT dicBufSize = p->dicBufSize;
SizeT dicPos = p->dicPos;
UInt32 processedPos = p->processedPos;
UInt32 checkDicSize = p->checkDicSize;
unsigned len = 0;
const Byte *buf = p->buf;
UInt32 range = p->range;
UInt32 code = p->code;
do
{
CLzmaProb *prob;
UInt32 bound;
unsigned ttt;
unsigned posState = processedPos & pbMask;
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
IF_BIT_0(prob)
{
unsigned symbol;
UPDATE_0(prob);
prob = probs + Literal;
if (checkDicSize != 0 || processedPos != 0)
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
if (state < kNumLitStates)
{
state -= (state < 4) ? state : 3;
symbol = 1;
do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
}
else
{
unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
unsigned offs = 0x100;
state -= (state < 10) ? 3 : 6;
symbol = 1;
do
{
unsigned bit;
CLzmaProb *probLit;
matchByte <<= 1;
bit = (matchByte & offs);
probLit = prob + offs + bit + symbol;
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
}
while (symbol < 0x100);
}
dic[dicPos++] = (Byte)symbol;
processedPos++;
continue;
}
else
{
UPDATE_1(prob);
prob = probs + IsRep + state;
IF_BIT_0(prob)
{
UPDATE_0(prob);
state += kNumStates;
prob = probs + LenCoder;
}
else
{
UPDATE_1(prob);
if (checkDicSize == 0 && processedPos == 0)
return SZ_ERROR_DATA;
prob = probs + IsRepG0 + state;
IF_BIT_0(prob)
{
UPDATE_0(prob);
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
IF_BIT_0(prob)
{
UPDATE_0(prob);
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dicPos++;
processedPos++;
state = state < kNumLitStates ? 9 : 11;
continue;
}
UPDATE_1(prob);
}
else
{
UInt32 distance;
UPDATE_1(prob);
prob = probs + IsRepG1 + state;
IF_BIT_0(prob)
{
UPDATE_0(prob);
distance = rep1;
}
else
{
UPDATE_1(prob);
prob = probs + IsRepG2 + state;
IF_BIT_0(prob)
{
UPDATE_0(prob);
distance = rep2;
}
else
{
UPDATE_1(prob);
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
state = state < kNumLitStates ? 8 : 11;
prob = probs + RepLenCoder;
}
{
unsigned limit, offset;
CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
limit = (1 << kLenNumLowBits);
}
else
{
UPDATE_1(probLen);
probLen = prob + LenChoice2;
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
limit = (1 << kLenNumMidBits);
}
else
{
UPDATE_1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
limit = (1 << kLenNumHighBits);
}
}
TREE_DECODE(probLen, limit, len);
len += offset;
}
if (state >= kNumStates)
{
UInt32 distance;
prob = probs + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
TREE_6_DECODE(prob, distance);
if (distance >= kStartPosModelIndex)
{
unsigned posSlot = (unsigned)distance;
int numDirectBits = (int)(((distance >> 1) - 1));
distance = (2 | (distance & 1));
if (posSlot < kEndPosModelIndex)
{
distance <<= numDirectBits;
prob = probs + SpecPos + distance - posSlot - 1;
{
UInt32 mask = 1;
unsigned i = 1;
do
{
GET_BIT2(prob + i, i, ; , distance |= mask);
mask <<= 1;
}
while (--numDirectBits != 0);
}
}
else
{
numDirectBits -= kNumAlignBits;
do
{
NORMALIZE
range >>= 1;
{
UInt32 t;
code -= range;
t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
distance = (distance << 1) + (t + 1);
code += range & t;
}
/*
distance <<= 1;
if (code >= range)
{
code -= range;
distance |= 1;
}
*/
}
while (--numDirectBits != 0);
prob = probs + Align;
distance <<= kNumAlignBits;
{
unsigned i = 1;
GET_BIT2(prob + i, i, ; , distance |= 1);
GET_BIT2(prob + i, i, ; , distance |= 2);
GET_BIT2(prob + i, i, ; , distance |= 4);
GET_BIT2(prob + i, i, ; , distance |= 8);
}
if (distance == (UInt32)0xFFFFFFFF)
{
len += kMatchSpecLenStart;
state -= kNumStates;
break;
}
}
}
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
rep0 = distance + 1;
if (checkDicSize == 0)
{
if (distance >= processedPos)
return SZ_ERROR_DATA;
}
else if (distance >= checkDicSize)
return SZ_ERROR_DATA;
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
}
len += kMatchMinLen;
if (limit == dicPos)
return SZ_ERROR_DATA;
{
SizeT rem = limit - dicPos;
unsigned curLen = ((rem < len) ? (unsigned)rem : len);
SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
processedPos += curLen;
len -= curLen;
if (pos + curLen <= dicBufSize)
{
Byte *dest = dic + dicPos;
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
const Byte *lim = dest + curLen;
dicPos += curLen;
do
*(dest) = (Byte)*(dest + src);
while (++dest != lim);
}
else
{
do
{
dic[dicPos++] = dic[pos];
if (++pos == dicBufSize)
pos = 0;
}
while (--curLen != 0);
}
}
}
}
while (dicPos < limit && buf < bufLimit);
NORMALIZE;
p->buf = buf;
p->range = range;
p->code = code;
p->remainLen = len;
p->dicPos = dicPos;
p->processedPos = processedPos;
p->reps[0] = rep0;
p->reps[1] = rep1;
p->reps[2] = rep2;
p->reps[3] = rep3;
p->state = state;
return SZ_OK;
}
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
{
if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
{
Byte *dic = p->dic;
SizeT dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize;
unsigned len = p->remainLen;
UInt32 rep0 = p->reps[0];
if (limit - dicPos < len)
len = (unsigned)(limit - dicPos);
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
p->checkDicSize = p->prop.dicSize;
p->processedPos += len;
p->remainLen -= len;
while (len-- != 0)
{
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dicPos++;
}
p->dicPos = dicPos;
}
}
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{
do
{
SizeT limit2 = limit;
if (p->checkDicSize == 0)
{
UInt32 rem = p->prop.dicSize - p->processedPos;
if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem;
}
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
if (p->processedPos >= p->prop.dicSize)
p->checkDicSize = p->prop.dicSize;
LzmaDec_WriteRem(p, limit);
}
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart)
{
p->remainLen = kMatchSpecLenStart;
}
return 0;
}
typedef enum
{
DUMMY_ERROR, /* unexpected end of input stream */
DUMMY_LIT,
DUMMY_MATCH,
DUMMY_REP
} ELzmaDummy;
static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
{
UInt32 range = p->range;
UInt32 code = p->code;
const Byte *bufLimit = buf + inSize;
CLzmaProb *probs = p->probs;
unsigned state = p->state;
ELzmaDummy res;
{
CLzmaProb *prob;
UInt32 bound;
unsigned ttt;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK
/* if (bufLimit - buf >= 7) return DUMMY_LIT; */
prob = probs + Literal;
if (p->checkDicSize != 0 || p->processedPos != 0)
prob += (LZMA_LIT_SIZE *
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
if (state < kNumLitStates)
{
unsigned symbol = 1;
do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
}
else
{
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
unsigned offs = 0x100;
unsigned symbol = 1;
do
{
unsigned bit;
CLzmaProb *probLit;
matchByte <<= 1;
bit = (matchByte & offs);
probLit = prob + offs + bit + symbol;
GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
}
while (symbol < 0x100);
}
res = DUMMY_LIT;
}
else
{
unsigned len;
UPDATE_1_CHECK;
prob = probs + IsRep + state;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK;
state = 0;
prob = probs + LenCoder;
res = DUMMY_MATCH;
}
else
{
UPDATE_1_CHECK;
res = DUMMY_REP;
prob = probs + IsRepG0 + state;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK;
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK;
NORMALIZE_CHECK;
return DUMMY_REP;
}
else
{
UPDATE_1_CHECK;
}
}
else
{
UPDATE_1_CHECK;
prob = probs + IsRepG1 + state;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK;
}
else
{
UPDATE_1_CHECK;
prob = probs + IsRepG2 + state;
IF_BIT_0_CHECK(prob)
{
UPDATE_0_CHECK;
}
else
{
UPDATE_1_CHECK;
}
}
}
state = kNumStates;
prob = probs + RepLenCoder;
}
{
unsigned limit, offset;
CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0_CHECK(probLen)
{
UPDATE_0_CHECK;
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
limit = 1 << kLenNumLowBits;
}
else
{
UPDATE_1_CHECK;
probLen = prob + LenChoice2;
IF_BIT_0_CHECK(probLen)
{
UPDATE_0_CHECK;
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
limit = 1 << kLenNumMidBits;
}
else
{
UPDATE_1_CHECK;
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
limit = 1 << kLenNumHighBits;
}
}
TREE_DECODE_CHECK(probLen, limit, len);
len += offset;
}
if (state < 4)
{
unsigned posSlot;
prob = probs + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits);
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
if (posSlot < kEndPosModelIndex)
{
prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
}
else
{
numDirectBits -= kNumAlignBits;
do
{
NORMALIZE_CHECK
range >>= 1;
code -= range & (((code - range) >> 31) - 1);
/* if (code >= range) code -= range; */
}
while (--numDirectBits != 0);
prob = probs + Align;
numDirectBits = kNumAlignBits;
}
{
unsigned i = 1;
do
{
GET_BIT_CHECK(prob + i, i);
}
while (--numDirectBits != 0);
}
}
}
}
}
NORMALIZE_CHECK;
return res;
}
static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
{
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0;
}
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{
p->needFlush = 1;
p->remainLen = 0;
p->tempBufSize = 0;
if (initDic)
{
p->processedPos = 0;
p->checkDicSize = 0;
p->needInitState = 1;
}
if (initState)
p->needInitState = 1;
}
void LzmaDec_Init(CLzmaDec *p)
{
p->dicPos = 0;
LzmaDec_InitDicAndState(p, True, True);
}
static void LzmaDec_InitStateReal(CLzmaDec *p)
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
UInt32 i;
CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1;
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
p->state = 0;
p->needInitState = 0;
}
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT inSize = *srcLen;
(*srcLen) = 0;
LzmaDec_WriteRem(p, dicLimit);
*status = LZMA_STATUS_NOT_SPECIFIED;
while (p->remainLen != kMatchSpecLenStart)
{
int checkEndMarkNow;
if (p->needFlush != 0)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++;
if (p->tempBufSize < RC_INIT_SIZE)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA;
LzmaDec_InitRc(p, p->tempBuf);
p->tempBufSize = 0;
}
checkEndMarkNow = 0;
if (p->dicPos >= dicLimit)
{
if (p->remainLen == 0 && p->code == 0)
{
*status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
return SZ_OK;
}
if (finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK;
}
if (p->remainLen != 0)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA;
}
checkEndMarkNow = 1;
}
if (p->needInitState)
LzmaDec_InitStateReal(p);
if (p->tempBufSize == 0)
{
SizeT processed;
const Byte *bufLimit;
if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
{
int dummyRes = LzmaDec_TryDummy(p, src, inSize);
if (dummyRes == DUMMY_ERROR)
{
memcpy(p->tempBuf, src, inSize);
p->tempBufSize = (unsigned)inSize;
(*srcLen) += inSize;
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA;
}
bufLimit = src;
}
else
bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
p->buf = src;
if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
return SZ_ERROR_DATA;
processed = (SizeT)(p->buf - src);
(*srcLen) += processed;
src += processed;
inSize -= processed;
}
else
{
unsigned rem = p->tempBufSize, lookAhead = 0;
while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
p->tempBuf[rem++] = src[lookAhead++];
p->tempBufSize = rem;
if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
{
int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
if (dummyRes == DUMMY_ERROR)
{
(*srcLen) += lookAhead;
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA;
}
}
p->buf = p->tempBuf;
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
return SZ_ERROR_DATA;
lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
(*srcLen) += lookAhead;
src += lookAhead;
inSize -= lookAhead;
p->tempBufSize = 0;
}
}
if (p->code == 0)
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
}
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT outSize = *destLen;
SizeT inSize = *srcLen;
*srcLen = *destLen = 0;
for (;;)
{
SizeT inSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode;
SRes res;
if (p->dicPos == p->dicBufSize)
p->dicPos = 0;
dicPos = p->dicPos;
if (outSize > p->dicBufSize - dicPos)
{
outSizeCur = p->dicBufSize;
curFinishMode = LZMA_FINISH_ANY;
}
else
{
outSizeCur = dicPos + outSize;
curFinishMode = finishMode;
}
res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
src += inSizeCur;
inSize -= inSizeCur;
*srcLen += inSizeCur;
outSizeCur = p->dicPos - dicPos;
memcpy(dest, p->dic + dicPos, outSizeCur);
dest += outSizeCur;
outSize -= outSizeCur;
*destLen += outSizeCur;
if (res != 0)
return res;
if (outSizeCur == 0 || outSize == 0)
return SZ_OK;
}
}
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->probs);
p->probs = 0;
}
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->dic);
p->dic = 0;
}
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
{
LzmaDec_FreeProbs(p, alloc);
LzmaDec_FreeDict(p, alloc);
}
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
{
UInt32 dicSize;
Byte d;
if (size < LZMA_PROPS_SIZE)
return SZ_ERROR_UNSUPPORTED;
else
dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
if (dicSize < LZMA_DIC_MIN)
dicSize = LZMA_DIC_MIN;
p->dicSize = dicSize;
d = data[0];
if (d >= (9 * 5 * 5))
return SZ_ERROR_UNSUPPORTED;
p->lc = d % 9;
d /= 9;
p->pb = d / 5;
p->lp = d % 5;
return SZ_OK;
}
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
{
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
if (p->probs == 0 || numProbs != p->numProbs)
{
LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs;
if (p->probs == 0)
return SZ_ERROR_MEM;
}
return SZ_OK;
}
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
{
CLzmaProps propNew;
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
p->prop = propNew;
return SZ_OK;
}
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
{
CLzmaProps propNew;
SizeT dicBufSize;
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
dicBufSize = propNew.dicSize;
if (p->dic == 0 || dicBufSize != p->dicBufSize)
{
LzmaDec_FreeDict(p, alloc);
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
if (p->dic == 0)
{
LzmaDec_FreeProbs(p, alloc);
return SZ_ERROR_MEM;
}
}
p->dicBufSize = dicBufSize;
p->prop = propNew;
return SZ_OK;
}
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc)
{
CLzmaDec p;
SRes res;
SizeT inSize = *srcLen;
SizeT outSize = *destLen;
*srcLen = *destLen = 0;
if (inSize < RC_INIT_SIZE)
return SZ_ERROR_INPUT_EOF;
LzmaDec_Construct(&p);
res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
if (res != 0)
return res;
p.dic = dest;
p.dicBufSize = outSize;
LzmaDec_Init(&p);
*srcLen = inSize;
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
(*destLen) = p.dicPos;
LzmaDec_FreeProbs(&p, alloc);
return res;
}

View File

@ -0,0 +1,231 @@
/* LzmaDec.h -- LZMA Decoder
2009-02-07 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
#include "Types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */
#ifdef _LZMA_PROB32
#define CLzmaProb UInt32
#else
#define CLzmaProb UInt16
#endif
/* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5
typedef struct _CLzmaProps
{
unsigned lc, lp, pb;
UInt32 dicSize;
} CLzmaProps;
/* LzmaProps_Decode - decodes properties
Returns:
SZ_OK
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
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.
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
#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];
} CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams:
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 */
} ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
You must use LZMA_FINISH_END, when you know that current output buffer
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
and output value of destLen will be less than output buffer size limit.
You can check status result also.
You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
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 */
} ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces:
1) Dictionary Interface
2) Buffer Interface
3) One Call Interface
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
You can use variant 2, if you set dictionary buffer manually.
For Buffer Interface you must always use variant 1.
LzmaDec_Allocate* can return:
SZ_OK
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);
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
/* ---------- Dictionary Interface ---------- */
/* You can use it, if you want to eliminate the overhead for data copying from
dictionary to some other external buffer.
You must work with CLzmaDec variables directly in this interface.
STEPS:
LzmaDec_Constr()
LzmaDec_Allocate()
for (each new stream)
{
LzmaDec_Init()
while (it needs more decompression)
{
LzmaDec_DecodeToDic()
use data from CLzmaDec::dic and update CLzmaDec::dicPos
}
}
LzmaDec_Free()
*/
/* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
finishMode:
It has meaning only if the decoding reaches output limit (dicLimit).
LZMA_FINISH_ANY - Decode just dicLimit bytes.
LZMA_FINISH_END - Stream must be finished after dicLimit.
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
*/
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */
/* It's zlib-like interface.
See LzmaDec_DecodeToDic description for information about STEPS and return results,
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
to work with CLzmaDec variables manually.
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
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);
/* ---------- One Call Interface ---------- */
/* LzmaDecode
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
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);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,81 @@
/* Ppmd.h -- PPMD codec common code
2010-03-12 : Igor Pavlov : Public domain
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"
EXTERN_C_BEGIN
#ifdef MY_CPU_32BIT
#define PPMD_32BIT
#endif
#define PPMD_INT_BITS 7
#define PPMD_PERIOD_BITS 7
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
#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_N1 4
#define PPMD_N2 4
#define PPMD_N3 4
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
#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 */
} 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++); }
typedef struct
{
Byte Symbol;
Byte Freq;
UInt16 SuccessorLow;
UInt16 SuccessorHigh;
} CPpmd_State;
typedef
#ifdef PPMD_32BIT
CPpmd_State *
#else
UInt32
#endif
CPpmd_State_Ref;
typedef
#ifdef PPMD_32BIT
void *
#else
UInt32
#endif
CPpmd_Void_Ref;
typedef
#ifdef PPMD_32BIT
Byte *
#else
UInt32
#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; }}
EXTERN_C_END
#endif

View File

@ -0,0 +1,708 @@
/* Ppmd7.c -- PPMdH codec
2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include <memory.h>
#include "Ppmd7.h"
const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
#define MAX_FREQ 124
#define UNIT_SIZE 12
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
#define U2I(nu) (p->Units2Indx[(nu) - 1])
#define I2U(indx) (p->Indx2Units[indx])
#ifdef PPMD_32BIT
#define REF(ptr) (ptr)
#else
#define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
#endif
#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
#define STATS(ctx) Ppmd7_GetStats(p, ctx)
#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)
#define SUFFIX(ctx) CTX((ctx)->Suffix)
typedef CPpmd7_Context * CTX_PTR;
struct CPpmd7_Node_;
typedef
#ifdef PPMD_32BIT
struct CPpmd7_Node_ *
#else
UInt32
#endif
CPpmd7_Node_Ref;
typedef struct CPpmd7_Node_
{
UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */
UInt16 NU;
CPpmd7_Node_Ref Next; /* must be at offset >= 4 */
CPpmd7_Node_Ref Prev;
} CPpmd7_Node;
#ifdef PPMD_32BIT
#define NODE(ptr) (ptr)
#else
#define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs)))
#endif
void Ppmd7_Construct(CPpmd7 *p)
{
unsigned i, k, m;
p->Base = 0;
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
{
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
do { p->Units2Indx[k++] = (Byte)i; } while(--step);
p->Indx2Units[i] = (Byte)k;
}
p->NS2BSIndx[0] = (0 << 1);
p->NS2BSIndx[1] = (1 << 1);
memset(p->NS2BSIndx + 2, (2 << 1), 9);
memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
for (i = 0; i < 3; i++)
p->NS2Indx[i] = (Byte)i;
for (m = i, k = 1; i < 256; i++)
{
p->NS2Indx[i] = (Byte)m;
if (--k == 0)
k = (++m) - 2;
}
memset(p->HB2Flag, 0, 0x40);
memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
}
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->Base);
p->Size = 0;
p->Base = 0;
}
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
{
if (p->Base == 0 || p->Size != size)
{
Ppmd7_Free(p, alloc);
p->AlignOffset =
#ifdef PPMD_32BIT
(4 - size) & 3;
#else
4 - (size & 3);
#endif
if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
#ifndef PPMD_32BIT
+ UNIT_SIZE
#endif
)) == 0)
return False;
p->Size = size;
}
return True;
}
static void InsertNode(CPpmd7 *p, void *node, unsigned indx)
{
*((CPpmd_Void_Ref *)node) = p->FreeList[indx];
p->FreeList[indx] = REF(node);
}
static void *RemoveNode(CPpmd7 *p, unsigned indx)
{
CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]);
p->FreeList[indx] = *node;
return node;
}
static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
{
unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
ptr = (Byte *)ptr + U2B(I2U(newIndx));
if (I2U(i = U2I(nu)) != nu)
{
unsigned k = I2U(--i);
InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
}
InsertNode(p, ptr, i);
}
static void GlueFreeBlocks(CPpmd7 *p)
{
#ifdef PPMD_32BIT
CPpmd7_Node headItem;
CPpmd7_Node_Ref head = &headItem;
#else
CPpmd7_Node_Ref head = p->AlignOffset + p->Size;
#endif
CPpmd7_Node_Ref n = head;
unsigned i;
p->GlueCount = 255;
/* create doubly-linked list of free blocks */
for (i = 0; i < PPMD_NUM_INDEXES; i++)
{
UInt16 nu = I2U(i);
CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];
p->FreeList[i] = 0;
while (next != 0)
{
CPpmd7_Node *node = NODE(next);
node->Next = n;
n = NODE(n)->Prev = next;
next = *(const CPpmd7_Node_Ref *)node;
node->Stamp = 0;
node->NU = (UInt16)nu;
}
}
NODE(head)->Stamp = 1;
NODE(head)->Next = n;
NODE(n)->Prev = head;
if (p->LoUnit != p->HiUnit)
((CPpmd7_Node *)p->LoUnit)->Stamp = 1;
/* Glue free blocks */
while (n != head)
{
CPpmd7_Node *node = NODE(n);
UInt32 nu = (UInt32)node->NU;
for (;;)
{
CPpmd7_Node *node2 = NODE(n) + nu;
nu += node2->NU;
if (node2->Stamp != 0 || nu >= 0x10000)
break;
NODE(node2->Prev)->Next = node2->Next;
NODE(node2->Next)->Prev = node2->Prev;
node->NU = (UInt16)nu;
}
n = node->Next;
}
/* Fill lists of free blocks */
for (n = NODE(head)->Next; n != head;)
{
CPpmd7_Node *node = NODE(n);
unsigned nu;
CPpmd7_Node_Ref next = node->Next;
for (nu = node->NU; nu > 128; nu -= 128, node += 128)
InsertNode(p, node, PPMD_NUM_INDEXES - 1);
if (I2U(i = U2I(nu)) != nu)
{
unsigned k = I2U(--i);
InsertNode(p, node + k, nu - k - 1);
}
InsertNode(p, node, i);
n = next;
}
}
static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)
{
unsigned i;
void *retVal;
if (p->GlueCount == 0)
{
GlueFreeBlocks(p);
if (p->FreeList[indx] != 0)
return RemoveNode(p, indx);
}
i = indx;
do
{
if (++i == PPMD_NUM_INDEXES)
{
UInt32 numBytes = U2B(I2U(indx));
p->GlueCount--;
return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
}
}
while (p->FreeList[i] == 0);
retVal = RemoveNode(p, i);
SplitBlock(p, retVal, i, indx);
return retVal;
}
static void *AllocUnits(CPpmd7 *p, unsigned indx)
{
UInt32 numBytes;
if (p->FreeList[indx] != 0)
return RemoveNode(p, indx);
numBytes = U2B(I2U(indx));
if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
{
void *retVal = p->LoUnit;
p->LoUnit += numBytes;
return retVal;
}
return AllocUnitsRare(p, indx);
}
#define MyMem12Cpy(dest, src, num) \
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
{
unsigned i0 = U2I(oldNU);
unsigned i1 = U2I(newNU);
if (i0 == i1)
return oldPtr;
if (p->FreeList[i1] != 0)
{
void *ptr = RemoveNode(p, i1);
MyMem12Cpy(ptr, oldPtr, newNU);
InsertNode(p, oldPtr, i0);
return ptr;
}
SplitBlock(p, oldPtr, i0, i1);
return oldPtr;
}
#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
{
(p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
(p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
}
static void RestartModel(CPpmd7 *p)
{
unsigned i, k, m;
memset(p->FreeList, 0, sizeof(p->FreeList));
p->Text = p->Base + p->AlignOffset;
p->HiUnit = p->Text + p->Size;
p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
p->GlueCount = 0;
p->OrderFall = p->MaxOrder;
p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
p->PrevSuccess = 0;
p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
p->MinContext->Suffix = 0;
p->MinContext->NumStats = 256;
p->MinContext->SummFreq = 256 + 1;
p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
p->LoUnit += U2B(256 / 2);
p->MinContext->Stats = REF(p->FoundState);
for (i = 0; i < 256; i++)
{
CPpmd_State *s = &p->FoundState[i];
s->Symbol = (Byte)i;
s->Freq = 1;
SetSuccessor(s, 0);
}
for (i = 0; i < 128; i++)
for (k = 0; k < 8; k++)
{
UInt16 *dest = p->BinSumm[i] + k;
UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
for (m = 0; m < 64; m += 8)
dest[m] = val;
}
for (i = 0; i < 25; i++)
for (k = 0; k < 16; k++)
{
CPpmd_See *s = &p->See[i][k];
s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
s->Count = 4;
}
}
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
{
p->MaxOrder = maxOrder;
RestartModel(p);
p->DummySee.Shift = PPMD_PERIOD_BITS;
p->DummySee.Summ = 0; /* unused */
p->DummySee.Count = 64; /* unused */
}
static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
{
CPpmd_State upState;
CTX_PTR c = p->MinContext;
CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
CPpmd_State *ps[PPMD7_MAX_ORDER];
unsigned numPs = 0;
if (!skip)
ps[numPs++] = p->FoundState;
while (c->Suffix)
{
CPpmd_Void_Ref successor;
CPpmd_State *s;
c = SUFFIX(c);
if (c->NumStats != 1)
{
for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
}
else
s = ONE_STATE(c);
successor = SUCCESSOR(s);
if (successor != upBranch)
{
c = CTX(successor);
if (numPs == 0)
return c;
break;
}
ps[numPs++] = s;
}
upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch);
SetSuccessor(&upState, upBranch + 1);
if (c->NumStats == 1)
upState.Freq = ONE_STATE(c)->Freq;
else
{
UInt32 cf, s0;
CPpmd_State *s;
for (s = STATS(c); s->Symbol != upState.Symbol; s++);
cf = s->Freq - 1;
s0 = c->SummFreq - c->NumStats - cf;
upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
}
do
{
/* Create Child */
CTX_PTR c1; /* = AllocContext(p); */
if (p->HiUnit != p->LoUnit)
c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
else if (p->FreeList[0] != 0)
c1 = (CTX_PTR)RemoveNode(p, 0);
else
{
c1 = (CTX_PTR)AllocUnitsRare(p, 0);
if (!c1)
return NULL;
}
c1->NumStats = 1;
*ONE_STATE(c1) = upState;
c1->Suffix = REF(c);
SetSuccessor(ps[--numPs], REF(c1));
c = c1;
}
while (numPs != 0);
return c;
}
static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
{
CPpmd_State tmp = *t1;
*t1 = *t2;
*t2 = tmp;
}
static void UpdateModel(CPpmd7 *p)
{
CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
CTX_PTR c;
unsigned s0, ns;
if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
{
c = SUFFIX(p->MinContext);
if (c->NumStats == 1)
{
CPpmd_State *s = ONE_STATE(c);
if (s->Freq < 32)
s->Freq++;
}
else
{
CPpmd_State *s = STATS(c);
if (s->Symbol != p->FoundState->Symbol)
{
do { s++; } while (s->Symbol != p->FoundState->Symbol);
if (s[0].Freq >= s[-1].Freq)
{
SwapStates(&s[0], &s[-1]);
s--;
}
}
if (s->Freq < MAX_FREQ - 9)
{
s->Freq += 2;
c->SummFreq += 2;
}
}
}
if (p->OrderFall == 0)
{
p->MinContext = p->MaxContext = CreateSuccessors(p, True);
if (p->MinContext == 0)
{
RestartModel(p);
return;
}
SetSuccessor(p->FoundState, REF(p->MinContext));
return;
}
*p->Text++ = p->FoundState->Symbol;
successor = REF(p->Text);
if (p->Text >= p->UnitsStart)
{
RestartModel(p);
return;
}
if (fSuccessor)
{
if (fSuccessor <= successor)
{
CTX_PTR cs = CreateSuccessors(p, False);
if (cs == NULL)
{
RestartModel(p);
return;
}
fSuccessor = REF(cs);
}
if (--p->OrderFall == 0)
{
successor = fSuccessor;
p->Text -= (p->MaxContext != p->MinContext);
}
}
else
{
SetSuccessor(p->FoundState, successor);
fSuccessor = REF(p->MinContext);
}
s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);
for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))
{
unsigned ns1;
UInt32 cf, sf;
if ((ns1 = c->NumStats) != 1)
{
if ((ns1 & 1) == 0)
{
/* Expand for one UNIT */
unsigned oldNU = ns1 >> 1;
unsigned i = U2I(oldNU);
if (i != U2I(oldNU + 1))
{
void *ptr = AllocUnits(p, i + 1);
void *oldPtr;
if (!ptr)
{
RestartModel(p);
return;
}
oldPtr = STATS(c);
MyMem12Cpy(ptr, oldPtr, oldNU);
InsertNode(p, oldPtr, i);
c->Stats = STATS_REF(ptr);
}
}
c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));
}
else
{
CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
if (!s)
{
RestartModel(p);
return;
}
*s = *ONE_STATE(c);
c->Stats = REF(s);
if (s->Freq < MAX_FREQ / 4 - 1)
s->Freq <<= 1;
else
s->Freq = MAX_FREQ - 4;
c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3));
}
cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);
sf = (UInt32)s0 + c->SummFreq;
if (cf < 6 * sf)
{
cf = 1 + (cf > sf) + (cf >= 4 * sf);
c->SummFreq += 3;
}
else
{
cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
c->SummFreq = (UInt16)(c->SummFreq + cf);
}
{
CPpmd_State *s = STATS(c) + ns1;
SetSuccessor(s, successor);
s->Symbol = p->FoundState->Symbol;
s->Freq = (Byte)cf;
c->NumStats = (UInt16)(ns1 + 1);
}
}
p->MaxContext = p->MinContext = CTX(fSuccessor);
}
static void Rescale(CPpmd7 *p)
{
unsigned i, adder, sumFreq, escFreq;
CPpmd_State *stats = STATS(p->MinContext);
CPpmd_State *s = p->FoundState;
{
CPpmd_State tmp = *s;
for (; s != stats; s--)
s[0] = s[-1];
*s = tmp;
}
escFreq = p->MinContext->SummFreq - s->Freq;
s->Freq += 4;
adder = (p->OrderFall != 0);
s->Freq = (Byte)((s->Freq + adder) >> 1);
sumFreq = s->Freq;
i = p->MinContext->NumStats - 1;
do
{
escFreq -= (++s)->Freq;
s->Freq = (Byte)((s->Freq + adder) >> 1);
sumFreq += s->Freq;
if (s[0].Freq > s[-1].Freq)
{
CPpmd_State *s1 = s;
CPpmd_State tmp = *s1;
do
s1[0] = s1[-1];
while (--s1 != stats && tmp.Freq > s1[-1].Freq);
*s1 = tmp;
}
}
while (--i);
if (s->Freq == 0)
{
unsigned numStats = p->MinContext->NumStats;
unsigned n0, n1;
do { i++; } while ((--s)->Freq == 0);
escFreq += i;
p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);
if (p->MinContext->NumStats == 1)
{
CPpmd_State tmp = *stats;
do
{
tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));
escFreq >>= 1;
}
while (escFreq > 1);
InsertNode(p, stats, U2I(((numStats + 1) >> 1)));
*(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
return;
}
n0 = (numStats + 1) >> 1;
n1 = (p->MinContext->NumStats + 1) >> 1;
if (n0 != n1)
p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
}
p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
p->FoundState = STATS(p->MinContext);
}
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
{
CPpmd_See *see;
unsigned nonMasked = p->MinContext->NumStats - numMasked;
if (p->MinContext->NumStats != 256)
{
see = p->See[p->NS2Indx[nonMasked - 1]] +
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
4 * (numMasked > nonMasked) +
p->HiBitsFlag;
{
unsigned r = (see->Summ >> see->Shift);
see->Summ = (UInt16)(see->Summ - r);
*escFreq = r + (r == 0);
}
}
else
{
see = &p->DummySee;
*escFreq = 1;
}
return see;
}
static void NextContext(CPpmd7 *p)
{
CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
if (p->OrderFall == 0 && (Byte *)c > p->Text)
p->MinContext = p->MaxContext = c;
else
UpdateModel(p);
}
void Ppmd7_Update1(CPpmd7 *p)
{
CPpmd_State *s = p->FoundState;
s->Freq += 4;
p->MinContext->SummFreq += 4;
if (s[0].Freq > s[-1].Freq)
{
SwapStates(&s[0], &s[-1]);
p->FoundState = --s;
if (s->Freq > MAX_FREQ)
Rescale(p);
}
NextContext(p);
}
void Ppmd7_Update1_0(CPpmd7 *p)
{
p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq);
p->RunLength += p->PrevSuccess;
p->MinContext->SummFreq += 4;
if ((p->FoundState->Freq += 4) > MAX_FREQ)
Rescale(p);
NextContext(p);
}
void Ppmd7_UpdateBin(CPpmd7 *p)
{
p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));
p->PrevSuccess = 1;
p->RunLength++;
NextContext(p);
}
void Ppmd7_Update2(CPpmd7 *p)
{
p->MinContext->SummFreq += 4;
if ((p->FoundState->Freq += 4) > MAX_FREQ)
Rescale(p);
p->RunLength = p->InitRL;
UpdateModel(p);
}

View File

@ -0,0 +1,140 @@
/* Ppmd7.h -- PPMdH compression codec
2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
/* This code supports virtual RangeDecoder and includes the implementation
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
#ifndef __PPMD7_H
#define __PPMD7_H
#include "Ppmd.h"
EXTERN_C_BEGIN
#define PPMD7_MIN_ORDER 2
#define PPMD7_MAX_ORDER 64
#define PPMD7_MIN_MEM_SIZE (1 << 11)
#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
struct CPpmd7_Context_;
typedef
#ifdef PPMD_32BIT
struct CPpmd7_Context_ *
#else
UInt32
#endif
CPpmd7_Context_Ref;
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 */
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];
} CPpmd7;
void Ppmd7_Construct(CPpmd7 *p);
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
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)
#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)))
#endif
void Ppmd7_Update1(CPpmd7 *p);
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)]
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);
} IPpmd7_RangeDec;
typedef struct
{
IPpmd7_RangeDec p;
UInt32 Range;
UInt32 Code;
IByteIn *Stream;
} CPpmd7z_RangeDec;
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
/* ---------- Encode ---------- */
typedef struct
{
UInt64 Low;
UInt32 Range;
Byte Cache;
UInt64 CacheSize;
IByteOut *Stream;
} CPpmd7z_RangeEnc;
void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p);
void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p);
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
EXTERN_C_END
#endif

View File

@ -0,0 +1,187 @@
/* Ppmd7Dec.c -- PPMdH Decoder
2010-03-12 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "Ppmd7.h"
#define kTopValue (1 << 24)
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);
}
static UInt32 Range_GetThreshold(void *pp, UInt32 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;
}
}
}
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);
}
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;
}
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
{
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);
}
}

View File

@ -0,0 +1,254 @@
/* Types.h -- Basic types
2010-10-09 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
#include <stddef.h>
#ifdef _WIN32
#include <windows.h>
#endif
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif
EXTERN_C_BEGIN
#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
typedef int SRes;
#ifdef _WIN32
typedef DWORD WRes;
#else
typedef int WRes;
#endif
#ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif
typedef unsigned char Byte;
typedef short Int16;
typedef unsigned short UInt16;
#ifdef _LZMA_UINT32_IS_ULONG
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
#ifdef _SZ_NO_INT_64
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
NOTES: Some code will work incorrectly in that case! */
typedef long Int64;
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL
#endif
#endif
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
typedef size_t SizeT;
#endif
typedef int Bool;
#define True 1
#define False 0
#ifdef _WIN32
#define MY_STD_CALL __stdcall
#else
#define MY_STD_CALL
#endif
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define MY_NO_INLINE __declspec(noinline)
#else
#define MY_NO_INLINE
#endif
#define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall
#else
#define MY_CDECL
#define MY_FAST_CALL
#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 */
} IByteIn;
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 */
} ISeqInStream;
/* it can return SZ_ERROR_INPUT_EOF */
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 */
} ISeqOutStream;
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);
} 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 */
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);
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
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];
} CLookToRead;
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
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. */
} ICompressProgress;
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)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\"
#else
#define CHAR_PATH_SEPARATOR '/'
#define WCHAR_PATH_SEPARATOR L'/'
#define STRING_PATH_SEPARATOR "/"
#define WSTRING_PATH_SEPARATOR L"/"
#endif
EXTERN_C_END
#endif

View File

@ -0,0 +1,106 @@
//
// 僶乕僕儑儞僟僀傾儘僌僋儔僗
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Wnd.h"
#include "AboutDlg.h"
DLG_MESSAGE_BEGIN(CAboutDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDC_VER_WEBSITE, OnWebsite )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CAboutDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_VERSION),
hWndParent, g_DlgProc, (LPARAM)this );
}
DLGMSG CAboutDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CAboutDlg::OnInitDialog\n" );
::SendDlgItemMessage( m_hWnd, IDC_VER_ICON, STM_SETICON,
(WPARAM)CApp::LoadIcon( IDI_ICON ), 0 );
TCHAR str[256];
::wsprintf( str, "VirtuaNESex version %01d.%01d%01d%s",
(VIRTUANES_VERSION&0xF00)>>8,
(VIRTUANES_VERSION&0x0F0)>>4,
(VIRTUANES_VERSION&0x00F),
VIRTUANES_FIXVERSION );
::SetDlgItemText( m_hWnd, IDC_VER_VERSION, str );
::wsprintf( str,
"编译时间:\r\n\
%s %s\r\n\r\n\
\r\n\
tpu \r\n\
temryu \r\n\
byemu \r\n\
\r\n\
",
__DATE__,__TIME__);
::SetDlgItemText( m_hWnd, IDC_VER_CONTRIBUTOR, str );
// ::SetDlgItemText( m_hWnd, IDC_VER_WEBSITE, VIRTUANES_WEBSITE );
m_Website.Attach( ::GetDlgItem( m_hWnd, IDC_VER_WEBSITE ), VIRTUANES_WEBSITE );
string email, mailto;
email = VIRTUANES_EMAILNAME;
email += "@";
email += VIRTUANES_EMAILDOMAIN;
mailto = "mailto:" + email;
m_Email.Attach( ::GetDlgItem( m_hWnd, IDC_VER_EMAIL ), email.c_str(), mailto.c_str() );
return TRUE;
}
DLGCMD CAboutDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CAboutDlg::OnOK\n" );
// m_Website.Detach();
// m_Email.Detach();
::EndDialog( m_hWnd, IDOK );
}
DLGCMD CAboutDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CAboutDlg::OnCancel\n" );
// m_Website.Detach();
// m_Email.Detach();
::EndDialog( m_hWnd, IDCANCEL );
}
DLGCMD CAboutDlg::OnWebsite( DLGCMDPARAM )
{
// DEBUGOUT( "CAboutDlg::OnCancel\n" );
::ShellExecute( HWND_DESKTOP, "open", VIRTUANES_WEBSITE, NULL, NULL, SW_SHOWNORMAL );
// ::ShellExecute( m_hWnd, "open", VIRTUANES_WEBSITE, NULL, NULL, SW_SHOWNORMAL );
}

View File

@ -0,0 +1,36 @@
//
// バージョンダイアログクラス
//
#ifndef __CABOUTDLG_INCLUDED__
#define __CABOUTDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
#include "CHyperLink.h"
class CAboutDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnWebsite( DLGCMDPARAM );
//
CHyperLink m_Website;
CHyperLink m_Email;
private:
};
#endif // !__CABOUTDLG_INCLUDED__

View File

@ -0,0 +1,81 @@
//
// アプリケーションサポートクラス
//
#include "VirtuaNESres.h"
#include "App.h"
// _tWinMainからの引数そのまま
HINSTANCE CApp::m_hInstance = NULL;
HINSTANCE CApp::m_hPrevInstance = NULL;
LPTSTR CApp::m_lpCmdLine = NULL;
INT CApp::m_nCmdShow = 0;
// 言語リソースプラグインのインスタンスハンドル
HINSTANCE CApp::m_hPlugin = NULL;
// メインウインドウのウインドウハンドル
HWND CApp::m_hWnd = NULL;
// メインウインドウのメニューハンドル
HMENU CApp::m_hMenu = NULL;
// プログラムのパス(起動時のパス)
CHAR CApp::m_szModulePath[_MAX_PATH];
// エラーストリング(テンポラリ)
CHAR szErrorString[256];
// エラー処理用
INT CApp::m_ErrorStringTableID[] = {
IDS_ERROR,
IDS_ERROR_STARTUP,
IDS_ERROR_UNKNOWN,
IDS_ERROR_OPEN,
IDS_ERROR_READ,
IDS_ERROR_WRITE,
IDS_ERROR_OUTOFMEMORY,
IDS_ERROR_ILLEGALOPCODE,
IDS_ERROR_UNSUPPORTFORMAT,
IDS_ERROR_INVALIDNESHEADER,
IDS_ERROR_SMALLFILE,
IDS_ERROR_UNSUPPORTMAPPER,
IDS_ERROR_NODISKBIOS,
IDS_ERROR_UNSUPPORTDISK,
IDS_ERROR_ILLEGALDISKSIZE,
IDS_ERROR_ILLEGALMAPPERNO,
IDS_ERROR_ILLEGALHEADER,
IDS_ERROR_ILLEGALSTATECRC,
IDS_ERROR_ILLEGALMOVIEOLD,
IDS_ERROR_ILLEGALMOVIEVER,
IDS_ERROR_ILLEGALMOVIECRC,
IDS_ERROR_ILLEGALMOVIEOLD_A,
IDS_ERROR_ILLEGALMOVIEVER_A,
IDS_ERROR_ILLEGALMOVIECRC_A,
IDS_ERROR_NETWORKDISCONNECT,
IDS_ERROR_NETWORKERROR,
0,
};
CHAR CApp::m_ErrorString[ERRORSTRING_MAX][256];
void CApp::LoadErrorString()
{
if( !m_hPlugin )
return;
for( INT i = 0; m_ErrorStringTableID[i]; i++ ) {
LoadString( m_ErrorStringTableID[i], m_ErrorString[i], sizeof(m_ErrorString[i]) );
}
}
CHAR* CApp::GetErrorString( INT nID )
{
for( INT i = 0; m_ErrorStringTableID[i]; i++ ) {
if( m_ErrorStringTableID[i] == nID )
return m_ErrorString[i];
}
return ""; // NULL ストリングとして渡す
}

View File

@ -0,0 +1,76 @@
//
// アプリケーションサポートクラス
//
#ifndef __CAPP_INCLUDED__
#define __CAPP_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#define ERRORSTRING_MAX 32
class CApp {
public:
// 起動時に設定する
static void SetInstance( HINSTANCE hInstance ) { m_hInstance = hInstance; }
static void SetPrevInstance( HINSTANCE hInstance ) { m_hPrevInstance = hInstance; }
static void SetCmdLine( LPSTR lpCmdLine ) { m_lpCmdLine = lpCmdLine; }
static void SetCmdShow( INT nCmdShow ) { m_nCmdShow = nCmdShow; }
static void SetHWnd( HWND hWnd ) { m_hWnd = hWnd; }
static void SetMenu( HMENU hMenu ) { m_hMenu = hMenu; }
static void SetPlugin( HINSTANCE hPlugin ) { m_hPlugin = hPlugin; LoadErrorString(); }
static void SetModulePath( LPCSTR lpModulePath ) { ::strcpy( m_szModulePath, lpModulePath ); }
// アプリ内部で使用する
static HINSTANCE GetInstance() { return m_hInstance; }
static HINSTANCE GetPrevInstance() { return m_hPrevInstance; }
static LPTSTR GetCmdLine() { return m_lpCmdLine; }
static INT GetCmdShow() { return m_nCmdShow; }
static HWND GetHWnd() { return m_hWnd; }
static HMENU GetMenu() { return m_hMenu; }
static HINSTANCE GetPlugin() { return m_hPlugin; }
static LPCSTR GetModulePath() { return m_szModulePath; }
static HMENU LoadMenu( UINT uID ) { return ::LoadMenu( m_hPlugin, MAKEINTRESOURCE(uID) ); }
static HICON LoadIcon( UINT uID ) { return ::LoadIcon( m_hInstance, MAKEINTRESOURCE(uID) ); }
static INT LoadString( UINT uID, LPTSTR lpBuffer, INT nBufferMax ) {
return ::LoadString( m_hPlugin, uID, lpBuffer, nBufferMax ); }
// エラー処理用
static void LoadErrorString();
static CHAR* GetErrorString( INT nID );
protected:
// WinMain からの引数そのまま
static HINSTANCE m_hInstance;
static HINSTANCE m_hPrevInstance;
static LPSTR m_lpCmdLine;
static INT m_nCmdShow;
// 言語リソースプラグインのインスタンスハンドル
static HINSTANCE m_hPlugin;
// メインウインドウのウインドウハンドル
static HWND m_hWnd;
// メインウインドウのメニューハンドル
static HMENU m_hMenu;
// プログラムのパス(起動時のパス)
static CHAR m_szModulePath[_MAX_PATH];
// エラー処理用
static INT m_ErrorStringTableID[ERRORSTRING_MAX];
static CHAR m_ErrorString[ERRORSTRING_MAX][256];
private:
};
// エラーメッセージ用テンポラリ
extern CHAR szErrorString[256];
#endif // !__CAPP_INCLUDED__

View File

@ -0,0 +1,332 @@
//
// アーカイブファイル操作
//
// Original:NesterJ arc.cpp arc.h by Mikami Kana
// Original:NNNesterJ ulunzip.cpp
//
// Zlib use!
// Reprogrammed by Norix
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shlwapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mbstring.h>
#include <time.h>
#include "typedef.h"
#include "macro.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "VirtuaNESres.h"
#define UNZ_BUFSIZE (65536)
#include "unzip.h"
#ifdef __cplusplus
extern "C" {
#endif
int SevenZipUnCompress( char *fname, unsigned char ** ppBuf,size_t * lpdwSize);
#ifdef __cplusplus
}
#endif
#pragma pack(1)
#define FNAME_MAX32 512
typedef struct {
DWORD dwOriginalSize;
DWORD dwCompressedSize;
DWORD dwCRC;
UINT uFlag;
UINT uOSType;
WORD wRatio;
WORD wDate;
WORD wTime;
char szFileName[FNAME_MAX32 + 1];
char dummy1[3];
char szAttribute[8];
char szMode[8];
} INDIVIDUALINFO, *LPINDIVIDUALINFO;
#pragma pack()
// Un??? use function
typedef int(WINAPI *EXECUTECOMMAND)(HWND,LPCSTR,LPSTR,const DWORD);
typedef BOOL(WINAPI *CHECKARCHIVE)(LPCSTR,const int);
typedef int(WINAPI *EXTRACTMEM)(HWND,LPCSTR,LPBYTE,const DWORD,time_t,LPWORD,LPDWORD);
typedef HGLOBAL(WINAPI *OPENARCHIVE)(HWND,LPCSTR,const DWORD);
typedef int(WINAPI *CLOSEARCHIVE)(HGLOBAL);
typedef int(WINAPI *FINDFIRST)(HGLOBAL,LPCSTR,INDIVIDUALINFO*);
static LPCSTR pszArchiver[] = {
"UNLHA32",
"UNZIP32",
"UNRAR32",
"CAB32",
NULL
};
static LPCSTR pszFuncPrefix[] = {
"Unlha",
"UnZip",
"Unrar",
"Cab",
};
static LPCSTR pszCommand[] = {
NULL,
NULL,
"-e -u \"%s\" \"%s\" \"%s\"",
"-x -j \"%s\" \"%s\" \"%s\"",
};
static LPCSTR pszExtension[] = {
"*.nes",
"*.fds",
"*.nsf",
NULL
};
static BOOL bFileMatching[] = {
FALSE,
TRUE,
FALSE,
FALSE,
};
#define FREEDLL(h) if( h ) { FreeLibrary(h);h=NULL; }
#define M_ERROR_MESSAGE_OFF 0x00800000L
// zlibを使用したZIP解凍ルーチン
BOOL ZlibUnZip( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize )
{
unzFile unzipFile = NULL;
unz_global_info unzipGlobalInfo;
unz_file_info unzipFileInfo;
char fname_buf[256];
*ppBuf = NULL;
*lpdwSize = 0;
if( !(unzipFile = unzOpen( (const char*)fname )) )
return FALSE;
if( unzGetGlobalInfo( unzipFile, &unzipGlobalInfo ) != UNZ_OK ) {
unzClose( unzipFile );
return FALSE;
}
for( uLong i = 0; i < unzipGlobalInfo.number_entry; i++ ) {
if( unzGetCurrentFileInfo( unzipFile, &unzipFileInfo, fname_buf, sizeof(fname_buf), NULL, 0, NULL, 0 ) != UNZ_OK )
break;
char* pExt = ::PathFindExtension( fname_buf );
if( _stricmp( pExt, ".nes" ) == 0 || _stricmp( pExt, ".fds" ) == 0 || _stricmp( pExt, ".nsf" ) == 0 ) {
if( unzipFileInfo.uncompressed_size ) {
if( unzOpenCurrentFile( unzipFile ) != UNZ_OK )
break;
if( unzipFileInfo.uncompressed_size > 0 ) {
if( !(*ppBuf = (LPBYTE)::malloc( unzipFileInfo.uncompressed_size )) )
break;
uInt size = unzReadCurrentFile( unzipFile, *ppBuf, unzipFileInfo.uncompressed_size );
if( size != unzipFileInfo.uncompressed_size )
break;
}
*lpdwSize = unzipFileInfo.uncompressed_size;
if( unzCloseCurrentFile( unzipFile ) != UNZ_OK )
break;
unzClose( unzipFile );
return TRUE;
}
}
// Next file
if( (i+1) < unzipGlobalInfo.number_entry ) {
if( unzGoToNextFile( unzipFile ) != UNZ_OK ) {
break;
}
}
}
FREE( *ppBuf );
if( unzipFile ) {
unzCloseCurrentFile( unzipFile );
unzClose( unzipFile );
}
return FALSE;
}
BOOL UnCompress( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize )
{
HMODULE hDLL;
INDIVIDUALINFO idvinfo;
char* pExt = ::PathFindExtension( fname );
if( _stricmp( pExt, ".zip" ) == 0 ) {
// ZIPならまずzlibライブラリの解凍を使ってみる
if( ZlibUnZip( fname, ppBuf, lpdwSize ) ) {
// DEBUGOUT( "zlib unzip ok! [%s]\n", fname );
return TRUE;
}
} else if( _stricmp( pExt, ".7z" ) == 0 ) {
return SevenZipUnCompress((char*)fname, ppBuf, (size_t*)lpdwSize);
}
hDLL = NULL;
for( INT i = 0; pszArchiver[i]; i++ ) {
// DLLアンロード
FREEDLL( hDLL );
// DLLロード
if( !(hDLL = LoadLibrary( pszArchiver[i] )) )
continue;
CHAR szTemp[256];
sprintf( szTemp, "%sCheckArchive", pszFuncPrefix[i] );
CHECKARCHIVE CheckArchive;
if( !(CheckArchive = (CHECKARCHIVE)GetProcAddress( hDLL, szTemp )) )
continue;
// 対応するアーカイブかチェックする
if( !CheckArchive( fname, 1 ) )
continue;
// アーカイブ内に対応するファイルがあるかのチェック
OPENARCHIVE OpenArchive;
CLOSEARCHIVE CloseArchive;
FINDFIRST FindFirst;
sprintf( szTemp, "%sOpenArchive", pszFuncPrefix[i] );
OpenArchive = (OPENARCHIVE)GetProcAddress( hDLL, szTemp );
sprintf( szTemp, "%sFindFirst", pszFuncPrefix[i] );
FindFirst = (FINDFIRST)GetProcAddress( hDLL, szTemp );
sprintf( szTemp, "%sCloseArchive", pszFuncPrefix[i] );
CloseArchive = (CLOSEARCHIVE)GetProcAddress( hDLL, szTemp );
HGLOBAL hARC;
BOOL bFound = FALSE;
for( INT j = 0; pszExtension[j]; j++ ) {
if( !(hARC = OpenArchive( NULL, fname, M_ERROR_MESSAGE_OFF ) ) ) {
CloseArchive( hARC );
break;
}
INT ret = FindFirst( hARC, pszExtension[j], &idvinfo );
CloseArchive( hARC );
if( ret == 0 ) { // Found!!
bFound = TRUE;
break;
} else if( ret == -1 ) { // Not found.
} else { // 異常終了
break;
}
}
if( !bFound )
continue;
if( !pszCommand[i] ) {
// メモリ解凍あり(UNLHA32,UNZIP32)
*lpdwSize = idvinfo.dwOriginalSize;
*ppBuf = (LPBYTE)malloc( *lpdwSize );
CHAR szCmd [256];
CHAR szFunc[256];
if( !bFileMatching[i] ) {
sprintf( szCmd, "\"%s\" \"%s\"", fname, idvinfo.szFileName );
} else {
// UNZIP32 only
BYTE szFile[FNAME_MAX32+1];
LPBYTE lpF0, lpF1;
// 正規表現を切るオプションが欲しかった....
lpF0 = (LPBYTE)idvinfo.szFileName;
lpF1 = szFile;
while( *lpF0 ) {
if( *lpF0 == '[' || *lpF0 == ']' ) {
*lpF1++ = '\\';
}
_mbsncpy( lpF1, lpF0, 1 );
lpF0 = _mbsinc( lpF0 );
lpF1 = _mbsinc( lpF1 );
}
*lpF1 = '\0';
sprintf( szCmd, "\"%s\" \"%s\"", fname, szFile );
}
sprintf( szFunc, "%sExtractMem", pszFuncPrefix[i] );
EXTRACTMEM ExtractMem;
ExtractMem = (EXTRACTMEM)GetProcAddress( hDLL, szFunc );
INT ret = ExtractMem( NULL, szCmd, (LPBYTE)(*ppBuf), *lpdwSize, NULL, NULL, NULL );
FREEDLL( hDLL );
if( ret == 0 )
return TRUE;
} else {
// メモリ解凍が無い場合
CHAR szCmd [256];
CHAR szTempPath[_MAX_PATH];
EXECUTECOMMAND ExecuteCommand;
GetTempPath( _MAX_PATH, szTempPath );
//DEBUGOUT( "TempPath:%s\n", szTempPath );
sprintf( szCmd, pszCommand[i], fname, szTempPath, idvinfo.szFileName );
ExecuteCommand = (EXECUTECOMMAND)GetProcAddress( hDLL, pszFuncPrefix[i] );
ExecuteCommand( NULL, szCmd, NULL, 0 );
FREEDLL( hDLL );
string FileName = CPathlib::MakePath( szTempPath, idvinfo.szFileName );
FILE *fp = NULL;
if( (fp = fopen( FileName.c_str(), "rb" )) ) {
// ファイルサイズ取得
fseek( fp, 0, SEEK_END );
*lpdwSize = ftell( fp );
fseek( fp, 0, SEEK_SET );
if( *lpdwSize < 17 ) {
// ファイルサイズが小さすぎます
throw CApp::GetErrorString( IDS_ERROR_SMALLFILE );
}
// テンポラリメモリ確保
if( !(*ppBuf = (LPBYTE)malloc( *lpdwSize )) ) {
FCLOSE( fp );
// メモリを確保出来ません
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
}
// サイズ分読み込み
if( fread( *ppBuf, *lpdwSize, 1, fp ) != 1 ) {
FCLOSE( fp );
FREE( *ppBuf );
// ファイルの読み込みに失敗しました
throw CApp::GetErrorString( IDS_ERROR_READ );
}
FCLOSE( fp );
DeleteFile( FileName.c_str() );
} else {
// xxx ファイルを開けません
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
sprintf( szErrorString, szErrStr, fname );
throw szErrorString;
}
return TRUE;
}
}
FREEDLL( hDLL );
return FALSE;
}
// Archive

View File

@ -0,0 +1,12 @@
//
// アーカイブファイル操作
//
#ifndef __CARCHIVEFILE_INCLUDED__
#define __CARCHIVEFILE_INCLUDED__
#include "typedef.h"
extern BOOL UnCompress( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize );
#endif // !__CARCHIVEFILE_INCLUDED__

View File

@ -0,0 +1,250 @@
#ifndef __CHYPERLINK_INCLUDED__
#define __CHYPERLINK_INCLUDED__
//
// スタティックコントロールをSubclass化してハイパーリンクをサポート
//
// Usage: CHyperLink hyperlink;
// hyperlink.Attach( GetDlgItem( hWnd, IDC_URL ) );
//
class CHyperLink
{
public:
CHyperLink() : m_hWnd(NULL), m_lpLabel(NULL),
m_hCursor(NULL), m_hFont(NULL),
m_lpHyperLink(NULL), m_lpfnOldWndProc(NULL)
{
}
~CHyperLink()
{
Detach();
}
// コントロールにアタッチする
BOOL Attach( HWND hWnd, LPCSTR lpLabel = NULL, LPCSTR lpHyperLink = NULL )
{
if( m_hWnd )
return FALSE; // 既にAttach済み
m_hWnd = hWnd;
// 文字列をコピー
if( lpLabel ) {
m_lpLabel = new CHAR[::lstrlen(lpLabel)+1];
::lstrcpy( m_lpLabel, lpLabel );
::SendMessage( m_hWnd, WM_SETTEXT, 0, (LPARAM)m_lpLabel );
}
// 表示とハイパーリンクが同じ場合はハイパーリンクはラベルと同じに
if( lpLabel && !lpHyperLink ) {
m_lpHyperLink = new CHAR[::lstrlen(lpLabel)+1];
::lstrcpy( m_lpHyperLink, lpLabel );
}
// ハイパーリンクが別の場合
if( lpHyperLink ) {
m_lpHyperLink = new CHAR[::lstrlen(lpHyperLink)+1];
::lstrcpy( m_lpHyperLink, lpHyperLink );
}
// ポイントカーソル(無ければデフォルト)
m_hCursor = ::LoadCursor( NULL, MAKEINTRESOURCE(32649) );
// アンダーラインフォントの作成
HFONT m_hOldFont = (HFONT)::SendMessage( hWnd, WM_GETFONT, 0, 0 );
LOGFONT lFont;
::GetObject( m_hOldFont, sizeof(LOGFONT), &lFont );
lFont.lfUnderline = TRUE;
m_hFont = ::CreateFontIndirect( &lFont );
// ラベルの表示領域を計算
CalcLabelRectangle();
// スタイルの変更(通知をイネーブルにする)
DWORD dwStyle = ::GetWindowLong( hWnd, GWL_STYLE );
dwStyle |= SS_NOTIFY;
::SetWindowLong( hWnd, GWL_STYLE, (LONG)dwStyle );
// コントロールのサブクラス化
m_lpfnOldWndProc = (WNDPROC)::SetWindowLong( hWnd, GWL_WNDPROC, (LONG)HyperLinkProc );
// Thisを埋め込む
::SetWindowLong( hWnd, GWL_USERDATA, (LONG)this );
return TRUE;
}
BOOL Detach()
{
if( m_hWnd ) {
// サブクラス化を解除
if( m_lpfnOldWndProc ) {
::SetWindowLong( m_hWnd, GWL_WNDPROC, (LONG)m_lpfnOldWndProc );
m_lpfnOldWndProc = NULL;
}
// フォントを削除
if( m_hFont ) {
::DeleteObject( (HGDIOBJ)m_hFont );
m_hFont = NULL;
}
// 文字列を削除
if( m_lpLabel ) {
delete[] m_lpLabel;
m_lpLabel = NULL;
}
if( m_lpHyperLink ) {
delete[] m_lpHyperLink;
m_lpHyperLink = NULL;
}
}
m_hWnd = NULL;
return TRUE;
}
BOOL SetLabel( LPCSTR lpLabel )
{
if( m_lpLabel ) {
delete[] m_lpLabel;
}
m_lpLabel = new CHAR[::lstrlen(lpLabel)+1];
::lstrcpy( m_lpLabel, lpLabel );
// コントロールに文字列を設定
::SendMessage( m_hWnd, WM_SETTEXT, 0, (LPARAM)m_lpLabel );
// ラベルの表示領域を計算
CalcLabelRectangle();
}
BOOL SetHyperLink( LPCSTR lpHyperLink )
{
if( m_lpHyperLink ) {
delete[] m_lpHyperLink;
}
m_lpHyperLink = new CHAR[::lstrlen(lpHyperLink)+1];
::lstrcpy( m_lpHyperLink, lpHyperLink );
}
protected:
BOOL CalcLabelRectangle()
{
if( !::IsWindow(m_hWnd) )
return FALSE;
if( !m_lpLabel )
return FALSE;
RECT rcClient;
::GetClientRect( m_hWnd, &rcClient );
m_rcLabel = rcClient;
HDC hDC = ::GetDC( m_hWnd );
HFONT hOldFont = (HFONT)::SelectObject( hDC, m_hFont );
// スタイル
DWORD dwStyle = ::GetWindowLong( m_hWnd, GWL_STYLE );
INT nDrawStyle = DT_LEFT;
if( dwStyle && SS_CENTER ) {
nDrawStyle = DT_CENTER;
} else if( dwStyle && SS_RIGHT ) {
nDrawStyle = DT_RIGHT;
}
// 文字列表示と描画領域の計算
::DrawText( hDC, m_lpLabel, -1, &m_rcLabel, nDrawStyle | DT_WORDBREAK | DT_CALCRECT );
::SelectObject( hDC, hOldFont );
// スタイルによってオフセットを計算
if( dwStyle & SS_CENTER ) {
::OffsetRect( &m_rcLabel, (rcClient.right - m_rcLabel.right) / 2, 0 );
} else if (dwStyle & SS_RIGHT) {
::OffsetRect( &m_rcLabel, rcClient.right - m_rcLabel.right, 0 );
}
return true;
}
static LRESULT CALLBACK HyperLinkProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
CHyperLink* pHyperLink = reinterpret_cast<CHyperLink*>(::GetWindowLong( hWnd, GWL_USERDATA));
switch( msg ) {
case WM_DESTROY:
{
// 2003/10/11 リリース後にfix...
WNDPROC pWndProcOld = pHyperLink->m_lpfnOldWndProc;
pHyperLink->Detach();
return CallWindowProc( pWndProcOld, hWnd, msg, wParam, lParam );
}
break;
case WM_LBUTTONDOWN: {
POINT pt = { LOWORD(lParam), HIWORD(lParam) };
if( pHyperLink->m_lpLabel && pHyperLink->m_lpHyperLink ) {
if( ::PtInRect( &pHyperLink->m_rcLabel, pt ) ) {
::ShellExecute( hWnd, NULL, pHyperLink->m_lpHyperLink, NULL, NULL, SW_SHOWNORMAL );
return TRUE;
}
}
}
break;
case WM_MOUSEMOVE: {
POINT pt = { LOWORD(lParam), HIWORD(lParam) };
if( pHyperLink->m_lpLabel && pHyperLink->m_lpHyperLink ) {
if( ::PtInRect( &pHyperLink->m_rcLabel, pt ) ) {
::SetCursor( pHyperLink->m_hCursor );
return TRUE;
}
}
}
break;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hDC = ::BeginPaint( hWnd, &ps );
DWORD dwStyle = ::GetWindowLong( hWnd, GWL_STYLE );
INT nDrawStyle = DT_LEFT;
if( dwStyle && SS_CENTER ) {
nDrawStyle = DT_CENTER;
} else if( dwStyle && SS_RIGHT ) {
nDrawStyle = DT_RIGHT;
}
// アトリビュート
::SetBkMode( hDC, TRANSPARENT );
::SetTextColor( hDC, 0x00FF0000 );
// 文字列表示
if( pHyperLink->m_lpLabel ) {
HFONT hOldFont = (HFONT)::SelectObject( hDC, pHyperLink->m_hFont );
::DrawText( hDC, pHyperLink->m_lpLabel, -1, &pHyperLink->m_rcLabel, nDrawStyle | DT_WORDBREAK );
::SelectObject( hDC, hOldFont );
}
::EndPaint( hWnd, &ps );
}
return TRUE;
default:
break;
}
return CallWindowProc( pHyperLink->m_lpfnOldWndProc, hWnd, msg, wParam, lParam );
}
HWND m_hWnd;
HFONT m_hFont;
HFONT m_hOldFont;
HCURSOR m_hCursor;
WNDPROC m_lpfnOldWndProc;
RECT m_rcLabel;
LPSTR m_lpLabel;
LPSTR m_lpHyperLink;
private:
};
#endif // !__CHYPERLINK_INCLUDED__

View File

@ -0,0 +1,277 @@
//
// チャットダイアログクラス
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <mbstring.h>
#include <shlwapi.h>
#include <string>
using namespace std;
#include "typedef.h"
#include "macro.h"
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Config.h"
#include "NetPlay.h"
#include "Wnd.h"
#include "ChatDlg.h"
// メッセージ
DLG_MESSAGE_BEGIN(CChatDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_ON_MESSAGE( WM_DESTROY, OnDestroy )
DLG_ON_MESSAGE( WM_CLOSE, OnClose )
DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate )
DLG_ON_MESSAGE( WM_SETCURSOR, OnSetCursor )
DLG_ON_MESSAGE( WM_SIZE, OnSize )
DLG_ON_MESSAGE( WM_CTLCOLORSTATIC, OnControlColorStatic )
DLG_ON_MESSAGE( WM_COPYDATA, OnCopyData )
// コマンド
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND_NOTIFY( IDC_NCT_MESSAGE, EN_SETFOCUS, OnMessageFocus )
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDC_NCT_SEND, OnSend )
DLG_COMMAND_END()
// Notify メッセージ
DLG_NOTIFY_BEGIN()
DLG_NOTIFY_END()
DLG_MESSAGE_END()
BOOL CChatDlg::Create( HWND hWndParent )
{
// 親はデスクトップにする
m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_NETPLAY_CHAT),
NULL, g_DlgProc, (LPARAM)this );
if( !m_hWnd )
return FALSE;
// モードレスダイアログリストに加える
CWndList::Add( this );
return TRUE;
}
void CChatDlg::Destroy()
{
if( m_hWnd ) {
// モードレスダイアログリストから削除
CWndList::Del( this );
::GetWindowRect( m_hWnd, &Config.netplay.rcChatPos );
::DestroyWindow( m_hWnd );
m_hWnd = NULL;
}
}
void CChatDlg::SetEditText()
{
CHAR szText[256+1];
::GetWindowText( ::GetDlgItem(m_hWnd, IDC_NCT_EDIT), szText, sizeof(szText)-1 );
::SetWindowText( ::GetDlgItem(m_hWnd, IDC_NCT_EDIT), "" );
if( ::strlen(szText) ) {
// clear message window
if( ::StrCmpI( szText, "/clear" ) == 0 ) {
::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_SETSEL, 0, -1 );
::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_REPLACESEL, FALSE, (WPARAM)"" );
return;
}
string str;
if( NetPlay.IsConnect() ) {
str = "(";
str = str + Config.netplay.szNick;
str = str + ") ";
}
str = str + szText;
str = str + "\r\n";
// 相手に送信
if( NetPlay.IsConnect() ) {
NetPlay.ChatSend( (LPSTR)str.c_str() );
}
// 自分自身のメッセージを表示
INT n = GetWindowTextLength( GetDlgItem( m_hWnd, IDC_NCT_MESSAGE ) );
::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_SETSEL, (WPARAM)n, (LPARAM)n );
::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)str.c_str() );
}
}
DLGMSG CChatDlg::OnCopyData( DLGMSGPARAM )
{
COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;
CHAR* lpStr = (CHAR*)pcds->lpData;
INT n = GetWindowTextLength( GetDlgItem( hWnd, IDC_NCT_MESSAGE ) );
::SendDlgItemMessage( hWnd, IDC_NCT_MESSAGE, EM_SETSEL, (WPARAM)n, (LPARAM)n );
::SendDlgItemMessage( hWnd, IDC_NCT_MESSAGE, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)lpStr );
if( ::GetFocus() != m_hWnd && ::strlen( lpStr ) > 0 ) {
::MessageBeep( MB_OK );
// ::PlaySound( "MailBeep", NULL, SND_ALIAS|SND_ASYNC );
}
// メッセージが来たらポップアップさせるため
::SendMessage( CApp::GetHWnd(), WM_VNS_CHATPOPUP, 0, 0 );
return TRUE;
}
DLGMSG CChatDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CChatDlg::OnInitDialog\n" );
NetPlay.SetChatWnd( m_hWnd );
// 位置情報を保存
::GetClientRect( m_hWnd, &m_rcClient );
::GetWindowRect( ::GetDlgItem(m_hWnd, IDC_NCT_MESSAGE), &m_rcMessage );
::GetWindowRect( ::GetDlgItem(m_hWnd, IDC_NCT_EDIT), &m_rcEdit );
::GetWindowRect( ::GetDlgItem(m_hWnd, IDC_NCT_SEND), &m_rcButton );
// クライアント座標への変換
::ScreenToClient( m_hWnd, (POINT*)&m_rcMessage.left );
::ScreenToClient( m_hWnd, (POINT*)&m_rcMessage.right );
::ScreenToClient( m_hWnd, (POINT*)&m_rcEdit.left );
::ScreenToClient( m_hWnd, (POINT*)&m_rcEdit.right );
::ScreenToClient( m_hWnd, (POINT*)&m_rcButton.left );
::ScreenToClient( m_hWnd, (POINT*)&m_rcButton.right );
// ウインドウ位置/サイズの設定
// RECT rc = Config.launcher.rcWindowPos;
// if( (rc.right-rc.left) && (rc.bottom-rc.top) ) {
// ::SetWindowPos( m_hWnd, NULL, rc.left, rc.top, RCWIDTH(rc), RCHEIGHT(rc), SWP_NOZORDER );
// }
// ウインドウ位置/サイズの設定
RECT rc = Config.netplay.rcChatPos;
if( (rc.right-rc.left) && (rc.bottom-rc.top) ) {
::SetWindowPos( m_hWnd, NULL, rc.left, rc.top, RCWIDTH(rc), RCHEIGHT(rc), SWP_NOZORDER );
}
// 表示
::ShowWindow( m_hWnd, SW_SHOW );
return TRUE;
}
DLGMSG CChatDlg::OnDestroy( DLGMSGPARAM )
{
return TRUE;
}
DLGMSG CChatDlg::OnClose( DLGMSGPARAM )
{
::ShowWindow( m_hWnd, SW_HIDE ); // 非表示にするだけ
return TRUE;
}
DLGMSG CChatDlg::OnActivate( DLGMSGPARAM )
{
if( LOWORD(wParam) == WA_INACTIVE ) {
// DEBUGOUT( "CChatDlg::OnActivate:Inactive\n" );
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 );
Config.InputKeyboardDisable( FALSE );
} else {
// DEBUGOUT( "CChatDlg::OnActivate:Active\n" );
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 );
Config.InputKeyboardDisable( TRUE );
}
return TRUE;
}
DLGMSG CChatDlg::OnSetCursor( DLGMSGPARAM )
{
// DEBUGOUT( "CChatDlg::OnSetCursor\n" );
return FALSE;
}
DLGMSG CChatDlg::OnSize( DLGMSGPARAM )
{
// DEBUGOUT( "CChatDlg::OnSize\n" );
HWND hWndCtrl;
RECT rcC, rcT;
::GetClientRect( m_hWnd, &rcC );
// メッセージ枠
if( (hWndCtrl = ::GetDlgItem( m_hWnd, IDC_NCT_MESSAGE )) ) {
rcT.left = rcC.left;
rcT.right = rcC.right;
rcT.top = rcC.top;
rcT.bottom = rcC.bottom - (m_rcClient.bottom-m_rcMessage.bottom);
::MoveWindow( hWndCtrl, rcT.left, rcT.top, RCWIDTH(rcT), RCHEIGHT(rcT), TRUE );
}
if( (hWndCtrl = ::GetDlgItem( m_hWnd, IDC_NCT_EDIT )) ) {
rcT.left = rcC.left;
rcT.right = rcC.right - (m_rcClient.right-m_rcEdit.right);
rcT.top = rcC.bottom - (m_rcClient.bottom-m_rcEdit.top);
rcT.bottom = rcC.bottom - (m_rcClient.bottom-m_rcEdit.bottom);
::MoveWindow( hWndCtrl, rcT.left, rcT.top, RCWIDTH(rcT), RCHEIGHT(rcT), TRUE );
}
if( (hWndCtrl = ::GetDlgItem( m_hWnd, IDC_NCT_SEND )) ) {
rcT.left = rcC.right - (m_rcClient.right-m_rcButton.left);
rcT.right = rcT.left + RCWIDTH(m_rcButton);
rcT.top = rcC.bottom - (m_rcClient.bottom-m_rcButton.top);
rcT.bottom = rcT.top + RCHEIGHT(m_rcButton);
::MoveWindow( hWndCtrl, rcT.left, rcT.top, RCWIDTH(rcT), RCHEIGHT(rcT), TRUE );
}
return FALSE;
}
DLGMSG CChatDlg::OnControlColorStatic( DLGMSGPARAM )
{
if( (HWND)lParam == ::GetDlgItem( m_hWnd, IDC_NCT_MESSAGE ) ) {
SetBkColor( (HDC)wParam, (COLORREF)0x00FFFFFF );
bResult = (LRESULT)GetStockObject( WHITE_BRUSH );
return TRUE;
}
return FALSE;
}
DLGCMD CChatDlg::OnMessageFocus( DLGCMDPARAM )
{
DEBUGOUT( "CChatDlg::OnMessageFocus\n" );
// ::SetFocus( ::GetDlgItem( m_hWnd, IDC_NCT_EDIT ) );
::SetFocus( m_hWnd );
}
DLGCMD CChatDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CChatDlg::OnOK\n" );
SetEditText();
}
DLGCMD CChatDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CChatDlg::OnCancel\n" );
::ShowWindow( m_hWnd, SW_HIDE ); // 非表示にするだけ
}
DLGCMD CChatDlg::OnSend( DLGCMDPARAM )
{
// DEBUGOUT( "CChatDlg::OnSend\n" );
SetEditText();
::SetFocus( ::GetDlgItem( m_hWnd, IDC_NCT_EDIT ) );
}

View File

@ -0,0 +1,55 @@
//
// チャットダイアログクラス
//
#ifndef __CCHATDLG_INCLUDED__
#define __CCHATDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
class CChatDlg : public CWnd
{
public:
// Override from CWnd
BOOL Create( HWND hWndParent );
void Destroy();
// Set Message
void SetEditText();
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGMSG OnDestroy( DLGMSGPARAM );
DLGMSG OnClose( DLGMSGPARAM );
DLGMSG OnActivate( DLGMSGPARAM );
DLGMSG OnSetCursor( DLGMSGPARAM );
DLGMSG OnSize( DLGMSGPARAM );
DLGMSG OnControlColorStatic( DLGMSGPARAM );
DLGMSG OnCopyData( DLGMSGPARAM );
DLGCMD OnMessageFocus( DLGCMDPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnSend( DLGCMDPARAM );
//
// 位置
RECT m_rcClient; // クライアントエリア
RECT m_rcMessage; // メッセージ枠
RECT m_rcEdit; // エディット枠
RECT m_rcButton; // 送信ボタン
private:
};
#endif // !__CCHATDLG_INCLUDED__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,175 @@
//
// チートダイアログクラス
//
#ifndef __CCHEATDLG_INCLUDED__
#define __CCHEATDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <list>
#include <vector>
#include <string>
using namespace std;
#include "Wnd.h"
#include "cheat.h"
// サーチダイアログ
class CSearchDlg : public CWnd
{
public:
// Override from CWnd
BOOL Create( HWND hWndParent );
void Destroy();
protected:
void OnListUpdate();
// Utils
DWORD GetNesMemory( INT length, DWORD addr );
DWORD GetSearchMemory( INT length, DWORD addr );
DWORD GetSearchMemoryOld( INT length, DWORD addr );
BOOL CompareData( INT type, DWORD dataA, DWORD dataB );
BOOL CompareRange( INT length, DWORD dataA, DWORD dataB, DWORD range );
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGMSG OnActivate( DLGMSGPARAM );
DLGMSG OnClose( DLGMSGPARAM );
DLGMSG OnContextMenu( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnRadixCommand( DLGCMDPARAM );
DLGCMD OnLengthCommand( DLGCMDPARAM );
DLGCMD OnStart( DLGCMDPARAM );
DLGCMD OnUpdate( DLGCMDPARAM );
DLGCMD OnUndo( DLGCMDPARAM );
DLGCMD OnSearchCommand( DLGCMDPARAM );
DLGCMD OnSearchData( DLGCMDPARAM );
DLGCMD OnWriteData( DLGCMDPARAM );
DLGCMD OnCodeAppend( DLGCMDPARAM );
//
DLGNOTIFY OnDoubleClickListView( DLGNOTIFYPARAM );
private:
HMENU m_hMenu;
HMENU m_hSubMenu;
BOOL m_bShortCutDisable;
WORD m_Address;
INT m_nRadix;
INT m_nLength;
struct RESULT {
BYTE RAM_N[0x0800]; // RAM New value
BYTE RAM_O[0x0800]; // RAM Old value
BYTE RAM_F[0x0800]; // RAM Flag
BYTE SRAM_N[0x2000]; // RAM New value
BYTE SRAM_O[0x2000]; // RAM Old value
BYTE SRAM_F[0x2000]; // RAM Flag
};
struct RESULT m_Result; // 今回データ
struct RESULT m_ResultOld; // 1回前
};
// チートコード編集ダイアログ
class CCheatCodeEditDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
//
CHEATCODE m_Code;
INT m_nRadix;
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
//
private:
};
// チートコード入力ダイアログ
class CCheatCodeInputDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
string m_Codes;
string m_Comment;
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
//
private:
};
// チートコードダイアログ
class CCheatCodeDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
void OnListUpdate();
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGMSG OnDestroy( DLGMSGPARAM );
DLGMSG OnTimer( DLGMSGPARAM );
DLGNOTIFY OnKeyDownListView( DLGNOTIFYPARAM );
DLGNOTIFY OnClickListView( DLGNOTIFYPARAM );
DLGNOTIFY OnDblClkListView( DLGNOTIFYPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnEnable( DLGCMDPARAM );
DLGCMD OnDisable( DLGCMDPARAM );
DLGCMD OnClear( DLGCMDPARAM );
DLGCMD OnRemove( DLGCMDPARAM );
DLGCMD OnInput( DLGCMDPARAM );
DLGCMD OnEdit( DLGCMDPARAM );
DLGCMD OnLoad( DLGCMDPARAM );
DLGCMD OnSave( DLGCMDPARAM );
// Image List
HIMAGELIST m_hImageList;
// Timer
UINT m_uTimerID;
// Temp buffer
vector<CHEATCODE> m_CheatCode;
private:
};
#endif // !__CCHEATDLG_INCLUDED__

View File

@ -0,0 +1,35 @@
//
// COM—˜—pƒTƒ|<7C>[ƒgƒNƒ‰ƒX
//
#include <objbase.h>
#include "DebugOut.h"
#include "Com.h"
INT COM::m_nRefCount = 0;
LRESULT COM::AddRef()
{
if( !m_nRefCount ) {
HRESULT hr;
if( (hr = ::CoInitialize( NULL )) != S_OK ) {
DEBUGOUT( "COM::AddRef() CoInitialize failed.\n" );
return hr;
}
DEBUGOUT( "COM::AddRef() CoInitialize.\n" );
}
m_nRefCount++;
return 0L;
}
void COM::Release()
{
if( !m_nRefCount ) {
DEBUGOUT( "COM::Release() too many released.\n" );
return;
}
if( !(--m_nRefCount) ) {
::CoUninitialize();
DEBUGOUT( "COM::AddRef() CoUninitialize.\n" );
}
}

View File

@ -0,0 +1,21 @@
//
// COM利用サポートクラス
//
#ifndef __CCOM_INCLUDED__
#define __CCOM_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
class COM
{
public:
static LRESULT AddRef();
static void Release();
protected:
static INT m_nRefCount;
};
#endif // !__CCOM_INCLUDED__

View File

@ -0,0 +1,817 @@
//
// 設定保存クラス
//
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "Config.h"
#include "Registry.h"
#include "DirectInput.h"
#include "extsoundfile.h"
// Global instance
CConfig Config;
// Sampling rate table
INT CConfig::SamplingRateTable[] = {
11025, 8, 11025, 16, 22050, 8, 22050, 16,
44100, 8, 44100, 16, 48000, 8, 48000, 16,
};
// Shortcut key IDs table
INT CConfig::ShortcutKeyID[] = {
// Main controls
ID_OPEN, IDS_CUT_OPEN, 0,
ID_CLOSE, IDS_CUT_CLOSE, 1,
ID_LAUNCHER, IDS_CUT_LAUNCHER, 2,
ID_NETPLAY_CONNECT, IDS_CUT_NETPLAY_CONNECT, 3,
ID_NETPLAY_DISCONNECT, IDS_CUT_NETPLAY_DISCONNECT, 4,
ID_NETPLAY_CHAT, IDS_CUT_NETPLAY_CHAT, 5,
ID_ROMINFO, IDS_CUT_ROMINFO, 8,
ID_WAVERECORD, IDS_CUT_WAVERECORD, 9,
ID_EXIT, IDS_CUT_EXIT, 15,
// Emulation controls
ID_HWRESET, IDS_CUT_HWRESET, 16,
ID_SWRESET, IDS_CUT_SWRESET, 17,
ID_PAUSE, IDS_CUT_PAUSE, 18,
ID_ONEFRAME, IDS_CUT_ONEFRAME, 23,
ID_THROTTLE, IDS_CUT_THROTTLE, 19,
ID_KEYTHROTTLE, IDS_CUT_KEYTHROTTLE, 24,
ID_FRAMESKIP_AUTO, IDS_CUT_FRAMESKIP_AUTO, 20,
ID_FRAMESKIP_UP, IDS_CUT_FRAMESKIP_UP, 21,
ID_FRAMESKIP_DOWN, IDS_CUT_FRAMESKIP_DOWN, 22,
// State controls
ID_STATE_LOAD, IDS_CUT_STATE_LOAD, 32,
ID_STATE_SAVE, IDS_CUT_STATE_SAVE, 33,
ID_STATE_UP, IDS_CUT_STATE_UP, 34,
ID_STATE_DOWN, IDS_CUT_STATE_DOWN, 35,
ID_STATE_SLOT0, IDS_CUT_STATE_SLOT0, 36,
ID_STATE_SLOT1, IDS_CUT_STATE_SLOT1, 37,
ID_STATE_SLOT2, IDS_CUT_STATE_SLOT2, 38,
ID_STATE_SLOT3, IDS_CUT_STATE_SLOT3, 39,
ID_STATE_SLOT4, IDS_CUT_STATE_SLOT4, 40,
ID_STATE_SLOT5, IDS_CUT_STATE_SLOT5, 41,
ID_STATE_SLOT6, IDS_CUT_STATE_SLOT6, 42,
ID_STATE_SLOT7, IDS_CUT_STATE_SLOT7, 43,
ID_STATE_SLOT8, IDS_CUT_STATE_SLOT8, 44,
ID_STATE_SLOT9, IDS_CUT_STATE_SLOT9, 45,
// QuickLoad
ID_QUICKLOAD_SLOT0, IDS_CUT_QUICKLOAD_SLOT0, 256,
ID_QUICKLOAD_SLOT1, IDS_CUT_QUICKLOAD_SLOT1, 257,
ID_QUICKLOAD_SLOT2, IDS_CUT_QUICKLOAD_SLOT2, 258,
ID_QUICKLOAD_SLOT3, IDS_CUT_QUICKLOAD_SLOT3, 259,
ID_QUICKLOAD_SLOT4, IDS_CUT_QUICKLOAD_SLOT4, 260,
ID_QUICKLOAD_SLOT5, IDS_CUT_QUICKLOAD_SLOT5, 261,
ID_QUICKLOAD_SLOT6, IDS_CUT_QUICKLOAD_SLOT6, 262,
ID_QUICKLOAD_SLOT7, IDS_CUT_QUICKLOAD_SLOT7, 263,
ID_QUICKLOAD_SLOT8, IDS_CUT_QUICKLOAD_SLOT8, 264,
ID_QUICKLOAD_SLOT9, IDS_CUT_QUICKLOAD_SLOT9, 265,
// QuickSave
ID_QUICKSAVE_SLOT0, IDS_CUT_QUICKSAVE_SLOT0, 266,
ID_QUICKSAVE_SLOT1, IDS_CUT_QUICKSAVE_SLOT1, 267,
ID_QUICKSAVE_SLOT2, IDS_CUT_QUICKSAVE_SLOT2, 268,
ID_QUICKSAVE_SLOT3, IDS_CUT_QUICKSAVE_SLOT3, 269,
ID_QUICKSAVE_SLOT4, IDS_CUT_QUICKSAVE_SLOT4, 270,
ID_QUICKSAVE_SLOT5, IDS_CUT_QUICKSAVE_SLOT5, 271,
ID_QUICKSAVE_SLOT6, IDS_CUT_QUICKSAVE_SLOT6, 272,
ID_QUICKSAVE_SLOT7, IDS_CUT_QUICKSAVE_SLOT7, 273,
ID_QUICKSAVE_SLOT8, IDS_CUT_QUICKSAVE_SLOT8, 274,
ID_QUICKSAVE_SLOT9, IDS_CUT_QUICKSAVE_SLOT9, 275,
// Disk controls
ID_DISK_EJECT, IDS_CUT_DISK_EJECT, 48,
ID_DISK_0A, IDS_CUT_DISK_0A, 49,
ID_DISK_0B, IDS_CUT_DISK_0B, 50,
ID_DISK_1A, IDS_CUT_DISK_1A, 51,
ID_DISK_1B, IDS_CUT_DISK_1B, 52,
// Movie controls
ID_MOVIE_PLAY, IDS_CUT_MOVIE_PLAY, 56,
ID_MOVIE_REC, IDS_CUT_MOVIE_REC, 57,
ID_MOVIE_REC_APPEND, IDS_CUT_MOVIE_REC_APPEND, 58,
ID_MOVIE_STOP, IDS_CUT_MOVIE_STOP, 59,
ID_MOVIE_INFO, IDS_CUT_MOVIE_INFO, 60,
// Screen controls
ID_ZOOMx1, IDS_CUT_ZOOMx1, 64,
ID_ZOOMx2, IDS_CUT_ZOOMx2, 65,
ID_ZOOMx3, IDS_CUT_ZOOMx3, 66,
ID_ZOOMx4, IDS_CUT_ZOOMx4, 67,
ID_FULLSCREEN, IDS_CUT_FULLSCREEN, 68,
// Sound controls
ID_MUTE_0, IDS_CUT_MUTE_MASTER, 72,
ID_MUTE_1, IDS_CUT_MUTE_RECTANGLE1, 73,
ID_MUTE_2, IDS_CUT_MUTE_RECTANGLE2, 74,
ID_MUTE_3, IDS_CUT_MUTE_TRIANGLE, 75,
ID_MUTE_4, IDS_CUT_MUTE_NOISE, 76,
ID_MUTE_5, IDS_CUT_MUTE_DPCM, 77,
ID_MUTE_6, IDS_CUT_MUTE_EXTERNAL1, 78,
ID_MUTE_7, IDS_CUT_MUTE_EXTERNAL2, 79,
ID_MUTE_8, IDS_CUT_MUTE_EXTERNAL3, 80,
ID_MUTE_9, IDS_CUT_MUTE_EXTERNAL4, 81,
ID_MUTE_A, IDS_CUT_MUTE_EXTERNAL5, 82,
ID_MUTE_B, IDS_CUT_MUTE_EXTERNAL6, 83,
ID_MUTE_C, IDS_CUT_MUTE_EXTERNAL7, 84,
ID_MUTE_D, IDS_CUT_MUTE_EXTERNAL8, 85,
// Tape controls
ID_TAPE_PLAY, IDS_CUT_TAPE_PLAY, 90,
ID_TAPE_REC, IDS_CUT_TAPE_REC, 91,
ID_TAPE_STOP, IDS_CUT_TAPE_STOP, 92,
// Other controls
ID_SNAPSHOT, IDS_CUT_SNAPSHOT, 96,
ID_FPSDISP, IDS_CUT_FPSDISP, 97,
ID_TVASPECT, IDS_CUT_TVASPECT, 98,
ID_TVFRAME, IDS_CUT_TVFRAME, 99,
ID_SCANLINE, IDS_CUT_SCANLINE, 100,
ID_ALLLINE, IDS_CUT_ALLLINE, 101,
ID_ALLSPRITE, IDS_CUT_ALLSPRITE, 102,
ID_LEFTCLIP, IDS_CUT_LEFTCLIP, 105,
ID_SYNCDRAW, IDS_CUT_SYNCDRAW, 103,
ID_FITSCREEN, IDS_CUT_FITSCREEN, 104,
// Tool controls
ID_SEARCH, IDS_CUT_SEARCH, 110,
ID_CHEAT, IDS_CUT_CHEAT, 111,
ID_CHEAT_ENABLE, IDS_CUT_CHEAT_ENABLE, 112,
ID_CHEAT_DISABLE, IDS_CUT_CHEAT_DISABLE, 113,
ID_GENIE, IDS_CUT_GENIE, 114,
ID_VIEW_PATTERN, IDS_CUT_VIEW_PATTERN, 116,
ID_VIEW_NAMETABLE, IDS_CUT_VIEW_NAMETABLE, 117,
ID_VIEW_PALETTE, IDS_CUT_VIEW_PALETTE, 118,
ID_VIEW_MEMORY, IDS_CUT_VIEW_MEMORY, 119,
0, 0, 0
};
void CConfig::Load()
{
INT i, j;
string ret;
string section;
CHAR keys[64];
CHAR szTemp[MAX_PATH];
WORD szKeyTemp[64];
// General
section = "General";
general.bDoubleExecute = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DoubleExecute", general.bDoubleExecute );
general.bStartupLauncher = (BOOL)CRegistry::GetProfileInt( section.c_str(), "StartupLauncher", general.bStartupLauncher );
// general.bWindowSave = CRegistry::GetProfileInt( section.c_str(), "WindowPosSave", general.bWindowSave );
general.bWindowZoom = CRegistry::GetProfileInt( section.c_str(), "WindowZoom", general.bWindowZoom );
RECT rc;
if( CRegistry::GetProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
general.rcWindowPos = rc;
}
if( CRegistry::GetProfileBinary( section.c_str(), "SearchDialogPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
general.rcSearchDlgPos = rc;
}
if( CRegistry::GetProfileBinary( section.c_str(), "PatternViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
general.rcPatternViewPos = rc;
}
if( CRegistry::GetProfileBinary( section.c_str(), "NameTableViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
general.rcNameTableViewPos = rc;
}
if( CRegistry::GetProfileBinary( section.c_str(), "PaletteViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
general.rcPaletteViewPos = rc;
}
if( CRegistry::GetProfileBinary( section.c_str(), "MemoryViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
general.rcMemoryViewPos = rc;
}
if( CRegistry::GetProfileBinary( section.c_str(), "BarcodePos", (LPBYTE)&rc, sizeof(RECT) ) ) {
general.rcBarcodePos = rc;
}
if( CRegistry::GetProfileBinary( section.c_str(), "PaletteEditPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
general.rcPaletteEditPos = rc;
}
general.nScreenZoom = CRegistry::GetProfileInt( section.c_str(), "ScreenZoom", general.nScreenZoom );
general.bNoJoystickID = (BOOL)CRegistry::GetProfileInt( section.c_str(), "NoJoystickID", general.bNoJoystickID );
general.nJoyAxisDisable = CRegistry::GetProfileInt( section.c_str(), "JoyAxisDisable", general.nJoyAxisDisable );
if( general.nJoyAxisDisable ) {
// 以前の設定を引き継ぐ為
WORD bits = 0;
switch( general.nJoyAxisDisable ) {
case 1:
bits = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5);
break;
case 2:
bits = (1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5);
break;
case 3:
bits = (1<<2)|(1<<3)|(1<<4)|(1<<5);
break;
case 4:
bits = (1<<3)|(1<<4)|(1<<5);
break;
case 5:
bits = (1<<4)|(1<<5);
break;
case 6:
bits = (1<<5);
break;
}
for( i = 0; i < 16; i++ ) {
general.JoyAxisSetting[i] = bits;
}
general.nJoyAxisDisable = 0;
} else {
if( CRegistry::GetProfileBinary( section.c_str(), "JoyAxisSetting", szKeyTemp, 16*sizeof(WORD) ) ) {
::memcpy( general.JoyAxisSetting, szKeyTemp, 16*sizeof(WORD) );
}
}
// Paths
section = "Path";
path.bRomAutoRunPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "RomAutoRunPathUse", path.bRomAutoRunPath );
path.bRomPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "RomPathUse", path.bRomPath );
path.bSavePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SavePathUse", path.bSavePath );
path.bStatePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "StatePathUse", path.bStatePath );
path.bSnapshotPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SnapshotPathUse", path.bSnapshotPath );
path.bMoviePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "MoviePathUse", path.bMoviePath );
path.bWavePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "WavePathUse", path.bWavePath );
path.bCheatPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "CheatPathUse", path.bCheatPath );
if( CRegistry::GetProfileString(section.c_str(), "RomAutoRunPath", szTemp, sizeof(szTemp))) {
::strcpy(path.szRomAutoRunPath, szTemp);
DEBUGOUT("RomAutoRunPath = %s\n", szTemp);
} else {
DEBUGOUT("RomAutoRunPath get failed! write default path\n");
CRegistry::WriteProfileString( section.c_str(), "RomAutoRunPath", path.szRomAutoRunPath );
}
if( CRegistry::GetProfileString( section.c_str(), "RomPath", szTemp, sizeof(szTemp) ) )
::strcpy( path.szRomPath, szTemp );
if( CRegistry::GetProfileString( section.c_str(), "SavePath", szTemp, sizeof(szTemp) ) )
::strcpy( path.szSavePath, szTemp );
if( CRegistry::GetProfileString( section.c_str(), "StatePath", szTemp, sizeof(szTemp) ) )
::strcpy( path.szStatePath, szTemp );
if( CRegistry::GetProfileString( section.c_str(), "SnapshotPath", szTemp, sizeof(szTemp) ) )
::strcpy( path.szSnapshotPath, szTemp );
if( CRegistry::GetProfileString( section.c_str(), "MoviePath", szTemp, sizeof(szTemp) ) )
::strcpy( path.szMoviePath, szTemp );
if( CRegistry::GetProfileString( section.c_str(), "WavePath", szTemp, sizeof(szTemp) ) )
::strcpy( path.szWavePath, szTemp );
if( CRegistry::GetProfileString( section.c_str(), "CheatPath", szTemp, sizeof(szTemp) ) )
::strcpy( path.szCheatPath, szTemp );
// Emulator
section = "Emulation";
emulator.bIllegalOp = (BOOL)CRegistry::GetProfileInt( section.c_str(), "IllegalOp", emulator.bIllegalOp );
emulator.bAutoFrameSkip = (BOOL)CRegistry::GetProfileInt( section.c_str(), "AutoFrameSkip", emulator.bAutoFrameSkip );
emulator.bThrottle = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Throttle", emulator.bThrottle );
emulator.nThrottleFPS = CRegistry::GetProfileInt( section.c_str(), "ThrottleFPS", emulator.nThrottleFPS );
emulator.bBackground = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Background", emulator.bBackground );
emulator.nPriority = CRegistry::GetProfileInt( section.c_str(), "Priority", emulator.nPriority );
emulator.bFourPlayer = (BOOL)CRegistry::GetProfileInt( section.c_str(), "FourPlayer", emulator.bFourPlayer );
emulator.bCrcCheck = (BOOL)CRegistry::GetProfileInt( section.c_str(), "CrcCheck", emulator.bCrcCheck );
emulator.bDiskThrottle = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DiskThrottle", emulator.bDiskThrottle );
emulator.bLoadFullscreen= (BOOL)CRegistry::GetProfileInt( section.c_str(), "LoadFullscreen",emulator.bLoadFullscreen );
emulator.bPNGsnapshot = (BOOL)CRegistry::GetProfileInt( section.c_str(), "PNGsnapshot", emulator.bPNGsnapshot );
// Graphic
section = "Graphics";
graphics.bAspect = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Aspect", graphics.bAspect );
graphics.bAllSprite = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SpriteMax", graphics.bAllSprite );
graphics.bAllLine = (BOOL)CRegistry::GetProfileInt( section.c_str(), "AllLine", graphics.bAllLine );
graphics.bFPSDisp = (BOOL)CRegistry::GetProfileInt( section.c_str(), "FPSDisp", graphics.bFPSDisp );
graphics.bTVFrame = (BOOL)CRegistry::GetProfileInt( section.c_str(), "TVFrameMode", graphics.bTVFrame );
graphics.bScanline = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ScanlineMode", graphics.bScanline );
graphics.nScanlineColor = CRegistry::GetProfileInt( section.c_str(), "ScanlineColor", graphics.nScanlineColor );
graphics.bSyncDraw = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SyncDraw", graphics.bSyncDraw );
graphics.bFitZoom = (BOOL)CRegistry::GetProfileInt( section.c_str(), "MaxZoom", graphics.bFitZoom );
graphics.bLeftClip = (BOOL)CRegistry::GetProfileInt( section.c_str(), "LeftClip", graphics.bLeftClip );
graphics.bWindowVSync = (BOOL)CRegistry::GetProfileInt( section.c_str(), "WindowVSync", graphics.bWindowVSync );
graphics.bSyncNoSleep = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SyncNoSleep", graphics.bSyncNoSleep );
graphics.bDiskAccessLamp= (BOOL)CRegistry::GetProfileInt( section.c_str(), "DiskAccessLamp",graphics.bDiskAccessLamp );
graphics.bDoubleSize = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DoubleSize", graphics.bDoubleSize );
graphics.bSystemMemory = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SystemMemory", graphics.bSystemMemory );
graphics.bUseHEL = (BOOL)CRegistry::GetProfileInt( section.c_str(), "UseHEL", graphics.bUseHEL );
graphics.bNoSquareList = (BOOL)CRegistry::GetProfileInt( section.c_str(), "NoSquareList", graphics.bNoSquareList );
graphics.nGraphicsFilter= CRegistry::GetProfileInt( section.c_str(), "GraphicsFilter",graphics.nGraphicsFilter );
graphics.dwDisplayWidth = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayWidth", graphics.dwDisplayWidth );
graphics.dwDisplayHeight = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayHeight", graphics.dwDisplayHeight );
graphics.dwDisplayDepth = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayDepth", graphics.dwDisplayDepth );
graphics.dwDisplayRate = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayRate", graphics.dwDisplayRate );
graphics.bPaletteFile = (BOOL)CRegistry::GetProfileInt( section.c_str(), "PaletteUse", graphics.bPaletteFile );
if( CRegistry::GetProfileString( section.c_str(), "PaletteFile", szTemp, sizeof(szTemp) ) )
::strcpy( graphics.szPaletteFile, szTemp );
// Sound
section = "Sound";
sound.bEnable = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Enable", sound.bEnable );
sound.nRate = CRegistry::GetProfileInt( section.c_str(), "SamplingRate", sound.nRate );
sound.nBits = CRegistry::GetProfileInt( section.c_str(), "SamplingBits", sound.nBits );
sound.nBufferSize = CRegistry::GetProfileInt( section.c_str(), "BufferSize", sound.nBufferSize );
sound.nFilterType = CRegistry::GetProfileInt( section.c_str(), "FilterType", sound.nFilterType );
sound.bChangeTone = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ChangeTone", sound.bChangeTone );
sound.bDisableVolumeEffect = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DisableVolumeEffect", sound.bDisableVolumeEffect );
sound.bExtraSoundEnable = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ExtraSoundEnable", sound.bExtraSoundEnable );
if( CRegistry::GetProfileBinary( section.c_str(), "Volume", szTemp, sizeof(sound.nVolume) ) )
::memcpy( sound.nVolume, szTemp, sizeof(sound.nVolume) );
// ShortCuts
section = "ShortCut";
for( i = 0; i < sizeof(shortcut.nShortCut)/(16*sizeof(WORD)); i++ ) {
::wsprintf( keys, "Tbl%02d", i );
if( CRegistry::GetProfileBinary( section.c_str(), keys, szTemp, 16*sizeof(WORD) ) )
::memcpy( &shortcut.nShortCut[i*16], szTemp, 16*sizeof(WORD) );
}
// Controllers
for( i = 0; i < 4; i++ ) {
::wsprintf( keys, "Controller %d", i+1 );
if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 64*sizeof(WORD) ) ) {
::memcpy( controller.nButton[i], szKeyTemp, 64*sizeof(WORD) );
} else if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 32*sizeof(WORD) ) ) {
// 古い設定を引き継ぐ為の措置
::memcpy( &controller.nButton[i][ 0], &szKeyTemp[ 0], 16*sizeof(WORD) );
::memcpy( &controller.nButton[i][32], &szKeyTemp[16], 16*sizeof(WORD) );
::memcpy( controller.nButton[i], szKeyTemp, 32*sizeof(WORD) );
} else if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 20*sizeof(WORD) ) ) {
// 古い設定を引き継ぐ為の措置
::memcpy( &controller.nButton[i][ 0], &szKeyTemp[ 0], 10*sizeof(WORD) );
::memcpy( &controller.nButton[i][32], &szKeyTemp[10], 10*sizeof(WORD) );
// Micの変更
if( i == 1 ) {
controller.nButton[i][10] = szKeyTemp[ 8];
controller.nButton[i][ 8] = 0;
controller.nButton[i][42] = szKeyTemp[18];
controller.nButton[i][40] = 0;
}
} else if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 10*sizeof(WORD) ) ) {
// 古い設定を引き継ぐ為の措置
::memcpy( controller.nButton[i], szKeyTemp, 10*sizeof(WORD) );
// Micの変更
if( i == 1 ) {
controller.nButton[i][10] = szKeyTemp[ 8];
controller.nButton[i][ 8] = 0;
}
}
if( CRegistry::GetProfileBinary( keys, "Rapid", szTemp, 2*sizeof(WORD) ) )
::memcpy( controller.nRapid[i], szTemp, 2*sizeof(WORD) );
}
// ExControllers
for( i = 0; i < 4; i++ ) {
if( i == 0 ) section = "Crazy Climber";
if( i == 1 ) section = "Family Trainer";
if( i == 2 ) section = "Exciting Boxing";
if( i == 3 ) section = "Mahjang";
if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 64*sizeof(WORD) ) ) {
::memcpy( controller.nExButton[i], szKeyTemp, 64*sizeof(WORD) );
} else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 32*sizeof(WORD) ) ) {
::memcpy( &controller.nExButton[i][ 0], &szKeyTemp[ 0], 16*sizeof(WORD) );
::memcpy( &controller.nExButton[i][32], &szKeyTemp[16], 16*sizeof(WORD) );
} else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 20*sizeof(WORD) ) ) {
// 古い設定を引き継ぐ為の措置
::memcpy( &controller.nExButton[i][ 0], &szKeyTemp[ 0], 10*sizeof(WORD) );
::memcpy( &controller.nExButton[i][32], &szKeyTemp[10], 10*sizeof(WORD) );
} else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 10*sizeof(WORD) ) ) {
// 古い設定を引き継ぐ為の措置
::memcpy( controller.nExButton[i], szKeyTemp, 10*sizeof(WORD) );
}
}
// NSF Contoller
section = "NSF controller";
if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 64*sizeof(WORD) ) ) {
::memcpy( controller.nNsfButton, szKeyTemp, 64*sizeof(WORD) );
} else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 32*sizeof(WORD) ) ) {
::memcpy( &controller.nNsfButton[ 0], &szKeyTemp[ 0], 16*sizeof(WORD) );
::memcpy( &controller.nNsfButton[32], &szKeyTemp[16], 16*sizeof(WORD) );
} else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 20*sizeof(WORD) ) ) {
// 古い設定を引き継ぐ為の措置
::memcpy( &controller.nNsfButton[ 0], &szKeyTemp[ 0], 10*sizeof(WORD) );
::memcpy( &controller.nNsfButton[32], &szKeyTemp[10], 10*sizeof(WORD) );
}
// VS-Unisystem
section = "VS-Unisystem";
if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 64*sizeof(WORD) ) ) {
::memcpy( controller.nVSUnisystem, szKeyTemp, 64*sizeof(WORD) );
}
// Movie
section = "Movie";
if( CRegistry::GetProfileBinary( section.c_str(), "UsePlayer", szTemp, sizeof(movie.bUsePlayer) ) )
::memcpy( movie.bUsePlayer, szTemp, sizeof(movie.bUsePlayer) );
movie.bResetRec = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ResetRec", movie.bResetRec );
movie.bRerecord = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Rerecord", movie.bRerecord );
movie.bLoopPlay = (BOOL)CRegistry::GetProfileInt( section.c_str(), "LoopPlay", movie.bLoopPlay );
movie.bPadDisplay = (BOOL)CRegistry::GetProfileInt( section.c_str(), "PadDisplay", movie.bPadDisplay );
// Launcher
section = "Launcher";
if( CRegistry::GetProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&rc, sizeof(RECT) ) )
launcher.rcWindowPos = rc;
if( CRegistry::GetProfileBinary( section.c_str(), "ColumnView", szTemp, sizeof(launcher.bHeaderView) ) )
::memcpy( launcher.bHeaderView, szTemp, sizeof(launcher.bHeaderView) );
if( CRegistry::GetProfileBinary( section.c_str(), "ColumnOrder", szTemp, sizeof(launcher.nHeaderOrder) ) )
::memcpy( launcher.nHeaderOrder, szTemp, sizeof(launcher.nHeaderOrder) );
if( CRegistry::GetProfileBinary( section.c_str(), "ColumnWidth", szTemp, sizeof(launcher.nHeaderWidth) ) )
::memcpy( launcher.nHeaderWidth, szTemp, sizeof(launcher.nHeaderWidth) );
launcher.nListSelect = CRegistry::GetProfileInt( section.c_str(), "ListSelect", launcher.nListSelect );
launcher.bSortDir = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SortDir", launcher.bSortDir );
launcher.nSortType = CRegistry::GetProfileInt( section.c_str(), "SortType", launcher.nSortType );
if( CRegistry::GetProfileBinary( section.c_str(), "ColumnSort", szTemp, sizeof(launcher.nHeaderWidth) ) )
::memcpy( launcher.nHeaderWidth, szTemp, sizeof(launcher.nHeaderWidth) );
if( CRegistry::GetProfileBinary( section.c_str(), "FolderUse", szTemp, sizeof(launcher.bFolderUse) ) )
::memcpy( launcher.bFolderUse, szTemp, sizeof(launcher.bFolderUse) );
for( i = 0; i < 16; i++ ) {
::wsprintf( keys, "Folder%02d", i );
if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) )
::strcpy( launcher.szFolder[i], szTemp );
}
if( CRegistry::GetProfileString( section.c_str(), "LastSelect", szTemp, sizeof(szTemp) ) )
::strcpy( launcher.szLastSelect, szTemp );
launcher.bActivePause = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ActivePause", launcher.bActivePause );
// ExtraSound
section = "ExtraSound";
for( i = ESF_MOEPRO_STRIKE; i <= ESF_MOEPRO_WA; i++ ) {
::wsprintf( keys, "Moepro%02d", i );
if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) )
::strcpy( extsound.szExtSoundFile[i], szTemp );
}
for( i = ESF_DISKSYSTEM_BOOT, j = 0; i <= ESF_DISKSYSTEM_SEEKEND; i++, j++ ) {
::wsprintf( keys, "DiskSound%02d", j );
if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) )
::strcpy( extsound.szExtSoundFile[i], szTemp );
}
// NetPlay
section = "Netplay";
if( CRegistry::GetProfileBinary( section.c_str(), "ChatPos", (LPBYTE)&rc, sizeof(RECT) ) )
netplay.rcChatPos = rc;
if( CRegistry::GetProfileString( section.c_str(), "NickName", szTemp, sizeof(szTemp) ) )
::strcpy( netplay.szNick, szTemp );
netplay.nRecentPort = CRegistry::GetProfileInt( section.c_str(), "RecnetPortNum", netplay.nRecentPort );
for( i = 0; i < netplay.nRecentPort; i++ ) {
::wsprintf( keys, "RecentPort%02d", i );
if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) )
::strcpy( netplay.szRecentPort[i], szTemp );
}
netplay.nRecentHost = CRegistry::GetProfileInt( section.c_str(), "RecnetHostNum", netplay.nRecentHost );
for( i = 0; i < netplay.nRecentHost; i++ ) {
::wsprintf( keys, "RecentHost%02d", i );
if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) )
::strcpy( netplay.szRecentHost[i], szTemp );
}
}
void CConfig::Save()
{
INT i;
string section;
CHAR keys[64];
// General
section = "General";
CRegistry::WriteProfileInt ( section.c_str(), "DoubleExecute", general.bDoubleExecute );
CRegistry::WriteProfileInt ( section.c_str(), "StartupLauncher", general.bStartupLauncher );
// CRegistry::WriteProfileInt( section.c_str(), "WindowPosSave", general.bWindowSave );
CRegistry::WriteProfileInt ( section.c_str(), "WindowZoom", general.bWindowZoom );
CRegistry::WriteProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&general.rcWindowPos, sizeof(RECT) );
CRegistry::WriteProfileInt ( section.c_str(), "ScreenZoom", general.nScreenZoom );
CRegistry::WriteProfileBinary( section.c_str(), "SearchDialogPos", (LPBYTE)&general.rcSearchDlgPos, sizeof(RECT) );
CRegistry::WriteProfileBinary( section.c_str(), "PatternViewPos", (LPBYTE)&general.rcPatternViewPos, sizeof(RECT) );
CRegistry::WriteProfileBinary( section.c_str(), "NameTableViewPos", (LPBYTE)&general.rcNameTableViewPos, sizeof(RECT) );
CRegistry::WriteProfileBinary( section.c_str(), "PaletteViewPos", (LPBYTE)&general.rcPaletteViewPos, sizeof(RECT) );
CRegistry::WriteProfileBinary( section.c_str(), "MemoryViewPos", (LPBYTE)&general.rcMemoryViewPos, sizeof(RECT) );
CRegistry::WriteProfileBinary( section.c_str(), "BarcodePos", (LPBYTE)&general.rcBarcodePos, sizeof(RECT) );
CRegistry::WriteProfileBinary( section.c_str(), "PaletteEditPos", (LPBYTE)&general.rcPaletteEditPos, sizeof(RECT) );
CRegistry::WriteProfileInt ( section.c_str(), "JoyAxisDisable", general.nJoyAxisDisable );
CRegistry::WriteProfileBinary( section.c_str(), "JoyAxisSetting", (LPBYTE)general.JoyAxisSetting, 16*sizeof(WORD) );
// Paths
section = "Path";
CRegistry::WriteProfileInt( section.c_str(), "RomPathUse", path.bRomPath );
CRegistry::WriteProfileInt( section.c_str(), "SavePathUse", path.bSavePath );
CRegistry::WriteProfileInt( section.c_str(), "StatePathUse", path.bStatePath );
CRegistry::WriteProfileInt( section.c_str(), "SnapshotPathUse", path.bSnapshotPath );
CRegistry::WriteProfileInt( section.c_str(), "MoviePathUse", path.bMoviePath );
CRegistry::WriteProfileInt( section.c_str(), "WavePathUse", path.bWavePath );
CRegistry::WriteProfileInt( section.c_str(), "CheatPathUse", path.bCheatPath );
CRegistry::WriteProfileString( section.c_str(), "RomAutoRunPath", path.szRomAutoRunPath );
CRegistry::WriteProfileString( section.c_str(), "RomPath", path.szRomPath );
CRegistry::WriteProfileString( section.c_str(), "SavePath", path.szSavePath );
CRegistry::WriteProfileString( section.c_str(), "StatePath", path.szStatePath );
CRegistry::WriteProfileString( section.c_str(), "SnapshotPath", path.szSnapshotPath );
CRegistry::WriteProfileString( section.c_str(), "MoviePath", path.szMoviePath );
CRegistry::WriteProfileString( section.c_str(), "WavePath", path.szWavePath );
CRegistry::WriteProfileString( section.c_str(), "CheatPath", path.szCheatPath );
// Emulation
section = "Emulation";
CRegistry::WriteProfileInt( section.c_str(), "IllegalOp", emulator.bIllegalOp );
CRegistry::WriteProfileInt( section.c_str(), "AutoFrameSkip", emulator.bAutoFrameSkip );
CRegistry::WriteProfileInt( section.c_str(), "Throttle", emulator.bThrottle );
CRegistry::WriteProfileInt( section.c_str(), "ThrottleFPS", emulator.nThrottleFPS );
CRegistry::WriteProfileInt( section.c_str(), "Background", emulator.bBackground );
CRegistry::WriteProfileInt( section.c_str(), "Priority", emulator.nPriority );
CRegistry::WriteProfileInt( section.c_str(), "FourPlayer", emulator.bFourPlayer );
CRegistry::WriteProfileInt( section.c_str(), "CrcCheck", emulator.bCrcCheck );
CRegistry::WriteProfileInt( section.c_str(), "DiskThrottle", emulator.bDiskThrottle );
CRegistry::WriteProfileInt( section.c_str(), "LoadFullscreen",emulator.bLoadFullscreen );
CRegistry::WriteProfileInt( section.c_str(), "PNGsnapshot", emulator.bPNGsnapshot );
// Graphic
section = "Graphics";
CRegistry::WriteProfileInt( section.c_str(), "Aspect", graphics.bAspect );
CRegistry::WriteProfileInt( section.c_str(), "SpriteMax", graphics.bAllSprite );
CRegistry::WriteProfileInt( section.c_str(), "AllLine", graphics.bAllLine );
CRegistry::WriteProfileInt( section.c_str(), "FPSDisp", graphics.bFPSDisp );
CRegistry::WriteProfileInt( section.c_str(), "TVFrameMode", graphics.bTVFrame );
CRegistry::WriteProfileInt( section.c_str(), "ScanlineMode", graphics.bScanline );
CRegistry::WriteProfileInt( section.c_str(), "ScanlineColor", graphics.nScanlineColor );
CRegistry::WriteProfileInt( section.c_str(), "SyncDraw", graphics.bSyncDraw );
CRegistry::WriteProfileInt( section.c_str(), "MaxZoom", graphics.bFitZoom );
CRegistry::WriteProfileInt( section.c_str(), "LeftClip", graphics.bLeftClip );
CRegistry::WriteProfileInt( section.c_str(), "WindowVSync", graphics.bWindowVSync );
CRegistry::WriteProfileInt( section.c_str(), "DiskAccessLamp",graphics.bDiskAccessLamp );
CRegistry::WriteProfileInt( section.c_str(), "DoubleSize", graphics.bDoubleSize );
CRegistry::WriteProfileInt( section.c_str(), "SystemMemory", graphics.bSystemMemory );
CRegistry::WriteProfileInt( section.c_str(), "UseHEL", graphics.bUseHEL );
CRegistry::WriteProfileInt( section.c_str(), "NoSquareList", graphics.bNoSquareList );
CRegistry::WriteProfileInt( section.c_str(), "GraphicsFilter",graphics.nGraphicsFilter );
CRegistry::WriteProfileInt( section.c_str(), "DisplayWidth", graphics.dwDisplayWidth );
CRegistry::WriteProfileInt( section.c_str(), "DisplayHeight", graphics.dwDisplayHeight );
CRegistry::WriteProfileInt( section.c_str(), "DisplayDepth", graphics.dwDisplayDepth );
CRegistry::WriteProfileInt( section.c_str(), "DisplayRate", graphics.dwDisplayRate );
CRegistry::WriteProfileInt( section.c_str(), "PaletteUse", graphics.bPaletteFile );
CRegistry::WriteProfileString( section.c_str(), "PaletteFile", graphics.szPaletteFile );
// Sound
section = "Sound";
CRegistry::WriteProfileInt( section.c_str(), "Enable", sound.bEnable );
CRegistry::WriteProfileInt( section.c_str(), "DisableVolumeEffect", sound.bDisableVolumeEffect );
CRegistry::WriteProfileInt( section.c_str(), "ExtraSoundEnable", sound.bExtraSoundEnable );
CRegistry::WriteProfileInt( section.c_str(), "SamplingRate", sound.nRate );
CRegistry::WriteProfileInt( section.c_str(), "SamplingBits", sound.nBits );
CRegistry::WriteProfileInt( section.c_str(), "BufferSize", sound.nBufferSize );
CRegistry::WriteProfileInt( section.c_str(), "FilterType", sound.nFilterType );
CRegistry::WriteProfileBinary( section.c_str(), "Volume", (LPBYTE)sound.nVolume, sizeof(sound.nVolume) );
// ShortCut
section = "ShortCut";
for( i = 0; i < sizeof(shortcut.nShortCut)/(16*sizeof(WORD)); i++ ) {
::wsprintf( keys, "TBL%02d", i );
CRegistry::WriteProfileBinary( section.c_str(), keys, (LPBYTE)&shortcut.nShortCut[i*16], 16*sizeof(WORD) );
}
// Controllers
for( i = 0; i < 4; i++ ) {
::wsprintf( keys, "Controller %01d", i+1 );
CRegistry::WriteProfileBinary( keys, "Keys", (LPBYTE)controller.nButton[i], 64*sizeof(WORD) );
CRegistry::WriteProfileBinary( keys, "Rapid", (LPBYTE)controller.nRapid[i], 2*sizeof(WORD) );
}
// ExControllers
section = "Crazy Climber";
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[0], 64*sizeof(WORD) );
section = "Family Trainer";
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[1], 64*sizeof(WORD) );
section = "Exciting Boxing";
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[2], 64*sizeof(WORD) );
section = "Mahjang";
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[3], 64*sizeof(WORD) );
// NSF Contoller
section = "NSF controller";
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nNsfButton, 64*sizeof(WORD) );
// VS-Unisystem
section = "VS-Unisystem";
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nVSUnisystem, 64*sizeof(WORD) );
// Movie
section = "Movie";
CRegistry::WriteProfileBinary( section.c_str(), "UsePlayer", (LPBYTE)movie.bUsePlayer, sizeof(movie.bUsePlayer) );
CRegistry::WriteProfileInt( section.c_str(), "ResetRec", movie.bResetRec );
CRegistry::WriteProfileInt( section.c_str(), "Rerecord", movie.bRerecord );
CRegistry::WriteProfileInt( section.c_str(), "LoopPlay", movie.bLoopPlay );
CRegistry::WriteProfileInt( section.c_str(), "PadDisplay", movie.bPadDisplay );
// Launcher
section = "Launcher";
CRegistry::WriteProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&launcher.rcWindowPos, sizeof(RECT) );
CRegistry::WriteProfileBinary( section.c_str(), "ColumnView", (LPBYTE)launcher.bHeaderView, sizeof(launcher.bHeaderView) );
CRegistry::WriteProfileBinary( section.c_str(), "ColumnOrder", (LPBYTE)launcher.nHeaderOrder, sizeof(launcher.nHeaderOrder) );
CRegistry::WriteProfileBinary( section.c_str(), "ColumnWidth", (LPBYTE)launcher.nHeaderWidth, sizeof(launcher.nHeaderWidth) );
CRegistry::WriteProfileInt( section.c_str(), "ListSelect", launcher.nListSelect );
CRegistry::WriteProfileInt( section.c_str(), "SortDir", launcher.bSortDir );
CRegistry::WriteProfileInt( section.c_str(), "SortType", launcher.nSortType );
CRegistry::WriteProfileBinary( section.c_str(), "FolderUse", (LPBYTE)launcher.bFolderUse, sizeof(launcher.bFolderUse) );
for( i = 0; i < 16; i++ ) {
::wsprintf( keys, "Folder%02d", i );
CRegistry::WriteProfileString( section.c_str(), keys, launcher.szFolder[i] );
}
CRegistry::WriteProfileString( section.c_str(), "LastSelect", launcher.szLastSelect );
CRegistry::WriteProfileInt( section.c_str(), "ActivePause", launcher.bActivePause );
// NetPlay
section = "Netplay";
CRegistry::WriteProfileBinary( section.c_str(), "ChatPos", (LPBYTE)&netplay.rcChatPos, sizeof(RECT) );
CRegistry::WriteProfileString( section.c_str(), "NickName", netplay.szNick );
CRegistry::WriteProfileInt( section.c_str(), "RecnetPortNum", netplay.nRecentPort );
for( i = 0; i < 16; i++ ) {
::wsprintf( keys, "RecentPort%02d", i );
CRegistry::WriteProfileString( section.c_str(), keys, netplay.szRecentPort[i] );
}
CRegistry::WriteProfileInt( section.c_str(), "RecnetHostNum", netplay.nRecentHost );
for( i = 0; i < 16; i++ ) {
::wsprintf( keys, "RecentHost%02d", i );
CRegistry::WriteProfileString( section.c_str(), keys, netplay.szRecentHost[i] );
}
}
BOOL CConfig::ButtonCheck( INT nNo, INT nID )
{
if( m_bKeyboardDisable ) {
if( (Config.controller.nButton[nNo][nID+ 0] >= 256) && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+ 0]]
|| (Config.controller.nButton[nNo][nID+32] >= 256) && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+32]] )
return TRUE;
} else {
if( Config.controller.nButton[nNo][nID+ 0] && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+ 0]]
|| Config.controller.nButton[nNo][nID+32] && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+32]] )
return TRUE;
}
return FALSE;
}
BOOL CConfig::ExButtonCheck( INT nNo, INT nID )
{
if( Config.controller.nExButton[nNo][nID+ 0] && DirectInput.m_Sw[Config.controller.nExButton[nNo][nID+ 0]]
|| Config.controller.nExButton[nNo][nID+32] && DirectInput.m_Sw[Config.controller.nExButton[nNo][nID+32]] )
return TRUE;
return FALSE;
}
BOOL CConfig::NsfButtonCheck( INT nID )
{
if( Config.controller.nNsfButton[nID+ 0] && DirectInput.m_Sw[Config.controller.nNsfButton[nID+ 0]]
|| Config.controller.nNsfButton[nID+32] && DirectInput.m_Sw[Config.controller.nNsfButton[nID+32]] )
return TRUE;
return FALSE;
}
BOOL CConfig::ButtonCheck( INT nID, WORD* pKey )
{
if( pKey[nID+ 0] && DirectInput.m_Sw[pKey[nID+ 0]]
|| pKey[nID+32] && DirectInput.m_Sw[pKey[nID+32]] )
return TRUE;
return FALSE;
}
string CConfig::ShortcutToKeyName( INT nShortcutKey )
{
string str;
if( nShortcutKey == 0 ) {
str = "----";
} else {
if( nShortcutKey & CCfgShortCut::K_ALT )
str = str + "Alt+";
if( nShortcutKey & CCfgShortCut::K_CTRL )
str = str + "Ctrl+";
if( nShortcutKey & CCfgShortCut::K_SHIFT )
str = str + "Shift+";
str = str + DirectInput.SearchKeyName( nShortcutKey & 0x0FFF );
}
return str;
}
/////////////////////////////////
CGameOption GameOption;
void CGameOption::Load( DWORD crc )
{
CRegistry::SetRegistryKey( "GameOption.ini" );
CHAR szSection[256];
::wsprintf( szSection, "%08X", crc );
nRenderMethod = CRegistry::GetProfileInt( szSection, "RenderMethod", defRenderMethod );
nIRQtype = CRegistry::GetProfileInt( szSection, "IRQtype", defIRQtype );
bFrameIRQ = (BOOL)CRegistry::GetProfileInt( szSection, "FrameIRQ", defFrameIRQ );
bVideoMode = (BOOL)CRegistry::GetProfileInt( szSection, "VideoMode", defVideoMode );
}
void CGameOption::Save( LPCSTR name, DWORD crc )
{
CRegistry::SetRegistryKey( "GameOption.ini" );
CHAR szSection[256];
::wsprintf( szSection, "%08X", crc );
CRegistry::WriteProfileString( szSection, "Title", name );
CRegistry::WriteProfileInt( szSection, "RenderMethod", nRenderMethod );
CRegistry::WriteProfileInt( szSection, "IRQtype", nIRQtype );
CRegistry::WriteProfileInt( szSection, "FrameIRQ", (INT)bFrameIRQ );
CRegistry::WriteProfileInt( szSection, "VideoMode", (INT)bVideoMode );
}
void CGameOption::Load( DWORD gid, DWORD mid )
{
CRegistry::SetRegistryKey( "GameOption.ini" );
CHAR szSection[256];
::wsprintf( szSection, "%08X%08X", gid, mid );
nRenderMethod = CRegistry::GetProfileInt( szSection, "RenderMethod", defRenderMethod );
nIRQtype = CRegistry::GetProfileInt( szSection, "IRQtype", defIRQtype );
bFrameIRQ = (BOOL)CRegistry::GetProfileInt( szSection, "FrameIRQ", defFrameIRQ );
}
void CGameOption::Save( LPCSTR name, DWORD gid, DWORD mid )
{
CRegistry::SetRegistryKey( "GameOption.ini" );
CHAR szSection[256];
::wsprintf( szSection, "%08X%08X", gid, mid );
CRegistry::WriteProfileString( szSection, "Title", name );
CRegistry::WriteProfileInt( szSection, "RenderMethod", nRenderMethod );
CRegistry::WriteProfileInt( szSection, "IRQtype", nIRQtype );
CRegistry::WriteProfileInt( szSection, "FrameIRQ", (INT)bFrameIRQ );
}

View File

@ -0,0 +1,783 @@
//
// 設定保存クラス
//
#ifndef __CCONFIG_INCLUDED__
#define __CCONFIG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#define DIRECTINPUT_VERSION 0x0700
#include <dinput.h>
#include <string>
using namespace std;
#include "extsoundfile.h"
#include "typedef.h"
#include "macro.h"
class CCfgGeneral
{
public:
BOOL bDoubleExecute;
BOOL bStartupLauncher;
BOOL bWindowSave;
BOOL bWindowZoom;
RECT rcWindowPos;
BOOL bScreenMode;
BOOL nScreenZoom;
RECT rcSearchDlgPos;
RECT rcPatternViewPos;
RECT rcNameTableViewPos;
RECT rcPaletteViewPos;
RECT rcMemoryViewPos;
RECT rcBarcodePos;
RECT rcPaletteEditPos;
BOOL bNoJoystickID;
WORD JoyAxisSetting[16];
// ジョイパッドの軸の無効化
// 0 : All enable
// 1 : X軸以降全て
// 2 : Y軸以降全て
// 3 : Z軸以降全て
// 4 : RX軸以降全て
// 5 : RY軸以降全て
// 6 : RZ軸以降全て
INT nJoyAxisDisable;
void Default() {
bWindowSave = FALSE;
bWindowZoom = FALSE;
rcWindowPos.left = rcWindowPos.right =
rcWindowPos.top = rcWindowPos.bottom = 0;
bDoubleExecute = TRUE;
bStartupLauncher = FALSE;
bScreenMode = FALSE;
nScreenZoom = 0;
rcSearchDlgPos.left = rcSearchDlgPos.right =
rcSearchDlgPos.top = rcSearchDlgPos.bottom = 0;
rcPatternViewPos.left = rcPatternViewPos.right =
rcPatternViewPos.top = rcPatternViewPos.bottom = 0;
rcNameTableViewPos.left = rcNameTableViewPos.right =
rcNameTableViewPos.top = rcNameTableViewPos.bottom = 0;
rcPaletteViewPos.left = rcPaletteViewPos.right =
rcPaletteViewPos.top = rcPaletteViewPos.bottom = 0;
rcMemoryViewPos.left = rcMemoryViewPos.right =
rcMemoryViewPos.top = rcMemoryViewPos.bottom = 0;
rcBarcodePos.left = rcBarcodePos.right =
rcBarcodePos.top = rcBarcodePos.bottom = 0;
rcPaletteEditPos.left = rcPaletteEditPos.right =
rcPaletteEditPos.top = rcPaletteEditPos.bottom = 0;
bNoJoystickID = FALSE;
nJoyAxisDisable = 0;
for( INT i = 0; i < 16; i++ ) {
JoyAxisSetting[i] = 0;
}
}
};
class CCfgPath
{
public:
BOOL bRomAutoRunPath;//ミト<EFBE90>ユlヨェサィ100エ<30><EFBDB4>メメカキ耿<EFBDB7>モオトケヲトワ ト」ト簇<EFBE84>ヒミミハアラヤカッエ<EFBDAF>ェヨクカィホトシ<EFBE84>
BOOL bRomPath;
BOOL bRamPath;
BOOL bSavePath;
BOOL bStatePath;
BOOL bSnapshotPath;
BOOL bMoviePath;
BOOL bWavePath;
BOOL bCheatPath;
CHAR szRomAutoRunPath [_MAX_PATH];
CHAR szRomPath [_MAX_PATH];
CHAR szRamPath [_MAX_PATH];
CHAR szSavePath [_MAX_PATH];
CHAR szStatePath [_MAX_PATH];
CHAR szSnapshotPath[_MAX_PATH];
CHAR szMoviePath [_MAX_PATH];
CHAR szWavePath [_MAX_PATH];
CHAR szCheatPath [_MAX_PATH];
void Default() {
#if 0
bRomPath = bRamPath = bSavePath =
bStatePath = bSnapshotPath =
bMoviePath = bWavePath =
bCheatPath = FALSE;
szRomPath[0] = szRamPath[0] = szSavePath[0] =
szStatePath[0] = szSnapshotPath[0] =
szMoviePath[0] = szWavePath[0] =
szCheatPath[0] = 0;
#endif
bRomPath = bRomPath = bSavePath =
bStatePath = bSnapshotPath =
bMoviePath = bWavePath =
bCheatPath = TRUE;
bRomAutoRunPath = FALSE;
::lstrcpy( szRomAutoRunPath, ".\\" );
::lstrcpy( szRomPath, ".\\roms\\" );
::lstrcpy( szRamPath, ".\\ram\\" );
::lstrcpy( szSavePath, ".\\save\\" );
::lstrcpy( szStatePath, ".\\state\\" );
::lstrcpy( szSnapshotPath, ".\\snapshot\\" );
::lstrcpy( szMoviePath, ".\\movie\\" );
::lstrcpy( szWavePath, ".\\wave\\" );
::lstrcpy( szCheatPath, ".\\cheatcode\\" );
}
};
class CCfgEmulator
{
public:
BOOL bIllegalOp;
BOOL bAutoFrameSkip;
BOOL bThrottle;
INT nThrottleFPS;
BOOL bBackground;
INT nPriority;
BOOL bFourPlayer;
BOOL bCrcCheck;
BOOL bDiskThrottle;
BOOL bLoadFullscreen;
BOOL bPNGsnapshot;
void Default() {
bIllegalOp = FALSE;
bAutoFrameSkip = TRUE;
bThrottle = TRUE;
nThrottleFPS = 120; // 120FPS
bBackground = FALSE;
nPriority = 3; // Normal
bFourPlayer = TRUE; // TRUE:NES FALSE:Famicom
bCrcCheck = TRUE;
bDiskThrottle = TRUE;
bLoadFullscreen = FALSE;
bPNGsnapshot = FALSE;
}
};
class CCfgGraphics
{
public:
BOOL bAspect;
BOOL bAllSprite;
BOOL bAllLine;
BOOL bFPSDisp;
BOOL bTVFrame;
BOOL bScanline;
INT nScanlineColor;
BOOL bSyncDraw;
BOOL bFitZoom;
BOOL bLeftClip;
BOOL bWindowVSync;
BOOL bSyncNoSleep;
BOOL bDiskAccessLamp;
BOOL bDoubleSize;
BOOL bSystemMemory;
BOOL bUseHEL;
BOOL bNoSquareList;
INT nGraphicsFilter;
DWORD dwDisplayWidth;
DWORD dwDisplayHeight;
DWORD dwDisplayDepth;
DWORD dwDisplayRate;
BOOL bPaletteFile;
CHAR szPaletteFile[_MAX_PATH];
void Default() {
bAspect = FALSE;
bAllSprite = TRUE;
bAllLine = FALSE;
bFPSDisp = FALSE;
bTVFrame = FALSE;
bScanline = FALSE;
nScanlineColor = 75;
bSyncDraw = FALSE;
bFitZoom = FALSE;
bLeftClip = TRUE;
bWindowVSync = FALSE;
bSyncNoSleep = FALSE;
bDiskAccessLamp = FALSE;
bDoubleSize = FALSE;
bSystemMemory = FALSE;
bUseHEL = FALSE;
bNoSquareList = FALSE;
nGraphicsFilter = 0;
dwDisplayWidth = 640;
dwDisplayHeight = 480;
dwDisplayDepth = 16;
dwDisplayRate = 0;
bPaletteFile = FALSE;
szPaletteFile[0] = 0;
}
};
class CCfgSound
{
public:
BOOL bEnable;
INT nRate;
INT nBits;
INT nBufferSize;
INT nFilterType;
BOOL bChangeTone;
BOOL bDisableVolumeEffect;
BOOL bExtraSoundEnable;
// 0:Master
// 1:Rectangle 1
// 2:Rectangle 2
// 3:Triangle
// 4:Noise
// 5:DPCM
// 6:VRC6
// 7:VRC7
// 8:FDS
// 9:MMC5
// 10:N106
// 11:FME7
SHORT nVolume[16];
void Default() {
bEnable = TRUE;
nRate = 22050;
nBits = 8;
nBufferSize = 4;
nFilterType = 0;
bChangeTone = FALSE;
bDisableVolumeEffect = FALSE;
bExtraSoundEnable = TRUE;
for( INT i = 0; i < 16; i++ ) {
nVolume[i] = 100;
}
}
};
class CCfgShortCut
{
public:
WORD nShortCut[512];
enum {
K_ALT = 0x8000,
K_CTRL = 0x4000,
K_SHIFT = 0x2000,
};
void Default() {
for( INT i = 0; i < (sizeof(nShortCut)/sizeof(WORD)); i++ ) {
nShortCut[i] = 0;
}
// Main controls
nShortCut[ 0] = DIK_O+K_CTRL; // ID_OPEN
nShortCut[ 1] = DIK_C+K_CTRL; // ID_CLOSE
nShortCut[ 2] = DIK_L+K_CTRL; // ID_LAUNCHER
nShortCut[ 3] = DIK_N+K_CTRL; // ID_NETPLAY_CONNECT
nShortCut[ 4] = DIK_D+K_CTRL; // ID_NETPLAY_DISCONNECT
nShortCut[ 5] = DIK_A+K_CTRL; // ID_NETPLAY_CHAT
nShortCut[ 8] = DIK_I+K_CTRL; // ID_ROMINFO
nShortCut[ 9] = DIK_W+K_CTRL; // ID_WAVERECORD
nShortCut[ 15] = DIK_X+K_CTRL; // ID_EXIT
// Emulation controls
nShortCut[ 16] = DIK_F1; // Hardware reset
nShortCut[ 17] = DIK_F2; // Software reset
nShortCut[ 18] = DIK_P; // Hardware pause
nShortCut[ 19] = DIK_TAB; // Throttle(toggled)
nShortCut[ 20] = DIK_NUMPADENTER; // Frame skip Auto
nShortCut[ 21] = DIK_ADD; // Frame skip +
nShortCut[ 22] = DIK_SUBTRACT; // Frame skip -
nShortCut[ 23] = DIK_SPACE; // One Frame step
nShortCut[ 24] = DIK_BACKSPACE; // Throttle(Not toggle)
// State controls
nShortCut[ 32] = DIK_L; // State Load
nShortCut[ 33] = DIK_S; // State Save
nShortCut[ 34] = DIK_F3; // State Slot +
nShortCut[ 35] = DIK_F4; // State Slot -
// Disk controls
nShortCut[ 48] = DIK_5; // Disk Eject
nShortCut[ 49] = DIK_1; // Disk 0 Side A
nShortCut[ 50] = DIK_2; // Disk 0 Side B
nShortCut[ 51] = DIK_3; // Disk 1 Side A
nShortCut[ 52] = DIK_4; // Disk 1 Side B
// Movie controls
nShortCut[ 56] = DIK_P+K_ALT; // Movie Play
nShortCut[ 57] = DIK_R+K_ALT; // Movie Rec
nShortCut[ 58] = DIK_A+K_ALT; // Movie Rec Append
nShortCut[ 59] = DIK_S+K_ALT; // Movie Stop
nShortCut[ 60] = DIK_M+K_ALT; // Movie Info
// Screen controls
nShortCut[ 64] = DIK_F5; // Zoom x1
nShortCut[ 65] = DIK_F6; // Zoom x2
nShortCut[ 66] = DIK_F7; // Zoom x3
nShortCut[ 67] = DIK_F8; // Zoom x4
nShortCut[ 68] = DIK_RETURN+K_ALT; // Fullscreen
// Sound controls
nShortCut[ 72] = DIK_BACK+K_CTRL; // Mute Master
nShortCut[ 73] = DIK_1+K_CTRL; // Mute Rectangle #1
nShortCut[ 74] = DIK_2+K_CTRL; // Mute Rectangle #2
nShortCut[ 75] = DIK_3+K_CTRL; // Mute Triangle
nShortCut[ 76] = DIK_4+K_CTRL; // Mute Noise
nShortCut[ 77] = DIK_5+K_CTRL; // Mute Dpcm
nShortCut[ 78] = DIK_6+K_CTRL; // Mute External #1
nShortCut[ 79] = DIK_7+K_CTRL; // Mute External #2
nShortCut[ 80] = DIK_8+K_CTRL; // Mute External #3
nShortCut[ 81] = DIK_9+K_CTRL; // Mute External #4
nShortCut[ 82] = DIK_0+K_CTRL; // Mute External #5
nShortCut[ 83] = DIK_MINUS+K_CTRL; // Mute External #6
nShortCut[ 84] = DIK_CIRCUMFLEX+K_CTRL; // Mute External #7
nShortCut[ 85] = DIK_YEN+K_CTRL; // Mute External #8
// Tape controls
nShortCut[ 90] = 0; // Tape Play
nShortCut[ 91] = 0; // Tape Rec
nShortCut[ 92] = 0; // Tape Stop
// Other controls
nShortCut[ 96] = DIK_P+K_CTRL; // Snapshot
nShortCut[ 97] = DIK_F11; // FPSDISP
nShortCut[ 98] = DIK_F12+K_CTRL; // TV Aspect
nShortCut[ 99] = DIK_F11+K_CTRL; // TV frame
nShortCut[100] = DIK_F12; // Scanline
nShortCut[101] = DIK_F9+K_CTRL; // Show 240 lines
nShortCut[102] = DIK_F9; // All sprites
nShortCut[103] = DIK_F10; // Sync draw
nShortCut[104] = DIK_F10+K_CTRL; // Fit screen
nShortCut[105] = 0; // Left clip
// Cheat
nShortCut[110] = DIK_HOME+K_CTRL; // Search
nShortCut[111] = DIK_END+K_CTRL; // Cheat
nShortCut[112] = DIK_INSERT; // Cheat enable
nShortCut[113] = DIK_DELETE; // Cheat disable
nShortCut[114] = 0; // GameGenie
// Tools
nShortCut[116] = 0; // Pattern Viewer
nShortCut[117] = 0; // NameTable Viewer
nShortCut[118] = 0; // Palette Viewer
nShortCut[119] = 0; // Memory Viewer
// Quick Load/Save
nShortCut[256] = DIK_NUMPAD0+K_CTRL; // QuickLoad Slot0
nShortCut[257] = DIK_NUMPAD1+K_CTRL; // QuickLoad Slot1
nShortCut[258] = DIK_NUMPAD2+K_CTRL; // QuickLoad Slot2
nShortCut[259] = DIK_NUMPAD3+K_CTRL; // QuickLoad Slot3
nShortCut[260] = DIK_NUMPAD4+K_CTRL; // QuickLoad Slot4
nShortCut[261] = DIK_NUMPAD5+K_CTRL; // QuickLoad Slot5
nShortCut[262] = DIK_NUMPAD6+K_CTRL; // QuickLoad Slot6
nShortCut[263] = DIK_NUMPAD7+K_CTRL; // QuickLoad Slot7
nShortCut[264] = DIK_NUMPAD8+K_CTRL; // QuickLoad Slot8
nShortCut[265] = DIK_NUMPAD9+K_CTRL; // QuickLoad Slot9
nShortCut[266] = DIK_NUMPAD0+K_ALT; // QuickSave Slot0
nShortCut[267] = DIK_NUMPAD1+K_ALT; // QuickSave Slot1
nShortCut[268] = DIK_NUMPAD2+K_ALT; // QuickSave Slot2
nShortCut[269] = DIK_NUMPAD3+K_ALT; // QuickSave Slot3
nShortCut[270] = DIK_NUMPAD4+K_ALT; // QuickSave Slot4
nShortCut[271] = DIK_NUMPAD5+K_ALT; // QuickSave Slot5
nShortCut[272] = DIK_NUMPAD6+K_ALT; // QuickSave Slot6
nShortCut[273] = DIK_NUMPAD7+K_ALT; // QuickSave Slot7
nShortCut[274] = DIK_NUMPAD8+K_ALT; // QuickSave Slot8
nShortCut[275] = DIK_NUMPAD9+K_ALT; // QuickSave Slot9
}
};
class CCfgLanguage
{
public:
LCID lcID;
CHAR szLanguage[256];
void Default() {
lcID = NULL;
szLanguage[0] = 0;
}
};
class CCfgController
{
public:
WORD nButton[4][64];
WORD nRapid [4][ 2];
// 0:Crazy Climber
// 1:Famly Trainer
// 2:Exciting Boxing
// 3:Mahjang
WORD nExButton[4][64];
WORD nNsfButton[64];
WORD nVSUnisystem[64];
void Default() {
DefaultController1();
DefaultController2();
DefaultController3();
DefaultController4();
DefaultExController0();
DefaultExController1();
DefaultExController2();
DefaultExController3();
DefaultNsfController();
DefaultVSUnisystem();
}
void DefaultController1() {
for( INT i = 0; i < 64; i++ )
nButton[0][i] = 0;
nButton[0][ 0] = DIK_UP;
nButton[0][ 1] = DIK_DOWN;
nButton[0][ 2] = DIK_LEFT;
nButton[0][ 3] = DIK_RIGHT;
nButton[0][ 4] = DIK_X; // A
nButton[0][ 5] = DIK_Z; // B
nButton[0][ 6] = 0; // A Rapid
nButton[0][ 7] = 0; // B Rapid
nButton[0][ 8] = DIK_RSHIFT; // SELECT
nButton[0][ 9] = DIK_RETURN; // START
nRapid[0][0] = 0; // A Rapid speed
nRapid[0][1] = 0; // B Rapid speed
}
void DefaultController2() {
for( INT i = 0; i < 64; i++ )
nButton[1][i] = 0;
nButton[1][ 0] = DIK_NUMPAD8;
nButton[1][ 1] = DIK_NUMPAD2;
nButton[1][ 2] = DIK_NUMPAD4;
nButton[1][ 3] = DIK_NUMPAD6;
nButton[1][ 4] = DIK_N; // A
nButton[1][ 5] = DIK_B; // B
nButton[1][ 6] = 0; // A Rapid
nButton[1][ 7] = 0; // B Rapid
nButton[1][ 8] = 0; // SELECT
nButton[1][ 9] = 0; // START
nButton[1][10] = DIK_M; // Mic
nRapid[1][0] = 0; // A Rapid speed
nRapid[1][1] = 0; // B Rapid speed
}
void DefaultController3() {
for( INT i = 0; i < 64; i++ )
nButton[2][i] = 0;
nRapid[2][0] = 0; // A Rapid speed
nRapid[2][1] = 0; // B Rapid speed
}
void DefaultController4() {
for( INT i = 0; i < 64; i++ )
nButton[3][i] = 0;
nRapid[3][0] = 0; // A Rapid speed
nRapid[3][1] = 0; // B Rapid speed
}
void DefaultExController0() {
// Crazy Climberコントローラ(実際には存在しない)
for( INT i = 0; i < 64; i++ )
nExButton[0][i] = 0;
// nExButton[0][ 0] = 0; // L up
// nExButton[0][ 1] = 0; // L down
// nExButton[0][ 2] = 0; // L left
// nExButton[0][ 3] = 0; // L right
// nExButton[0][ 4] = 0; // R up
// nExButton[0][ 5] = 0; // R down
// nExButton[0][ 6] = 0; // R left
// nExButton[0][ 7] = 0; // R right
}
void DefaultExController1() {
// Famly Trainerコントローラ
for( INT i = 0; i < 64; i++ )
nExButton[1][i] = 0;
}
void DefaultExController2() {
// Exciting Boxingコントローラ
for( INT i = 0; i < 64; i++ )
nExButton[2][i] = 0;
}
void DefaultExController3() {
// Mahjangコントローラ
for( INT i = 0; i < 64; i++ )
nExButton[3][i] = 0;
}
void DefaultNsfController() {
for( INT i = 0; i < 64; i++ )
nNsfButton[i] = 0;
nNsfButton[ 0] = DIK_UP; // Play
nNsfButton[ 1] = DIK_DOWN; // Stop
nNsfButton[ 2] = DIK_LEFT; // Number -1
nNsfButton[ 3] = DIK_RIGHT; // Number +1
nNsfButton[ 4] = DIK_PRIOR; // Number +16
nNsfButton[ 5] = DIK_NEXT; // Number -16
}
void DefaultVSUnisystem() {
for( INT i = 0; i < 64; i++ )
nVSUnisystem[i] = 0;
nVSUnisystem[0] = DIK_C; // Coin
}
};
class CCfgMovie
{
public:
BYTE bUsePlayer[4];
BOOL bRerecord;
BOOL bLoopPlay;
BOOL bResetRec;
BOOL bPadDisplay;
void Default() {
bUsePlayer[0] = 0xFF;
bUsePlayer[1] = 0x00;
bUsePlayer[2] = 0x00;
bUsePlayer[3] = 0x00;
bRerecord = TRUE;
bLoopPlay = FALSE;
bResetRec = FALSE;
bPadDisplay = FALSE;
}
};
class CCfgLauncher
{
public:
RECT rcWindowPos;
BYTE bHeaderView [16];
BYTE nHeaderOrder[16];
SHORT nHeaderWidth[16];
BOOL bActivePause;
INT nListSelect;
BOOL bSortDir;
INT nSortType;
BYTE bFolderUse[16];
CHAR szFolder[16][_MAX_PATH];
CHAR szLastSelect[_MAX_PATH];
void Default() {
rcWindowPos.left = rcWindowPos.right =
rcWindowPos.top = rcWindowPos.bottom = 0;
bActivePause = FALSE;
nListSelect = 0;
bSortDir = FALSE;
nSortType = 0;
INT i;
for( i = 0; i < 16; i++ ) {
bHeaderView [i] = TRUE;
nHeaderOrder[i] = i;
nHeaderWidth[i] = (i==0)?160:48;
}
for( i = 0; i < 16; i++ ) {
bFolderUse[i] = FALSE;
szFolder[i][0] = '\0';
}
szLastSelect[0] = '\0';
}
};
class CCfgExtraSound
{
public:
CHAR szExtSoundFile[ ESF_FILE_MAX ][ MAX_PATH ];
void Default() {
for( INT i = 0; i < ESF_FILE_MAX; i++ ) {
szExtSoundFile[i][0] = '\0';
}
}
};
class CCfgNetPlay
{
public:
RECT rcChatPos;
INT nRecentPort, nRecentHost;
CHAR szRecentPort[16][_MAX_PATH+1];
CHAR szRecentHost[16][_MAX_PATH+1];
CHAR szNick[_MAX_PATH+1];
void Default() {
rcChatPos.left = rcChatPos.right =
rcChatPos.top = rcChatPos.bottom = 0;
::lstrcpy( szNick, "NoName" );
for( INT i = 0; i < 16; i++ ) {
szRecentPort[i][0] = '\0';
szRecentHost[i][0] = '\0';
}
::lstrcpy( szRecentPort[0], "10000" );
::lstrcpy( szRecentHost[0], "localhost:10000" );
nRecentPort = 1;
nRecentHost = 1;
}
};
class CConfig
{
public:
CConfig() {
m_bKeyboardDisable = FALSE;
Default();
}
CCfgGeneral general;
CCfgPath path;
CCfgEmulator emulator;
CCfgGraphics graphics;
CCfgSound sound;
CCfgShortCut shortcut;
CCfgLanguage language;
CCfgController controller;
CCfgMovie movie;
CCfgLauncher launcher;
CCfgExtraSound extsound;
CCfgNetPlay netplay;
void Default() {
general.Default();
path.Default();
emulator.Default();
graphics.Default();
sound.Default();
shortcut.Default();
language.Default();
controller.Default();
movie.Default();
launcher.Default();
extsound.Default();
netplay.Default();
}
void Load();
void Save();
// Checker
void InputKeyboardDisable( BOOL bEnable ) {
m_bKeyboardDisable = bEnable;
}
BOOL ButtonCheck( INT nNo, INT nID );
BOOL ExButtonCheck( INT nNo, INT nID );
BOOL NsfButtonCheck( INT nID );
BOOL ButtonCheck( INT nID, WORD* pKey );
// Converter
string ShortcutToKeyName( INT nShortcut );
// Table
static INT SamplingRateTable[];
static INT ShortcutKeyID[];
protected:
BOOL m_bKeyboardDisable;
private:
};
// 個別ゲームオプション
class CGameOption
{
public:
// for Cartridge
void Load( DWORD crc );
void Save( LPCSTR name, DWORD crc );
// for FDS
void Load( DWORD gid, DWORD mid );
void Save( LPCSTR name, DWORD gid, DWORD mid );
// Default保存
INT defRenderMethod;
INT defIRQtype;
BOOL defFrameIRQ;
BOOL defVideoMode;
// データ
INT nRenderMethod;
INT nIRQtype;
BOOL bFrameIRQ;
BOOL bVideoMode;
protected:
private:
};
extern CConfig Config;
extern CGameOption GameOption;
#endif // !__CCONFIG_INCLUDED__

View File

@ -0,0 +1,516 @@
//
// コントローラダイアログクラス
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Wnd.h"
#include "ControllerDlg.h"
#include "DirectInput.h"
///////////////////////////////////////////////////////////////////////////////
DLG_MESSAGE_BEGIN(CControllerPageDlg)
// メッセージ
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
// NOTIFYメッセージ
DLG_NOTIFY_BEGIN()
DLG_NOTIFY_END()
// コマンド
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND_NOTIFY_RANGE( IDC_CTR_UP, IDC_CTR_END, STN_CLICKED, OnClicked )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CControllerPageDlg::Create( UINT nID, HWND hWndParent )
{
m_nPageID = nID;
m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(nID),
hWndParent, g_DlgProc, (LPARAM)this );
return (m_hWnd)?TRUE:FALSE;
}
void CControllerPageDlg::Destroy()
{
::DestroyWindow( m_hWnd );
}
DLGCMD CControllerPageDlg::OnClicked( DLGCMDPARAM )
{
// DEBUGOUT( "CControllerPageDlg::OnClicked uID=%d\n", uID );
// 親のタブコントロールをパスしてメッセージを通知:p
HWND hWndParent, hWndOwner;
hWndParent = ::GetParent( m_hWnd );
hWndOwner = ::GetParent( hWndParent );
::SendMessage( hWndOwner, WM_COMMAND, MAKELPARAM(uID,STN_CLICKED), (LPARAM)::GetDlgItem(m_hWnd,uID) );
}
DLGMSG CControllerPageDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CControllerPageDlg::OnInitDialog\n" );
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
UINT CControllerDlg::ControllerPageID[] = {
IDD_CTR_PLAYER1,
IDD_CTR_PLAYER2,
IDD_CTR_PLAYER3,
IDD_CTR_PLAYER4,
IDD_CTR_CRAZYCLIMBER,
IDD_CTR_FAMLYTRAINER,
IDD_CTR_EXCITINGBOXING,
IDD_CTR_MAHJANG,
IDD_CTR_NSFPLAYER,
IDD_CTR_VSUNISYSTEM,
0
};
DLG_MESSAGE_BEGIN(CControllerDlg)
// メッセージ
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_ON_MESSAGE( WM_DESTROY, OnDestroy )
DLG_ON_MESSAGE( WM_TIMER, OnTimer )
// NOTIFYメッセージ
DLG_NOTIFY_BEGIN()
DLG_ON_NOTIFY( IDC_CTR_TAB, TCN_SELCHANGE, OnSelectChange )
DLG_NOTIFY_END()
// コマンド
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDDEFAULT, OnDefault )
DLG_ON_COMMAND_NOTIFY_RANGE( IDC_CTR_UP, IDC_CTR_END, STN_CLICKED, OnClicked )
DLG_ON_COMMAND_NOTIFY( IDC_CTR_SELECT_COMBO, CBN_SELCHANGE, OnSettingSelectChange )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CControllerDlg::DoModal( HWND hWndParent )
{
m_bCancelMode = FALSE;
m_TimerID = 0;
m_SettingSel = 0;
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_CONTROLLER),
hWndParent, g_DlgProc, (LPARAM)this );
}
BOOL CControllerDlg::PreTranslateMessage( MSG* pMsg )
{
if( pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST ) {
// DEBUGOUT( "CControllerDlg::PreTranslateMessage WM_KEY????\n" );
return m_bCancelMode;
}
return FALSE;
}
void CControllerDlg::OnInitialMember()
{
HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CTR_TAB );
RECT rcT, rcP, rcW;
INT page;
// for( INT page = 0; ControllerPageID[page]; page++ ) {
for( page = 0; ControllerPageID[page]; page++ ) {
m_Page[page].Create( ControllerPageID[page], hWndCtrl );
// 名前の取得
CHAR szTitle[256];
::GetWindowText( m_Page[page].m_hWnd, szTitle, sizeof(szTitle) );
// 名前を取得したらキャプションを消す
LONG style;
style = ::GetWindowLong( m_Page[page].m_hWnd, GWL_STYLE );
style &= ~(WS_CAPTION|WS_BORDER|WS_OVERLAPPED);
::SetWindowLong( m_Page[page].m_hWnd, GWL_STYLE, style );
// サイズ変更
::GetWindowRect( m_Page[page].m_hWnd, &rcW );
rcW.right -= ::GetSystemMetrics( SM_CXSIZEFRAME );
rcW.bottom -= ::GetSystemMetrics( SM_CYCAPTION )+::GetSystemMetrics( SM_CYSIZEFRAME )*2;
::SetWindowPos( m_Page[page].m_hWnd, NULL, 0, 0, RCWIDTH(rcW), RCHEIGHT(rcW), SWP_NOMOVE|SWP_NOZORDER );
// タブに名前を設定する
TCITEM tcitem;
tcitem.mask = TCIF_TEXT;
tcitem.pszText = szTitle;
TabCtrl_InsertItem( hWndCtrl, page, &tcitem );
// // ページ位置の補正
// ::GetClientRect( hWndCtrl, &rcT );
// TabCtrl_AdjustRect( hWndCtrl, FALSE, &rcT );
// ::GetWindowRect( m_Page[page].m_hWnd, &rcP );
// 計算
// rcW.left = rcT.left + (RCWIDTH(rcT)-RCWIDTH(rcP))/2;
// rcW.top = rcT.top + (RCHEIGHT(rcT)-RCHEIGHT(rcP))/2;
// rcW.right = rcW.left + RCWIDTH(rcP);
// rcW.bottom = rcW.top + RCHEIGHT(rcP);
// ::SetWindowPos( m_Page[page].m_hWnd, NULL, rcW.left, rcW.top, RCWIDTH(rcW), RCHEIGHT(rcW), SWP_NOZORDER|SWP_NOACTIVATE );
// 各ページのリストボックスの設定
if( page < 4 ) {
HWND hWndList;
hWndList = ::GetDlgItem( m_Page[page].m_hWnd, IDC_CTR_A_RAPID_LIST );
::SendMessage( hWndList, LB_INSERTSTRING, 0, (LPARAM)" 10FPS" );
::SendMessage( hWndList, LB_INSERTSTRING, 1, (LPARAM)" 15FPS" );
::SendMessage( hWndList, LB_INSERTSTRING, 2, (LPARAM)" 20FPS" );
::SendMessage( hWndList, LB_INSERTSTRING, 3, (LPARAM)" 30FPS" );
hWndList = ::GetDlgItem( m_Page[page].m_hWnd, IDC_CTR_B_RAPID_LIST );
::SendMessage( hWndList, LB_INSERTSTRING, 0, (LPARAM)" 10FPS" );
::SendMessage( hWndList, LB_INSERTSTRING, 1, (LPARAM)" 15FPS" );
::SendMessage( hWndList, LB_INSERTSTRING, 2, (LPARAM)" 20FPS" );
::SendMessage( hWndList, LB_INSERTSTRING, 3, (LPARAM)" 30FPS" );
}
// ボタン名等の設定
OnPageSetup( page );
::ShowWindow( m_Page[page].m_hWnd, (page==0)?SW_SHOW:SW_HIDE );
}
// ページ位置再調整
for( page = 0; ControllerPageID[page]; page++ ) {
// ページ位置の補正
::GetClientRect( hWndCtrl, &rcT );
TabCtrl_AdjustRect( hWndCtrl, FALSE, &rcT );
::GetWindowRect( m_Page[page].m_hWnd, &rcP );
// 計算
rcW.left = rcT.left + (RCWIDTH(rcT)-RCWIDTH(rcP))/2;
rcW.top = rcT.top + (RCHEIGHT(rcT)-RCHEIGHT(rcP))/2;
rcW.right = rcW.left + RCWIDTH(rcP);
rcW.bottom = rcW.top + RCHEIGHT(rcP);
::SetWindowPos( m_Page[page].m_hWnd, NULL, rcW.left, rcW.top, RCWIDTH(rcW), RCHEIGHT(rcW), SWP_NOZORDER|SWP_NOACTIVATE );
}
TabCtrl_SetCurSel( hWndCtrl, 0 );
m_PageSel = 0;
m_PageNum = page;
// 設定コンボボックス
::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_RESETCONTENT, 0, 0 );
CHAR szStr[64];
for( INT i = IDS_CTR_SELECT1; i <= IDS_CTR_SELECT2; i++ ) {
CApp::LoadString( i, szStr, sizeof(szStr) );
::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_INSERTSTRING, (WPARAM)i-IDS_CTR_SELECT1, (LPARAM)szStr );
}
::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_SETCURSEL, 0, 0 );
}
void CControllerDlg::OnPageSetup( UINT nPage )
{
HWND hWnd = m_Page[nPage].m_hWnd;
HWND hWndCtrl;
INT nKey;
LPCSTR lpStr;
INT nOffset = m_SettingSel?32:0;
for( INT nID = IDC_CTR_UP; nID <= IDC_CTR_END; nID++ ) {
if( (hWndCtrl = ::GetDlgItem( hWnd, nID )) ) {
if( nPage < 4 ) {
nKey = Config.controller.nButton[nPage][nID-IDC_CTR_UP+nOffset];
} else if( ControllerPageID[nPage] == IDD_CTR_CRAZYCLIMBER ) {
nKey = Config.controller.nExButton[0][nID-IDC_CTR_UP+nOffset];
} else if( ControllerPageID[nPage] == IDD_CTR_FAMLYTRAINER ) {
nKey = Config.controller.nExButton[1][nID-IDC_CTR_UP+nOffset];
} else if( ControllerPageID[nPage] == IDD_CTR_EXCITINGBOXING ) {
nKey = Config.controller.nExButton[2][nID-IDC_CTR_UP+nOffset];
} else if( ControllerPageID[nPage] == IDD_CTR_MAHJANG ) {
nKey = Config.controller.nExButton[3][nID-IDC_CTR_UP+nOffset];
} else if( ControllerPageID[nPage] == IDD_CTR_NSFPLAYER ) {
nKey = Config.controller.nNsfButton[nID-IDC_CTR_UP+nOffset];
} else if( ControllerPageID[nPage] == IDD_CTR_VSUNISYSTEM ) {
nKey = Config.controller.nVSUnisystem[nID-IDC_CTR_UP+nOffset];
}
if( (lpStr = DirectInput.SearchKeyName(nKey)) ) {
::SetWindowText( hWndCtrl, lpStr );
} else {
::SetWindowText( hWndCtrl, "----" );
}
::InvalidateRect( hWndCtrl, NULL, TRUE );
}
}
if( nPage < 4 ) {
::SendDlgItemMessage( hWnd, IDC_CTR_A_RAPID_LIST, LB_SETCURSEL,
(WPARAM)Config.controller.nRapid[nPage][0], 0 );
::SendDlgItemMessage( hWnd, IDC_CTR_B_RAPID_LIST, LB_SETCURSEL,
(WPARAM)Config.controller.nRapid[nPage][1], 0 );
}
}
DLGMSG CControllerDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CControllerDlg::OnInitDialog\n" );
m_ConfigSave = Config.controller;
OnInitialMember();
return TRUE;
}
DLGMSG CControllerDlg::OnDestroy( DLGMSGPARAM )
{
// DEBUGOUT( "CControllerDlg::OnDestroy\n" );
// チャイルドウインドウを破棄
for( INT i = 0; i < m_PageNum; i++ ) {
::DestroyWindow( m_Page[i].m_hWnd );
}
return FALSE;
}
DLGNOTIFY CControllerDlg::OnSelectChange( DLGNOTIFYPARAM )
{
// DEBUGOUT( "CControllerDlg::OnSelectChange\n" );
HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CTR_TAB );
m_PageSel = TabCtrl_GetCurSel( hWndCtrl );
OnPageSetup( m_PageSel );
for( INT i = 0; i < m_PageNum; i++ ) {
if( i == m_PageSel ) {
::ShowWindow( m_Page[i].m_hWnd, SW_SHOW );
} else {
::ShowWindow( m_Page[i].m_hWnd, SW_HIDE );
}
}
if( m_TimerID ) {
::KillTimer( m_hWnd, m_TimerID );
m_TimerID = 0;
m_ControlID = 0;
// ::InvalidateRect( hWndCtrl, NULL, TRUE );
}
m_bCancelMode = FALSE;
}
DLGNOTIFY CControllerDlg::OnSettingSelectChange( DLGCMDPARAM )
{
// DEBUGOUT( "CControllerDlg::OnSettingSelectChange\n" );
if( m_TimerID ) {
::KillTimer( m_hWnd, m_TimerID );
m_TimerID = 0;
m_ControlID = 0;
// ::InvalidateRect( ::GetDlgItem( m_hWnd, IDC_CTR_TAB ), NULL, TRUE );
}
m_bCancelMode = FALSE;
m_SettingSel = ::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_GETCURSEL, 0, 0 );
OnPageSetup( m_PageSel );
}
DLGCMD CControllerDlg::OnClicked( DLGCMDPARAM )
{
// DEBUGOUT( "CControllerDlg::OnClicked uID=%d\n", uID );
if( !m_TimerID ) {
m_ControlID = uID;
m_TimerCount = 0;
m_TimerID = ::SetTimer( m_hWnd, 1, 50, NULL );
m_bCancelMode = TRUE;
}
}
DLGMSG CControllerDlg::OnTimer( DLGMSGPARAM )
{
HWND hWndCtrl = ::GetDlgItem( m_Page[m_PageSel].m_hWnd, m_ControlID );
INT nID = m_ControlID - IDC_CTR_UP;
INT nOffset = m_SettingSel?32:0;
if( wParam == (WPARAM)m_TimerID ) {
if( m_TimerCount == 0 )
m_TimerStart = ::timeGetTime();
m_TimerCount++;
DirectInput.Poll();
if( m_TimerCount > 60 ) {
// TimeOut
if( m_TimerID ) {
::KillTimer( m_hWnd, m_TimerID );
m_TimerID = 0;
m_ControlID = 0;
::InvalidateRect( hWndCtrl, NULL, TRUE );
}
m_bCancelMode = FALSE;
} else {
// Button push?
BOOL bSet = FALSE;
INT i;
LPCSTR str;
// Set cancel
if( DirectInput.m_Sw[DIK_ESCAPE] ) {
if( m_PageSel < 4 ) {
Config.controller.nButton[m_PageSel][nID+nOffset] = 0;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_CRAZYCLIMBER ) {
Config.controller.nExButton[0][nID+nOffset] = 0;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_FAMLYTRAINER ) {
Config.controller.nExButton[1][nID+nOffset] = 0;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_EXCITINGBOXING ) {
Config.controller.nExButton[2][nID+nOffset] = 0;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_MAHJANG ) {
Config.controller.nExButton[3][nID+nOffset] = 0;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_NSFPLAYER ) {
Config.controller.nNsfButton[nID+nOffset] = 0;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_VSUNISYSTEM ) {
Config.controller.nVSUnisystem[nID+nOffset] = 0;
}
::SetWindowText( hWndCtrl, "----" );
bSet = TRUE;
} else {
for( i = 0; i < 512; i++ ) {
if( DirectInput.m_Sw[i] ) {
if( (str=DirectInput.SearchKeyName( i )) ) {
if( m_PageSel < 4 ) {
Config.controller.nButton[m_PageSel][nID+nOffset] = i;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_CRAZYCLIMBER ) {
Config.controller.nExButton[0][nID+nOffset] = i;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_FAMLYTRAINER ) {
Config.controller.nExButton[1][nID+nOffset] = i;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_EXCITINGBOXING ) {
Config.controller.nExButton[2][nID+nOffset] = i;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_MAHJANG ) {
Config.controller.nExButton[3][nID+nOffset] = i;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_NSFPLAYER ) {
Config.controller.nNsfButton[nID+nOffset] = i;
} else if( ControllerPageID[m_PageSel] == IDD_CTR_VSUNISYSTEM ) {
Config.controller.nVSUnisystem[nID+nOffset] = i;
}
::SetWindowText( hWndCtrl, str );
bSet = TRUE;
}
}
}
}
if( bSet ) {
// Button Pressed
if( m_TimerID ) {
::KillTimer( m_hWnd, m_TimerID );
m_TimerID = 0;
m_ControlID = 0;
::InvalidateRect( hWndCtrl, NULL, TRUE );
}
m_bCancelMode = FALSE;
} else {
// Flashing
HDC hDC = ::GetDC( hWndCtrl );
RECT rc;
::GetClientRect( hWndCtrl, &rc );
DWORD c = ((::timeGetTime()-m_TimerStart)/3)&0xFF;
if( c > 0x7F )
c = 0x80 - (c - 0x7F);
c *= 2;
::SetBkColor( hDC, RGB(c,c,c) );
::ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL );
::ReleaseDC( hWndCtrl, hDC );
}
}
}
return FALSE;
}
DLGCMD CControllerDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CControllerDlg::OnOK\n" );
if( m_TimerID ) {
::KillTimer( m_hWnd, m_TimerID );
m_TimerID = 0;
m_ControlID = 0;
}
m_bCancelMode = FALSE;
for( INT page = 0; page < 4; page++ ) {
Config.controller.nRapid[page][0] = ::SendDlgItemMessage( m_Page[page].m_hWnd, IDC_CTR_A_RAPID_LIST, LB_GETCURSEL, 0, 0 );
Config.controller.nRapid[page][1] = ::SendDlgItemMessage( m_Page[page].m_hWnd, IDC_CTR_B_RAPID_LIST, LB_GETCURSEL, 0, 0 );
}
::EndDialog( m_hWnd, IDOK );
}
DLGCMD CControllerDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CControllerDlg::OnCancel\n" );
// if( m_bCancelMode )
// return;
if( m_TimerID ) {
::KillTimer( m_hWnd, m_TimerID );
m_TimerID = 0;
m_ControlID = 0;
}
m_bCancelMode = FALSE;
Config.controller = m_ConfigSave;
::EndDialog( m_hWnd, IDCANCEL );
}
DLGCMD CControllerDlg::OnDefault( DLGCMDPARAM )
{
// DEBUGOUT( "CControllerDlg::OnDefault\n" );
if( m_TimerID ) {
::KillTimer( m_hWnd, m_TimerID );
m_TimerID = 0;
m_ControlID = 0;
}
m_bCancelMode = FALSE;
switch( ControllerPageID[m_PageSel] ) {
case IDD_CTR_PLAYER1:
Config.controller.DefaultController1();
break;
case IDD_CTR_PLAYER2:
Config.controller.DefaultController2();
break;
case IDD_CTR_PLAYER3:
Config.controller.DefaultController3();
break;
case IDD_CTR_PLAYER4:
Config.controller.DefaultController4();
break;
case IDD_CTR_CRAZYCLIMBER:
Config.controller.DefaultExController0();
break;
case IDD_CTR_FAMLYTRAINER:
Config.controller.DefaultExController1();
break;
case IDD_CTR_EXCITINGBOXING:
Config.controller.DefaultExController2();
break;
case IDD_CTR_MAHJANG:
Config.controller.DefaultExController3();
break;
case IDD_CTR_NSFPLAYER:
Config.controller.DefaultNsfController();
break;
case IDD_CTR_VSUNISYSTEM:
Config.controller.DefaultVSUnisystem();
break;
default:
break;
}
OnPageSetup( m_PageSel );
}

View File

@ -0,0 +1,81 @@
//
// コントローラダイアログクラス
//
#ifndef __CCONTROLLERDLG_INCLUDED__
#define __CCONTROLLERDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
#include "Config.h"
class CControllerPageDlg : public CWnd
{
public:
BOOL Create( UINT nID, HWND hWndParent );
// Override from CWnd
void Destroy();
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnClicked( DLGCMDPARAM );
//
UINT m_nPageID;
private:
};
class CControllerDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
// Override from CWnd
BOOL PreTranslateMessage( MSG* pMsg );
protected:
void OnInitialMember();
void OnPageSetup( UINT nPage );
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGMSG OnDestroy( DLGMSGPARAM );
DLGMSG OnTimer( DLGMSGPARAM );
DLGNOTIFY OnSelectChange( DLGNOTIFYPARAM );
DLGNOTIFY OnSettingSelectChange( DLGCMDPARAM );
DLGCMD OnClicked( DLGCMDPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnDefault( DLGCMDPARAM );
//
enum { PAGE_MAX=12 };
BOOL m_bCancelMode;
INT m_ControlID;
INT m_TimerID;
INT m_TimerStart;
INT m_TimerCount;
INT m_SettingSel;
INT m_PageSel;
INT m_PageNum;
CControllerPageDlg m_Page[PAGE_MAX];
CCfgController m_ConfigSave;
static UINT ControllerPageID[];
private:
};
#endif // !__CCONTROLLERDLG_INCLUDED__

View File

@ -0,0 +1,71 @@
//
// CRCチェック用ライブラリクラス
//
#include "Crclib.h"
BOOL CRC::m_Init = FALSE;
BOOL CRC::m_InitRev = FALSE;
DWORD CRC::m_CrcTable[ UCHAR_MAX+1 ];
DWORD CRC::m_CrcTableRev[ UCHAR_MAX+1 ];
#define CRCPOLY1 0x04C11DB7UL
#define CRCPOLY2 0xEDB88320UL
DWORD CRC::Crc( INT size, LPBYTE c )
{
if( !m_Init ) {
MakeTable();
m_Init = TRUE;
}
DWORD r = 0xFFFFFFFFUL;
while( --size >= 0 ) {
r = (r << CHAR_BIT) ^ m_CrcTable[(BYTE)(r >> (32 - CHAR_BIT)) ^ *c++];
}
return ~r & 0xFFFFFFFFUL;
}
DWORD CRC::CrcRev( INT size, LPBYTE c )
{
if( !m_InitRev ) {
MakeTableRev();
m_InitRev = TRUE;
}
DWORD r = 0xFFFFFFFFUL;
while( --size >= 0 ) {
r = (r >> CHAR_BIT) ^ m_CrcTableRev[(BYTE)r ^ *c++];
}
return r ^ 0xFFFFFFFFUL;
}
void CRC::MakeTable()
{
INT i, j;
DWORD r;
for( i = 0; i <= UCHAR_MAX; i++ ) {
r = (DWORD)i << (32 - CHAR_BIT);
for( j = 0; j < CHAR_BIT; j++ ) {
if( r & 0x80000000UL ) r = (r << 1) ^ CRCPOLY1;
else r <<= 1;
}
m_CrcTable[i] = r & 0xFFFFFFFFUL;
}
}
void CRC::MakeTableRev()
{
INT i, j;
DWORD r;
for( i = 0; i <= UCHAR_MAX; i++ ) {
r = i;
for( j = 0; j < CHAR_BIT; j++ ) {
if( r & 1 ) r = (r >> 1) ^ CRCPOLY2;
else r >>= 1;
}
m_CrcTableRev[i] = r;
}
}

View File

@ -0,0 +1,24 @@
//
// CRCチェック用ライブラリクラス
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <limits.h>
class CRC
{
public:
static DWORD Crc( INT size, LPBYTE c );
static DWORD CrcRev( INT size, LPBYTE c ); // 逆順
protected:
static void MakeTable();
static void MakeTableRev(); // 逆順
static BOOL m_Init;
static BOOL m_InitRev;
static DWORD m_CrcTable[ UCHAR_MAX+1 ];
static DWORD m_CrcTableRev[ UCHAR_MAX+1 ];
private:
};

View File

@ -0,0 +1,173 @@
//
// DATACHバーコードバトラーダイアログクラス
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <list>
#include <vector>
#include <string>
using namespace std;
#include "typedef.h"
#include "macro.h"
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Config.h"
#include "Wnd.h"
#include "DatachBarcodeDlg.h"
#include "EmuThread.h"
#include "nes.h"
#include "mapper.h"
// メッセージ
DLG_MESSAGE_BEGIN(CDatachBarcodeDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate )
DLG_ON_MESSAGE( WM_DESTROY, OnDestroy )
DLG_ON_MESSAGE( WM_CLOSE, OnClose )
// コマンド
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDCANCEL, OnCancel )
//DLG_ON_COMMAND( IDC_EBB_CODE, OnCodeinput )
DLG_ON_COMMAND( IDC_EBB_TRANSFER, OnCodeTransfer )
DLG_ON_COMMAND( IDC_EBB_RANDOM, OnCodeCreate )
DLG_ON_COMMAND_NOTIFY( IDC_EBB_CODE, EN_CHANGE, OnCodeinput )
DLG_COMMAND_END()
// Notify メッセージ
DLG_NOTIFY_BEGIN()
//DLG_ON_NOTIFY( IDC_LCH_LIST, LVN_KEYDOWN, OnKeyDownListView )
DLG_NOTIFY_END()
DLG_MESSAGE_END()
BOOL CDatachBarcodeDlg::Create( HWND hWndParent )
{
// 親はデスクトップにする
m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_EXT_BARCODEBATTLER),
NULL, g_DlgProc, (LPARAM)this );
if( !m_hWnd )
return FALSE;
// モードレスダイアログリストに加える
CWndList::Add( this );
return TRUE;
}
void CDatachBarcodeDlg::Destroy()
{
if( m_hWnd ) {
// 位置保存
::GetWindowRect( m_hWnd, &Config.general.rcBarcodePos );
// モードレスダイアログリストから削除
CWndList::Del( this );
::DestroyWindow( m_hWnd );
m_hWnd = NULL;
}
}
DLGMSG CDatachBarcodeDlg::OnInitDialog( DLGMSGPARAM )
{
DEBUGOUT( "CDatachBarcodeDlg::OnInitDialog\n" );
// 位置修正
if( Config.general.rcBarcodePos.right-Config.general.rcBarcodePos.left != 0
&& Config.general.rcBarcodePos.bottom-Config.general.rcBarcodePos.top != 0 ) {
::SetWindowPos( m_hWnd, HWND_NOTOPMOST, Config.general.rcBarcodePos.left, Config.general.rcBarcodePos.top,
0, 0, SWP_NOSIZE | SWP_NOZORDER );
}
::SendDlgItemMessage( m_hWnd, IDC_EBB_CODE, EM_SETLIMITTEXT, 13, 0 );
CTRLENABLE( IDC_EBB_TRANSFER, FALSE );
::srand( (unsigned)::time( NULL ) );
return TRUE;
}
DLGMSG CDatachBarcodeDlg::OnActivate( DLGMSGPARAM )
{
DEBUGOUT( "CDatachBarcodeDlg::OnActivate\n" );
if( LOWORD(wParam) == WA_INACTIVE ) {
DEBUGOUT( "CDatachBarcodeDlg::OnActivate:Inactive\n" );
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 );
} else {
DEBUGOUT( "CDatachBarcodeDlg::OnActivate:Active\n" );
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 );
}
return FALSE;
}
DLGMSG CDatachBarcodeDlg::OnDestroy( DLGMSGPARAM )
{
return TRUE;
}
DLGMSG CDatachBarcodeDlg::OnClose( DLGMSGPARAM )
{
DEBUGOUT( "CDatachBarcodeDlg::OnClose\n" );
::ShowWindow( m_hWnd, SW_HIDE ); // 非表示にするだけ
return TRUE;
}
DLGCMD CDatachBarcodeDlg::OnCancel( DLGCMDPARAM )
{
DEBUGOUT( "CDatachBarcodeDlg::OnCancel\n" );
::ShowWindow( m_hWnd, SW_HIDE ); // 非表示にするだけ
}
DLGCMD CDatachBarcodeDlg::OnCodeinput( DLGCMDPARAM )
{
DEBUGOUT( "CDatachBarcodeDlg::OnCodeinput\n" );
INT len = ::SendDlgItemMessage( m_hWnd, IDC_EBB_CODE, WM_GETTEXTLENGTH, 0, 0 );
CTRLENABLE( IDC_EBB_TRANSFER, ((len==8)||(len==13))?TRUE:FALSE );
}
DLGCMD CDatachBarcodeDlg::OnCodeTransfer( DLGCMDPARAM )
{
DEBUGOUT( "CDatachBarcodeDlg::OnCodeTransfer\n" );
if( !Emu.IsRunning() )
return;
BYTE code[14], *p;
p = code;
INT len = ::GetDlgItemText( m_hWnd, IDC_EBB_CODE, (LPTSTR)code, 14 );
Emu.EventParam2( CEmuThread::EV_BARCODE, (LONG)code, (LONG)len );
}
DLGCMD CDatachBarcodeDlg::OnCodeCreate( DLGCMDPARAM )
{
DEBUGOUT( "CDatachBarcodeDlg::OnCodeCreate\n" );
BYTE code[14];
INT digit, sum;
sum = 0;
for( INT i = 0; i < 12; i++ ) {
digit = ::rand()%10;
code[i] = '0'+digit;
sum += digit*((i&1)?3:1);
}
code[12] = '0'+((10-(sum%10))%10);
code[13] = '\0';
::SetDlgItemText( m_hWnd, IDC_EBB_CODE, (LPCTSTR)code );
}

View File

@ -0,0 +1,40 @@
//
// DATACHバーコードバトラーダイアログクラス
//
#ifndef __CDATACHBARCODEDLG_INCLUDED__
#define __CDATACHBARCODEDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <list>
#include <vector>
#include <string>
using namespace std;
#include "Wnd.h"
class CDatachBarcodeDlg : public CWnd
{
public:
// Override from CWnd
BOOL Create( HWND hWndParent );
void Destroy();
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGMSG OnActivate( DLGMSGPARAM );
DLGMSG OnDestroy( DLGMSGPARAM );
DLGMSG OnClose( DLGMSGPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnCodeinput( DLGCMDPARAM );
DLGCMD OnCodeTransfer( DLGCMDPARAM );
DLGCMD OnCodeCreate( DLGCMDPARAM );
//
private:
};
#endif // !__CDATACHBARCODEDLG_INCLUDED__

Binary file not shown.

View File

@ -0,0 +1,211 @@
[Path]
RomAutoRunPath=.\
RomPathUse=1
SavePathUse=1
StatePathUse=1
SnapshotPathUse=1
MoviePathUse=1
WavePathUse=1
CheatPathUse=1
RomPath=.\roms\
SavePath=.\save\
StatePath=.\state\
SnapshotPath=.\snapshot\
MoviePath=.\movie\
WavePath=.\wave\
CheatPath=.\cheatcode\
[General]
DoubleExecute=1
StartupLauncher=0
WindowZoom=0
WindowPos=5B020000C10000006F040000E002000073
ScreenZoom=1
SearchDialogPos=0000000000000000000000000000000000
PatternViewPos=0000000000000000000000000000000000
NameTableViewPos=0000000000000000000000000000000000
PaletteViewPos=0000000000000000000000000000000000
MemoryViewPos=A50000009E00000078020000BC0200007B
BarcodePos=0000000000000000000000000000000000
PaletteEditPos=0000000000000000000000000000000000
JoyAxisDisable=0
JoyAxisSetting=000000000000000000000000000000000000000000000000000000000000000000
[Emulation]
IllegalOp=0
AutoFrameSkip=1
Throttle=1
ThrottleFPS=120
Background=0
Priority=3
FourPlayer=1
CrcCheck=1
DiskThrottle=1
LoadFullscreen=0
PNGsnapshot=0
[Graphics]
Aspect=0
SpriteMax=1
AllLine=1
FPSDisp=0
TVFrameMode=0
ScanlineMode=0
ScanlineColor=75
SyncDraw=0
MaxZoom=0
LeftClip=1
WindowVSync=0
DiskAccessLamp=0
DoubleSize=0
SystemMemory=0
UseHEL=0
NoSquareList=0
GraphicsFilter=0
DisplayWidth=640
DisplayHeight=480
DisplayDepth=32
DisplayRate=56
PaletteUse=0
PaletteFile=
[Sound]
Enable=1
DisableVolumeEffect=0
ExtraSoundEnable=1
SamplingRate=22050
SamplingBits=8
BufferSize=4
FilterType=0
Volume=640064006400640064006400640064006400640064006400640064006400640040
[ShortCut]
TBL00=18402E402640314020401E400000000017401140000000000000000000002D4070
TBL01=3B003C0019000F009C004E004A0039000E0000000000000000000000000000001A
TBL02=0C000D003D003E0000000000000000000000000000000000000000000000000094
TBL03=06000200030004000500000000000000198013801E801F8032800000000000002F
TBL04=3F004000410042001C800000000000000E400240034004400540064007400840CF
TBL05=09400A400B400C4090407D400000000000000000000000000000000000000000B7
TBL06=19405700584057405800434043004400444000000000000000000000C740CF40DB
TBL07=D200D30000000000000000000000000000000000000000000000000000000000A5
TBL08=000000000000000000000000000000000000000000000000000000000000000000
TBL09=000000000000000000000000000000000000000000000000000000000000000000
TBL10=000000000000000000000000000000000000000000000000000000000000000000
TBL11=000000000000000000000000000000000000000000000000000000000000000000
TBL12=000000000000000000000000000000000000000000000000000000000000000000
TBL13=000000000000000000000000000000000000000000000000000000000000000000
TBL14=000000000000000000000000000000000000000000000000000000000000000000
TBL15=000000000000000000000000000000000000000000000000000000000000000000
TBL16=52404F40504051404B404C404D4047404840494052804F80508051804B804C8057
TBL17=4D8047804880498000000000000000000000000000000000000000000000000025
TBL18=000000000000000000000000000000000000000000000000000000000000000000
TBL19=000000000000000000000000000000000000000000000000000000000000000000
TBL20=000000000000000000000000000000000000000000000000000000000000000000
TBL21=000000000000000000000000000000000000000000000000000000000000000000
TBL22=000000000000000000000000000000000000000000000000000000000000000000
TBL23=000000000000000000000000000000000000000000000000000000000000000000
TBL24=000000000000000000000000000000000000000000000000000000000000000000
TBL25=000000000000000000000000000000000000000000000000000000000000000000
TBL26=000000000000000000000000000000000000000000000000000000000000000000
TBL27=000000000000000000000000000000000000000000000000000000000000000000
TBL28=000000000000000000000000000000000000000000000000000000000000000000
TBL29=000000000000000000000000000000000000000000000000000000000000000000
TBL30=000000000000000000000000000000000000000000000000000000000000000000
TBL31=000000000000000000000000000000000000000000000000000000000000000000
[Controller 1]
Keys=120020001F0021002500240017001600220023000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D
Rapid=0000000000
[Controller 2]
Keys=480050004B004D00310030000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C3
Rapid=0000000000
[Controller 3]
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Rapid=0000000000
[Controller 4]
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Rapid=0000000000
[Crazy Climber]
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
[Family Trainer]
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
[Exciting Boxing]
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
[Mahjang]
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
[NSF controller]
Keys=C800D000CB00CD00C900D1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA
[VS-Unisystem]
Keys=2E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E
[Movie]
UsePlayer=FF000000FF
ResetRec=0
Rerecord=1
LoopPlay=0
PadDisplay=0
[Launcher]
WindowPos=0000000000000000000000000000000000
ColumnView=0101010101010101010101010101010110
ColumnOrder=000102030405060708090A0B0C0D0E0F78
ColumnWidth=A00030003000300030003000300030003000300030003000300030003000300070
ListSelect=0
SortDir=0
SortType=0
FolderUse=0000000000000000000000000000000000
Folder00=
Folder01=
Folder02=
Folder03=
Folder04=
Folder05=
Folder06=
Folder07=
Folder08=
Folder09=
Folder10=
Folder11=
Folder12=
Folder13=
Folder14=
Folder15=
LastSelect=
ActivePause=0
[Netplay]
ChatPos=0000000000000000000000000000000000
NickName=NoName
RecnetPortNum=1
RecentPort00=10000
RecentPort01=
RecentPort02=
RecentPort03=
RecentPort04=
RecentPort05=
RecentPort06=
RecentPort07=
RecentPort08=
RecentPort09=
RecentPort10=
RecentPort11=
RecentPort12=
RecentPort13=
RecentPort14=
RecentPort15=
RecnetHostNum=1
RecentHost00=localhost:10000
RecentHost01=
RecentHost02=
RecentHost03=
RecentHost04=
RecentHost05=
RecentHost06=
RecentHost07=
RecentHost08=
RecentHost09=
RecentHost10=
RecentHost11=
RecentHost12=
RecentHost13=
RecentHost14=
RecentHost15=
[Recent Path List]
Path1=E:\Game\NES\ProgramStudy\[Subor]Karaoke(C)\
Path2=E:\Game\NES\NSF\
Path3=E:\Game\NES\Rom\
[Recent File List]
File1=E:\Game\NES\ProgramStudy\[Subor]Karaoke(C)\[Subor]Karaoke(C).nsf
File2=E:\Game\NES\NSF\Contra.nsf
File3=E:\Game\NES\Rom\Contra(U).nes

View File

@ -0,0 +1,62 @@
//
// Debug output
//
#include "DebugOut.h"
CDebugOut Dbg;
static const CHAR szClassName[] = "DebugWindow_wndclass";
CDebugOut::CDebugOut()
{
#if defined(_DEBUG) || defined(_DEBUGOUT)
hWndDebugOutput = ::FindWindow( szClassName, NULL );
if( !hWndDebugOutput ) {
::OutputDebugString( "DebugWindow がありません\n" );
}
#endif
}
void CDebugOut::Clear()
{
#if defined(_DEBUG) || defined(_DEBUGOUT)
if( hWndDebugOutput ) {
if( ::IsWindow( hWndDebugOutput ) ) {
::SendMessage( hWndDebugOutput, WM_APP+1, (WPARAM)NULL, (LPARAM)NULL );
}
}
#endif
}
void __cdecl CDebugOut::Out( LPSTR fmt, ... )
{
#if defined(_DEBUG) || defined(_DEBUGOUT)
CHAR buf[1000];
va_list va;
va_start( va, fmt );
::vsprintf( buf, fmt, va );
if( hWndDebugOutput ) {
if( ::IsWindow( hWndDebugOutput ) ) {
COPYDATASTRUCT cds;
cds.dwData = 0;
cds.lpData = (void*)buf;
cds.cbData = ::strlen(buf)+1; // 終端のNULLも送る
// 文字列送信
::SendMessage( hWndDebugOutput, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds );
} else {
::OutputDebugString( buf );
}
} else {
::OutputDebugString( buf );
}
#endif
}
void CDebugOut::Out( const string& str )
{
#if defined(_DEBUG) || defined(_DEBUGOUT)
Out( (LPSTR)str.c_str() );
#endif
}

View File

@ -0,0 +1,45 @@
//
// Debug output
//
#ifndef __DEBUGOUT_INCLUDED__
#define __DEBUGOUT_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
typedef void (__cdecl *DEBUGWINDOWOUTPUT)(LPCTSTR);
class CDebugOut {
public:
CDebugOut();
void Clear();
void __cdecl Out( LPSTR fmt, ... );
void Out( const string& str );
protected:
HWND hWndDebugOutput;
private:
};
extern CDebugOut Dbg;
#if defined(_DEBUG) || defined(_DEBUGOUT)
#define DEBUGOUT Dbg.Out
#else
#define DEBUGOUT
#endif // !_DEBUG
#if defined(_DEBUG) || defined(_DEBUGOUT)
#define DEBUGCLR Dbg.Clear
#else
#define DEBUGCLR
#endif // !_DEBUG
#endif // !__DEBUGOUT_INCLUDED__

View File

@ -0,0 +1,130 @@
//
// チャットダイアログクラス
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <mbstring.h>
#include <shlwapi.h>
#include <string>
using namespace std;
#include "typedef.h"
#include "macro.h"
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "EmuThread.h"
#include "VsUnisystem.h"
#include "Wnd.h"
#include "DipSwitchDlg.h"
// メッセージ
DLG_MESSAGE_BEGIN(CDipSwitchDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
// コマンド
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_COMMAND_END()
// Notify メッセージ
DLG_NOTIFY_BEGIN()
DLG_NOTIFY_END()
DLG_MESSAGE_END()
INT CDipSwitchDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_EXT_VSUNISYSTEM),
hWndParent, g_DlgProc, (LPARAM)this );
}
DLGMSG CDipSwitchDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CDipSwitchDlg::OnInitDialog\n" );
for( INT i = IDC_EVS_DIPCOMBO0; i <= IDC_EVS_DIPCOMBO7; i++ ) {
::SendDlgItemMessage( m_hWnd, i, CB_RESETCONTENT, 0, 0 );
}
BYTE val = Emu.GetNES()->GetVSDipSwitch();
VSDIPSWITCH* dip = Emu.GetNES()->GetVSDipSwitchTable();
DEBUGOUT( "GET DIPSWITCH:%02X\n", val );
BYTE mask;
INT nStatic = IDC_EVS_DIPNAME0;
INT nCombo = IDC_EVS_DIPCOMBO0;
BOOL bFlag;
INT nCount, nSelect;
bFlag = FALSE;
nCount = nSelect = 0;
for(;;) {
if( dip->name == NULL && dip->value == 0x0000 ) {
break;
} else if( dip->value == 0x00FF ) {
bFlag = FALSE;
::SendDlgItemMessage( m_hWnd, nCombo, CB_SETCURSEL, (WPARAM)nSelect, 0 );
nCombo++;
} else if( !bFlag ) {
bFlag = TRUE;
::SetDlgItemText( m_hWnd, nStatic, (LPCTSTR)dip->name );
mask = dip->value>>8;
nCount = 0;
nStatic++;
} else {
if( dip->value == (val & mask) )
nSelect = nCount;
::SendDlgItemMessage( m_hWnd, nCombo, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dip->name );
::SendDlgItemMessage( m_hWnd, nCombo, CB_SETITEMDATA, (WPARAM)nCount, (LPARAM)(dip->value&0xFF) );
nCount++;
}
dip++;
}
m_nDispCount = nStatic-IDC_EVS_DIPNAME0;
// 使わない奴は非表示にする
for( ; nStatic <= IDC_EVS_DIPNAME7; nStatic++, nCombo++ ) {
::ShowWindow( ::GetDlgItem( m_hWnd, nStatic ), SW_HIDE );
::ShowWindow( ::GetDlgItem( m_hWnd, nCombo ), SW_HIDE );
}
return TRUE;
}
DLGCMD CDipSwitchDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CDipSwitchDlg::OnOK\n" );
// 選択されている奴のItemDataを取得してDipSwitchデータを作り直す(OnInitDialogでItemDataを設定済み)
BYTE dipval = 0;
for( INT i = IDC_EVS_DIPCOMBO0; i < IDC_EVS_DIPCOMBO0+m_nDispCount; i++ ) {
INT sel = ::SendDlgItemMessage( m_hWnd, i, CB_GETCURSEL, 0, 0 );
DWORD val = (DWORD)::SendDlgItemMessage( m_hWnd, i, CB_GETITEMDATA, (WPARAM)sel, 0 );
dipval |= val & 0xFF;
}
Emu.GetNES()->SetVSDipSwitch( dipval );
DEBUGOUT( "SET DIPSWITCH:%02X\n", dipval );
::EndDialog( m_hWnd, IDOK );
}
DLGCMD CDipSwitchDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CDipSwitchDlg::OnCancel\n" );
::EndDialog( m_hWnd, IDCANCEL );
}

View File

@ -0,0 +1,36 @@
//
// チャットダイアログクラス
//
#ifndef __CDIPSWITCHDLG_INCLUDED__
#define __CDIPSWITCHDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
class CDipSwitchDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
//
INT m_nDispCount;
private:
};
#endif // !__CDIPSWITCHDLG_INCLUDED__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,372 @@
//
// DirectDraw class
//
#ifndef __DIRECTDRAW_INCLUDED__
#define __DIRECTDRAW_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <objbase.h>
#include <mmsystem.h>
#include <vector>
using namespace std;
#define DIRECTDRAW_VERSION 0x0700
#include <ddraw.h>
#include <stdio.h>
#include <stdlib.h>
#include "typedef.h"
#include "macro.h"
class CDirectDraw
{
public:
// パブリックメンバ変数
typedef struct tagDISPLAYMODE {
DWORD dwWidth;
DWORD dwHeight;
DWORD dwDepth;
DWORD dwRate;
} DISPLAYMODE, *LPDISPLAYMODE;
typedef struct tagPALBUF {
BYTE r;
BYTE g;
BYTE b;
} PALBUF, *LPPALBUF;
// 利用可能なディスプレイモード
enum { DD_DISPLAYMODEMAX = 256 };
INT m_DisplayModeNum; // ディスプレイモード数
DISPLAYMODE m_DisplayModeBuf[DD_DISPLAYMODEMAX];
// Screen size
enum { SCREEN_WIDTH = 256, SCREEN_HEIGHT = 240 };
// Render screen size
enum { RENDER_WIDTH = SCREEN_WIDTH+16, RENDER_HEIGHT = SCREEN_HEIGHT };
// Delta screen size
enum { DELTA_WIDTH = SCREEN_WIDTH, DELTA_HEIGHT = SCREEN_HEIGHT+6 };
// Filter
enum { BLTFILTER_NONE = 0,
BLTFILTER_2XSAI,
BLTFILTER_SUPER2XSAI,
BLTFILTER_SUPEREAGLE,
BLTFILTER_SCALE2X,
};
// パブリックメンバ関数
CDirectDraw();
virtual ~CDirectDraw();
BOOL InitialDDraw( HWND hWnd );
void ReleaseDDraw();
BOOL InitialSurface( BOOL bScreenMode );
BOOL ReleaseSurface();
BOOL RestoreSurface();
BOOL BeginDisplayChange();
BOOL EndDisplayChange();
BOOL OnChangeDisplayMode();
// Displayモード
INT GetDisplayModeNum() { return m_DisplayModes.size(); }
void SetDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate );
void GetDisplayMode( DWORD& dwWidth, DWORD& dwHeight, DWORD& dwDepth, DWORD& dwRate );
BOOL GetDisplayMode( INT no, DWORD& dwWidth, DWORD& dwHeight, DWORD& dwDepth, DWORD& dwRate );
INT GetMatchDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate );
BOOL IsNowDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate );
BOOL CalcPaletteTable();
void SetPaletteTable( LPBYTE pal );
void SetPaletteTable( RGBQUAD* pal );
void GetPaletteTable( RGBQUAD* pal );
void SetPaletteFile( LPCTSTR fname );
BOOL SetFullScreenGDI( BOOL bMode );
void SetUseHEL( BOOL bUseHEL ) {
m_bUseHEL = bUseHEL;
m_bDeltaUpdate = TRUE;
}
void SetSystemMemory( BOOL bSystemMemory ) {
m_bSystemMemory = bSystemMemory;
m_bDeltaUpdate = TRUE;
}
void SetScreenMode( BOOL bScreenMode ) {
m_bScreenMode = bScreenMode;
m_bDeltaUpdate = TRUE;
}
void SetFlipMode( BOOL bFlip ) {
m_bFlip = bFlip;
}
void SetAspectMode( BOOL bAspect ) {
m_bAspect = bAspect;
}
void SetAllLineMode( BOOL bAllLine ) {
m_bAllLine = bAllLine;
}
void SetMaxZoom( BOOL bZoom ) {
m_bMaxZoom = bZoom;
}
void SetDoubleSize( BOOL bDoubleSize ) {
m_bDoubleSize = bDoubleSize;
m_bDeltaUpdate = TRUE;
}
void SetTVFrameMode( BOOL bTVFrame ) {
m_bTVFrameMode = bTVFrame;
}
void SetScanlineMode( BOOL bScanline ) {
m_bScanlineMode = bScanline;
m_bDeltaUpdate = TRUE;
}
void SetScanlineColor( INT nScanlineColor ) {
m_nScanlineColor = nScanlineColor;
}
void SetZapperMode( BOOL bZapper ) {
m_bZapper = bZapper;
}
void SetZapperDrawMode( BOOL bDraw ) {
m_bZapperDraw = bDraw;
}
void SetWindowVSyncMode( BOOL bVSync ) {
m_bWindowVSync = bVSync;
}
void SetGraphicsFilter( INT nFilter ) {
m_nBltFilter = nFilter;
m_bDeltaUpdate = TRUE;
}
BOOL GetUseHEL() { return m_bUseHEL; }
BOOL GetSystemMemory() { return m_bSystemMemory; }
BOOL GetScreenMode() { return m_bScreenMode; }
BOOL GetFlipMode() { return m_bFlip; }
BOOL GetAspectMode() { return m_bAspect; }
BOOL GetAllLineMode() { return m_bAllLine; }
BOOL GetMaxZoom() { return m_bMaxZoom; }
BOOL GetDoubleSize() { return m_bDoubleSize; }
BOOL GetTVFrameMode() { return m_bTVFrameMode; }
BOOL GetScanlineMode() { return m_bScanlineMode; }
INT GetScanlineColor() { return m_nScanlineColor; }
BOOL GetZapperMode() { return m_bZapper; }
BOOL GetZapperDrawMode() { return m_bZapperDraw; }
BOOL GetWindowVSyncMode() { return m_bWindowVSync; }
INT GetGraphicsFilter() { return m_nBltFilter; }
LPBYTE GetRenderScreen() { return m_lpRender; }
LPBYTE GetLineColormode() { return m_LineColormode; }
// For Zapper
BYTE GetZapperHit();
void GetZapperPos( LONG& x, LONG& y );
void SetZapperPos( LONG x, LONG y );
void SetInfoString( LPCSTR str );
void SetMessageString( LPCSTR str );
void RealizePalette();
void OnScreenDraw();
void SetPaletteMode( INT nMode, BOOL bMono );
void GetPaletteData( RGBQUAD* rgb );
void SetDiskAccessLamp( BOOL bAccess ) {
m_bDiskAccessLamp = bAccess;
}
void Blt();
void Flip();
// MMX
BOOL IsMMX() { return m_bMMX; }
unsigned char * font;
void ViewChars( unsigned char * lpRdr ); //ハ鰔エク。カッオトホトアセ
protected:
// プロテクトメンバ変数
// General
HWND m_hWnd; // Window handle
BOOL m_bChangeMode; // Screen Mode changing flag
BOOL m_bDraw; // Drawing flag
BOOL m_bNoRestore;
BOOL m_bMessage; // Message display?
DWORD m_dwMessageTime; // Message display times
BOOL m_bMMX; // Existence of MMX technology.
// Options
BOOL m_bUseHEL; // HALを使わずHELを使用
BOOL m_bSystemMemory; // サーフェスにシステムメモリを使用
BOOL m_bScreenMode; // FALSE:Window TRUE:Fullscreen
BOOL m_bFlip; // フリップ使用
BOOL m_bGDI; // GDI
BOOL m_bAspect; // TVアスペクト補正
BOOL m_bAllLine; // 全ライン表示
BOOL m_bMaxZoom; // 画面全体まで拡大
BOOL m_bDoubleSize; // 2倍サイズレンダリング
BOOL m_bTVFrameMode; // TV枠表示
BOOL m_bScanlineMode; // スキャンラインモード
INT m_nScanlineColor; // スキャンラインカラー
BOOL m_bZapper; // Zapper
BOOL m_bZapperDraw; // Zapper Sight drawing
BOOL m_bWindowVSync; // Wait for VSync(Window mode)
BOOL m_bForceWrite; // 常に上書き描画
INT m_nBltFilter; // Blit Filter
// 利用可能なディスプレイモード
std::vector<DISPLAYMODE> m_DisplayModes;
// フルスクリーンディスプレイモード
DWORD m_dwDisplayWidth;
DWORD m_dwDisplayHeight;
DWORD m_dwDisplayDepth;
DWORD m_dwDisplayRate;
// DLL dynamic load
HINSTANCE m_hDDraw; // DLL Instance handle
// DirectDraw object
LPDIRECTDRAW7 m_lpDD; // DirectDraw Object
LPDIRECTDRAWSURFACE7 m_lpDDPrimary; // PrimarySurface
LPDIRECTDRAWSURFACE7 m_lpDDBack; // BackSurface
LPDIRECTDRAWSURFACE7 m_lpDDRender; // RenderSurface
LPDIRECTDRAWSURFACE7 m_lpDDRender2; // RenderSurface2
LPDIRECTDRAWSURFACE7 m_lpDDAscii; // AsciiSurface
LPDIRECTDRAWSURFACE7 m_lpDDZapper; // ZapperSurface
LPDIRECTDRAWSURFACE7 m_lpDDTV; // TV枠(^^;
LPDIRECTDRAWCLIPPER m_lpDDClipper; // Clipper
LPDIRECTDRAWCLIPPER m_lpDDClipper2; // Render window Clipper
LPDIRECTDRAWPALETTE m_lpDDPalette; // DirectDraw Palette
LPBYTE m_lpRender;
LPBYTE m_lpRenderDelta;
BYTE m_LineColormode[RENDER_HEIGHT];
BOOL m_bDeltaUpdate;
// パレット
INT m_nPaletteMode;
BOOL m_bMonoMode;
BOOL m_bPaletteUpdate; // Palette Update?
static PALBUF m_PalDefault[64]; // デフォルトパレット
PALBUF m_PaletteBuf[64]; // パレットバッファ
typedef struct tagLOGPAL {
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY pe[256];
} LOGPAL, *LPLOGPAL;
HPALETTE m_hPalette; // Windows GDI Palette handle
LOGPAL m_logPalette; // Windows GDI Palette
// 256色モード用
RGBQUAD m_cpPalette[8][64*2]; // Color
RGBQUAD m_mpPalette[8][64*2]; // Monochrome
// ピクセルフォーマットに変換したパレット
DWORD m_cnPalette[8][256]; // Color
DWORD m_csPalette[8][256]; // Color/Scanline
DWORD m_mnPalette[8][256]; // Monochrome
DWORD m_msPalette[8][256]; // Monochrome/Scanline
// 2xSaI mmx用のRGB555パレット
DWORD m_cfPalette[8][256]; // Color
DWORD m_mfPalette[8][256]; // Monochrome
// For Zapper
LONG m_ZapperPosX, m_ZapperPosY;
// For Infomation&Message
enum { INFOSTR_SIZE = 64 };
CHAR m_szInfo[INFOSTR_SIZE+1];
CHAR m_szMess[INFOSTR_SIZE+1];
// For DiskAccessLamp
BOOL m_bDiskAccessLamp;
// プロテクトメンバ関数
static HRESULT WINAPI EnumModesCallback( LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext );
void RenderString( INT x, INT y, LPCSTR str );
BOOL RestoreSurfaceSub( LPDIRECTDRAWSURFACE7 lpSurface );
void GetBitMask( DWORD val, int& shift, int& bits );
void SetLZSSChar( LPBYTE lpLZ, LPDIRECTDRAWSURFACE7 lpDDSurface );
// Blitters
typedef void (CDirectDraw::*BLTFUNC)(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
static BLTFUNC NormalBltTable[];
static BLTFUNC ScanlineBltTable[];
static BLTFUNC DoubleBltTable[];
static BLTFUNC DoubleScanlineBltTable[];
static BLTFUNC nx2xSaIBltTable[];
static BLTFUNC nxSuper2xSaIBltTable[];
static BLTFUNC nxSuperEagleBltTable[];
static BLTFUNC nxScale2xBltTable[];
// 大量…
void Render8bpp_Normal(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render16bpp_Normal(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render24bpp_Normal(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render32bpp_Normal(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render8bpp_Scanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render16bpp_Scanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render24bpp_Scanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render32bpp_Scanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render8bpp_Double(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render16bpp_Double(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render24bpp_Double(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render32bpp_Double(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render8bpp_DoubleScanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render16bpp_DoubleScanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render24bpp_DoubleScanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void Render32bpp_DoubleScanline(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
// プリレンダ用
void Render16bpp( LPBYTE lpSrc, LPBYTE lpDst );
void Render16bppPrefilter( LPBYTE lpSrc, LPBYTE lpDst );
void Render32bpp( LPBYTE lpSrc, LPBYTE lpDst );
// Effects
void nx_2xSaI_16bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void nx_2xSaI_32bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void nx_Super2xSaI_16bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void nx_Super2xSaI_32bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void nx_SuperEagle_16bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void nx_SuperEagle_32bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void nx_Scale2x_16bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
void nx_Scale2x_32bpp(LPBYTE,LPBYTE,DDSURFACEDESC2&,BOOL);
private:
// プライベートメンバ変数
// プライベートメンバ関数
};
extern CDirectDraw DirectDraw;
#endif // !__DIRECTDRAW_INCLUDED__

View File

@ -0,0 +1,477 @@
//
// DirectInput class
//
#include "DebugOut.h"
#include "DirectInput.h"
#include "COM.h"
#include "Config.h"
CDirectInput DirectInput;
#define COMUSE TRUE
//
// Table
//
CDirectInput::DIKEYTBL CDirectInput::DIKeyTable[] = {
DIK_ESCAPE, "ESC", DIK_1, "1",
DIK_2, "2", DIK_3, "3",
DIK_4, "4", DIK_5, "5",
DIK_6, "6", DIK_7, "7",
DIK_8, "8", DIK_9, "9",
DIK_0, "0", DIK_MINUS, "-",
DIK_EQUALS, "=", DIK_BACK, "BackSpace",
DIK_TAB, "TAB", DIK_Q, "Q",
DIK_W, "W", DIK_E, "E",
DIK_R, "R", DIK_T, "T",
DIK_Y, "Y", DIK_U, "U",
DIK_I, "I", DIK_O, "O",
DIK_P, "P", DIK_LBRACKET, "[",
DIK_RBRACKET, "]", DIK_RETURN, "Enter",
DIK_LCONTROL, "L Ctrl", DIK_A, "A",
DIK_S, "S", DIK_D, "D",
DIK_F, "F", DIK_G, "G",
DIK_H, "H", DIK_J, "J",
DIK_K, "K", DIK_L, "L",
DIK_SEMICOLON, ";", DIK_APOSTROPHE, "'",
DIK_GRAVE, "`", DIK_LSHIFT, "L Shift",
DIK_BACKSLASH, "\\", DIK_Z, "Z",
DIK_X, "X", DIK_C, "C",
DIK_V, "V", DIK_B, "B",
DIK_N, "N", DIK_M, "M",
DIK_COMMA, ",", DIK_PERIOD, ".",
DIK_SLASH, "/", DIK_RSHIFT, "R Shift",
DIK_MULTIPLY, "*", DIK_LMENU, "L Alt",
DIK_SPACE, "Space",
DIK_F1, "F1", DIK_F2, "F2",
DIK_F3, "F3", DIK_F4, "F4",
DIK_F5, "F5", DIK_F6, "F6",
DIK_F7, "F7", DIK_F8, "F8",
DIK_F9, "F9", DIK_F10, "F10",
DIK_NUMPAD7, "Num 7", DIK_NUMPAD8, "Num 8",
DIK_NUMPAD9, "Num 9", DIK_SUBTRACT, "Num -",
DIK_NUMPAD4, "Num 4", DIK_NUMPAD5, "Num 5",
DIK_NUMPAD6, "Num 6", DIK_ADD, "Num +",
DIK_NUMPAD1, "Num 1", DIK_NUMPAD2, "Num 2",
DIK_NUMPAD3, "Num 3", DIK_NUMPAD0, "Num 0",
DIK_DECIMAL, "Num .", DIK_F11, "F11",
DIK_F12, "F12", DIK_F13, "F13",
DIK_F14, "F14", DIK_F15, "F15",
DIK_CONVERT, "変換",
DIK_NOCONVERT, "無変換", DIK_YEN, "\\",
DIK_NUMPADEQUALS,"Num =", DIK_CIRCUMFLEX, "^",
DIK_AT, "@", DIK_COLON, ":",
DIK_UNDERLINE, "_",
DIK_STOP, "Stop", DIK_NUMPADENTER,"Num Enter",
DIK_RCONTROL, "R Ctrl", DIK_NUMPADCOMMA,"Num ,",
DIK_DIVIDE, "Num /", DIK_SYSRQ, "SysRq",
DIK_RMENU, "R Alt", DIK_PAUSE, "Pause",
DIK_HOME, "Home", DIK_UP, "Up",
DIK_PRIOR, "Page Up", DIK_LEFT, "Left",
DIK_RIGHT, "Right", DIK_END, "End",
DIK_DOWN, "Down", DIK_NEXT, "Page Down",
DIK_INSERT, "Insert", DIK_DELETE, "Delete",
DIK_LWIN, "L Windows", DIK_LWIN, "R Windows",
DIK_APPS, "AppMenu",
#if 0
// トグル系キーなので使えない
DIK_CAPITAL, "Caps Lock",
DIK_NUMLOCK, "NumLock",
DIK_SCROLL, "ScrollLock",
DIK_KANA, "カナ",
DIK_KANJI, "漢字",
#endif
0x00, NULL
};
LPSTR CDirectInput::DIKeyDirTable[] = {
"X+", "X-", "Y+", "Y-", "Z+", "Z-",
"RX+", "RX-", "RY+", "RY-", "RZ+", "RZ-",
"S0+", "S0-", "S1+", "S1-",
};
LPSTR CDirectInput::DIKeyDirTable2[] = {
"P0 Up", "P0 Down", "P0 Left", "P0 Right",
"P1 Up", "P1 Down", "P1 Left", "P1 Right",
"P2 Up", "P2 Down", "P2 Left", "P2 Right",
"P3 Up", "P3 Down", "P3 Left", "P3 Right",
};
//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////
CDirectInput::CDirectInput()
{
m_lpDI = NULL;
m_lpKeyboard = NULL;
m_nJoystickNum = 0;
ZEROMEMORY( m_lpJoystick, sizeof(m_lpJoystick) );
ZEROMEMORY( m_Sw, sizeof(m_Sw) );
ZEROMEMORY( m_JoyAxisMode, sizeof(m_JoyAxisMode) );
#if COMUSE
COM::AddRef();
#endif
}
CDirectInput::~CDirectInput()
{
ReleaseDInput();
#if COMUSE
COM::AddRef();
#endif
}
//////////////////////////////////////////////////////////////////////
// メンバ関数
//////////////////////////////////////////////////////////////////////
// デバイスオブジェクト列挙コールバック
BOOL CALLBACK CDirectInput::DIEnumDevicesCallback( LPDIDEVICEINSTANCE lpddi, LPVOID pvRef )
{
CDirectInput* pCDi = (CDirectInput*)pvRef;
// DEBUGOUT( "dwDevType=%08X IName:%s PName:%s\n", lpddi->dwDevType, lpddi->tszInstanceName, lpddi->tszProductName );
if( pCDi->AddJoystickDevice( lpddi->guidInstance ) )
return DIENUM_CONTINUE;
return DIENUM_STOP;
}
// ジョイスティックデバイスオブジェクトの作成
BOOL CDirectInput::AddJoystickDevice( GUID deviceguid )
{
LPDIRECTINPUTDEVICE7 lpDIDev;
if( m_lpDI->CreateDeviceEx( deviceguid, IID_IDirectInputDevice7,
(LPVOID*)&lpDIDev, NULL ) != DI_OK ) {
return FALSE;
}
if( lpDIDev->SetDataFormat( &c_dfDIJoystick ) != DI_OK ) {
DEBUGOUT( "CDirectInput:SetDataFormat failed.\n" );
RELEASE( lpDIDev );
return FALSE;
}
INT nID = m_nJoystickNum;
if( !Config.general.bNoJoystickID ) {
// DX7では隠し要素のジョイスティックIDの取得(DX8からはマニュアルに記載されている)
DIPROPDWORD diprp_dw;
ZEROMEMORY( &diprp_dw, sizeof(diprp_dw) );
diprp_dw.diph.dwSize = sizeof(DIPROPDWORD);
diprp_dw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprp_dw.diph.dwHow = DIPH_DEVICE;
diprp_dw.diph.dwObj = 0;
if( lpDIDev->GetProperty( DIPROP_JOYSTICKID, &diprp_dw.diph ) != DI_OK ) {
DEBUGOUT( "CDirectInput:GetProperty failed.\n" );
RELEASE( lpDIDev );
return FALSE;
}
DEBUGOUT( "ID:%d\n", diprp_dw.dwData );
nID = diprp_dw.dwData;
}
if( nID < DIJOYSTICK_MAX ) {
m_lpJoystick[ nID ] = lpDIDev;
// 各軸のレンジを設定
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYOFFSET;
diprg.diph.dwObj = DIJOFS_X;
diprg.lMin = -10000;
diprg.lMax = +10000;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_Y;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_Z;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_RX;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_RY;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_RZ;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_SLIDER(0);
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_SLIDER(1);
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
// 名称の取得
DIDEVICEINSTANCE didins;
ZEROMEMORY( &didins, sizeof(didins) );
didins.dwSize = sizeof( didins );
lpDIDev->GetDeviceInfo( &didins );
m_JoyName[ nID ] = didins.tszInstanceName;
DEBUGOUT( "Instance Name:%s\n", didins.tszInstanceName );
//DEBUGOUT( "Product Name:%s\n", didins.tszProductName );
} else {
m_lpJoystick[ nID ] = NULL;
RELEASE( lpDIDev );
}
m_nJoystickNum++;
return TRUE;
}
// DirectInputオブジェクトデバイスオブジェクトの構築
BOOL CDirectInput::InitialDInput(HWND hWnd, HINSTANCE hInst)
{
try {
// CDirectInputオブジェクトの作成
#if !COMUSE
if( DirectInputCreateEx( hInst, DIRECTINPUT_VERSION, IID_IDirectInput7, (LPVOID*)&m_lpDI, NULL ) != DI_OK ) {
m_lpDI = NULL;
throw "CDirectInput:DirectInputCreateEx failed.";
}
#else
// COM的利用
// COM::AddRef();
if( FAILED(CoCreateInstance( CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, IID_IDirectInput7, (VOID**)&m_lpDI )) ) {
m_lpDI = NULL;
throw "CDirectInput:CoCreateInstance failed.";
}
if( m_lpDI->Initialize( hInst, DIRECTINPUT_VERSION ) != DI_OK )
throw "CDirectInput:IDirectInput7->Initialize failed.";
#endif
if( m_lpDI->CreateDevice( GUID_SysKeyboard, &m_lpKeyboard, NULL ) != DI_OK )
throw "CDirectInput:CreateDevice failed.";
if( m_lpKeyboard ) {
if( m_lpKeyboard->SetDataFormat( &c_dfDIKeyboard ) != DI_OK )
throw "CDirectInput:SetDataFormat failed.";
if( m_lpKeyboard->SetCooperativeLevel( hWnd, DISCL_NONEXCLUSIVE|DISCL_BACKGROUND) != DI_OK )
throw "CDirectInput:SetCooperativeLevel failed.";
if( m_lpKeyboard->Acquire() != DI_OK ) {
// DEBUGOUT( "CDirectInput:Acquire failed.\n" );
}
}
m_nJoystickNum = 0;
if( m_lpDI->EnumDevices( DIDEVTYPE_JOYSTICK, (LPDIENUMDEVICESCALLBACK)DIEnumDevicesCallback,
(LPVOID)this, DIEDFL_ATTACHEDONLY ) != DI_OK ) {
DEBUGOUT( "CDirectInput:EnumDevices failed.\n" );
}
if( !m_nJoystickNum ) {
DEBUGOUT( "CDirectInput:No Joystick device available.\n" );
} else {
for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) {
if( m_lpJoystick[i] ) {
if( m_lpJoystick[i]->SetCooperativeLevel( hWnd, DISCL_NONEXCLUSIVE|DISCL_BACKGROUND) != DI_OK ) {
DEBUGOUT( "CDirectInput:SetCooperativeLevel failed.\n" );
throw "CDirectInput:SetCooperativeLevel failed.";
}
}
}
DEBUGOUT( "CDirectInput:Can use %d Joystick(s)\n", m_nJoystickNum );
}
} catch( char *str ) {
ReleaseDInput();
MessageBox( hWnd, str, "ERROR", MB_ICONERROR|MB_OK );
return FALSE;
}
return TRUE;
}
void CDirectInput::ReleaseDInput()
{
for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) {
RELEASE( m_lpJoystick[i] );
}
if( m_lpKeyboard ) {
// m_lpKeyboard->Unacquire();
RELEASE( m_lpKeyboard );
}
if( m_lpDI ) {
RELEASE( m_lpDI );
#if COMUSE
// COM::Release();
#endif
}
}
// 入力フォーカスを取得
void CDirectInput::Acquire()
{
if( !m_lpDI )
return;
if( m_lpKeyboard )
m_lpKeyboard->Acquire();
for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) {
if( m_lpJoystick[i] ) {
m_lpJoystick[i]->Acquire();
}
}
}
// 入力フォーカスを開放
void CDirectInput::Unacquire()
{
if( !m_lpDI )
return;
if( m_lpKeyboard )
m_lpKeyboard->Unacquire();
for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) {
if( m_lpJoystick[i] ) {
m_lpJoystick[i]->Unacquire();
}
}
}
// データポーリング
void CDirectInput::Poll()
{
DIJOYSTATE js;
ZEROMEMORY( m_Sw, sizeof(m_Sw) );
if( !m_lpDI ) {
return;
}
if( m_lpKeyboard ) {
if( m_lpKeyboard->GetDeviceState( 256, &m_Sw ) == DIERR_INPUTLOST ) {
m_lpKeyboard->Acquire();
m_lpKeyboard->GetDeviceState( 256, &m_Sw );
}
}
INT idx;
for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) {
if( !m_lpJoystick[i] )
continue;
idx = 256+i*64;
if( m_lpJoystick[i]->Poll() == DIERR_INPUTLOST ) {
m_lpJoystick[i]->Acquire();
m_lpJoystick[i]->Poll();
}
if( m_lpJoystick[i]->GetDeviceState( sizeof(DIJOYSTATE), &js ) != DI_OK ) {
ZEROMEMORY( &js, sizeof(DIJOYSTATE) );
}
m_JoyAxis[i][0] = js.lX;
m_JoyAxis[i][1] = js.lY;
m_JoyAxis[i][2] = js.lZ;
m_JoyAxis[i][3] = js.lRx;
m_JoyAxis[i][4] = js.lRy;
m_JoyAxis[i][5] = js.lRz;
if( !(m_JoyAxisMode[i] & (1<<0)) ) {
if( js.lX > 8000 ) m_Sw[idx + DI_XAXIS+0] = 0x80;
if( js.lX < -8000 ) m_Sw[idx + DI_XAXIS+1] = 0x80;
}
if( !(m_JoyAxisMode[i] & (1<<1)) ) {
if( js.lY > 8000 ) m_Sw[idx + DI_YAXIS+0] = 0x80;
if( js.lY < -8000 ) m_Sw[idx + DI_YAXIS+1] = 0x80;
}
if( !(m_JoyAxisMode[i] & (1<<2)) ) {
if( js.lZ > 8000 ) m_Sw[idx + DI_ZAXIS+0] = 0x80;
if( js.lZ < -8000 ) m_Sw[idx + DI_ZAXIS+1] = 0x80;
}
if( !(m_JoyAxisMode[i] & (1<<3)) ) {
if( js.lRx > 8000 ) m_Sw[idx + DI_RXAXIS+0] = 0x80;
if( js.lRx < -8000 ) m_Sw[idx + DI_RXAXIS+1] = 0x80;
}
if( !(m_JoyAxisMode[i] & (1<<4)) ) {
if( js.lRy > 8000 ) m_Sw[idx + DI_RYAXIS+0] = 0x80;
if( js.lRy < -8000 ) m_Sw[idx + DI_RYAXIS+1] = 0x80;
}
if( !(m_JoyAxisMode[i] & (1<<5)) ) {
if( js.lRz > 8000 ) m_Sw[idx + DI_RZAXIS+0] = 0x80;
if( js.lRz < -8000 ) m_Sw[idx + DI_RZAXIS+1] = 0x80;
}
#if 0
// 2003/11/3 とりあえず無効化
if( js.rglSlider[0] > 8000 ) m_Sw[idx + DI_SLIDER0+0] = 0x80;
if( js.rglSlider[0] < -8000 ) m_Sw[idx + DI_SLIDER0+1] = 0x80;
if( js.rglSlider[1] > 8000 ) m_Sw[idx + DI_SLIDER1+0] = 0x80;
if( js.rglSlider[1] < -8000 ) m_Sw[idx + DI_SLIDER1+1] = 0x80;
#endif
for( INT j = 0; j < 32; j++ ) {
m_Sw[idx + DI_BUTTON + j] = js.rgbButtons[j];
}
// POV
for( INT pov = 0; pov < 4; pov++ ) {
DWORD dwPOV = js.rgdwPOV[pov];
BOOL bPOVcenter = (LOWORD(dwPOV) == 0xFFFF);
BYTE data = 0;
if( !bPOVcenter ) {
static const BYTE dirtbl[] = {
(1<<0), (1<<0)|(1<<3), (1<<3), (1<<1)|(1<<3),
(1<<1), (1<<1)|(1<<2), (1<<2), (1<<0)|(1<<2),
};
data = dirtbl[ ((dwPOV+(DWORD)(22.5*DI_DEGREES)) % (360*DI_DEGREES))/(45*DI_DEGREES) ];
}
// Up/Down
if( data & (1<<0) ) m_Sw[idx + DI_POV0_UD+i*4+0] = 0x80;
if( data & (1<<1) ) m_Sw[idx + DI_POV0_UD+i*4+1] = 0x80;
// Left/Right
if( data & (1<<2) ) m_Sw[idx + DI_POV0_LR+i*4+0] = 0x80;
if( data & (1<<3) ) m_Sw[idx + DI_POV0_LR+i*4+1] = 0x80;
}
}
}
LPCSTR CDirectInput::SearchKeyName( INT key )
{
LPDIKEYTBL kt = DIKeyTable;
static CHAR KeyStr[256];
if( key == 0x00 )
return NULL;
if( key < 0x100 ) {
while( kt->name != NULL ) {
if( kt->key == key )
return kt->name;
kt++;
}
} else {
INT no = (key-256)>>6;
INT idx = key & 0x3F;
if( idx < DI_MAXAXIS ) {
::wsprintf( KeyStr, "J:%d %s", no, DIKeyDirTable[idx] );
return KeyStr;
} else if( idx >= DI_BUTTON && idx < DI_BUTTON_END ) {
::wsprintf( KeyStr, "J:%d B:%02d", no, idx-DI_BUTTON );
return KeyStr;
} else if( idx >= DI_EXT && idx < DI_EXT_END ) {
::wsprintf( KeyStr, "J:%d %s", no, DIKeyDirTable2[idx-DI_EXT] );
return KeyStr;
}
}
return NULL;
}

View File

@ -0,0 +1,87 @@
//
// DirectInput class
//
#ifndef __DIRECTINPUT_INCLUDED__
#define __DIRECTINPUT_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#define DIRECTINPUT_VERSION 0x0700
#include <dinput.h>
#include "typedef.h"
#include "macro.h"
#include <string>
using namespace std;
class CDirectInput
{
public:
// パブリックメンバ変数
typedef struct tagDIKEYTBL {
WORD key;
LPCSTR name;
} DIKEYTBL, *LPDIKEYTBL;
static DIKEYTBL DIKeyTable[];
INT m_nJoystickNum;
enum { DIJOYSTICK_MAX = 16 };
enum {
DI_XAXIS = 0, DI_YAXIS = 2, DI_ZAXIS = 4,
DI_RXAXIS = 6, DI_RYAXIS = 8, DI_RZAXIS = 10,
DI_SLIDER0 = 12, DI_SLIDER1 = 14,
DI_MAXAXIS = 16,
DI_BUTTON = 16, DI_BUTTON_END = 48,
DI_EXT = 48,
DI_POV0_UD = 48, DI_POV0_LR = 50,
DI_POV1_UD = 52, DI_POV1_LR = 54,
DI_POV2_UD = 56, DI_POV2_LR = 58,
DI_POV3_UD = 60, DI_POV3_LR = 62,
DI_EXT_END = 64,
};
BYTE m_Sw[256+64*DIJOYSTICK_MAX];
LONG m_JoyAxis[DIJOYSTICK_MAX][8];
string m_JoyName[DIJOYSTICK_MAX];
static LPSTR DIKeyDirTable[];
static LPSTR DIKeyDirTable2[];
// パブリックメンバ関数
CDirectInput();
virtual ~CDirectInput();
BOOL InitialDInput( HWND hWnd, HINSTANCE hInst );
void ReleaseDInput( void );
void Acquire();
void Unacquire();
void Poll();
BOOL AddJoystickDevice( GUID deviceguid );
void SetJoyAxisMode( LPWORD pMode ) {
for( INT i = 0; i < DIJOYSTICK_MAX; i++ )
m_JoyAxisMode[i] = pMode[i];
};
LPCSTR SearchKeyName( INT key );
protected:
// プロテクトメンバ変数
LPDIRECTINPUT7 m_lpDI;
LPDIRECTINPUTDEVICE m_lpKeyboard;
LPDIRECTINPUTDEVICE7 m_lpJoystick[DIJOYSTICK_MAX];
WORD m_JoyAxisMode[DIJOYSTICK_MAX];
// プロテクトメンバ関数
static BOOL CALLBACK DIEnumDevicesCallback( LPDIDEVICEINSTANCE lpddi, LPVOID pvRef );
};
extern CDirectInput DirectInput;
#endif // !__DIRECTINPUT_INCLUDED__

View File

@ -0,0 +1,607 @@
//
// DirectSound class
//
#include "DebugOut.h"
#include "DirectSound.h"
#include "COM.h"
CDirectSound DirectSound;
#define COMUSE TRUE
//
// WaveFileのロードとメモリへの保持
//
CWaveData::CWaveData()
{
m_pBuffer = NULL;
m_pwfex = NULL;
m_dwSize = 0;
m_pData = NULL;
}
CWaveData::~CWaveData()
{
Free();
}
BOOL CWaveData::Load( LPCSTR szFileName )
{
Free();
FILE* fp = NULL;
if( !(fp = ::fopen( szFileName, "rb" )) ) {
return FALSE;
}
LONG size;
::fseek( fp, 0, SEEK_END );
size = ::ftell( fp );
::fseek( fp, 0, SEEK_SET );
if( size < 0 ) {
return FALSE;
}
if( !(m_pBuffer = ::malloc( size )) ) {
return FALSE;
}
if( ::fread( m_pBuffer, size, 1, fp ) != 1 ) {
Free();
return FALSE;
}
FCLOSE( fp );
LPWAVEFORMATEX pWaveHeader;
BYTE *pbWaveData;
DWORD cbWaveSize;
DWORD *pdw, *pdwEnd;
DWORD dwRiff, dwLength, dwType;
// WAVEデータの解析
pWaveHeader = NULL;
pbWaveData = NULL;
cbWaveSize = 0;
pdw = (DWORD *)m_pBuffer;
dwRiff = *pdw++;
dwLength = *pdw++;
dwType = *pdw++;
if( dwRiff != mmioFOURCC( 'R','I','F','F' ) ) {
Free();
return FALSE;
}
if( dwType != mmioFOURCC( 'W','A','V','E' ) ) {
Free();
return FALSE;
}
pdwEnd = (DWORD*)((BYTE*)pdw+dwLength-sizeof(DWORD));
while( pdw < pdwEnd ) {
dwType = *pdw++;
dwLength = *pdw++;
switch( dwType ) {
case mmioFOURCC( 'f','m','t',' ' ):
if( pWaveHeader == NULL ) {
if( dwLength < sizeof(WAVEFORMAT) ) {
Free();
return FALSE;
}
pWaveHeader = (WAVEFORMATEX *)pdw;
}
break;
case mmioFOURCC( 'd','a','t','a' ):
if( (pbWaveData == NULL)||(!cbWaveSize) ) {
pbWaveData = (BYTE *)pdw;
cbWaveSize = dwLength;
}
}
if( pWaveHeader && (pbWaveData != NULL) && cbWaveSize)
break;
pdw = (DWORD *)((BYTE*)pdw + ((dwLength+1)&~1));
}
if( pdwEnd <= pdw ) {
Free();
return FALSE;
}
if( pWaveHeader->wFormatTag != WAVE_FORMAT_PCM ) {
Free();
return FALSE;
}
m_pwfex = pWaveHeader;
m_dwSize = dwLength;
m_pData = pbWaveData;
return TRUE;
}
void CWaveData::Free()
{
FREE( m_pBuffer );
}
DWORD CWaveData::GetSize()
{
if( !m_pBuffer )
return 0;
return m_dwSize;
}
WAVEFORMATEX* CWaveData::GetFormat()
{
if( !m_pBuffer )
return 0;
return m_pwfex;
}
LPVOID CWaveData::GetData()
{
if( !m_pBuffer )
return 0;
return m_pData;
}
//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////
CDirectSound::SAMPLERATE CDirectSound::m_SampleRateTable[] = {
11025, 8,
22050, 8,
44100, 8,
48000, 8,
11025, 16,
22050, 16,
44100, 16,
48000, 16,
0, 0
};
INT CDirectSound::m_BufferSizeTable[] = {
2, 3, 4, 5, 6, 7, 8, 9, 10, 0
};
CDirectSound::CDirectSound()
{
m_lpDS = NULL;
m_lpDSPrimary = NULL;
m_lpDSStream = NULL;
#if 1
m_SampleRate.Rate = 22050;
#else
m_SampleRate.Rate = 44100;
#endif
// m_SampleRate.Bits = 8;
m_SampleRate.Bits = 16;
m_BufferSize = 1;
// m_BufferSize = 2;
m_bStreamPlay = FALSE;
m_bStreamPause = FALSE;
for( INT i = 0; i < ESF_FILE_MAX; i++ ) {
m_pEsfDSBuffer[ i ] = NULL;
}
#if COMUSE
COM::AddRef();
#endif
}
CDirectSound::~CDirectSound()
{
ReleaseDSound();
#if COMUSE
COM::Release();
#endif
}
// DirectSoundの初期化
BOOL CDirectSound::InitialDSound( HWND hWnd )
{
DSBUFFERDESC dsbdesc;
m_hWnd = hWnd;
try {
// DirectSoundオブジェクトの作成
#if !COMUSE
if( DirectSoundCreate( NULL, &m_lpDS, NULL ) != DS_OK ) {
m_lpDS = NULL;
throw "CDirectSound:DirectSoundCreate failed.";
}
#else
// COM的利用
// COM::AddRef();
if( ::CoCreateInstance( CLSID_DirectSound, NULL, CLSCTX_ALL, IID_IDirectSound, (LPVOID*)&m_lpDS) != S_OK ) {
m_lpDS = NULL;
throw "CDirectSound:CoCreateInstance failed.";
}
if( m_lpDS->Initialize( NULL ) != DS_OK )
throw "CDirectSound:IDirectSound->Initialize failed.";
#endif
// 優先協調モードの設定
if( m_lpDS->SetCooperativeLevel( hWnd, DSSCL_PRIORITY ) != DS_OK )
throw "CDirectSound:SetCooperativeLevel failed.";
// スピーカの設定
// m_lpDS->SetSpeakerConfig( DSSPEAKER_COMBINED( DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE ) );
// プライマリバッファの作成
ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
// dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME
// | DSBCAPS_PRIMARYBUFFER;
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
dsbdesc.dwBufferBytes = 0;
dsbdesc.lpwfxFormat = NULL;
if( m_lpDS->CreateSoundBuffer( &dsbdesc, &m_lpDSPrimary, NULL ) != DS_OK )
throw "CDirectSound:CreateSoundBuffer failed.";
} catch( char *str ) {
ReleaseDSound();
::MessageBox( hWnd, str, "ERROR", MB_ICONERROR|MB_OK );
return FALSE;
}
return TRUE;
}
// DirectSoundの開放
void CDirectSound::ReleaseDSound()
{
ReleaseEsfBuffer();
ReleaseBuffer();
// DirectSoundオブジェクトの開放
RELEASE( m_lpDSPrimary );
if( m_lpDS ) {
RELEASE( m_lpDS );
#if COMUSE
// COM::Release();
#endif
}
m_hWnd = NULL;
}
// DirectSoundバッファの作成
BOOL CDirectSound::InitialBuffer()
{
DSBUFFERDESC dsbdesc;
WAVEFORMATEX pcmwf;
try {
if( !m_lpDSPrimary )
throw "CDirectSound:DirectSound object uninitialized.";
// プライマリバッファのWaveフォーマットを設定(常にモノラル)
ZEROMEMORY( &pcmwf, sizeof(WAVEFORMATEX) );
pcmwf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.nChannels = 1;
pcmwf.nSamplesPerSec = (WORD)m_SampleRate.Rate;
pcmwf.nBlockAlign = (WORD)m_SampleRate.Bits/8;
pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
pcmwf.wBitsPerSample = (WORD)m_SampleRate.Bits;
if( m_lpDSPrimary->SetFormat( &pcmwf ) != DS_OK )
throw "CDirectSound:SetFormat failed.";
// ストリームセカンダリバッファ作成
if( m_BufferSize < 2 )
m_BufferSize = 2;
// バッファサイズ等の計算
m_dwDSBlockNum = m_BufferSize * 10;
m_dwDSBlockSize = pcmwf.nAvgBytesPerSec * m_BufferSize / 60;
m_dwDSBlockSize-= m_dwDSBlockSize % pcmwf.nBlockAlign;
m_dwDSBufferSize = m_dwDSBlockSize * m_dwDSBlockNum;
m_dwDSLastBlock = 0;
ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_LOCSOFTWARE
| DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_GLOBALFOCUS;
dsbdesc.dwBufferBytes = m_dwDSBufferSize;
dsbdesc.lpwfxFormat = &pcmwf;
if( m_lpDS->CreateSoundBuffer( &dsbdesc, &m_lpDSStream, NULL ) != DS_OK )
throw "CDirectSound:CreateSoundBuffer failed.";
LPBYTE lpPtr;
DWORD dwBytes;
if( m_lpDSStream->Lock( 0, m_dwDSBufferSize, (LPVOID*)&lpPtr, &dwBytes, NULL, NULL, 0 ) != DS_OK ) {
throw "CDirectSound:Lock failed.";
} else {
FillMemory( lpPtr, dwBytes, (BYTE)(m_SampleRate.Bits==8?128:0) );
m_lpDSStream->Unlock( lpPtr, dwBytes, NULL, NULL );
}
} catch( char *str ) {
ReleaseBuffer();
::MessageBox( m_hWnd, str, "ERROR", MB_ICONERROR|MB_OK );
return FALSE;
}
return TRUE;
}
// DirectSoundバッファの開放
void CDirectSound::ReleaseBuffer()
{
StreamStop();
RELEASE( m_lpDSStream );
}
// サンプリングレートの設定
BOOL CDirectSound::SetSamplingRate( DWORD rate, DWORD bits )
{
INT i;
i = 0;
while( m_SampleRateTable[i].Rate != 0 ) {
if( m_SampleRateTable[i].Rate == rate
&& m_SampleRateTable[i].Bits == bits ) {
m_SampleRate.Rate = rate;
m_SampleRate.Bits = bits;
return TRUE;
}
i++;
}
return FALSE;
}
// サンプリングレートの取得
void CDirectSound::GetSamplingRate( DWORD& rate, DWORD& bits )
{
rate = m_SampleRate.Rate;
bits = m_SampleRate.Bits;
}
// ストリーミング再生
void CDirectSound::StreamPlay()
{
if( !m_lpDS || !m_lpDSStream )
return;
if( !m_bStreamPlay ) {
// Buffer clear
LPBYTE lpPtr;
DWORD dwBytes;
if( m_lpDSStream->Lock( 0, m_dwDSBufferSize, (LPVOID*)&lpPtr, &dwBytes, NULL, NULL, 0 ) != DS_OK ) {
throw "CDirectSound:Lock failed.";
} else {
FillMemory( lpPtr, dwBytes, (BYTE)(m_SampleRate.Bits==8?128:0) );
m_lpDSStream->Unlock( lpPtr, dwBytes, NULL, NULL );
}
m_dwDSLastBlock = 0xFFFFFFFF;
m_bStreamPlay = TRUE;
m_bStreamPause = FALSE;
m_lpDSStream->SetCurrentPosition( 0 );
m_lpDSStream->Play( 0, 0, DSBPLAY_LOOPING );
}
}
// ストリーミング停止
void CDirectSound::StreamStop()
{
if( !m_lpDS || !m_lpDSStream )
return;
if( m_bStreamPlay ) {
m_bStreamPlay = FALSE;
m_bStreamPause = FALSE;
m_lpDSStream->Stop();
// 完全停止まで待つ
DWORD dwStatus;
do {
m_lpDSStream->GetStatus( &dwStatus );
} while( dwStatus & DSBSTATUS_PLAYING );
m_lpDSStream->SetCurrentPosition( 0 );
}
}
// ストリーミングポーズ
void CDirectSound::StreamPause()
{
// DEBUGOUT( "CDirectSound::StreamPause\n" );
if( !m_lpDS || !m_lpDSStream )
return;
if( m_bStreamPlay ) {
if( !m_bStreamPause ) {
m_bStreamPause = TRUE;
m_lpDSStream->Stop();
}
}
}
// ストリーミングレジューム
void CDirectSound::StreamResume()
{
// DEBUGOUT( "CDirectSound::StreamResume\n" );
if( !m_lpDS || !m_lpDSStream )
return;
if( m_bStreamPlay ) {
if( m_bStreamPause ) {
m_bStreamPause = FALSE;
m_lpDSStream->Play( 0, 0, DSBPLAY_LOOPING );
}
}
}
// ストリーミング
BOOL CDirectSound::GetStreamLockPosition( LPDWORD lpdwStart, LPDWORD lpdwSize )
{
static BOOL bLockHalf = FALSE;
DWORD dwPlayPos, dwWritePos;
if( m_lpDSStream->GetCurrentPosition( &dwPlayPos, &dwWritePos ) == DS_OK ) {
if( (dwWritePos / m_dwDSBlockSize) != m_dwDSLastBlock ) {
m_dwDSLastBlock = dwWritePos / m_dwDSBlockSize;
dwWritePos = (((dwWritePos/m_dwDSBlockSize)+1)%m_dwDSBlockNum) * m_dwDSBlockSize;
// ロックすべき場所
*lpdwStart = dwWritePos;
*lpdwSize = m_dwDSBlockSize;
return TRUE;
}
}
return FALSE;
}
BOOL CDirectSound::StreamLock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID* lplpvPtr1, LPDWORD lpdwBytes1, LPVOID* lplpvPtr2, LPDWORD lpdwBytes2, DWORD dwFlags )
{
if( m_lpDSStream->Lock( dwWriteCursor, dwWriteBytes, lplpvPtr1, lpdwBytes1, lplpvPtr2, lpdwBytes2, dwFlags ) == DS_OK )
return TRUE;
return FALSE;
}
BOOL CDirectSound::StreamUnlock( LPVOID lpvPtr1, DWORD dwBytes1, LPVOID lpvPtr2, DWORD dwBytes2 )
{
if( m_lpDSStream->Unlock( lpvPtr1, dwBytes1, lpvPtr2, dwBytes2 ) == DS_OK )
return TRUE;
return FALSE;
}
BOOL CDirectSound::LoadEsf( LPCSTR szFileName, INT no )
{
if( no < 0 || no > ESF_FILE_MAX-1 )
return FALSE;
if( m_EsfWaveFile[no].Load( szFileName ) ) {
return CreateESFBuffer( no, m_EsfWaveFile[no].GetFormat(), m_EsfWaveFile[no].GetData(), m_EsfWaveFile[no].GetSize() );
} else {
DEBUGOUT( "CDirectSound::LoadEsf error. [%s]\n", szFileName );
}
return FALSE;
}
BOOL CDirectSound::EsfPlay( INT no )
{
if( !m_lpDS )
return FALSE;
if( !m_pEsfDSBuffer[no] )
return FALSE;
m_pEsfDSBuffer[no]->SetCurrentPosition( 0 );
if( m_pEsfDSBuffer[no]->Play( 0, 0, 0 ) == DSERR_BUFFERLOST ) {
if( m_pEsfDSBuffer[no]->Restore() == DS_OK ) {
CreateESFBuffer( no, m_EsfWaveFile[no].GetFormat(), m_EsfWaveFile[no].GetData(), m_EsfWaveFile[no].GetSize() );
m_pEsfDSBuffer[no]->Play( 0, 0, 0 );
}
}
return TRUE;
}
BOOL CDirectSound::EsfPlayLoop( INT no )
{
if( !m_lpDS )
return FALSE;
if( !m_pEsfDSBuffer[no] )
return FALSE;
// 既に再生中か?
DWORD dwStatus;
if( m_pEsfDSBuffer[no]->GetStatus( &dwStatus ) == DS_OK ) {
if( dwStatus == DSBSTATUS_PLAYING ) {
return TRUE;
}
}
m_pEsfDSBuffer[no]->SetCurrentPosition( 0 );
if( m_pEsfDSBuffer[no]->Play( 0, 0, DSBPLAY_LOOPING ) == DSERR_BUFFERLOST ) {
if( m_pEsfDSBuffer[no]->Restore() == DS_OK ) {
CreateESFBuffer( no, m_EsfWaveFile[no].GetFormat(), m_EsfWaveFile[no].GetData(), m_EsfWaveFile[no].GetSize() );
m_pEsfDSBuffer[no]->Play( 0, 0, DSBPLAY_LOOPING );
}
}
return TRUE;
}
BOOL CDirectSound::EsfStop( INT no )
{
if( !m_lpDS )
return FALSE;
if( !m_pEsfDSBuffer[no] )
return FALSE;
m_pEsfDSBuffer[no]->Stop();
m_pEsfDSBuffer[no]->SetCurrentPosition( 0 );
return TRUE;
}
void CDirectSound::EsfAllStop()
{
if( !m_lpDS )
return;
for( INT i = 0; i < ESF_FILE_MAX; i++ ) {
EsfStop( i );
}
}
BOOL CDirectSound::CreateESFBuffer( INT no, WAVEFORMATEX* pwfex, LPVOID pData, DWORD dwSize )
{
DSBUFFERDESC dsbdesc;
LPVOID lpPtr0, lpPtr1;
DWORD dwBytes0, dwBytes1;
// 既に使っていたら開放しておく
if( m_pEsfDSBuffer[no] ) {
RELEASE( m_pEsfDSBuffer[no] );
}
// DirectSound セカンダリバッファ作成
ZEROMEMORY( &dsbdesc, sizeof(DSBUFFERDESC) );
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_LOCSOFTWARE;
dsbdesc.dwBufferBytes = dwSize;
dsbdesc.lpwfxFormat = pwfex;
if( m_lpDS->CreateSoundBuffer( &dsbdesc, &m_pEsfDSBuffer[no], NULL ) != DS_OK ) {
m_pEsfDSBuffer[no] = NULL;
return FALSE;
}
// 作成したセカンダリバッファにウェーブデータをコピー
m_pEsfDSBuffer[no]->Lock( 0L, dwSize, &lpPtr0, &dwBytes0, &lpPtr1, &dwBytes1, 0 );
::CopyMemory( lpPtr0, pData, dwBytes0 );
if( dwBytes1 ) {
::CopyMemory( lpPtr1, (LPBYTE)pData + dwBytes1, dwBytes1 );
}
m_pEsfDSBuffer[no]->Unlock( &lpPtr0, dwBytes0, &lpPtr1, dwBytes1 );
return TRUE;
}
void CDirectSound::ReleaseEsfBuffer()
{
EsfAllStop();
for( INT i = 0; i < ESF_FILE_MAX; i++ ) {
RELEASE( m_pEsfDSBuffer[i] );
m_EsfWaveFile[i].Free();
}
}

View File

@ -0,0 +1,123 @@
//
// DirectSound class
//
#ifndef __DIRECTSOUND_INCLUDED__
#define __DIRECTSOUND_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#define DIRECTSOUND_VERSION 0x0700
#include <dsound.h>
#include "extsoundfile.h"
#include "typedef.h"
#include "macro.h"
class CWaveData
{
public:
CWaveData();
virtual ~CWaveData();
BOOL Load( LPCSTR szFileName );
void Free();
DWORD GetSize();
WAVEFORMATEX* GetFormat();
LPVOID GetData();
protected:
LPVOID m_pBuffer;
WAVEFORMATEX* m_pwfex;
DWORD m_dwSize;
LPVOID m_pData;
private:
};
class CDirectSound
{
public:
// パブリックメンバ変数
typedef struct tagSAMPLERATE {
DWORD Rate;
DWORD Bits;
} SAMPLERATE, *LPSAMPLERATE;
SAMPLERATE m_SampleRate; // 現在サンプリングレート
INT m_BufferSize; // バッファサイズ(フレーム数)
static SAMPLERATE m_SampleRateTable[]; // サンプリングレートテーブル
static INT m_BufferSizeTable[]; // バッファサイズテーブル
// パブリックメンバ関数
CDirectSound();
virtual ~CDirectSound();
BOOL InitialDSound( HWND hWnd );
void ReleaseDSound();
BOOL InitialBuffer();
void ReleaseBuffer();
BOOL SetSamplingRate( DWORD rate, DWORD bits );
void GetSamplingRate( DWORD& rate, DWORD& bits );
void SetBufferSize( INT nSize ) { m_BufferSize = nSize; }
INT GetBufferSize() { return m_BufferSize; }
BOOL IsStreamPlaying() { return (m_bStreamPlay&&!m_bStreamPause); }
void StreamPlay();
void StreamStop();
void StreamPause();
void StreamResume();
BOOL GetStreamLockPosition( LPDWORD lpdwStart, LPDWORD lpdwSize );
BOOL StreamLock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID* lplpvPtr1, LPDWORD lpdwBytes1, LPVOID* lplpvPtr2, LPDWORD lpdwBytes2, DWORD dwFlags );
BOOL StreamUnlock( LPVOID lpvPtr1, DWORD dwBytes1, LPVOID lpvPtr2, DWORD dwBytes2 );
BOOL IsStreamPlay() { return m_bStreamPlay; }
BOOL IsStreamPause() { return m_bStreamPause; }
// 外部音声ファイル対応
BOOL LoadEsf( LPCSTR szFileName, INT no );
BOOL EsfPlay( INT no );
BOOL EsfPlayLoop( INT no );
BOOL EsfStop( INT no );
void EsfAllStop();
BOOL CreateESFBuffer( INT no, WAVEFORMATEX* pwfex, LPVOID pData, DWORD dwSize );
void ReleaseEsfBuffer();
protected:
// プロテクトメンバ変数
HWND m_hWnd; // Window handle
LPDIRECTSOUND m_lpDS; // DirectSoundオブジェクト
LPDIRECTSOUNDBUFFER m_lpDSPrimary; // プライマリオブジェクト
LPDIRECTSOUNDBUFFER m_lpDSStream; // ストリーミングオブジェクト
DWORD m_dwDSBufferSize;
DWORD m_dwDSBlockSize; // 1ブロックのサイズ
DWORD m_dwDSBlockNum; // ブロックの数
DWORD m_dwDSLastBlock; // 最後に書き込んだブロック位置
volatile BOOL m_bStreamPlay; // ストリーム再生中フラグ
volatile BOOL m_bStreamPause; // ストリームポーズフラグ
// 外部音声ファイル対応
CWaveData m_EsfWaveFile[ ESF_FILE_MAX ];
LPDIRECTSOUNDBUFFER m_pEsfDSBuffer[ ESF_FILE_MAX ];
// プロテクトメンバ関数
private:
// プライベートメンバ変数
// プライベートメンバ関数
};
extern CDirectSound DirectSound;
#endif // !__DIRECTSOUND_INCLUDED__

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,281 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

View File

@ -0,0 +1,33 @@
2019-11-05 叶枫更新:
代码参考了byemu在google code上托管的VirtuaNES plus项目由于IntroROM的整理使用了7z压缩档所以添加了7z支持。
1、模拟器默认调色板更换为Mesen调色板
2、添加 Mapper192Mapper195支持
3、修正 Mapper194
4、支持7z压缩文件
5、关于对话框添加文件编译时间及代码贡献者
2019-10-30 叶枫更新:
1、支持超大(1MB)nsf文件播放例如: [Subor]Karaoke(C).nsf
2019-10-26 叶枫和心傷誰知更新:
1、打开文件窗口中的文件名后缀提示由英文改为中文。
2、打开文件窗口中的所有可用文件后面增加后缀名提示。
3、打开文件窗口中增加.unf后缀名。
4、菜单栏的打开->最近使用过的路径弹出来的窗口中也增加以上3点。
5、控制台支持加载.unf文件。
6、关于中的版本号0.85改为0.86。
7、打开文件时找不到路劲时提示的"无法打开a"修正为"无法打开"。
8、模拟器启动时可以自动打开文件,文件路径请在VirtuaNESex.ini里的RomAutoRunPath设置。
9、修正无法播放NSF文件的问题(方向键上开启,方向键下关闭)。
2015-09-03 惊风更新:
支持新发布的高达三部曲
2014-01-30 惊风更新:
  很久没写更新日志了,真的忘记具体添加的东西了,把主要的说说吧。
1、南晶科技的《数独2合1》没开新mapper直接改在mapper198里面
2、添加mapper168小霸王卡带的一个Rom驱动感谢TPU老大的帮忙。用CRC Hack的方式把小霸王的《卡拉OK》卡带Rom也添加到这驱动里面因为图像处理方式一样所以懒得用其他mapper了
3、添加mapper169裕兴学习卡的Rom驱动还不完善的初步添加目前支持已知的裕兴V8.0、V8.2、V8.3、V9.0、V9.2版本的学习卡RomRom文件可以到这地址下载——(http://hi.baidu.com/yxleimeng/item/bdfb2f9fe08118d81a49df47)请将Rom的mapper修改成169
4、添加金字塔键盘及其改版键盘——科王键盘和泽诚键盘。使用这些键盘的Rom还未发布的敬请期待.

View File

@ -0,0 +1,5 @@
<ソースリストに付いて>
GNU Public License Version 2に従って下さい。(Copying.txt参照。英語です)

View File

@ -0,0 +1,40 @@
VirtuaNES 0.86a mapper extension
================================
Support mappers:
================
mapper 27:
WorldHero
mapper 163:NanJing's game
Paladin(C)
Harvest_Moon(C)
mapper 164:Union-bond's game
Digital_dragon(C)
sanguo2(C)
Final Fantasy V(C)
Pocket Monster Gold(C)
...
mapper 165:
Fire Emblem (Chinese version)
mapper 167:Subor Computer serias(PAL mode)
Subor Computer V1.0 (Russian)
Subor Computer V2.0 (Chinese)
Subor Computer V4.0 (Chinese)
Subor English (Chinese)
Support Controller:
===================
Subor Computer Keyboard:
Use by Subor Computer and EDU(C)
Fixed:
======
PAL timing:
Total scanlines : 313
Vblank start lines: 291
Others:
=======
This extension is made by tpu(tpunix [AT] 126.com).
You can find the new roms at (http://www.romchina.com).
Enjoy it!

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,197 @@
//
// エミュレータスレッドクラス
//
#ifndef __CEMUTHREAD_INCLUDED__
#define __CEMUTHREAD_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
#include <deque>
#include <queue>
using namespace std;
#include "App.h"
#include "MMTimer.h"
#include "Config.h"
#include "WaveRec.h"
#include "typedef.h"
#include "macro.h"
#include "nes.h"
#include "mmu.h"
#include "cpu.h"
#include "ppu.h"
#include "apu.h"
#include "pad.h"
#include "rom.h"
#include "mapper.h"
// Prototypes
// NetPlay Event
class NETEV {
public:
INT Event;
DWORD Param;
};
//class NES;
class CEmuThread
{
public:
CEmuThread();
~CEmuThread();
// イベント
enum EMUEVENT {
EV_EXIT = -1,
EV_NONE = 0,
EV_INITIAL,
EV_PAUSE,
EV_RESUME,
// 以下はEventで使用する
EV_MESSAGE_OUT, // メッセージだけ出力したい時に使用
EV_FULLSCREEN_GDI, // EventParam
EV_EMUPAUSE,
EV_ONEFRAME,
EV_THROTTLE,
EV_FRAMESKIP_AUTO,
EV_FRAMESKIP_UP,
EV_FRAMESKIP_DOWN,
EV_HWRESET,
EV_SWRESET,
EV_NETPLAY_START,
EV_STATE_LOAD, // EventParam2
EV_STATE_SAVE, // EventParam2
// For Disk system
EV_DISK_COMMAND, // EventParam
// For ExController
EV_EXCONTROLLER, // EventParam
// For Sound
EV_SOUND_MUTE, // EventParam
// For Snapshot
EV_SNAPSHOT,
// For Movie
EV_MOVIE_PLAY, // EventParam
EV_MOVIE_REC, // EventParam
EV_MOVIE_RECAPPEND, // EventParam
EV_MOVIE_STOP, // EventParam
// For Wave recording
EV_WAVEREC_START, // EventParam
EV_WAVEREC_STOP,
// For Tape recording
EV_TAPE_PLAY, // EventParam
EV_TAPE_REC, // EventParam
EV_TAPE_STOP,
// For Barcode
EV_BARCODE, // EventParam2
// For TurboFile
EV_TURBOFILE, // EventParam
// For Debugger
EV_DEBUG_RUN,
EV_DEBUG_BRAKE,
EV_DEBUG_STEP,
EV_DEBUG_COMMAND, // EventParam
};
// 動作モード
enum {
STATUS_NONE = 0,
STATUS_RUN,
STATUS_PAUSE,
};
// デバッガコマンド
//
void SetPriority( INT nPriority );
BOOL Start( HWND hWnd, NES* nes );
void Stop();
void Pause();
void Resume();
void Event( EMUEVENT ev );
void EventParam( EMUEVENT ev, LONG Param );
void EventParam2( EMUEVENT ev, LONG Param, LONG Param2 );
BOOL IsRunning() { return (g_Status!=STATUS_NONE); }
BOOL IsPausing() { return (g_Status==STATUS_PAUSE); }
BOOL IsWaveRecord() { return g_WaveRec.IsWaveRecord(); }
INT GetDiskNo() { if( g_nes ) return g_nes->rom->GetDiskNo(); else return 0; }
INT GetExController() { if( g_nes ) return g_nes->pad->GetExController(); else return 0; }
//
NES* GetNES() { return g_nes; }
protected:
static void DiskCommand( BYTE cmd );
static BOOL FrameInput();
static DWORD WINAPI ThreadProc( LPVOID lpVoid );
// サウンドストリーミング用
static void StreamProcess( BOOL bPause );
// スレッドハンドルとID
HANDLE m_hThread;
DWORD m_dwThreadID;
// Thisポインタ
static CEmuThread* g_pThis;
// ウインドウハンドル
static HWND g_hWnd;
// エミュレータオブジェクトポインタ
static NES* g_nes;
// Waveレコーダ
static CWaveRec g_WaveRec;
// ポーズカウント
INT m_nPauseCount;
// ステータス
static INT g_Status;
// スレッドイベントとイベントハンドル
static INT g_Event;
static LONG g_EventParam;
static LONG g_EventParam2;
static HANDLE g_hEvent;
static HANDLE g_hEventAccept;
// スレッドプライオリティ
INT m_nPriority;
static INT g_PriorityTable[];
// エラーメッセージ
static CHAR g_szErrorMessage[512];
// ストリングテーブル
static LPCSTR g_lpSoundMuteStringTable[];
// NetPlay Event
static deque<NETEV> NetEventQueue;
static string strNetStateName;
private:
};
extern CEmuThread Emu;
#endif // !__CEMUTHREAD_INCLUDED__

View File

@ -0,0 +1,136 @@
//
// エミュレータダイアログクラス
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Wnd.h"
#include "EmulatorDlg.h"
DLG_MESSAGE_BEGIN(CEmulatorDlg)
// メッセージ
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_ON_MESSAGE( WM_HSCROLL, OnHScroll )
// コマンド
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDDEFAULT, OnDefault )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CEmulatorDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_EMULATOR),
hWndParent, g_DlgProc, (LPARAM)this );
}
void CEmulatorDlg::OnInitialMember()
{
BTNCHECK( IDC_EMU_ILLEGALOP, Config.emulator.bIllegalOp );
BTNCHECK( IDC_EMU_FOURPLAYER, Config.emulator.bFourPlayer );
BTNCHECK( IDC_EMU_AUTOFRAMESKIP, Config.emulator.bAutoFrameSkip );
BTNCHECK( IDC_EMU_THROTTLE, Config.emulator.bThrottle );
BTNCHECK( IDC_EMU_BACKGROUND, Config.emulator.bBackground );
BTNCHECK( IDC_EMU_CRCCHECK, Config.emulator.bCrcCheck );
BTNCHECK( IDC_EMU_DISKTHROTTLE, Config.emulator.bDiskThrottle );
BTNCHECK( IDC_EMU_LOADFULLSCREEN, Config.emulator.bLoadFullscreen );
BTNCHECK( IDC_EMU_DOUBLEEXECUTE, Config.general.bDoubleExecute );
BTNCHECK( IDC_EMU_STARTUPLAUNCHER,Config.general.bStartupLauncher );
BTNCHECK( IDC_EMU_PNGSNAPSHOT, Config.emulator.bPNGsnapshot );
// スライダ
::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_SETRANGE, TRUE, MAKELONG(1,60) );
::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_SETPOS, TRUE, (WPARAM)Config.emulator.nThrottleFPS/10 );
::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_SETTICFREQ, 2, 0 );
::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_SETLINESIZE, 0, 1 );
::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_SETPAGESIZE, 0, 1 );
// FPS値
CHAR str[64];
::wsprintf( str, "%d", Config.emulator.nThrottleFPS );
::SetDlgItemText( m_hWnd, IDC_EMU_FPS, str );
// プライオリティコンボボックス
::SendDlgItemMessage( m_hWnd, IDC_EMU_PRIORITY_COMBO, CB_RESETCONTENT, 0, 0 );
INT i, j;
for( i = IDS_EMU_PRIORITY_IDLE, j = 0; i <= IDS_EMU_PRIORITY_REALTIME; i++, j++ ) {
CApp::LoadString( i, str, sizeof(str) );
::SendDlgItemMessage( m_hWnd, IDC_EMU_PRIORITY_COMBO, CB_INSERTSTRING, (WPARAM)j, (LPARAM)str );
}
::SendDlgItemMessage( m_hWnd, IDC_EMU_PRIORITY_COMBO, CB_SETCURSEL, (WPARAM)Config.emulator.nPriority, 0 );
}
DLGMSG CEmulatorDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CEmulatorDlg::OnInitDialog\n" );
m_ConfigSave = Config.emulator;
OnInitialMember();
return TRUE;
}
DLGMSG CEmulatorDlg::OnHScroll( DLGMSGPARAM )
{
// DEBUGOUT( "CEmulatorDlg::OnHScroll\n" );
INT pos = ::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_GETPOS, 0, 0 );
CHAR str[16];
::wsprintf( str, "%d", pos*10 );
::SetDlgItemText( m_hWnd, IDC_EMU_FPS, str );
return FALSE;
}
DLGCMD CEmulatorDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CEmulatorDlg::OnOK\n" );
Config.emulator.bIllegalOp = IsBTNCHECK( IDC_EMU_ILLEGALOP );
Config.emulator.bFourPlayer = IsBTNCHECK( IDC_EMU_FOURPLAYER );
Config.emulator.bAutoFrameSkip = IsBTNCHECK( IDC_EMU_AUTOFRAMESKIP );
Config.emulator.bThrottle = IsBTNCHECK( IDC_EMU_THROTTLE );
Config.emulator.bBackground = IsBTNCHECK( IDC_EMU_BACKGROUND );
Config.emulator.bCrcCheck = IsBTNCHECK( IDC_EMU_CRCCHECK );
Config.emulator.bDiskThrottle = IsBTNCHECK( IDC_EMU_DISKTHROTTLE );
Config.emulator.bLoadFullscreen = IsBTNCHECK( IDC_EMU_LOADFULLSCREEN );
Config.general.bDoubleExecute = IsBTNCHECK( IDC_EMU_DOUBLEEXECUTE );
Config.general.bStartupLauncher = IsBTNCHECK( IDC_EMU_STARTUPLAUNCHER );
Config.emulator.bPNGsnapshot = IsBTNCHECK( IDC_EMU_PNGSNAPSHOT );
Config.emulator.nThrottleFPS = 10 * ::SendDlgItemMessage( m_hWnd, IDC_EMU_THROTTLE_SLIDER, TBM_GETPOS, 0, 0 );
Config.emulator.nPriority = ::SendDlgItemMessage( m_hWnd, IDC_EMU_PRIORITY_COMBO, CB_GETCURSEL, 0, 0 );
::EndDialog( m_hWnd, IDOK );
}
DLGCMD CEmulatorDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CEmulatorDlg::OnCancel\n" );
Config.emulator = m_ConfigSave;
::EndDialog( m_hWnd, IDCANCEL );
}
DLGCMD CEmulatorDlg::OnDefault( DLGCMDPARAM )
{
// DEBUGOUT( "CEmulatorDlg::OnDefault\n" );
Config.emulator.Default();
OnInitialMember();
}

View File

@ -0,0 +1,38 @@
//
// エミュレータダイアログクラス
//
#ifndef __CEMULATORDLG_INCLUDED__
#define __CEMULATORDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
#include "Config.h"
class CEmulatorDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
void OnInitialMember();
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGMSG OnHScroll( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnDefault( DLGCMDPARAM );
//
CCfgEmulator m_ConfigSave;
private:
};
#endif // !__CEMULATORDLG_INCLUDED__

View File

@ -0,0 +1,30 @@
#ifndef __EXTSOUNDFILE_INCLUDED__
#define __EXTSOUNDFILE_INCLUDED__
enum EXTSOUNDFILE
{
ESF_MOEPRO_STRIKE = 0, // ストライクッ!
ESF_MOEPRO_BALL, // ボール
ESF_MOEPRO_TIME, // ターイム
ESF_MOEPRO_OUT, // アウッ!
ESF_MOEPRO_SAFE, // セーフ
ESF_MOEPRO_FAIRBALL, // ファール
ESF_MOEPRO_FOULBALL, // フェアッ!
ESF_MOEPRO_BATTEROUT, // バッターアウッ!
ESF_MOEPRO_PLAYBALL, // プレイボール
ESF_MOEPRO_FOURBALL, // フォアボー
ESF_MOEPRO_HOMERUN, // ホーマンッ!
ESF_MOEPRO_PITCHER, // ピチャ交代
ESF_MOEPRO_OUCH, // イテッ
ESF_MOEPRO_AHO, // あ~ほっ
ESF_MOEPRO_KNOCK, // 打撃音
ESF_MOEPRO_WA, // ワーッ!(オーライッ?
ESF_DISKSYSTEM_BOOT, // カム音
ESF_DISKSYSTEM_MOTOR, // モーター音(ループ)
ESF_DISKSYSTEM_SEEKEND, // 停止音
ESF_FILE_MAX
};
#endif // !__EXTSOUNDFILE_INCLUDED__

View File

@ -0,0 +1,279 @@
//
// フォルダダイアログクラス
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Wnd.h"
#include "FolderDlg.h"
DLG_MESSAGE_BEGIN(CFolderDlg)
// メッセージ
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
// コマンド
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDDEFAULT, OnDefault )
DLG_ON_COMMAND( IDC_FLD_ROM_BROWSE, OnRomBrowse )
DLG_ON_COMMAND( IDC_FLD_SAVE_BROWSE, OnSaveBrowse )
DLG_ON_COMMAND( IDC_FLD_STATE_BROWSE, OnStateBrowse )
DLG_ON_COMMAND( IDC_FLD_SNAPSHOT_BROWSE, OnSnapshotBrowse )
DLG_ON_COMMAND( IDC_FLD_MOVIE_BROWSE, OnMovieBrowse )
DLG_ON_COMMAND( IDC_FLD_WAVE_BROWSE, OnWaveBrowse )
DLG_ON_COMMAND( IDC_FLD_CHEAT_BROWSE, OnCheatBrowse )
DLG_COMMAND_END()
DLG_MESSAGE_END()
CFolderDlg::CFolderDlg()
{
m_hFont = NULL;
}
CFolderDlg::~CFolderDlg()
{
GDIDELETE( m_hFont );
}
INT CFolderDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_FOLDER),
hWndParent, g_DlgProc, (LPARAM)this );
}
void CFolderDlg::OnInitialMember()
{
BTNCHECK( IDC_FLD_ROM_USE, Config.path.bRomPath );
BTNCHECK( IDC_FLD_SAVE_USE, Config.path.bSavePath );
BTNCHECK( IDC_FLD_STATE_USE, Config.path.bStatePath );
BTNCHECK( IDC_FLD_SNAPSHOT_USE, Config.path.bSnapshotPath );
BTNCHECK( IDC_FLD_MOVIE_USE, Config.path.bMoviePath );
BTNCHECK( IDC_FLD_WAVE_USE, Config.path.bWavePath );
BTNCHECK( IDC_FLD_CHEAT_USE, Config.path.bCheatPath );
::SetDlgItemText( m_hWnd, IDC_FLD_ROM_EDIT, Config.path.szRomPath );
::SetDlgItemText( m_hWnd, IDC_FLD_SAVE_EDIT, Config.path.szSavePath );
::SetDlgItemText( m_hWnd, IDC_FLD_STATE_EDIT, Config.path.szStatePath );
::SetDlgItemText( m_hWnd, IDC_FLD_SNAPSHOT_EDIT, Config.path.szSnapshotPath );
::SetDlgItemText( m_hWnd, IDC_FLD_MOVIE_EDIT, Config.path.szMoviePath );
::SetDlgItemText( m_hWnd, IDC_FLD_WAVE_EDIT, Config.path.szWavePath );
::SetDlgItemText( m_hWnd, IDC_FLD_CHEAT_EDIT, Config.path.szCheatPath );
}
void CFolderDlg::PathCheck( LPSTR lpszPath )
{
INT len = ::strlen( lpszPath );
if( len > 3 ) {
if( isleadbyte( (UINT)lpszPath[len-2] ) ) {
// MBCSで¥が無い場合
::strcat( lpszPath, "\\" );
} else {
if( lpszPath[ len-1 ] != '\\' ) {
::strcat( lpszPath, "\\" );
}
}
}
}
DLGMSG CFolderDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CFolderDlg::OnInitDialog\n" );
m_ConfigSave = Config.path;
OnInitialMember();
return TRUE;
}
DLGCMD CFolderDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CFolderDlg::OnOK\n" );
Config.path.bRomPath = IsBTNCHECK( IDC_FLD_ROM_USE );
Config.path.bSavePath = IsBTNCHECK( IDC_FLD_SAVE_USE );
Config.path.bStatePath = IsBTNCHECK( IDC_FLD_STATE_USE );
Config.path.bSnapshotPath = IsBTNCHECK( IDC_FLD_SNAPSHOT_USE );
Config.path.bMoviePath = IsBTNCHECK( IDC_FLD_MOVIE_USE );
Config.path.bWavePath = IsBTNCHECK( IDC_FLD_WAVE_USE );
Config.path.bCheatPath = IsBTNCHECK( IDC_FLD_CHEAT_USE );
::GetDlgItemText( m_hWnd, IDC_FLD_ROM_EDIT, Config.path.szRomPath, _MAX_PATH );
::GetDlgItemText( m_hWnd, IDC_FLD_SAVE_EDIT, Config.path.szSavePath, _MAX_PATH );
::GetDlgItemText( m_hWnd, IDC_FLD_STATE_EDIT, Config.path.szStatePath, _MAX_PATH );
::GetDlgItemText( m_hWnd, IDC_FLD_SNAPSHOT_EDIT, Config.path.szSnapshotPath, _MAX_PATH );
::GetDlgItemText( m_hWnd, IDC_FLD_MOVIE_EDIT, Config.path.szMoviePath, _MAX_PATH );
::GetDlgItemText( m_hWnd, IDC_FLD_WAVE_EDIT, Config.path.szWavePath, _MAX_PATH );
::GetDlgItemText( m_hWnd, IDC_FLD_CHEAT_EDIT, Config.path.szCheatPath, _MAX_PATH );
PathCheck( Config.path.szRomPath );
PathCheck( Config.path.szSavePath );
PathCheck( Config.path.szStatePath );
PathCheck( Config.path.szSnapshotPath );
PathCheck( Config.path.szMoviePath );
PathCheck( Config.path.szWavePath );
PathCheck( Config.path.szCheatPath );
::EndDialog( m_hWnd, IDOK );
}
DLGCMD CFolderDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CFolderDlg::OnCancel\n" );
Config.path = m_ConfigSave;
::EndDialog( m_hWnd, IDCANCEL );
}
DLGCMD CFolderDlg::OnDefault( DLGCMDPARAM )
{
// DEBUGOUT( "CFolderDlg::OnDefault\n" );
Config.path.Default();
OnInitialMember();
}
DLGCMD CFolderDlg::OnRomBrowse( DLGCMDPARAM )
{
// DEBUGOUT( "CFolderDlg::OnRomBrowse\n" );
CHAR szTemp[_MAX_PATH];
::GetDlgItemText( m_hWnd, IDC_FLD_ROM_EDIT, szTemp, _MAX_PATH );
CHAR szFolder[_MAX_PATH];
string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp );
::lstrcpy( szFolder, pathstr.c_str() );
DEBUGOUT( "Path:%s\n", szFolder );
CHAR szTitle[256];
CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) );
if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) {
::SetDlgItemText( m_hWnd, IDC_FLD_ROM_EDIT, szFolder );
BTNCHECK( IDC_FLD_ROM_USE, TRUE );
}
}
DLGCMD CFolderDlg::OnSaveBrowse( DLGCMDPARAM )
{
// DEBUGOUT( "CFolderDlg::OnSaveBrowse\n" );
CHAR szTemp[_MAX_PATH];
::GetDlgItemText( m_hWnd, IDC_FLD_SAVE_EDIT, szTemp, _MAX_PATH );
CHAR szFolder[_MAX_PATH];
string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp );
::lstrcpy( szFolder, pathstr.c_str() );
DEBUGOUT( "Path:%s\n", szFolder );
CHAR szTitle[256];
CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) );
if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) {
::SetDlgItemText( m_hWnd, IDC_FLD_SAVE_EDIT, szFolder );
BTNCHECK( IDC_FLD_SAVE_USE, TRUE );
}
}
DLGCMD CFolderDlg::OnStateBrowse( DLGCMDPARAM )
{
// DEBUGOUT( "CFolderDlg::OnStateBrowse\n" );
CHAR szTemp[_MAX_PATH];
::GetDlgItemText( m_hWnd, IDC_FLD_STATE_EDIT, szTemp, _MAX_PATH );
CHAR szFolder[_MAX_PATH];
string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp );
::lstrcpy( szFolder, pathstr.c_str() );
DEBUGOUT( "Path:%s\n", szFolder );
CHAR szTitle[256];
CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) );
if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) {
::SetDlgItemText( m_hWnd, IDC_FLD_STATE_EDIT, szFolder );
BTNCHECK( IDC_FLD_STATE_USE, TRUE );
}
}
DLGCMD CFolderDlg::OnSnapshotBrowse( DLGCMDPARAM )
{
// DEBUGOUT( "CFolderDlg::OnSnapshotBrowse\n" );
CHAR szTemp[_MAX_PATH];
::GetDlgItemText( m_hWnd, IDC_FLD_SNAPSHOT_EDIT, szTemp, _MAX_PATH );
CHAR szFolder[_MAX_PATH];
string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp );
::lstrcpy( szFolder, pathstr.c_str() );
DEBUGOUT( "Path:%s\n", szFolder );
CHAR szTitle[256];
CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) );
if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) {
::SetDlgItemText( m_hWnd, IDC_FLD_SNAPSHOT_EDIT, szFolder );
BTNCHECK( IDC_FLD_SNAPSHOT_USE, TRUE );
}
}
DLGCMD CFolderDlg::OnMovieBrowse( DLGCMDPARAM )
{
// DEBUGOUT( "CFolderDlg::OnMovieBrowse\n" );
CHAR szTemp[_MAX_PATH];
::GetDlgItemText( m_hWnd, IDC_FLD_MOVIE_EDIT, szTemp, _MAX_PATH );
CHAR szFolder[_MAX_PATH];
string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp );
::lstrcpy( szFolder, pathstr.c_str() );
DEBUGOUT( "Path:%s\n", szFolder );
CHAR szTitle[256];
CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) );
if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) {
::SetDlgItemText( m_hWnd, IDC_FLD_MOVIE_EDIT, szFolder );
BTNCHECK( IDC_FLD_MOVIE_USE, TRUE );
}
}
DLGCMD CFolderDlg::OnWaveBrowse( DLGCMDPARAM )
{
// DEBUGOUT( "CFolderDlg::OnWaveBrowse\n" );
CHAR szTemp[_MAX_PATH];
::GetDlgItemText( m_hWnd, IDC_FLD_WAVE_EDIT, szTemp, _MAX_PATH );
CHAR szFolder[_MAX_PATH];
string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp );
::lstrcpy( szFolder, pathstr.c_str() );
DEBUGOUT( "Path:%s\n", szFolder );
CHAR szTitle[256];
CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) );
if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) {
::SetDlgItemText( m_hWnd, IDC_FLD_WAVE_EDIT, szFolder );
BTNCHECK( IDC_FLD_WAVE_USE, TRUE );
}
}
DLGCMD CFolderDlg::OnCheatBrowse( DLGCMDPARAM )
{
// DEBUGOUT( "CFolderDlg::OnCheatBrowse\n" );
CHAR szTemp[_MAX_PATH];
::GetDlgItemText( m_hWnd, IDC_FLD_CHEAT_EDIT, szTemp, _MAX_PATH );
CHAR szFolder[_MAX_PATH];
string pathstr = CPathlib::CreatePath( CApp::GetModulePath(), szTemp );
::lstrcpy( szFolder, pathstr.c_str() );
DEBUGOUT( "Path:%s\n", szFolder );
CHAR szTitle[256];
CApp::LoadString( IDS_UI_BROWSE, szTitle, sizeof(szTitle) );
if( CPathlib::SelectFolder( m_hWnd, szTitle, szFolder ) ) {
::SetDlgItemText( m_hWnd, IDC_FLD_CHEAT_EDIT, szFolder );
BTNCHECK( IDC_FLD_CHEAT_USE, TRUE );
}
}

View File

@ -0,0 +1,48 @@
//
// フォルダダイアログクラス
//
#ifndef __CFOLDERDLG_INCLUDED__
#define __CFOLDERDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
#include "Config.h"
class CFolderDlg : public CWnd
{
public:
CFolderDlg();
~CFolderDlg();
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
void OnInitialMember();
void PathCheck( LPSTR szPath );
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnDefault( DLGCMDPARAM );
DLGCMD OnRomBrowse( DLGCMDPARAM );
DLGCMD OnSaveBrowse( DLGCMDPARAM );
DLGCMD OnStateBrowse( DLGCMDPARAM );
DLGCMD OnSnapshotBrowse( DLGCMDPARAM );
DLGCMD OnMovieBrowse( DLGCMDPARAM );
DLGCMD OnWaveBrowse( DLGCMDPARAM );
DLGCMD OnCheatBrowse( DLGCMDPARAM );
//
CCfgPath m_ConfigSave;
private:
HFONT m_hFont;
};
#endif // !__CFOLDERDLG_INCLUDED__

View File

@ -0,0 +1,136 @@
//
// ゲームオプションダイアログクラス
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "EmuThread.h"
#include "Wnd.h"
#include "GameOptionDlg.h"
DLG_MESSAGE_BEGIN(CGameOptionDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDDEFAULT, OnDefault )
DLG_ON_COMMAND( IDC_OPT_NOTSAVE, OnNotSave )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CGameOptionDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_GAMEOPTION),
hWndParent, g_DlgProc, (LPARAM)this );
}
void CGameOptionDlg::OnInitialMember()
{
::SendDlgItemMessage( m_hWnd, IDC_OPT_RENDER_COMBO, CB_RESETCONTENT, 0, 0 );
::SendDlgItemMessage( m_hWnd, IDC_OPT_IRQTYPE_COMBO, CB_RESETCONTENT, 0, 0 );
::SendDlgItemMessage( m_hWnd, IDC_OPT_VIDEOMODE_COMBO, CB_RESETCONTENT, 0, 0 );
INT i, j;
CHAR szStr[256];
for( i = IDS_OPT_RENDER_POST_ALL, j = 0; i <= IDS_OPT_RENDER_TILE; i++, j++ ) {
CApp::LoadString( i, szStr, sizeof(szStr) );
::SendDlgItemMessage( m_hWnd, IDC_OPT_RENDER_COMBO, CB_INSERTSTRING, (WPARAM)j, (LPARAM)szStr );
}
for( i = IDS_OPT_IRQ_HSYNC, j = 0; i <= IDS_OPT_IRQ_CLOCK; i++, j++ ) {
CApp::LoadString( i, szStr, sizeof(szStr) );
::SendDlgItemMessage( m_hWnd, IDC_OPT_IRQTYPE_COMBO, CB_INSERTSTRING, (WPARAM)j, (LPARAM)szStr );
}
for( i = IDS_OPT_VIDEOMODE_NTSC, j = 0; i <= IDS_OPT_VIDEOMODE_PALCHINA; i++, j++ ) {
CApp::LoadString( i, szStr, sizeof(szStr) );
::SendDlgItemMessage( m_hWnd, IDC_OPT_VIDEOMODE_COMBO, CB_INSERTSTRING, (WPARAM)j, (LPARAM)szStr );
}
::SendDlgItemMessage( m_hWnd, IDC_OPT_RENDER_COMBO, CB_SETCURSEL, (WPARAM)GameOption.nRenderMethod, 0 );
::SendDlgItemMessage( m_hWnd, IDC_OPT_IRQTYPE_COMBO, CB_SETCURSEL, (WPARAM)GameOption.nIRQtype, 0 );
::SendDlgItemMessage( m_hWnd, IDC_OPT_VIDEOMODE_COMBO, CB_SETCURSEL, (WPARAM)(GameOption.bVideoMode?1:0), 0 );
BTNCHECK( IDC_OPT_FRAMEIRQ, !GameOption.bFrameIRQ );
}
DLGMSG CGameOptionDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CGameOptionDlg::OnInitDialog\n" );
OnInitialMember();
return TRUE;
}
DLGCMD CGameOptionDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CGameOptionDlg::OnOK\n" );
GameOption.nRenderMethod = ::SendDlgItemMessage( m_hWnd, IDC_OPT_RENDER_COMBO, CB_GETCURSEL, 0, 0 );
GameOption.nIRQtype = ::SendDlgItemMessage( m_hWnd, IDC_OPT_IRQTYPE_COMBO, CB_GETCURSEL, 0, 0 );
GameOption.bVideoMode = ::SendDlgItemMessage( m_hWnd, IDC_OPT_VIDEOMODE_COMBO, CB_GETCURSEL, 0, 0 );
GameOption.bFrameIRQ = !IsBTNCHECK( IDC_OPT_FRAMEIRQ );
// 設定しる
Emu.GetNES()->SetRenderMethod( (NES::RENDERMETHOD)GameOption.nRenderMethod );
Emu.GetNES()->SetIrqType ( GameOption.nIRQtype );
Emu.GetNES()->SetFrameIRQmode( GameOption.bFrameIRQ );
Emu.GetNES()->SetVideoMode ( GameOption.bVideoMode );
// セーブ
if( Emu.GetNES()->rom->GetMapperNo() == 20 ) {
GameOption.Save( Emu.GetNES()->rom->GetRomName(), Emu.GetNES()->rom->GetGameID(), Emu.GetNES()->rom->GetMakerID() );
} else if( Emu.GetNES()->rom->GetMapperNo() < 256 ) {
GameOption.Save( Emu.GetNES()->rom->GetRomName(), Emu.GetNES()->rom->GetPROM_CRC() );
}
//
::EndDialog( m_hWnd, IDOK );
}
DLGCMD CGameOptionDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CGameOptionDlg::OnCancel\n" );
::EndDialog( m_hWnd, IDCANCEL );
}
DLGCMD CGameOptionDlg::OnDefault( DLGCMDPARAM )
{
// DEBUGOUT( "CGameOptionDlg::OnCancel\n" );
GameOption.nRenderMethod = GameOption.defRenderMethod;
GameOption.nIRQtype = GameOption.defIRQtype;
GameOption.bFrameIRQ = GameOption.defFrameIRQ;
GameOption.bVideoMode = GameOption.defVideoMode;
OnInitialMember();
}
DLGCMD CGameOptionDlg::OnNotSave( DLGCMDPARAM )
{
// DEBUGOUT( "CGameOptionDlg::OnNotSave\n" );
GameOption.nRenderMethod = ::SendDlgItemMessage( m_hWnd, IDC_OPT_RENDER_COMBO, CB_GETCURSEL, 0, 0 );
GameOption.nIRQtype = ::SendDlgItemMessage( m_hWnd, IDC_OPT_IRQTYPE_COMBO, CB_GETCURSEL, 0, 0 );
GameOption.bVideoMode = ::SendDlgItemMessage( m_hWnd, IDC_OPT_VIDEOMODE_COMBO, CB_GETCURSEL, 0, 0 );
GameOption.bFrameIRQ = !IsBTNCHECK( IDC_OPT_FRAMEIRQ );
// 設定しる
Emu.GetNES()->SetRenderMethod( (NES::RENDERMETHOD)GameOption.nRenderMethod );
Emu.GetNES()->SetIrqType ( GameOption.nIRQtype );
Emu.GetNES()->SetFrameIRQmode( GameOption.bFrameIRQ );
Emu.GetNES()->SetVideoMode ( GameOption.bVideoMode );
::EndDialog( m_hWnd, IDOK );
}

View File

@ -0,0 +1,36 @@
//
// ゲームオプションダイアログクラス
//
#ifndef __CGAMEOPTIONDLG_INCLUDED__
#define __CGAMEOPTIONDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
#include "Config.h"
class CGameOptionDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
void OnInitialMember();
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnDefault( DLGCMDPARAM );
DLGCMD OnNotSave( DLGCMDPARAM );
//
private:
};
#endif // !__CGAMEOPTIONDLG_INCLUDED__

View File

@ -0,0 +1,261 @@
//
// グラフィックスダイアログクラス
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commdlg.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Wnd.h"
#include "GraphicsDlg.h"
#include "DirectDraw.h"
DLG_MESSAGE_BEGIN(CGraphicsDlg)
// メッセージ
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_ON_MESSAGE( WM_HSCROLL, OnHScroll )
// NOTIFYメッセージ
DLG_NOTIFY_BEGIN()
DLG_NOTIFY_END()
// コマンド
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDDEFAULT, OnDefault )
DLG_ON_COMMAND( IDC_GRA_PALETTE_BROWSE, OnPaletteBrowse )
DLG_ON_COMMAND_NOTIFY( IDC_GRA_PALETTE_USE, BN_CLICKED, OnPaletteUseClick )
DLG_ON_COMMAND_NOTIFY( IDC_GRA_NOSQUARELIST, BN_CLICKED, OnNoSquareListClick )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CGraphicsDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_GRAPHICS),
hWndParent, g_DlgProc, (LPARAM)this );
}
void CGraphicsDlg::OnInitialMember()
{
BTNCHECK( IDC_GRA_ASPECT, Config.graphics.bAspect );
BTNCHECK( IDC_GRA_ALLSPRITE, Config.graphics.bAllSprite );
BTNCHECK( IDC_GRA_ALLLINE, Config.graphics.bAllLine );
BTNCHECK( IDC_GRA_FPS, Config.graphics.bFPSDisp );
BTNCHECK( IDC_GRA_TVFRAME, Config.graphics.bTVFrame );
BTNCHECK( IDC_GRA_SCANLINE, Config.graphics.bScanline );
BTNCHECK( IDC_GRA_SYNCDRAW, Config.graphics.bSyncDraw );
BTNCHECK( IDC_GRA_FITZOOM, Config.graphics.bFitZoom );
BTNCHECK( IDC_GRA_LEFTCLIP, Config.graphics.bLeftClip );
BTNCHECK( IDC_GRA_DOUBLESIZE, Config.graphics.bDoubleSize );
BTNCHECK( IDC_GRA_SYSTEMMEMORY, Config.graphics.bSystemMemory );
BTNCHECK( IDC_GRA_USEHEL, Config.graphics.bUseHEL );
BTNCHECK( IDC_GRA_WAITVSYNC, Config.graphics.bWindowVSync );
BTNCHECK( IDC_GRA_DISKACCESSLAMP, Config.graphics.bDiskAccessLamp );
BTNCHECK( IDC_GRA_NOSQUARELIST, Config.graphics.bNoSquareList );
BTNCHECK( IDC_GRA_SYNCNOSLEEP, !Config.graphics.bSyncNoSleep );
// スライダ
::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_SETRANGE, TRUE, MAKELONG(0,100) );
::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_SETPOS, TRUE, (WPARAM)Config.graphics.nScanlineColor );
::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_SETLINESIZE, 0, 1 );
::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_SETPAGESIZE, 0, 10 );
// スキャンラインカラー値
CHAR str[64];
::wsprintf( str, "%d%%", Config.graphics.nScanlineColor );
::SetDlgItemText( m_hWnd, IDC_GRA_SCANLINE_COLOR, str );
// パレット
BTNCHECK( IDC_GRA_PALETTE_USE, Config.graphics.bPaletteFile );
::SetDlgItemText( m_hWnd, IDC_GRA_PALETTE_EDIT, Config.graphics.szPaletteFile );
// 解像度コンボボックス
OnUpdateComboBox();
}
void CGraphicsDlg::OnUpdateComboBox()
{
// 解像度コンボボックス
::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_RESETCONTENT, 0, 0 );
INT i, listno, select = 0;
CHAR szMode[64];
for( i = 0, listno = 0; i < DirectDraw.GetDisplayModeNum(); i++ ) {
DWORD dwWidth, dwHeight, dwDepth, dwRate;
DirectDraw.GetDisplayMode( i, dwWidth, dwHeight, dwDepth, dwRate );
if( !Config.graphics.bNoSquareList && dwWidth*3 != dwHeight*4 )
continue;
if( Config.graphics.dwDisplayWidth == dwWidth
&& Config.graphics.dwDisplayHeight == dwHeight
&& Config.graphics.dwDisplayDepth == dwDepth
&& Config.graphics.dwDisplayRate == dwRate ) {
select = listno;
}
::wsprintf( szMode, "%4dx%4d %dbit %dHz", dwWidth, dwHeight, dwDepth, dwRate );
::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_INSERTSTRING, (WPARAM)listno, (LPARAM)szMode );
::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_SETITEMDATA, (WPARAM)listno, (LPARAM)i );
listno++;
}
::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_SETCURSEL, (WPARAM)select, 0 );
}
DLGMSG CGraphicsDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CGraphicsDlg::OnInitDialog\n" );
m_ConfigSave = Config.graphics;
OnInitialMember();
return TRUE;
}
DLGMSG CGraphicsDlg::OnHScroll( DLGMSGPARAM )
{
// DEBUGOUT( "CGraphicsDlg::OnHScroll\n" );
INT pos;
CHAR str[16];
::wsprintf( str, "%d%%", pos = ::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_GETPOS, 0, 0 ) );
::SetDlgItemText( m_hWnd, IDC_GRA_SCANLINE_COLOR, str );
// スキャンラインカラーの変更
DirectDraw.SetScanlineColor( pos );
// パレットテーブルの計算
DirectDraw.CalcPaletteTable();
// 色が変わったのでペイントしてな
::PostMessage( CApp::GetHWnd(), WM_PAINT, 0, 0 );
return FALSE;
}
DLGCMD CGraphicsDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CGraphicsDlg::OnOK\n" );
Config.graphics.bAspect = IsBTNCHECK( IDC_GRA_ASPECT );
Config.graphics.bAllSprite = IsBTNCHECK( IDC_GRA_ALLSPRITE );
Config.graphics.bAllLine = IsBTNCHECK( IDC_GRA_ALLLINE );
Config.graphics.bFPSDisp = IsBTNCHECK( IDC_GRA_FPS );
Config.graphics.bTVFrame = IsBTNCHECK( IDC_GRA_TVFRAME );
Config.graphics.bScanline = IsBTNCHECK( IDC_GRA_SCANLINE );
Config.graphics.bSyncDraw = IsBTNCHECK( IDC_GRA_SYNCDRAW );
Config.graphics.bFitZoom = IsBTNCHECK( IDC_GRA_FITZOOM );
Config.graphics.bLeftClip = IsBTNCHECK( IDC_GRA_LEFTCLIP );
Config.graphics.bDoubleSize = IsBTNCHECK( IDC_GRA_DOUBLESIZE );
Config.graphics.bSystemMemory = IsBTNCHECK( IDC_GRA_SYSTEMMEMORY );
Config.graphics.bUseHEL = IsBTNCHECK( IDC_GRA_USEHEL );
Config.graphics.bWindowVSync = IsBTNCHECK( IDC_GRA_WAITVSYNC );
Config.graphics.bDiskAccessLamp = IsBTNCHECK( IDC_GRA_DISKACCESSLAMP );
Config.graphics.bNoSquareList = IsBTNCHECK( IDC_GRA_NOSQUARELIST );
Config.graphics.bSyncNoSleep = !IsBTNCHECK( IDC_GRA_SYNCNOSLEEP );
Config.graphics.nScanlineColor = ::SendDlgItemMessage( m_hWnd, IDC_GRA_SCANLINE_SLIDER, TBM_GETPOS, 0, 0 );
INT sel = ::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_GETCURSEL, 0, 0 );
INT no = ::SendDlgItemMessage( m_hWnd, IDC_GRA_RESOLUTION_COMBO, CB_GETITEMDATA, (WPARAM)sel, 0 );
DirectDraw.GetDisplayMode( no, Config.graphics.dwDisplayWidth,
Config.graphics.dwDisplayHeight,
Config.graphics.dwDisplayDepth,
Config.graphics.dwDisplayRate );
Config.graphics.bPaletteFile = IsBTNCHECK( IDC_GRA_PALETTE_USE );
::GetDlgItemText( m_hWnd, IDC_GRA_PALETTE_EDIT, Config.graphics.szPaletteFile, _MAX_PATH );
::EndDialog( m_hWnd, IDOK );
}
DLGCMD CGraphicsDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CGraphicsDlg::OnCancel\n" );
Config.graphics = m_ConfigSave;
::EndDialog( m_hWnd, IDCANCEL );
}
DLGCMD CGraphicsDlg::OnDefault( DLGCMDPARAM )
{
// DEBUGOUT( "CGraphicsDlg::OnDefault\n" );
Config.graphics.Default();
OnInitialMember();
}
DLGCMD CGraphicsDlg::OnPaletteBrowse( DLGCMDPARAM )
{
// DEBUGOUT( "CGraphicsDlg::OnPaletteBrowse\n" );
CHAR szTemp[ _MAX_PATH ];
::GetDlgItemText( m_hWnd, IDC_GRA_PALETTE_EDIT, szTemp, _MAX_PATH );
CHAR szPath[ _MAX_PATH ];
CHAR szFile[ _MAX_PATH ];
string temp;
temp = CPathlib::SplitPath( szTemp );
::strcpy( szPath, temp.c_str() );
temp = CPathlib::SplitFnameExt( szTemp );
::strcpy( szFile, temp.c_str() );
OPENFILENAME ofn;
ZeroMemory( &ofn, sizeof(ofn) );
if( strlen( szPath ) > 0 ) {
// 設定済みならばパス/ファイルネームの設定
ofn.lpstrInitialDir = szPath;
} else {
// 未設定ならば実行ファイルと同じパスの設定
ofn.lpstrInitialDir = CApp::GetModulePath();
szFile[0] = '\0';
}
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = m_hWnd;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
CHAR szTitle[256];
CApp::LoadString( IDS_UI_OPENPALETTE, szTitle, sizeof(szTitle) );
ofn.lpstrTitle = szTitle;
ofn.lpstrFilter = "Palette File(*.PAL)\0*.PAL\0All File(*.*)\0*.*\0";
ofn.nFilterIndex = 1;
ofn.Flags = OFN_READONLY|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_PATHMUSTEXIST;
if( ::GetOpenFileName( &ofn ) ) {
BTNCHECK( IDC_GRA_PALETTE_USE, TRUE );
::SetDlgItemText( m_hWnd, IDC_GRA_PALETTE_EDIT, szFile );
DirectDraw.SetPaletteFile( szFile );
}
}
DLGCMD CGraphicsDlg::OnPaletteUseClick( DLGCMDPARAM )
{
if( IsBTNCHECK(IDC_GRA_PALETTE_USE) ) {
CHAR szTemp[ _MAX_PATH ];
::GetDlgItemText( m_hWnd, IDC_GRA_PALETTE_EDIT, szTemp, _MAX_PATH );
DirectDraw.SetPaletteFile( szTemp );
} else {
DirectDraw.SetPaletteTable( (LPBYTE)NULL );
}
::PostMessage( CApp::GetHWnd(), WM_PAINT, 0, 0 );
}
DLGCMD CGraphicsDlg::OnNoSquareListClick( DLGCMDPARAM )
{
Config.graphics.bNoSquareList = IsBTNCHECK( IDC_GRA_NOSQUARELIST );
// 解像度コンボボックスの更新
OnUpdateComboBox();
}

View File

@ -0,0 +1,42 @@
//
// グラフィックスダイアログクラス
//
#ifndef __CGRAPHICSDLG_INCLUDED__
#define __CGRAPHICSDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
#include "Config.h"
class CGraphicsDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
void OnInitialMember();
void OnUpdateComboBox();
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGMSG OnHScroll( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnDefault( DLGCMDPARAM );
DLGCMD OnPaletteBrowse( DLGCMDPARAM );
DLGCMD OnPaletteUseClick( DLGCMDPARAM );
DLGCMD OnNoSquareListClick( DLGCMDPARAM );
//
CCfgGraphics m_ConfigSave;
private:
};
#endif // !__CGRAPHICSDLG_INCLUDED__

View File

@ -0,0 +1,141 @@
//
// ジョイスティック軸設定ダイアログクラス
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Wnd.h"
#include "JoyAxisDlg.h"
#include "DirectInput.h"
DLG_MESSAGE_BEGIN(CJoyAxisDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_ON_MESSAGE( WM_TIMER, OnTimer )
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDDEFAULT, OnDefault )
DLG_ON_COMMAND_NOTIFY( IDC_AST_ID_COMBO, CBN_SELCHANGE, OnSelectChange )
DLG_ON_COMMAND_NOTIFY_RANGE( IDC_AST_XAXIS, IDC_AST_RZAXIS, BN_CLICKED, OnCheckChange )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CJoyAxisDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_AXISSETTING),
hWndParent, g_DlgProc, (LPARAM)this );
}
void CJoyAxisDlg::OnJoySettingSetup( INT nID )
{
BTNCHECK( IDC_AST_XAXIS, m_JoyAxisSetting[nID]&(1<<0) );
BTNCHECK( IDC_AST_YAXIS, m_JoyAxisSetting[nID]&(1<<1) );
BTNCHECK( IDC_AST_ZAXIS, m_JoyAxisSetting[nID]&(1<<2) );
BTNCHECK( IDC_AST_RXAXIS, m_JoyAxisSetting[nID]&(1<<3) );
BTNCHECK( IDC_AST_RYAXIS, m_JoyAxisSetting[nID]&(1<<4) );
BTNCHECK( IDC_AST_RZAXIS, m_JoyAxisSetting[nID]&(1<<5) );
}
DLGMSG CJoyAxisDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CJoyAxisDlg::OnInitDialog\n" );
m_JoySel = 0;
::memcpy( m_JoyAxisSetting, Config.general.JoyAxisSetting, 16*sizeof(WORD) );
OnJoySettingSetup( m_JoySel );
for( INT i = IDC_AST_XAXIS_PROGRESS; i <= IDC_AST_RZAXIS_PROGRESS; i++ ) {
::SendDlgItemMessage( m_hWnd, i, PBM_SETRANGE32, (WPARAM)-10000, (LPARAM)10000 );
::SendDlgItemMessage( m_hWnd, i, PBM_SETSTEP, (WPARAM)1, 0 );
}
// IDコンボボックス
::SendDlgItemMessage( m_hWnd, IDC_AST_ID_COMBO, CB_RESETCONTENT, 0, 0 );
CHAR szStr[MAX_PATH+16];
for( i = 0; i < DirectInput.m_nJoystickNum; i++ ) {
::wsprintf( szStr, " %d : %s", i, DirectInput.m_JoyName[i].c_str() );
::SendDlgItemMessage( m_hWnd, IDC_AST_ID_COMBO, CB_INSERTSTRING, (WPARAM)i, (LPARAM)szStr );
}
::SendDlgItemMessage( m_hWnd, IDC_AST_ID_COMBO, CB_SETCURSEL, 0, 0 );
m_TimerID = ::SetTimer( m_hWnd, 1, 50, NULL );
return TRUE;
}
DLGMSG CJoyAxisDlg::OnTimer( DLGMSGPARAM )
{
// DEBUGOUT( "CJoyAxisDlg::OnTimer\n" );
DirectInput.Poll();
INT i, j;
for( i = IDC_AST_XAXIS_PROGRESS, j = 0; i <= IDC_AST_RZAXIS_PROGRESS; i++, j++ ) {
::SendDlgItemMessage( m_hWnd, i, PBM_SETPOS, (WPARAM)DirectInput.m_JoyAxis[ m_JoySel ][ j ], 0 );
}
return TRUE;
}
DLGCMD CJoyAxisDlg::OnCheckChange( DLGCMDPARAM )
{
// DEBUGOUT( "CJoyAxisDlg::OnCheckChange\n" );
WORD bits = 0;
bits |= IsBTNCHECK( IDC_AST_XAXIS )?(1<<0):0;
bits |= IsBTNCHECK( IDC_AST_YAXIS )?(1<<1):0;
bits |= IsBTNCHECK( IDC_AST_ZAXIS )?(1<<2):0;
bits |= IsBTNCHECK( IDC_AST_RXAXIS )?(1<<3):0;
bits |= IsBTNCHECK( IDC_AST_RYAXIS )?(1<<4):0;
bits |= IsBTNCHECK( IDC_AST_RZAXIS )?(1<<5):0;
m_JoyAxisSetting[ m_JoySel ] = bits;
}
DLGNOTIFY CJoyAxisDlg::OnSelectChange( DLGCMDPARAM )
{
m_JoySel = ::SendDlgItemMessage( m_hWnd, IDC_AST_ID_COMBO, CB_GETCURSEL, 0, 0 );
OnJoySettingSetup( m_JoySel );
}
DLGCMD CJoyAxisDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CJoyAxisDlg::OnOK\n" );
::memcpy( Config.general.JoyAxisSetting, m_JoyAxisSetting, 16*sizeof(WORD) );
::KillTimer( m_hWnd, m_TimerID );
::EndDialog( m_hWnd, IDOK );
}
DLGCMD CJoyAxisDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CJoyAxisDlg::OnCancel\n" );
::KillTimer( m_hWnd, m_TimerID );
::EndDialog( m_hWnd, IDCANCEL );
}
DLGCMD CJoyAxisDlg::OnDefault( DLGCMDPARAM )
{
// DEBUGOUT( "CJoyAxisDlg::OnDefault\n" );
::memset( m_JoyAxisSetting, 0, 16*sizeof(WORD) );
OnJoySettingSetup( m_JoySel );
}

View File

@ -0,0 +1,44 @@
//
// ジョイスティック軸設定ダイアログクラス
//
#ifndef __CJOYAXISDLG_INCLUDED__
#define __CJOYAXISDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
#include "Config.h"
class CJoyAxisDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
void OnJoySettingSetup( INT nID );
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGMSG OnTimer( DLGMSGPARAM );
DLGNOTIFY OnCheckChange( DLGCMDPARAM );
DLGNOTIFY OnSelectChange( DLGCMDPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnDefault( DLGCMDPARAM );
//
INT m_JoySel;
INT m_TimerID;
WORD m_JoyAxisSetting[16];
private:
};
#endif // !__CJOYAXISDLG_INCLUDED__

View File

@ -0,0 +1,77 @@
//
// ランゲージダイアログクラス
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Plugin.h"
#include "Wnd.h"
#include "LanguageDlg.h"
DLG_MESSAGE_BEGIN(CLanguageDlg)
// メッセージ
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
// コマンド
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_ON_COMMAND( IDDEFAULT, OnDefault )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CLanguageDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_LANGUAGE),
hWndParent, g_DlgProc, (LPARAM)this );
}
DLGMSG CLanguageDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CLanguageDlg::OnInitDialog\n" );
m_nPluginID = CPlugin::GetPluginID();
for( INT i = 0; i < CPlugin::GetPluginNum(); i++ ) {
::SendDlgItemMessage( m_hWnd, IDC_LNG_LIST, LB_INSERTSTRING, (WPARAM)i, (LPARAM)CPlugin::GetPluginLanguage(i) );
}
// デフォルト選択
::SendDlgItemMessage( m_hWnd, IDC_LNG_LIST, LB_SETCURSEL, (WPARAM)m_nPluginID, 0 );
return TRUE;
}
DLGCMD CLanguageDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CLanguageDlg::OnOK\n" );
INT nID = ::SendDlgItemMessage( m_hWnd, IDC_LNG_LIST, LB_GETCURSEL, 0, 0 );
if( m_nPluginID != nID ) {
CPlugin::SetPluginID( nID );
::EndDialog( m_hWnd, IDOK );
} else {
::EndDialog( m_hWnd, IDCANCEL );
}
}
DLGCMD CLanguageDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CLanguageDlg::OnCancel\n" );
::EndDialog( m_hWnd, IDCANCEL );
}
DLGCMD CLanguageDlg::OnDefault( DLGCMDPARAM )
{
// DEBUGOUT( "CLanguageDlg::OnDefault\n" );
// デフォルト選択
SendDlgItemMessage( m_hWnd, IDC_LNG_LIST, LB_SETCURSEL, (WPARAM)CPlugin::GetPluginID(), 0 );
}

View File

@ -0,0 +1,33 @@
//
// ランゲージダイアログクラス
//
#ifndef __CLANGUAGEDLG_INCLUDED__
#define __CLANGUAGEDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
class CLanguageDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnDefault( DLGCMDPARAM );
//
INT m_nPluginID;
private:
};
#endif // !__CLANGUAGEDLG_INCLUDED__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,214 @@
//
// ランチャーダイアログクラス
//
#ifndef __CLAUNCHERDLG_INCLUDED__
#define __CLAUNCHERDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <list>
#include <vector>
#include <string>
using namespace std;
#include "Wnd.h"
class FILELIST
{
public:
string fname;
string path;
INT mapper;
INT prg_size;
INT chr_size;
DWORD crcall;
DWORD crc;
string info;
string db;
string title;
string country;
string manufacturer;
string saledate;
string price;
string genre;
};
class CLauncherDlg : public CWnd
{
public:
// Override from CWnd
BOOL Create( HWND hWndParent );
void Destroy();
// Table
static INT m_HeaderID[];
protected:
enum {
COLUMN_FILENAME = 0,
COLUMN_PATH,
COLUMN_MAPPER,
COLUMN_PRG,
COLUMN_CHR,
COLUMN_ALLCRC,
COLUMN_PRGCRC,
COLUMN_INFO,
COLUMN_DB,
COLUMN_TITLE,
COLUMN_COUNTRY,
COLUMN_MANUFACTURER,
COLUMN_SALEDATE,
COLUMN_PRICE,
COLUMN_GENRE,
};
static INT CALLBACK ListViewCompare( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort );
void ResetListViewHeader();
void ResetFileList();
void ResetListView();
void SetListView( INT index, FILELIST& fl );
void SortListView();
void SetLastSelect();
void OnUpdateStart();
void OnUpdateStop();
void UpdateListView();
void CheckFile( FILELIST& fl );
void OnUpdateMenu( HMENU hMenu, UINT uID );
BOOL LoadFileList();
void SaveFileList();
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGMSG OnDestroy( DLGMSGPARAM );
DLGMSG OnClose( DLGMSGPARAM );
DLGMSG OnActivate( DLGMSGPARAM );
DLGMSG OnSetCursor( DLGMSGPARAM );
DLGMSG OnSize( DLGMSGPARAM );
DLGMSG OnTimer( DLGMSGPARAM );
DLGMSG OnInitMenuPopup( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnListSelect( DLGCMDPARAM );
DLGCMD OnRefresh( DLGCMDPARAM );
DLGCMD OnDispEdit( DLGCMDPARAM );
DLGCMD OnFolder( DLGCMDPARAM );
DLGCMD OnHeaderEdit( DLGCMDPARAM );
DLGNOTIFY OnKeyDownListView( DLGNOTIFYPARAM );
DLGNOTIFY OnReturnListView( DLGNOTIFYPARAM );
DLGNOTIFY OnDoubleClickListView( DLGNOTIFYPARAM );
DLGNOTIFY OnColumnClickListView( DLGNOTIFYPARAM );
DLGNOTIFY OnItemChangedListView( DLGNOTIFYPARAM );
//
// Image List
HIMAGELIST m_hImageList;
HIMAGELIST m_hImageListHdr; // sort
//
BOOL m_bFileLoaded;
// ランチャーリスト番号
INT m_nListSelect;
INT m_nSortType;
INT m_SelectPos;
INT m_UpdatePos;
BOOL m_bUpdate;
volatile BOOL m_bUpdating;
INT m_nTimerID;
INT m_nUpdateIndex;
// Sort type
static BOOL m_bSortDir;
// File list
static INT m_FileListNum;
static vector<FILELIST> m_FileList;
// Path
static CHAR m_LaunchPath[_MAX_PATH];
private:
};
class CLchDispEditDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnAdd( DLGCMDPARAM );
DLGCMD OnDel( DLGCMDPARAM );
DLGCMD OnUp( DLGCMDPARAM );
DLGCMD OnDown( DLGCMDPARAM );
//
// Temp
INT m_nViewOrder[16];
INT m_nViewNum;
INT m_nHideOrder[16];
INT m_nHideNum;
private:
};
class CLchFolderConfigDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
DLGCMD OnAdd( DLGCMDPARAM );
DLGCMD OnDel( DLGCMDPARAM );
//
private:
};
class CLchHeaderEditDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
INT m_nMapperNo;
BOOL m_bMirror;
BOOL m_bSram;
BOOL m_bTrainer;
BOOL m_bFourScreen;
BOOL m_bVSUnisystem;
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
//
private:
};
#endif // !__CLAUNCHERDLG_INCLUDED__

View File

@ -0,0 +1,58 @@
//
// Multimedia timer support
//
#include "DebugOut.h"
#include "MMTimer.h"
// コンストラクタ/デストラクタの為のインスタンス
static CMMTimer MMTimer;
BOOL CMMTimer::m_bInitialize = FALSE;
BOOL CMMTimer::m_bHigh = FALSE;
SQWORD CMMTimer::m_hpFrequency = 0;
CMMTimer::CMMTimer()
{
// 1ms単位を保証する為だけに呼ぶ…なんちゅう仕様じゃ
if( !m_bInitialize ) {
if( ::timeBeginPeriod( 1 ) == TIMERR_NOERROR )
m_bInitialize = TRUE;
}
// ハイパフォーマンスカウンタでの時間計測用
if( ::QueryPerformanceFrequency( (LARGE_INTEGER*)&m_hpFrequency ) ) {
DEBUGOUT( "CMMTimer:Use high performance counter.(QueryPerformanceCounter)\n" );
m_bHigh = TRUE;
}
}
CMMTimer::~CMMTimer()
{
if( m_bInitialize ) {
::timeEndPeriod( 1 );
m_bInitialize = FALSE;
}
}
SQWORD CMMTimer::GetMMTimer()
{
if( m_bHigh ) {
SQWORD freq;
::QueryPerformanceCounter( (LARGE_INTEGER*)&freq );
return freq;
}
return (SQWORD)::timeGetTime();
}
FLOAT CMMTimer::CalcTimeDifference( SQWORD t0, SQWORD t1 )
{
if( m_bHigh ) {
return (FLOAT)(1000.0*(double)(t1-t0)/(double)m_hpFrequency);
}
return (FLOAT)(t1-t0)*1000.0f;
}

View File

@ -0,0 +1,32 @@
//
// Multimedia timer support
//
#ifndef __CMMTIMER_INCLUDED__
#define __CMMTIMER_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#include "typedef.h"
class CMMTimer
{
public:
CMMTimer();
~CMMTimer();
static SQWORD GetMMTimer();
static FLOAT CalcTimeDifference( SQWORD t0, SQWORD t1 );
protected:
private:
static BOOL m_bInitialize;
// 高分解能カウンタを利用出来るかどうかのフラグ
static BOOL m_bHigh;
// 高分解能カウンタ周波数
static SQWORD m_hpFrequency;
};
#endif // !__CMMTIMER_INCLUDED__

View File

@ -0,0 +1,23 @@
//
// 便利かも知れないマクロたち
//
#ifndef __MACRO_INCLUDED__
#define __MACRO_INCLUDED__
// 多重呼び出し対応マクロちゃん
#define DELETEPTR(x) if(x) { delete x; x = NULL; }
#define DELETEARR(x) if(x) { delete[] x; x = NULL; }
#define RELEASE(x) if(x) { x->Release(); x=NULL; }
#define FREE(x) if(x) { free(x); x=NULL; }
#define FCLOSE(x) if(x) { fclose(x); x=NULL; }
#define GDIDELETE(x) if(x) { ::DeleteObject(x); x=NULL; }
#define CLOSEHANDLE(x) if(x) { ::CloseHandle(x); x = NULL; }
// その他
#define ZEROMEMORY(p,s) ::memset( (p), 0, (s) )
// RECT構造体用
#define RCWIDTH(rc) ((rc).right-(rc).left)
#define RCHEIGHT(rc) ((rc).bottom-(rc).top)
#endif // !__MACRO_INCLUDED__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,208 @@
//
// メインウインドウクラス
//
#ifndef __CMAINFRAME_INCLUDED__
#define __CMAINFRAME_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
#include "EmuThread.h"
#include "LauncherDlg.h"
#include "CheatDlg.h"
#include "PatternView.h"
#include "NameTableView.h"
#include "PaletteView.h"
#include "MemoryView.h"
#include "DatachBarcodeDlg.h"
#include "ChatDlg.h"
#include "PaletteEdit.h"
#include "DipSwitchDlg.h"
class CMainFrame : public CWnd
{
public:
// Override from CWnd
BOOL Create( HWND hWndParent );
void Destroy();
// Override from CWnd
BOOL PreTranslateMessage( MSG* pMsg );
static void OnKeyControl();
protected:
void OnEmulationStart( LPCSTR szFile, BOOL bChecked );
void OnFullScreenGDI( BOOL bFlag );
void OnShowCursor( BOOL bFlag );
void OnChangeMenu( BOOL bFlag );
void OnSetWindowSize();
void OnRebuildMenu();
void OnUpdateMenu( HMENU hMenu, UINT uID );
static void _cdecl KeyThreadProc( LPVOID lpParam );
// Message map
WND_MESSAGE_MAP()
WNDMSG OnCreate( WNDMSGPARAM );
WNDMSG OnClose( WNDMSGPARAM );
WNDMSG OnDestroy( WNDMSGPARAM );
WNDMSG OnActivate( WNDMSGPARAM );
WNDMSG OnActivateApp( WNDMSGPARAM );
WNDMSG OnShortCutEnable( WNDMSGPARAM ); // Private message
WNDMSG OnEnable( WNDMSGPARAM );
WNDMSG OnEnterMenuLoop( WNDMSGPARAM );
WNDMSG OnExitMenuLoop( WNDMSGPARAM );
WNDMSG OnSetFocus( WNDMSGPARAM );
WNDMSG OnKillFocus( WNDMSGPARAM );
WNDMSG OnInitMenu( WNDMSGPARAM );
WNDMSG OnInitMenuPopup( WNDMSGPARAM );
WNDMSG OnGetMinMaxInfo( WNDMSGPARAM );
WNDMSG OnPaint( WNDMSGPARAM );
WNDMSG OnDisplayChange( WNDMSGPARAM );
WNDMSG OnPaletteChanged( WNDMSGPARAM );
WNDMSG OnQueryNewPalette( WNDMSGPARAM );
WNDMSG OnMenuChar( WNDMSGPARAM );
WNDMSG OnKeyDown( WNDMSGPARAM );
WNDMSG OnSize( WNDMSGPARAM );
WNDMSG OnSysCommand( WNDMSGPARAM );
WNDMSG OnExitSizeMove( WNDMSGPARAM );
WNDMSG OnSetCursor( WNDMSGPARAM );
WNDMSG OnTimer( WNDMSGPARAM );
WNDMSG OnCopyData( WNDMSGPARAM );
WNDMSG OnErrorMessage( WNDMSGPARAM ); // Private message
WNDMSG OnDropFiles( WNDMSGPARAM );
WNDMSG OnCommandLine( WNDMSGPARAM ); // Private message
WNDMSG OnLauncherCommand( WNDMSGPARAM ); // Private message
WNDMSG OnNetPlay( WNDMSGPARAM );
WNDMSG OnNetPlayClose( WNDMSGPARAM );
WNDMSG OnNetPlayError( WNDMSGPARAM );
WNDMSG OnNetPlayChatPopup( WNDMSGPARAM );
WNDCMD OnExit( WNDCMDPARAM );
WNDCMD OnHelp( WNDCMDPARAM );
WNDCMD OnAbout( WNDCMDPARAM );
WNDCMD OnFileOpen( WNDCMDPARAM );
WNDCMD OnFileClose( WNDCMDPARAM );
WNDCMD OnRecentOpen( WNDCMDPARAM );
WNDCMD OnRecentOpenPath( WNDCMDPARAM );
WNDCMD OnRomInfo( WNDCMDPARAM );
WNDCMD OnWaveRecord( WNDCMDPARAM );
WNDCMD OnLauncher( WNDCMDPARAM );
WNDCMD OnSearch( WNDCMDPARAM );
WNDCMD OnCheat( WNDCMDPARAM );
WNDCMD OnGenie( WNDCMDPARAM );
WNDCMD OnCheatCommand( WNDCMDPARAM );
WNDCMD OnDatachBacode( WNDCMDPARAM );
WNDCMD OnDipSwitch( WNDCMDPARAM );
WNDCMD OnNetPlayConnect( WNDCMDPARAM );
WNDCMD OnNetPlayDisconnect( WNDCMDPARAM );
WNDCMD OnNetPlayChat( WNDCMDPARAM );
WNDCMD OnEmulatorCfg( WNDCMDPARAM );
WNDCMD OnGraphicsCfg( WNDCMDPARAM );
WNDCMD OnSoundCfg( WNDCMDPARAM );
WNDCMD OnControllerCfg( WNDCMDPARAM );
WNDCMD OnShortcutCfg( WNDCMDPARAM );
WNDCMD OnFolderCfg( WNDCMDPARAM );
WNDCMD OnLanguageCfg( WNDCMDPARAM );
WNDCMD OnMovieCfg( WNDCMDPARAM );
WNDCMD OnGameOptionCfg( WNDCMDPARAM );
WNDCMD OnJoyAxisCfg( WNDCMDPARAM );
WNDCMD OnPaletteEditCfg( WNDCMDPARAM );
WNDCMD OnFullScreen( WNDCMDPARAM );
WNDCMD OnZoom( WNDCMDPARAM );
WNDCMD OnViewCommand( WNDCMDPARAM );
WNDCMD OnEmuCommand( WNDCMDPARAM );
WNDCMD OnStateCommand( WNDCMDPARAM );
WNDCMD OnStateCommand2( WNDCMDPARAM ); // For QuickLoad/Save
WNDCMD OnMovieCommand( WNDCMDPARAM );
WNDCMD OnMovieInfo( WNDCMDPARAM );
WNDCMD OnTapeCommand( WNDCMDPARAM );
// Command line
CHAR m_szCommandLine[_MAX_PATH];
// Window activate flags
BOOL m_bActivate;
BOOL m_bActivateApp;
BOOL m_bForcus;
BOOL m_bEnable;
static BOOL m_bKeyEnable;
// Cursor
BOOL m_bCursor;
UINT m_uTimerID;
DWORD m_LastMovedTime;
// Menu flags
BOOL m_bMenu;
// Window Position
BOOL m_bZoomed;
RECT m_WindowRect;
WINDOWPLACEMENT m_WindowPlacement;
// Window Style
LONG m_ExStyleBackup;
LONG m_StyleBackup;
// Short Cut
UINT m_uKeyTimerID;
volatile BOOL m_bKeyChecking;
static DWORD m_dwKeyTime;
static BYTE m_KeyBuf[256+64*8];
static BYTE m_KeyOld[256+64*8];
static BYTE m_KeyCnt[256*64*8];
static volatile BOOL m_bKeyThreadExit;
// Emulator
NES* Nes;
// CEmuThread Emu;
// State slot
INT m_nStateSlot;
// Launcher
CLauncherDlg m_LauncherDlg;
// Cheat
CSearchDlg m_SearchDlg;
// Viewer
CPatternView m_PatternView;
CNameTableView m_NameTableView;
CPaletteView m_PaletteView;
CMemoryView m_MemoryView;
// Palette Editor
CPaletteEdit m_PaletteEdit;
// Cheat
CDatachBarcodeDlg m_DatachBarcodeDlg;
// Chat
CChatDlg m_ChatDlg;
private:
};
#endif // !__CMAINFRAME_INCLUDED__

View File

@ -0,0 +1,589 @@
//
// メモリビュークラス
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <mbstring.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Wnd.h"
#include "MemoryView.h"
#include "EmuThread.h"
#include "MMU.h"
#include "DirectDraw.h"
#define OFFSETH 4
#define OFFSETV 4
#define FONTWIDTH 6
#define FONTHEIGHT 12
LOGFONT CMemoryView::m_logFont={ FONTHEIGHT, FONTWIDTH, 0, 0, 0, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_TT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, NULL };
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#endif
WND_MESSAGE_BEGIN(CMemoryView)
WND_ON_MESSAGE( WM_CREATE, OnCreate )
WND_ON_MESSAGE( WM_CLOSE, OnClose )
WND_ON_MESSAGE( WM_DESTROY, OnDestroy )
WND_ON_MESSAGE( WM_ACTIVATE, OnActivate )
WND_ON_MESSAGE( WM_SIZE, OnSize )
WND_ON_MESSAGE( WM_LBUTTONDOWN, OnLButtonDown )
WND_ON_MESSAGE( WM_MOUSEWHEEL, OnMouseWheel )
WND_ON_MESSAGE( WM_CHAR, OnChar )
WND_ON_MESSAGE( WM_KEYDOWN, OnKeyDown )
WND_ON_MESSAGE( WM_VSCROLL, OnVScroll )
WND_ON_MESSAGE( WM_PAINT, OnPaint )
WND_ON_MESSAGE( WM_TIMER, OnTimer )
WND_COMMAND_BEGIN()
WND_COMMAND_END()
WND_MESSAGE_END()
CMemoryView::CMemoryView()
{
m_hFont = NULL;
m_StartAddress = 0;
m_CursorX = m_CursorY = 0;
m_DispLines = 16;
}
CMemoryView::~CMemoryView()
{
}
BOOL CMemoryView::Create( HWND hWndParent )
{
m_logFont.lfCharSet = SHIFTJIS_CHARSET;
if( !(m_hFont = ::CreateFontIndirect( &m_logFont )) ) {
m_logFont.lfCharSet = ANSI_CHARSET;
if( !(m_hFont = ::CreateFontIndirect( &m_logFont )) ) {
return FALSE;
}
}
HWND hWnd = ::CreateWindowEx(
WS_EX_TOOLWINDOW,
VIRTUANES_WNDCLASS,
"MemoryView",
WS_OVERLAPPEDWINDOW|WS_VSCROLL, // Window拡大縮小可能
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
hWndParent,
NULL,
CApp::GetInstance(),
(LPVOID)this // This を埋め込む為
);
if( !hWnd ) {
DEBUGOUT( "CreateWindow faild.\n" );
return FALSE;
}
m_hWnd = hWnd;
return TRUE;
}
void CMemoryView::Destroy()
{
if( m_hWnd && IsWindow(m_hWnd) ) {
// 位置保存
::GetWindowRect( m_hWnd, &Config.general.rcMemoryViewPos );
::DestroyWindow( m_hWnd );
m_hWnd = NULL;
}
if( m_hFont ) {
::DeleteObject( m_hFont );
m_hFont = NULL;
}
}
WNDMSG CMemoryView::OnCreate( WNDMSGPARAM )
{
// DEBUGOUT( "CMemoryView::OnCreate\n" );
// ウインドウサイズの設定
if( RCWIDTH(Config.general.rcMemoryViewPos) > 0 && RCHEIGHT(Config.general.rcMemoryViewPos) > 0 ) {
::MoveWindow( m_hWnd, Config.general.rcMemoryViewPos.left, Config.general.rcMemoryViewPos.top,
RCWIDTH(Config.general.rcMemoryViewPos), RCHEIGHT(Config.general.rcMemoryViewPos), FALSE );
} else {
RECT rw, rc;
::GetWindowRect( m_hWnd, &rw );
::GetClientRect( m_hWnd, &rc );
INT x = rw.right - rw.left - rc.right + OFFSETH*2+FONTWIDTH*71;
INT y = rw.bottom - rw.top - rc.bottom + OFFSETV*2+FONTHEIGHT*18;
::MoveWindow( m_hWnd, 0, 0, x, y, FALSE );
}
RECT rc;
::GetClientRect( m_hWnd, &rc );
// スクロールレンジの設定
m_DispLines = (RCHEIGHT(rc)-(OFFSETV*2+FONTHEIGHT*2))/FONTHEIGHT;
if( m_DispLines < 0 )
m_DispLines = 0;
DEBUGOUT( "Display Lines:%d\n", m_DispLines );
DEBUGOUT( "Scroll Max :%d\n", (0xFFF-m_DispLines)<0?0:(0xFFF-m_DispLines) );
SCROLLINFO sif;
::ZeroMemory( &sif, sizeof(sif) );
sif.cbSize = sizeof(sif);
sif.fMask = SIF_ALL;
sif.nMin = 0;
sif.nMax = (0x1000-m_DispLines);
sif.nPos = 0;
sif.nPage = 1;
sif.nTrackPos = 1;
::SetScrollInfo( m_hWnd, SB_VERT, &sif, TRUE );
m_StartAddress = 0;
m_CursorX = m_CursorY = 0;
// 表示
::ShowWindow( m_hWnd, SW_SHOW );
// タイマー起動
::SetTimer( m_hWnd, 1, 50, NULL );
return TRUE;
}
WNDMSG CMemoryView::OnClose( WNDMSGPARAM )
{
// DEBUGOUT( "CMemoryView::OnClose\n" );
::KillTimer( m_hWnd, 1 );
::DestroyWindow( m_hWnd );
return TRUE;
}
WNDMSG CMemoryView::OnDestroy( WNDMSGPARAM )
{
// DEBUGOUT( "CMemoryView::OnDestroy\n" );
// 位置保存
::GetWindowRect( m_hWnd, &Config.general.rcMemoryViewPos );
m_hWnd = NULL;
return TRUE;
}
WNDMSG CMemoryView::OnActivate( WNDMSGPARAM )
{
if( LOWORD(wParam) == WA_INACTIVE ) {
// DEBUGOUT( "CMemoryView::OnActivate:Inactive\n" );
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 );
} else {
// DEBUGOUT( "CMemoryView::OnActivate:Active\n" );
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 );
}
return TRUE;
}
WNDMSG CMemoryView::OnSize( WNDMSGPARAM )
{
// DEBUGOUT( "CMemoryView::OnSize\n" );
m_DispLines = (HIWORD(lParam)-(OFFSETV*2+FONTHEIGHT*2))/FONTHEIGHT;
if( m_DispLines < 0 )
m_DispLines = 0;
// DEBUGOUT( "Display Lines:%d\n", m_DispLines );
SCROLLINFO sif;
::ZeroMemory( &sif, sizeof(sif) );
sif.cbSize = sizeof(sif);
sif.fMask = SIF_POS;
::GetScrollInfo( m_hWnd, SB_VERT, &sif );
sif.fMask = SIF_POS|SIF_RANGE;
sif.nMin = 0;
sif.nMax = (0x1000-m_DispLines)<0?0:(0x1000-m_DispLines);
if( sif.nMin > sif.nPos )
sif.nPos = sif.nMin;
if( sif.nMax < sif.nPos )
sif.nPos = sif.nMax;
::SetScrollInfo( m_hWnd, SB_VERT, &sif, TRUE );
m_StartAddress = sif.nPos * 0x10;
if( m_CursorY > m_DispLines-1 )
m_CursorY = m_DispLines-1;
if( m_CursorY < 0 )
m_CursorY = 0;
return TRUE;
}
WNDMSG CMemoryView::OnLButtonDown( WNDMSGPARAM )
{
// DEBUGOUT( "CMemoryView::OnLButtonDown\n" );
INT x = LOWORD(lParam);
INT y = HIWORD(lParam);
x -= OFFSETH+FONTWIDTH*6;
y -= OFFSETV+FONTHEIGHT*2;
if( x >= 0 && x < FONTWIDTH*(3*16)
&& y >= 0 && y < FONTHEIGHT*m_DispLines ) {
if( (x%(FONTWIDTH*3)) < FONTWIDTH*2 ) {
m_CursorX = (x / (FONTWIDTH*3))*2;
m_CursorY = y / FONTHEIGHT;
}
}
return TRUE;
}
WNDMSG CMemoryView::OnMouseWheel( WNDMSGPARAM )
{
// DEBUGOUT( "CMemoryView::OnMouseWheel\n" );
short zDelta = (short)HIWORD(wParam);
if( zDelta > 0 ) {
while( zDelta > 0 ) {
if( LOWORD(wParam) == MK_CONTROL )
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0L );
else
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0L );
zDelta -= 30;
}
return TRUE;
} else {
while( zDelta < 0 ) {
if( LOWORD(wParam) == MK_CONTROL )
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0L );
else
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0L );
zDelta += 30;
}
}
return TRUE;
}
WNDMSG CMemoryView::OnChar( WNDMSGPARAM )
{
// DEBUGOUT( "CMemoryView::OnChar\n" );
WORD wScrollNotify = 0xFFFF;
CHAR Keys = ::toupper((CHAR)wParam);
switch( Keys ) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if( m_DispLines ) {
INT addr = m_StartAddress+(m_CursorX/2)+m_CursorY*16;
BYTE data = CPU_MEM_BANK[addr>>13][addr&0x1FFF];
if( !(m_CursorX&1) ) {
data &= 0x0F;
data |= (Keys-'0')<<4;
} else {
data &= 0xF0;
data |= (Keys-'0');
}
CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data;
if( ++m_CursorX > 32-1 ) {
if( ++m_CursorY > m_DispLines-1 ) {
wScrollNotify = SB_LINEDOWN;
m_CursorY = m_DispLines-1;
}
if( (m_CursorX/2)+m_CursorY*16+m_StartAddress > 0xFFFF ) {
m_CursorX = 32-1;
} else {
m_CursorX = 0;
}
}
}
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
if( m_DispLines ) {
INT addr = m_StartAddress+(m_CursorX/2)+m_CursorY*16;
BYTE data = CPU_MEM_BANK[addr>>13][addr&0x1FFF];
if( !(m_CursorX&1) ) {
data &= 0x0F;
data |= (Keys-'A'+10)<<4;
} else {
data &= 0xF0;
data |= (Keys-'A'+10);
}
CPU_MEM_BANK[addr>>13][addr&0x1FFF] = data;
if( ++m_CursorX > 32-1 ) {
if( ++m_CursorY > m_DispLines-1 ) {
wScrollNotify = SB_LINEDOWN;
m_CursorY = m_DispLines-1;
}
if( (m_CursorX/2)+m_CursorY*16+m_StartAddress > 0xFFFF ) {
m_CursorX = 32-1;
} else {
m_CursorX = 0;
}
}
}
break;
default:
break;
}
if( wScrollNotify != 0xFFFF )
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(wScrollNotify, 0), 0L );
return TRUE;
}
WNDMSG CMemoryView::OnKeyDown( WNDMSGPARAM )
{
// DEBUGOUT( "CMemoryView::OnKeyDown\n" );
WORD wScrollNotify = 0xFFFF;
switch( wParam ) {
case VK_UP:
m_CursorX &= ~1;
if( --m_CursorY < 0 ) {
wScrollNotify = SB_LINEUP;
m_CursorY = 0;
}
break;
case VK_DOWN:
m_CursorX &= ~1;
if( ++m_CursorY > m_DispLines-1 ) {
wScrollNotify = SB_LINEDOWN;
m_CursorY = m_DispLines-1;
}
break;
case VK_LEFT:
if( m_CursorX & 1 ) {
m_CursorX &= ~1;
} else
if( (m_CursorX-=2) < 0 ) {
if( --m_CursorY < 0 ) {
wScrollNotify = SB_LINEUP;
m_CursorX = 0;
m_CursorY = 0;
} else {
m_CursorX = 32-1;
}
}
break;
case VK_RIGHT:
m_CursorX &= ~1;
if( (m_CursorX+=2) > 32-1 ) {
if( ++m_CursorY > m_DispLines-1 ) {
wScrollNotify = SB_LINEDOWN;
m_CursorY = m_DispLines-1;
}
if( (m_CursorX/2)+m_CursorY*16+m_StartAddress > 0xFFFF ) {
m_CursorX = 32-1;
} else {
m_CursorX = 0;
}
}
break;
case VK_PRIOR:
m_CursorX &= ~1;
if( (m_CursorY-16) < 0 ) {
wScrollNotify = SB_PAGEUP;
if( m_StartAddress <= 0 ) {
m_CursorY = 0;
}
} else {
m_CursorY-= 16;
}
break;
case VK_NEXT:
m_CursorX &= ~1;
if( (m_CursorY+16) > m_DispLines-1 ) {
wScrollNotify = SB_PAGEDOWN;
if( m_StartAddress+m_DispLines*16 >= 0xFFFF ) {
m_CursorY = m_DispLines-1;
}
} else {
m_CursorY += 16;
}
break;
case VK_HOME:
wScrollNotify = SB_TOP;
m_CursorY = 0;
break;
case VK_END:
wScrollNotify = SB_BOTTOM;
m_CursorY = m_DispLines-1;
break;
default:
break;
}
if( wScrollNotify != 0xFFFF )
::SendMessage( hWnd, WM_VSCROLL, MAKELONG(wScrollNotify, 0), 0L );
return TRUE;
}
WNDMSG CMemoryView::OnVScroll( WNDMSGPARAM )
{
// DEBUGOUT( "CMemoryView::OnVScroll\n" );
SCROLLINFO sif;
::ZeroMemory( &sif, sizeof(sif) );
sif.cbSize = sizeof(sif);
sif.fMask = SIF_POS|SIF_RANGE;
::GetScrollInfo( m_hWnd, SB_VERT, &sif );
switch( LOWORD(wParam) ) {
case SB_TOP:
sif.nPos = 0;
break;
case SB_BOTTOM:
sif.nPos = sif.nMax;
break;
case SB_PAGEUP:
sif.nPos -= 16;
break;
case SB_PAGEDOWN:
sif.nPos += 16;
break;
case SB_LINEUP:
sif.nPos--;
break;
case SB_LINEDOWN:
sif.nPos++;
break;
case SB_THUMBTRACK:
sif.nPos = HIWORD(wParam);
break;
default:
break;
}
if( sif.nMin > sif.nPos )
sif.nPos = sif.nMin;
if( sif.nMax < sif.nPos )
sif.nPos = sif.nMax;
sif.fMask = SIF_POS;
::SetScrollInfo( m_hWnd, SB_VERT, &sif, TRUE );
m_StartAddress = sif.nPos * 0x10;
return TRUE;
}
WNDMSG CMemoryView::OnPaint( WNDMSGPARAM )
{
// DEBUGOUT( "CMemoryView::OnPaint\n" );
PAINTSTRUCT ps;
HDC hDC = ::BeginPaint( hWnd, &ps );
RECT rc;
::GetClientRect( m_hWnd, &rc );
::FillRect( hDC, &rc, (HBRUSH)::GetStockObject(WHITE_BRUSH) );
OnDraw( hDC );
::EndPaint( hWnd, &ps );
return TRUE;
}
WNDMSG CMemoryView::OnTimer( WNDMSGPARAM )
{
if( !Emu.IsRunning() )
return TRUE;
HDC hDC = ::GetDC( m_hWnd );
OnDraw( hDC );
::ReleaseDC( m_hWnd, hDC );
return TRUE;
}
void CMemoryView::OnDraw( HDC hDC )
{
RECT rc;
::GetClientRect( m_hWnd, &rc );
HFONT hFontOld = (HFONT)::SelectObject( hDC, m_hFont );
::SetBkMode( hDC, OPAQUE );
::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT* 0, "ADDR +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF", 71 );
::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT* 1, "-----------------------------------------------------------------------", 71 );
CHAR szBuf[256];
INT address = m_StartAddress;
for( INT i = 0; i < m_DispLines; i++ ) {
::wsprintf( szBuf, "%04X ", address&0xFFFF );
for( INT d = 0; d < 16; d++ ) {
CHAR szTemp[16];
INT addr = address+d;
::wsprintf( szTemp, "%02X ", CPU_MEM_BANK[addr>>13][addr&0x1FFF] );
::strcat( szBuf, szTemp );
}
::strcat( szBuf, " " );
for( INT a = 0; a < 16; a++ ) {
CHAR szTemp[16];
INT addr = address+a;
if( m_logFont.lfCharSet == SHIFTJIS_CHARSET ) {
::wsprintf( szTemp, "%1c", ::_ismbcprint(CPU_MEM_BANK[addr>>13][addr&0x1FFF])?CPU_MEM_BANK[addr>>13][addr&0x1FFF]:'.' );
} else {
::wsprintf( szTemp, "%1c", ::isprint(CPU_MEM_BANK[addr>>13][addr&0x1FFF])?CPU_MEM_BANK[addr>>13][addr&0x1FFF]:'.' );
}
::strcat( szBuf, szTemp );
}
::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT*(2+i), szBuf, ::strlen(szBuf) );
address += 16;
address &= 0xFFFF;
}
::TextOut( hDC, OFFSETH, OFFSETV+FONTHEIGHT*(2+i), " ", 71 );
// Cursor
if( m_DispLines ) {
RECT rcInv;
rcInv.left = OFFSETH+FONTWIDTH*6+FONTWIDTH*3*(m_CursorX>>1)+FONTWIDTH*(m_CursorX&1)-1;
rcInv.top = OFFSETV+FONTHEIGHT*2+FONTHEIGHT*m_CursorY;
rcInv.right = rcInv.left+FONTWIDTH;
rcInv.bottom = rcInv.top+FONTHEIGHT;
::InvertRect( hDC, &rcInv );
rcInv.left = OFFSETH+FONTWIDTH*55+FONTWIDTH*(m_CursorX>>1)-1;
rcInv.top = OFFSETV+FONTHEIGHT*2+FONTHEIGHT*m_CursorY;
rcInv.right = rcInv.left+FONTWIDTH;
rcInv.bottom = rcInv.top+FONTHEIGHT;
::InvertRect( hDC, &rcInv );
}
// 元に戻して消す?
::SelectObject( hDC, hFontOld );
}

View File

@ -0,0 +1,55 @@
//
// ƒ<>ƒƒŠƒrƒ…<C692>[ƒNƒ‰ƒX
//
#ifndef __CMEMORYVIEW_INCLUDED__
#define __CMEMORYVIEW_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
class CMemoryView : public CWnd
{
public:
// Constructor/Destructor
CMemoryView();
~CMemoryView();
// Override from CWnd
BOOL Create( HWND hWndParent );
void Destroy();
protected:
// Message map
WND_MESSAGE_MAP()
WNDMSG OnCreate( WNDMSGPARAM );
WNDMSG OnClose( WNDMSGPARAM );
WNDMSG OnDestroy( WNDMSGPARAM );
WNDMSG OnActivate( WNDMSGPARAM );
WNDMSG OnSize( WNDMSGPARAM );
WNDMSG OnLButtonDown( WNDMSGPARAM );
WNDMSG OnMouseWheel( WNDMSGPARAM );
WNDMSG OnChar( WNDMSGPARAM );
WNDMSG OnKeyDown( WNDMSGPARAM );
WNDMSG OnVScroll( WNDMSGPARAM );
WNDMSG OnPaint( WNDMSGPARAM );
WNDMSG OnTimer( WNDMSGPARAM );
//
void OnDraw( HDC hDC );
static LOGFONT m_logFont;
HFONT m_hFont;
INT m_StartAddress;
INT m_DispLines;
INT m_CursorX, m_CursorY;
private:
};
#endif // !__CMEMORYVIEW_INCLUDED__

View File

@ -0,0 +1,77 @@
//
// バージョンダイアログクラス
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Wnd.h"
#include "MovieDlg.h"
DLG_MESSAGE_BEGIN(CMovieDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CMovieDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_MOVIE),
hWndParent, g_DlgProc, (LPARAM)this );
}
DLGMSG CMovieDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CAboutDlg::OnInitDialog\n" );
m_ConfigSave = Config.movie;
BTNCHECK( IDC_MVI_1P_USE, Config.movie.bUsePlayer[0]?TRUE:FALSE );
BTNCHECK( IDC_MVI_2P_USE, Config.movie.bUsePlayer[1]?TRUE:FALSE );
BTNCHECK( IDC_MVI_3P_USE, Config.movie.bUsePlayer[2]?TRUE:FALSE );
BTNCHECK( IDC_MVI_4P_USE, Config.movie.bUsePlayer[3]?TRUE:FALSE );
BTNCHECK( IDC_MVI_RESETRECORD, Config.movie.bResetRec );
BTNCHECK( IDC_MVI_RERECORD_DISABLE, !Config.movie.bRerecord );
BTNCHECK( IDC_MVI_LOOPPLAY, Config.movie.bLoopPlay );
BTNCHECK( IDC_MVI_PADDISPLAY, Config.movie.bPadDisplay );
return TRUE;
}
DLGCMD CMovieDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CMovieDlg::OnOK\n" );
Config.movie.bUsePlayer[0] = IsBTNCHECK(IDC_MVI_1P_USE)?0xFF:0x00;
Config.movie.bUsePlayer[1] = IsBTNCHECK(IDC_MVI_2P_USE)?0xFF:0x00;
Config.movie.bUsePlayer[2] = IsBTNCHECK(IDC_MVI_3P_USE)?0xFF:0x00;
Config.movie.bUsePlayer[3] = IsBTNCHECK(IDC_MVI_4P_USE)?0xFF:0x00;
Config.movie.bResetRec = IsBTNCHECK( IDC_MVI_RESETRECORD );
Config.movie.bRerecord = !IsBTNCHECK( IDC_MVI_RERECORD_DISABLE );
Config.movie.bLoopPlay = IsBTNCHECK( IDC_MVI_LOOPPLAY );
Config.movie.bPadDisplay = IsBTNCHECK( IDC_MVI_PADDISPLAY );
// 全部OFFの場合は1Pだけ記録可能にしておく
if( !Config.movie.bUsePlayer[0] && !Config.movie.bUsePlayer[1]
&& !Config.movie.bUsePlayer[2] && !Config.movie.bUsePlayer[3] ) {
Config.movie.bUsePlayer[0] = 0xFF;
}
::EndDialog( m_hWnd, IDOK );
}
DLGCMD CMovieDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CMovieDlg::OnCancel\n" );
Config.movie = m_ConfigSave;
::EndDialog( m_hWnd, IDCANCEL );
}

View File

@ -0,0 +1,34 @@
//
// ムービーダイアログクラス
//
#ifndef __CMOVIEDLG_INCLUDED__
#define __CMOVIEDLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
#include "Config.h"
class CMovieDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
//
CCfgMovie m_ConfigSave;
private:
};
#endif // !__CMOVIEDLG_INCLUDED__

View File

@ -0,0 +1,89 @@
//
// ムービー情報ダイアログクラス
//
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <string>
using namespace std;
#include "VirtuaNESres.h"
#include "DebugOut.h"
#include "App.h"
#include "Pathlib.h"
#include "Wnd.h"
#include "MovieInfoDlg.h"
DLG_MESSAGE_BEGIN(CMovieInfoDlg)
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
DLG_COMMAND_BEGIN()
DLG_ON_COMMAND( IDOK, OnOK )
DLG_ON_COMMAND( IDCANCEL, OnCancel )
DLG_COMMAND_END()
DLG_MESSAGE_END()
INT CMovieInfoDlg::DoModal( HWND hWndParent )
{
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_MOVIEINFO),
hWndParent, g_DlgProc, (LPARAM)this );
}
DLGMSG CMovieInfoDlg::OnInitDialog( DLGMSGPARAM )
{
// DEBUGOUT( "CMovieInfoDlg::OnInitDialog\n" );
CHAR szTemp[256];
::wsprintf( szTemp, "%01d.%01d%01d",
(m_wRecVersion&0xF00)>>8,
(m_wRecVersion&0x0F0)>>4,
(m_wRecVersion&0x00F) );
::SetDlgItemText( m_hWnd, IDC_MIF_RERECORDVERSION, szTemp );
::wsprintf( szTemp, "%04X", m_wVersion );
::SetDlgItemText( m_hWnd, IDC_MIF_VERSION, szTemp );
// フレーム数
::wsprintf( szTemp, "%d frames", m_dwFrames );
::SetDlgItemText( m_hWnd, IDC_MIF_FRAMES, szTemp );
// 時間
INT t, h, m, s;
t = (INT)m_dwFrames;
h = t / (60*60*60);
t -= h * (60*60*60);
m = t / (60*60);
t -= m * (60*60);
s = t / 60;
::wsprintf( szTemp, "%02d:%02d:%02d", h, m, s );
::SetDlgItemText( m_hWnd, IDC_MIF_TIMES, szTemp );
// 撮り直し回数
if( m_dwRerecordTimes == 0xFFFFFFFF ) {
::SetDlgItemText( m_hWnd, IDC_MIF_RERECORDTIMES, "----" );
} else {
::wsprintf( szTemp, "%d times", m_dwRerecordTimes );
::SetDlgItemText( m_hWnd, IDC_MIF_RERECORDTIMES, szTemp );
}
return TRUE;
}
DLGCMD CMovieInfoDlg::OnOK( DLGCMDPARAM )
{
// DEBUGOUT( "CMovieInfoDlg::OnOK\n" );
::EndDialog( m_hWnd, IDOK );
}
DLGCMD CMovieInfoDlg::OnCancel( DLGCMDPARAM )
{
// DEBUGOUT( "CMovieInfoDlg::OnCancel\n" );
::EndDialog( m_hWnd, IDCANCEL );
}

View File

@ -0,0 +1,36 @@
//
// ムービー情報ダイアログクラス
//
#ifndef __CMOVIEINFODLG_INCLUDED__
#define __CMOVIEINFODLG_INCLUDED__
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
using namespace std;
#include "Wnd.h"
class CMovieInfoDlg : public CWnd
{
public:
// Override from CWnd
INT DoModal( HWND hWndParent );
WORD m_wRecVersion;
WORD m_wVersion;
DWORD m_dwFrames;
DWORD m_dwRerecordTimes;
protected:
// Message map
DLG_MESSAGE_MAP()
DLGMSG OnInitDialog( DLGMSGPARAM );
DLGCMD OnOK( DLGCMDPARAM );
DLGCMD OnCancel( DLGCMDPARAM );
//
private:
};
#endif // !__CMOVIEINFODLG_INCLUDED__

Some files were not shown because too many files have changed in this diff Show More