From 024462c221b2d5427c472d2e845824fbe2582124 Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 10 Nov 2008 22:34:52 +0000 Subject: [PATCH] need to move these files over to another computer. dont think they should get in anyone else's way --- desmume/src/NDSSystem.cpp | 106 + desmume/src/NDSSystem.h | 4 + desmume/src/memorystream.h | 2 +- desmume/src/saves.cpp | 3 +- desmume/src/types.h | 36 +- desmume/src/utils/ConvertUTF.c | 539 ++++ desmume/src/utils/ConvertUTF.h | 149 + desmume/src/utils/guid.cpp | 48 + desmume/src/utils/guid.h | 18 + desmume/src/utils/md5.cpp | 248 ++ desmume/src/utils/md5.h | 23 + desmume/src/utils/valuearray.h | 21 + desmume/src/utils/xstring.cpp | 688 ++++ desmume/src/utils/xstring.h | 113 + desmume/src/windows/DeSmuME_2005.vcproj | 50 + desmume/src/windows/inputdx.cpp | 53 +- desmume/src/windows/main.cpp | 3805 +++++++++++------------ desmume/src/windows/snddx.cpp | 19 +- desmume/src/windows/windriver.h | 6 + 19 files changed, 3988 insertions(+), 1943 deletions(-) create mode 100644 desmume/src/utils/ConvertUTF.c create mode 100644 desmume/src/utils/ConvertUTF.h create mode 100644 desmume/src/utils/guid.cpp create mode 100644 desmume/src/utils/guid.h create mode 100644 desmume/src/utils/md5.cpp create mode 100644 desmume/src/utils/md5.h create mode 100644 desmume/src/utils/valuearray.h create mode 100644 desmume/src/utils/xstring.cpp create mode 100644 desmume/src/utils/xstring.h diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 7438885dc..d3c11b824 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -250,6 +250,7 @@ void NDS_setTouchPos(u16 x, u16 y) { nds.touchX = (x <<4); nds.touchY = (y <<4); + nds.isTouch = 1; MMU.ARM7_REG[0x136] &= 0xBF; } @@ -258,6 +259,7 @@ void NDS_releaseTouch(void) { nds.touchX = 0; nds.touchY = 0; + nds.isTouch = 0; MMU.ARM7_REG[0x136] |= 0x40; } @@ -477,6 +479,7 @@ void NDS_Reset( void) nds.diff = 0; nds.lignerendu = FALSE; nds.touchX = nds.touchY = 0; + nds.isTouch = 0; MMU_write16(0, 0x04000130, 0x3FF); MMU_write16(1, 0x04000130, 0x3FF); @@ -1571,3 +1574,106 @@ NDS_exec(s32 nb, BOOL force) return nds.cycles; } + +void NDS_setPadFromMovie(u16 pad) +{ + #define FIX(b,n) (((pad>>n)&1)!=0) + NDS_setPad( + FIX(pad,0), + FIX(pad,1), + FIX(pad,2), + FIX(pad,3), + FIX(pad,4), + FIX(pad,5), + FIX(pad,6), + FIX(pad,7), + FIX(pad,8), + FIX(pad,9), + FIX(pad,10), + FIX(pad,11), + FIX(pad,12) + ); + #undef FIX +} + +void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,bool X,bool W,bool E,bool G) +{ + + //this macro is the opposite of what you would expect + #define FIX(b) (b?0:0x80) + + int r = FIX(R); + int l = FIX(L); + int d = FIX(D); + int u = FIX(U); + int t = FIX(T); + int s = FIX(S); + int b = FIX(B); + int a = FIX(A); + int y = FIX(Y); + int x = FIX(X); + int w = FIX(W); + int e = FIX(E); + int g = FIX(G); + + u16 pad = (0 | + ((a) >> 7) | + ((b) >> 6) | + ((s) >> 5) | + ((t) >> 4) | + ((r) >> 3) | + ((l) >> 2) | + ((u) >> 1) | + ((d)) | + ((r) << 1) | + ((l) << 2)) ; + + ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] = (u16)pad; + ((u16 *)MMU.ARM7_REG)[0x130>>1] = (u16)pad; + + u16 padExt = (((u16 *)MMU.ARM7_REG)[0x136>>1] & 0x00F0) | + ((x) >> 7) | + ((y) >> 6) | + ((g) >> 4) | + 0x0034; + + ((u16 *)MMU.ARM7_REG)[0x136>>1] = (u16)padExt; + + + //put into the format we want for the movie system + //RLDUTSBAYXWEG + #undef FIX + #define FIX(b) (b?1:0) + + r = FIX(R); + l = FIX(L); + d = FIX(D); + u = FIX(U); + t = FIX(T); + s = FIX(S); + b = FIX(B); + a = FIX(A); + y = FIX(Y); + x = FIX(X); + w = FIX(W); + e = FIX(E); + g = FIX(G); + + + nds.pad = + (FIX(r)<<0)| + (FIX(l)<<1)| + (FIX(d)<<2)| + (FIX(u)<<3)| + (FIX(t)<<4)| + (FIX(s)<<5)| + (FIX(b)<<6)| + (FIX(a)<<7)| + (FIX(y)<<8)| + (FIX(x)<<9)| + (FIX(w)<<10)| + (FIX(e)<<11)| + (FIX(g)<<12); + + // TODO: low power IRQ +} diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index fe0e5f3ab..3f01bb4da 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -118,6 +118,8 @@ typedef struct u16 touchX; u16 touchY; + BOOL isTouch; + u16 pad; //this is not essential NDS runtime state. //it was perhaps a mistake to put it here. @@ -187,6 +189,8 @@ NDS_header * NDS_getROMHeader(void); void NDS_setTouchPos(u16 x, u16 y); void NDS_releaseTouch(void); +void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,bool X,bool W,bool E,bool G); +void NDS_setPadFromMovie(u16 pad); int NDS_LoadROM(const char *filename, int bmtype, u32 bmsize, const char *cflash_disk_image_file); diff --git a/desmume/src/memorystream.h b/desmume/src/memorystream.h index 98be24b1c..82ca09106 100644 --- a/desmume/src/memorystream.h +++ b/desmume/src/memorystream.h @@ -215,7 +215,7 @@ protected: int overflow(int c) { - expand(-1); + expand((size_t)-1); dosync(c); return 1; } diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index a26c80731..79db912a9 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -159,6 +159,7 @@ SFORMAT SF_NDS[]={ { "_LIG", 4, 1, &nds.lignerendu}, { "_TPX", 2, 1, &nds.touchX}, { "_TPY", 2, 1, &nds.touchY}, + { "_TPB", 4, 1, &nds.isTouch}, { 0 } }; @@ -647,7 +648,7 @@ static bool savestate_save(std::ostream* outstream, int compressionLevel) //save the length of the file u32 len = ms.size(); - u32 comprlen = -1; + u32 comprlen = 0xFFFFFFFF; u8* cbuf = (u8*)ms.buf(); #ifdef HAVE_LIBZ diff --git a/desmume/src/types.h b/desmume/src/types.h index 64570df5c..99ab243b5 100644 --- a/desmume/src/types.h +++ b/desmume/src/types.h @@ -26,7 +26,7 @@ #define DESMUME_NAME_AND_VERSION DESMUME_NAME " " DESMUME_VERSION_STRING " " VERSION #ifdef _WIN32 -#define strcasecmp(x,y) stricmp(x,y) +#define strcasecmp(x,y) _stricmp(x,y) #else #define WINAPI #endif @@ -239,5 +239,39 @@ inline double u64_to_double(u64 u) { return fuxor.b; } + +///stores a 32bit value into the provided byte array in guaranteed little endian form +inline void en32lsb(u8 *buf, u32 morp) +{ + buf[0]=morp; + buf[1]=morp>>8; + buf[2]=morp>>16; + buf[3]=morp>>24; +} + +inline void en16lsb(u8* buf, u16 morp) +{ + buf[0]=morp; + buf[1]=morp>>8; +} + +///unpacks a 64bit little endian value from the provided byte array into host byte order +inline u64 de64lsb(u8 *morp) +{ + return morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24)|((u64)morp[4]<<32)|((u64)morp[5]<<40)|((u64)morp[6]<<48)|((u64)morp[7]<<56); +} + +///unpacks a 32bit little endian value from the provided byte array into host byte order +inline u32 de32lsb(u8 *morp) +{ + return morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24); +} + +///unpacks a 16bit little endian value from the provided byte array into host byte order +inline u16 de16lsb(u8 *morp) +{ + return morp[0]|(morp[1]<<8); +} + #endif diff --git a/desmume/src/utils/ConvertUTF.c b/desmume/src/utils/ConvertUTF.c new file mode 100644 index 000000000..9b3deebd6 --- /dev/null +++ b/desmume/src/utils/ConvertUTF.c @@ -0,0 +1,539 @@ +/* + * Copyright 2001-2004 Unicode, Inc. + * + * Disclaimer + * + * This source code is provided as is by Unicode, Inc. No claims are + * made as to fitness for any particular purpose. No warranties of any + * kind are expressed or implied. The recipient agrees to determine + * applicability of information provided. If this file has been + * purchased on magnetic or optical media from Unicode, Inc., the + * sole remedy for any claim will be exchange of defective media + * within 90 days of receipt. + * + * Limitations on Rights to Redistribute This Code + * + * Unicode, Inc. hereby grants the right to freely use the information + * supplied in this file in the creation of products supporting the + * Unicode Standard, and to make copies of this file in any form + * for internal or external distribution as long as this notice + * remains attached. + */ + +/* --------------------------------------------------------------------- + + Conversions between UTF32, UTF-16, and UTF-8. Source code file. + Author: Mark E. Davis, 1994. + Rev History: Rick McGowan, fixes & updates May 2001. + Sept 2001: fixed const & error conditions per + mods suggested by S. Parent & A. Lillich. + June 2002: Tim Dodd added detection and handling of incomplete + source sequences, enhanced error detection, added casts + to eliminate compiler warnings. + July 2003: slight mods to back out aggressive FFFE detection. + Jan 2004: updated switches in from-UTF8 conversions. + Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. + + See the header file "ConvertUTF.h" for complete documentation. + +------------------------------------------------------------------------ */ + + +#include "ConvertUTF.h" +#ifdef CVTUTF_DEBUG +#include +#endif + +static const int halfShift = 10; /* used for shifting by 10 bits */ + +static const UTF32 halfBase = 0x0010000UL; +static const UTF32 halfMask = 0x3FFUL; + +#define UNI_SUR_HIGH_START (UTF32)0xD800 +#define UNI_SUR_HIGH_END (UTF32)0xDBFF +#define UNI_SUR_LOW_START (UTF32)0xDC00 +#define UNI_SUR_LOW_END (UTF32)0xDFFF +#define false 0 +#define true 1 + +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF32toUTF16 ( + const UTF32** sourceStart, const UTF32* sourceEnd, + UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF32* source = *sourceStart; + UTF16* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + if (target >= targetEnd) { + result = targetExhausted; break; + } + ch = *source++; + if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ + /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + if (flags == strictConversion) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + *target++ = (UTF16)ch; /* normal case */ + } + } else if (ch > UNI_MAX_LEGAL_UTF32) { + if (flags == strictConversion) { + result = sourceIllegal; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + /* target is a character in range 0xFFFF - 0x10FFFF. */ + if (target + 1 >= targetEnd) { + --source; /* Back up source pointer! */ + result = targetExhausted; break; + } + ch -= halfBase; + *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); + *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF16toUTF32 ( + const UTF16** sourceStart, const UTF16* sourceEnd, + UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF16* source = *sourceStart; + UTF32* target = *targetStart; + UTF32 ch, ch2; + while (source < sourceEnd) { + const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ + ch = *source++; + /* If we have a surrogate pair, convert to UTF32 first. */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { + /* If the 16 bits following the high surrogate are in the source buffer... */ + if (source < sourceEnd) { + ch2 = *source; + /* If it's a low surrogate, convert to UTF32. */ + if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { + ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + + (ch2 - UNI_SUR_LOW_START) + halfBase; + ++source; + } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } else { /* We don't have the 16 bits following the high surrogate. */ + --source; /* return to the high surrogate */ + result = sourceExhausted; + break; + } + } else if (flags == strictConversion) { + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } + if (target >= targetEnd) { + source = oldSource; /* Back up source pointer! */ + result = targetExhausted; break; + } + *target++ = ch; + } + *sourceStart = source; + *targetStart = target; +#ifdef CVTUTF_DEBUG +if (result == sourceIllegal) { + fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); + fflush(stderr); +} +#endif + return result; +} + +/* --------------------------------------------------------------------- */ + +/* + * Index into the table below with the first byte of a UTF-8 sequence to + * get the number of trailing bytes that are supposed to follow it. + * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is + * left as-is for anyone who may want to do such conversion, which was + * allowed in earlier algorithms. + */ +static const char trailingBytesForUTF8[256] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 +}; + +/* + * Magic values subtracted from a buffer value during UTF8 conversion. + * This table contains as many values as there might be trailing bytes + * in a UTF-8 sequence. + */ +static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, + 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; + +/* + * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed + * into the first byte, depending on how many bytes follow. There are + * as many entries in this table as there are UTF-8 sequence types. + * (I.e., one byte sequence, two byte... etc.). Remember that sequencs + * for *legal* UTF-8 will be 4 or fewer bytes total. + */ +static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +/* --------------------------------------------------------------------- */ + +/* The interface converts a whole buffer to avoid function-call overhead. + * Constants have been gathered. Loops & conditionals have been removed as + * much as possible for efficiency, in favor of drop-through switches. + * (See "Note A" at the bottom of the file for equivalent code.) + * If your compiler supports it, the "isLegalUTF8" call can be turned + * into an inline function. + */ + +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF16toUTF8 ( + const UTF16** sourceStart, const UTF16* sourceEnd, + UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF16* source = *sourceStart; + UTF8* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + unsigned short bytesToWrite = 0; + const UTF32 byteMask = 0xBF; + const UTF32 byteMark = 0x80; + const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ + ch = *source++; + /* If we have a surrogate pair, convert to UTF32 first. */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { + /* If the 16 bits following the high surrogate are in the source buffer... */ + if (source < sourceEnd) { + UTF32 ch2 = *source; + /* If it's a low surrogate, convert to UTF32. */ + if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { + ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + + (ch2 - UNI_SUR_LOW_START) + halfBase; + ++source; + } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } else { /* We don't have the 16 bits following the high surrogate. */ + --source; /* return to the high surrogate */ + result = sourceExhausted; + break; + } + } else if (flags == strictConversion) { + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } + /* Figure out how many bytes the result will require */ + if (ch < (UTF32)0x80) { bytesToWrite = 1; + } else if (ch < (UTF32)0x800) { bytesToWrite = 2; + } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; + } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; + } else { bytesToWrite = 3; + ch = UNI_REPLACEMENT_CHAR; + } + + target += bytesToWrite; + if (target > targetEnd) { + source = oldSource; /* Back up source pointer! */ + target -= bytesToWrite; result = targetExhausted; break; + } + switch (bytesToWrite) { /* note: everything falls through. */ + case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +/* + * Utility routine to tell whether a sequence of bytes is legal UTF-8. + * This must be called with the length pre-determined by the first byte. + * If not calling this from ConvertUTF8to*, then the length can be set by: + * length = trailingBytesForUTF8[*source]+1; + * and the sequence is illegal right away if there aren't that many bytes + * available. + * If presented with a length > 4, this returns false. The Unicode + * definition of UTF-8 goes up to 4-byte sequences. + */ + +static Boolean isLegalUTF8(const UTF8 *source, int length) { + UTF8 a; + const UTF8 *srcptr = source+length; + switch (length) { + default: return false; + /* Everything else falls through when "true"... */ + case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; + case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; + case 2: if ((a = (*--srcptr)) > 0xBF) return false; + + switch (*source) { + /* no fall-through in this inner switch */ + case 0xE0: if (a < 0xA0) return false; break; + case 0xED: if (a > 0x9F) return false; break; + case 0xF0: if (a < 0x90) return false; break; + case 0xF4: if (a > 0x8F) return false; break; + default: if (a < 0x80) return false; + } + + case 1: if (*source >= 0x80 && *source < 0xC2) return false; + } + if (*source > 0xF4) return false; + return true; +} + +/* --------------------------------------------------------------------- */ + +/* + * Exported function to return whether a UTF-8 sequence is legal or not. + * This is not used here; it's just exported. + */ +Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { + int length = trailingBytesForUTF8[*source]+1; + if (source+length > sourceEnd) { + return false; + } + return isLegalUTF8(source, length); +} + +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF8toUTF16 ( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF8* source = *sourceStart; + UTF16* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) { + result = sourceExhausted; break; + } + /* Do this check whether lenient or strict */ + if (! isLegalUTF8(source, extraBytesToRead+1)) { + result = sourceIllegal; + break; + } + /* + * The cases all fall through. See "Note A" below. + */ + switch (extraBytesToRead) { + case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ + case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ + case 3: ch += *source++; ch <<= 6; + case 2: ch += *source++; ch <<= 6; + case 1: ch += *source++; ch <<= 6; + case 0: ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (target >= targetEnd) { + source -= (extraBytesToRead+1); /* Back up source pointer! */ + result = targetExhausted; break; + } + if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + if (flags == strictConversion) { + source -= (extraBytesToRead+1); /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + *target++ = (UTF16)ch; /* normal case */ + } + } else if (ch > UNI_MAX_UTF16) { + if (flags == strictConversion) { + result = sourceIllegal; + source -= (extraBytesToRead+1); /* return to the start */ + break; /* Bail out; shouldn't continue */ + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + /* target is a character in range 0xFFFF - 0x10FFFF. */ + if (target + 1 >= targetEnd) { + source -= (extraBytesToRead+1); /* Back up source pointer! */ + result = targetExhausted; break; + } + ch -= halfBase; + *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); + *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF32toUTF8 ( + const UTF32** sourceStart, const UTF32* sourceEnd, + UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF32* source = *sourceStart; + UTF8* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch; + unsigned short bytesToWrite = 0; + const UTF32 byteMask = 0xBF; + const UTF32 byteMark = 0x80; + ch = *source++; + if (flags == strictConversion ) { + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + --source; /* return to the illegal value itself */ + result = sourceIllegal; + break; + } + } + /* + * Figure out how many bytes the result will require. Turn any + * illegally large UTF32 things (> Plane 17) into replacement chars. + */ + if (ch < (UTF32)0x80) { bytesToWrite = 1; + } else if (ch < (UTF32)0x800) { bytesToWrite = 2; + } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; + } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; + } else { bytesToWrite = 3; + ch = UNI_REPLACEMENT_CHAR; + result = sourceIllegal; + } + + target += bytesToWrite; + if (target > targetEnd) { + --source; /* Back up source pointer! */ + target -= bytesToWrite; result = targetExhausted; break; + } + switch (bytesToWrite) { /* note: everything falls through. */ + case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; + case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- */ + +ConversionResult ConvertUTF8toUTF32 ( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { + ConversionResult result = conversionOK; + const UTF8* source = *sourceStart; + UTF32* target = *targetStart; + while (source < sourceEnd) { + UTF32 ch = 0; + unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; + if (source + extraBytesToRead >= sourceEnd) { + result = sourceExhausted; break; + } + /* Do this check whether lenient or strict */ + if (! isLegalUTF8(source, extraBytesToRead+1)) { + result = sourceIllegal; + break; + } + /* + * The cases all fall through. See "Note A" below. + */ + switch (extraBytesToRead) { + case 5: ch += *source++; ch <<= 6; + case 4: ch += *source++; ch <<= 6; + case 3: ch += *source++; ch <<= 6; + case 2: ch += *source++; ch <<= 6; + case 1: ch += *source++; ch <<= 6; + case 0: ch += *source++; + } + ch -= offsetsFromUTF8[extraBytesToRead]; + + if (target >= targetEnd) { + source -= (extraBytesToRead+1); /* Back up the source pointer! */ + result = targetExhausted; break; + } + if (ch <= UNI_MAX_LEGAL_UTF32) { + /* + * UTF-16 surrogate values are illegal in UTF-32, and anything + * over Plane 17 (> 0x10FFFF) is illegal. + */ + if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { + if (flags == strictConversion) { + source -= (extraBytesToRead+1); /* return to the illegal value itself */ + result = sourceIllegal; + break; + } else { + *target++ = UNI_REPLACEMENT_CHAR; + } + } else { + *target++ = ch; + } + } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ + result = sourceIllegal; + *target++ = UNI_REPLACEMENT_CHAR; + } + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/* --------------------------------------------------------------------- + + Note A. + The fall-through switches in UTF-8 reading code save a + temp variable, some decrements & conditionals. The switches + are equivalent to the following loop: + { + int tmpBytesToRead = extraBytesToRead+1; + do { + ch += *source++; + --tmpBytesToRead; + if (tmpBytesToRead) ch <<= 6; + } while (tmpBytesToRead > 0); + } + In UTF-8 writing code, the switches on "bytesToWrite" are + similarly unrolled loops. + + --------------------------------------------------------------------- */ diff --git a/desmume/src/utils/ConvertUTF.h b/desmume/src/utils/ConvertUTF.h new file mode 100644 index 000000000..e26491536 --- /dev/null +++ b/desmume/src/utils/ConvertUTF.h @@ -0,0 +1,149 @@ +/* + * Copyright 2001-2004 Unicode, Inc. + * + * Disclaimer + * + * This source code is provided as is by Unicode, Inc. No claims are + * made as to fitness for any particular purpose. No warranties of any + * kind are expressed or implied. The recipient agrees to determine + * applicability of information provided. If this file has been + * purchased on magnetic or optical media from Unicode, Inc., the + * sole remedy for any claim will be exchange of defective media + * within 90 days of receipt. + * + * Limitations on Rights to Redistribute This Code + * + * Unicode, Inc. hereby grants the right to freely use the information + * supplied in this file in the creation of products supporting the + * Unicode Standard, and to make copies of this file in any form + * for internal or external distribution as long as this notice + * remains attached. + */ + +/* --------------------------------------------------------------------- + + Conversions between UTF32, UTF-16, and UTF-8. Header file. + + Several funtions are included here, forming a complete set of + conversions between the three formats. UTF-7 is not included + here, but is handled in a separate source file. + + Each of these routines takes pointers to input buffers and output + buffers. The input buffers are const. + + Each routine converts the text between *sourceStart and sourceEnd, + putting the result into the buffer between *targetStart and + targetEnd. Note: the end pointers are *after* the last item: e.g. + *(sourceEnd - 1) is the last item. + + The return result indicates whether the conversion was successful, + and if not, whether the problem was in the source or target buffers. + (Only the first encountered problem is indicated.) + + After the conversion, *sourceStart and *targetStart are both + updated to point to the end of last text successfully converted in + the respective buffers. + + Input parameters: + sourceStart - pointer to a pointer to the source buffer. + The contents of this are modified on return so that + it points at the next thing to be converted. + targetStart - similarly, pointer to pointer to the target buffer. + sourceEnd, targetEnd - respectively pointers to the ends of the + two buffers, for overflow checking only. + + These conversion functions take a ConversionFlags argument. When this + flag is set to strict, both irregular sequences and isolated surrogates + will cause an error. When the flag is set to lenient, both irregular + sequences and isolated surrogates are converted. + + Whether the flag is strict or lenient, all illegal sequences will cause + an error return. This includes sequences such as: , , + or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code + must check for illegal sequences. + + When the flag is set to lenient, characters over 0x10FFFF are converted + to the replacement character; otherwise (when the flag is set to strict) + they constitute an error. + + Output parameters: + The value "sourceIllegal" is returned from some routines if the input + sequence is malformed. When "sourceIllegal" is returned, the source + value will point to the illegal value that caused the problem. E.g., + in UTF-8 when a sequence is malformed, it points to the start of the + malformed sequence. + + Author: Mark E. Davis, 1994. + Rev History: Rick McGowan, fixes & updates May 2001. + Fixes & updates, Sept 2001. + +------------------------------------------------------------------------ */ + +/* --------------------------------------------------------------------- + The following 4 definitions are compiler-specific. + The C standard does not guarantee that wchar_t has at least + 16 bits, so wchar_t is no less portable than unsigned short! + All should be unsigned values to avoid sign extension during + bit mask & shift operations. +------------------------------------------------------------------------ */ + +typedef unsigned long UTF32; /* at least 32 bits */ +typedef unsigned short UTF16; /* at least 16 bits */ +typedef unsigned char UTF8; /* typically 8 bits */ +typedef unsigned char Boolean; /* 0 or 1 */ + +/* Some fundamental constants */ +#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD +#define UNI_MAX_BMP (UTF32)0x0000FFFF +#define UNI_MAX_UTF16 (UTF32)0x0010FFFF +#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF +#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF + +typedef enum { + conversionOK, /* conversion successful */ + sourceExhausted, /* partial character in source, but hit end */ + targetExhausted, /* insuff. room in target for conversion */ + sourceIllegal /* source sequence is illegal/malformed */ +} ConversionResult; + +typedef enum { + strictConversion = 0, + lenientConversion +} ConversionFlags; + +/* This is for C++ and does no harm in C */ +#ifdef __cplusplus +extern "C" { +#endif + +ConversionResult ConvertUTF8toUTF16 ( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF16toUTF8 ( + const UTF16** sourceStart, const UTF16* sourceEnd, + UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF8toUTF32 ( + const UTF8** sourceStart, const UTF8* sourceEnd, + UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF32toUTF8 ( + const UTF32** sourceStart, const UTF32* sourceEnd, + UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF16toUTF32 ( + const UTF16** sourceStart, const UTF16* sourceEnd, + UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); + +ConversionResult ConvertUTF32toUTF16 ( + const UTF32** sourceStart, const UTF32* sourceEnd, + UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); + +Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); + +#ifdef __cplusplus +} +#endif + +/* --------------------------------------------------------------------- */ diff --git a/desmume/src/utils/guid.cpp b/desmume/src/utils/guid.cpp new file mode 100644 index 000000000..dc9aed93b --- /dev/null +++ b/desmume/src/utils/guid.cpp @@ -0,0 +1,48 @@ +#include "guid.h" +#include "types.h" + +void Desmume_Guid::newGuid() +{ + for(int i=0;i='A') a=a-'A'+10; + else a-='0'; + if(b>='A') b=b-'A'+10; + else b-='0'; + return ((unsigned char)a<<4)|(unsigned char)b; +} + +void Desmume_Guid::scan(std::string& str) +{ + char* endptr = (char*)str.c_str(); + en32lsb(data,strtoul(endptr,&endptr,16)); + en16lsb(data+4,strtoul(endptr+1,&endptr,16)); + en16lsb(data+6,strtoul(endptr+1,&endptr,16)); + en16lsb(data+8,strtoul(endptr+1,&endptr,16)); + endptr++; + for(int i=0;i<6;i++) + data[10+i] = hexToByte(&endptr); +} diff --git a/desmume/src/utils/guid.h b/desmume/src/utils/guid.h new file mode 100644 index 000000000..0360ea53d --- /dev/null +++ b/desmume/src/utils/guid.h @@ -0,0 +1,18 @@ +#ifndef _guid_h_ +#define _guid_h_ + +#include +#include "types.h" +#include "valuearray.h" + +struct Desmume_Guid : public ValueArray +{ + void newGuid(); + std::string toString(); + static Desmume_Guid fromString(std::string str); + static uint8 hexToByte(char** ptrptr); + void scan(std::string& str); +}; + + +#endif diff --git a/desmume/src/utils/md5.cpp b/desmume/src/utils/md5.cpp new file mode 100644 index 000000000..144536c2f --- /dev/null +++ b/desmume/src/utils/md5.cpp @@ -0,0 +1,248 @@ +/// \file +/// \brief RFC 1321 compliant MD5 implementation, +/// RFC 1321 compliant MD5 implementation, +/// by Christophe Devine ; +/// this program is licensed under the GPL. + +//Modified October 3, 2003, to remove testing code, and add include of "types.h". +//Added simple MD5 to ASCII string conversion function. +// -Xodnizel + +#include +#include "../types.h" +#include "md5.h" + +typedef u8 uint8; +typedef u16 uint16; +typedef u32 uint32; + +#define GET_UINT32(n,b,i) \ +{ \ + (n) = ( (uint32) (b)[(i) + 3] << 24 ) \ + | ( (uint32) (b)[(i) + 2] << 16 ) \ + | ( (uint32) (b)[(i) + 1] << 8 ) \ + | ( (uint32) (b)[(i) ] ); \ +} + +#define PUT_UINT32(n,b,i) \ +{ \ + (b)[(i) ] = (uint8) ( (n) ); \ + (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \ + (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \ + (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \ +} + +void md5_starts( struct md5_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +void md5_process( struct md5_context *ctx, uint8 data[64] ) +{ + uint32 A, B, C, D, X[16]; + + GET_UINT32( X[0], data, 0 ); + GET_UINT32( X[1], data, 4 ); + GET_UINT32( X[2], data, 8 ); + GET_UINT32( X[3], data, 12 ); + GET_UINT32( X[4], data, 16 ); + GET_UINT32( X[5], data, 20 ); + GET_UINT32( X[6], data, 24 ); + GET_UINT32( X[7], data, 28 ); + GET_UINT32( X[8], data, 32 ); + GET_UINT32( X[9], data, 36 ); + GET_UINT32( X[10], data, 40 ); + GET_UINT32( X[11], data, 44 ); + GET_UINT32( X[12], data, 48 ); + GET_UINT32( X[13], data, 52 ); + GET_UINT32( X[14], data, 56 ); + GET_UINT32( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a,b,c,d,k,s,t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) + + P( A, B, C, D, 0, 7, 0xD76AA478 ); + P( D, A, B, C, 1, 12, 0xE8C7B756 ); + P( C, D, A, B, 2, 17, 0x242070DB ); + P( B, C, D, A, 3, 22, 0xC1BDCEEE ); + P( A, B, C, D, 4, 7, 0xF57C0FAF ); + P( D, A, B, C, 5, 12, 0x4787C62A ); + P( C, D, A, B, 6, 17, 0xA8304613 ); + P( B, C, D, A, 7, 22, 0xFD469501 ); + P( A, B, C, D, 8, 7, 0x698098D8 ); + P( D, A, B, C, 9, 12, 0x8B44F7AF ); + P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); + P( B, C, D, A, 11, 22, 0x895CD7BE ); + P( A, B, C, D, 12, 7, 0x6B901122 ); + P( D, A, B, C, 13, 12, 0xFD987193 ); + P( C, D, A, B, 14, 17, 0xA679438E ); + P( B, C, D, A, 15, 22, 0x49B40821 ); + +#undef F + +#define F(x,y,z) (y ^ (z & (x ^ y))) + + P( A, B, C, D, 1, 5, 0xF61E2562 ); + P( D, A, B, C, 6, 9, 0xC040B340 ); + P( C, D, A, B, 11, 14, 0x265E5A51 ); + P( B, C, D, A, 0, 20, 0xE9B6C7AA ); + P( A, B, C, D, 5, 5, 0xD62F105D ); + P( D, A, B, C, 10, 9, 0x02441453 ); + P( C, D, A, B, 15, 14, 0xD8A1E681 ); + P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); + P( A, B, C, D, 9, 5, 0x21E1CDE6 ); + P( D, A, B, C, 14, 9, 0xC33707D6 ); + P( C, D, A, B, 3, 14, 0xF4D50D87 ); + P( B, C, D, A, 8, 20, 0x455A14ED ); + P( A, B, C, D, 13, 5, 0xA9E3E905 ); + P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); + P( C, D, A, B, 7, 14, 0x676F02D9 ); + P( B, C, D, A, 12, 20, 0x8D2A4C8A ); + +#undef F + +#define F(x,y,z) (x ^ y ^ z) + + P( A, B, C, D, 5, 4, 0xFFFA3942 ); + P( D, A, B, C, 8, 11, 0x8771F681 ); + P( C, D, A, B, 11, 16, 0x6D9D6122 ); + P( B, C, D, A, 14, 23, 0xFDE5380C ); + P( A, B, C, D, 1, 4, 0xA4BEEA44 ); + P( D, A, B, C, 4, 11, 0x4BDECFA9 ); + P( C, D, A, B, 7, 16, 0xF6BB4B60 ); + P( B, C, D, A, 10, 23, 0xBEBFBC70 ); + P( A, B, C, D, 13, 4, 0x289B7EC6 ); + P( D, A, B, C, 0, 11, 0xEAA127FA ); + P( C, D, A, B, 3, 16, 0xD4EF3085 ); + P( B, C, D, A, 6, 23, 0x04881D05 ); + P( A, B, C, D, 9, 4, 0xD9D4D039 ); + P( D, A, B, C, 12, 11, 0xE6DB99E5 ); + P( C, D, A, B, 15, 16, 0x1FA27CF8 ); + P( B, C, D, A, 2, 23, 0xC4AC5665 ); + +#undef F + +#define F(x,y,z) (y ^ (x | ~z)) + + P( A, B, C, D, 0, 6, 0xF4292244 ); + P( D, A, B, C, 7, 10, 0x432AFF97 ); + P( C, D, A, B, 14, 15, 0xAB9423A7 ); + P( B, C, D, A, 5, 21, 0xFC93A039 ); + P( A, B, C, D, 12, 6, 0x655B59C3 ); + P( D, A, B, C, 3, 10, 0x8F0CCC92 ); + P( C, D, A, B, 10, 15, 0xFFEFF47D ); + P( B, C, D, A, 1, 21, 0x85845DD1 ); + P( A, B, C, D, 8, 6, 0x6FA87E4F ); + P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); + P( C, D, A, B, 6, 15, 0xA3014314 ); + P( B, C, D, A, 13, 21, 0x4E0811A1 ); + P( A, B, C, D, 4, 6, 0xF7537E82 ); + P( D, A, B, C, 11, 10, 0xBD3AF235 ); + P( C, D, A, B, 2, 15, 0x2AD7D2BB ); + P( B, C, D, A, 9, 21, 0xEB86D391 ); + +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +void md5_update( struct md5_context *ctx, uint8 *input, uint32 length ) +{ + uint32 left, fill; + + if( ! length ) return; + + left = ( ctx->total[0] >> 3 ) & 0x3F; + fill = 64 - left; + + ctx->total[0] += length << 3; + ctx->total[1] += length >> 29; + + ctx->total[0] &= 0xFFFFFFFF; + ctx->total[1] += ctx->total[0] < ( length << 3 ); + + if( left && length >= fill ) + { + memcpy( (void *) (ctx->buffer + left), (void *) input, fill ); + md5_process( ctx, ctx->buffer ); + length -= fill; + input += fill; + left = 0; + } + + while( length >= 64 ) + { + md5_process( ctx, input ); + length -= 64; + input += 64; + } + + if( length ) + { + memcpy( (void *) (ctx->buffer + left), (void *) input, length ); + } +} + +static uint8 md5_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void md5_finish( struct md5_context *ctx, uint8 digest[16] ) +{ + uint32 last, padn; + uint8 msglen[8]; + + PUT_UINT32( ctx->total[0], msglen, 0 ); + PUT_UINT32( ctx->total[1], msglen, 4 ); + + last = ( ctx->total[0] >> 3 ) & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md5_update( ctx, md5_padding, padn ); + md5_update( ctx, msglen, 8 ); + + PUT_UINT32( ctx->state[0], digest, 0 ); + PUT_UINT32( ctx->state[1], digest, 4 ); + PUT_UINT32( ctx->state[2], digest, 8 ); + PUT_UINT32( ctx->state[3], digest, 12 ); +} + + +/* Uses a static buffer, so beware of how it's used. */ +char *md5_asciistr(MD5DATA& md5) +{ + uint8* digest = md5.data; + static char str[33]; + static char trans[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + int x; + + for(x=0;x<16;x++) + { + str[x*2]=trans[digest[x]&0x0F]; + str[x*2+1]=trans[digest[x]>>4]; + } + return(str); +} diff --git a/desmume/src/utils/md5.h b/desmume/src/utils/md5.h new file mode 100644 index 000000000..369266ce1 --- /dev/null +++ b/desmume/src/utils/md5.h @@ -0,0 +1,23 @@ +#ifndef _MD5_H +#define _MD5_H + +#include "types.h" +#include "valuearray.h" + +struct md5_context +{ + u32 total[2]; + u32 state[4]; + u8 buffer[64]; +}; + +typedef ValueArray MD5DATA; + +void md5_starts( struct md5_context *ctx ); +void md5_update( struct md5_context *ctx, u8 *input, u32 length ); +void md5_finish( struct md5_context *ctx, u8 digest[16] ); + +/* Uses a static buffer, so beware of how it's used. */ +char *md5_asciistr(MD5DATA& md5); + +#endif /* md5.h */ diff --git a/desmume/src/utils/valuearray.h b/desmume/src/utils/valuearray.h new file mode 100644 index 000000000..8606ff829 --- /dev/null +++ b/desmume/src/utils/valuearray.h @@ -0,0 +1,21 @@ +#ifndef _VALUEARRAY_H_ +#define _VALUEARRAY_H_ + +template +struct ValueArray +{ + T data[N]; + T &operator[](int index) { return data[index]; } + static const int size = N; + bool operator!=(ValueArray &other) { return !operator==(other); } + bool operator==(ValueArray &other) + { + for(int i=0;i + +///Upper case routine. Returns number of characters modified +int str_ucase(char *str) { + unsigned int i=0,j=0; //mbg merge 7/17/06 changed to unsigned int + + while (i < strlen(str)) { + if ((str[i] >= 'a') && (str[i] <= 'z')) { + str[i] &= ~0x20; + j++; + } + i++; + } + return j; +} + + +///Lower case routine. Returns number of characters modified +int str_lcase(char *str) { + unsigned int i=0,j=0; //mbg merge 7/17/06 changed to unsigned int + + while (i < strlen(str)) { + if ((str[i] >= 'A') && (str[i] <= 'Z')) { + str[i] |= 0x20; + j++; + } + i++; + } + return j; +} + + +///White space-trimming routine + +///Removes whitespace from left side of string, depending on the flags set (See STRIP_x definitions in xstring.h) +///Returns number of characters removed +int str_ltrim(char *str, int flags) { + unsigned int i=0; //mbg merge 7/17/06 changed to unsigned int + + while (str[0]) { + if ((str[0] != ' ') || (str[0] != '\t') || (str[0] != '\r') || (str[0] != '\n')) break; + + if ((flags & STRIP_SP) && (str[0] == ' ')) { + i++; + strcpy(str,str+1); + } + if ((flags & STRIP_TAB) && (str[0] == '\t')) { + i++; + strcpy(str,str+1); + } + if ((flags & STRIP_CR) && (str[0] == '\r')) { + i++; + strcpy(str,str+1); + } + if ((flags & STRIP_LF) && (str[0] == '\n')) { + i++; + strcpy(str,str+1); + } + } + return i; +} + + +///White space-trimming routine + +///Removes whitespace from right side of string, depending on the flags set (See STRIP_x definitions in xstring.h) +///Returns number of characters removed +int str_rtrim(char *str, int flags) { + unsigned int i=0; //mbg merge 7/17/06 changed to unsigned int + + while (strlen(str)) { + if ((str[strlen(str)-1] != ' ') || + (str[strlen(str)-1] != '\t') || + (str[strlen(str)-1] != '\r') || + (str[strlen(str)-1] != '\n')) break; + + if ((flags & STRIP_SP) && (str[0] == ' ')) { + i++; + str[strlen(str)-1] = 0; + } + if ((flags & STRIP_TAB) && (str[0] == '\t')) { + i++; + str[strlen(str)-1] = 0; + } + if ((flags & STRIP_CR) && (str[0] == '\r')) { + i++; + str[strlen(str)-1] = 0; + } + if ((flags & STRIP_LF) && (str[0] == '\n')) { + i++; + str[strlen(str)-1] = 0; + } + } + return i; +} + + +///White space-stripping routine + +///Removes whitespace depending on the flags set (See STRIP_x definitions in xstring.h) +///Returns number of characters removed, or -1 on error +int str_strip(char *str, int flags) { + unsigned int i=0,j=0; //mbg merge 7/17/06 changed to unsigned int + char *astr,chr; + + if (!strlen(str)) return -1; + if (!(flags & (STRIP_SP|STRIP_TAB|STRIP_CR|STRIP_LF))) return -1; + if (!(astr = (char*)malloc(strlen(str)+1))) return -1; + while (i < strlen(str)) { + chr = str[i++]; + if ((flags & STRIP_SP) && (chr == ' ')) chr = 0; + if ((flags & STRIP_TAB) && (chr == '\t')) chr = 0; + if ((flags & STRIP_CR) && (chr == '\r')) chr = 0; + if ((flags & STRIP_LF) && (chr == '\n')) chr = 0; + + if (chr) astr[j++] = chr; + } + astr[j] = 0; + strcpy(str,astr); + free(astr); + return j; +} + + +///Character replacement routine + +///Replaces all instances of 'search' with 'replace' +///Returns number of characters modified +int chr_replace(char *str, char search, char replace) { + unsigned int i=0,j=0; //mbg merge 7/17/06 changed to unsigned int + + while (i < strlen(str)) { + if (str[i] == search) { + str[i] = replace; + j++; + } + i++; + } + return j; +} + + +///Sub-String replacement routine + +///Replaces all instances of 'search' with 'replace' +///Returns number of sub-strings modified, or -1 on error +int str_replace(char *str, char *search, char *replace) { + unsigned int i=0,j=0; //mbg merge 7/17/06 changed to unsigned int + int searchlen,replacelen; + char *astr; + + searchlen = strlen(search); + replacelen = strlen(replace); + if ((!strlen(str)) || (!searchlen)) return -1; //note: allow *replace to have a length of zero! + if (!(astr = (char*)malloc(strlen(str)+1))) return -1; + while (i < strlen(str)) { + if (!strncmp(str+i,search,searchlen)) { + if (replacelen) memcpy(astr+j,replace,replacelen); + i += searchlen; + j += replacelen; + } + else astr[j++] = str[i++]; + } + astr[j] = 0; + strcpy(str,astr); + free(astr); + return j; +} + +static const struct Base64Table +{ + Base64Table() + { + size_t a=0; + for(a=0; a<256; ++a) data[a] = 0xFF; // mark everything as invalid by default + // create value->ascii mapping + a=0; + for(unsigned char c='A'; c<='Z'; ++c) data[a++] = c; // 0..25 + for(unsigned char c='a'; c<='z'; ++c) data[a++] = c; // 26..51 + for(unsigned char c='0'; c<='9'; ++c) data[a++] = c; // 52..61 + data[62] = '+'; // 62 + data[63] = '/'; // 63 + // create ascii->value mapping (but due to overlap, write it to highbit region) + for(a=0; a<64; ++a) data[data[a]^0x80] = a; // + data[((unsigned char)'=') ^ 0x80] = 0; + } + unsigned char operator[] (size_t pos) const { return data[pos]; } +private: + unsigned char data[256]; +} Base64Table; + +///Converts the provided data to a string in a standard, user-friendly, round-trippable format +std::string BytesToString(const void* data, int len) +{ + char temp[16]; + if(len==1) { + sprintf(temp,"%d",*(const unsigned char*)data); + return temp; + } else if(len==2) { + sprintf(temp,"%d",*(const unsigned short*)data); + return temp; + } else if(len==4) { + sprintf(temp,"%d",*(const unsigned int*)data); + return temp; + } + + std::string ret; + if(1) // use base64 + { + const unsigned char* src = (const unsigned char*)data; + ret = "base64:"; + for(int n; len > 0; len -= n) + { + unsigned char input[3] = {0,0,0}; + for(n=0; n<3 && n> 2 ], + Base64Table[ ((input[0] & 0x03) << 4) | (input[1] >> 4) ], + n<2 ? '=' : Base64Table[ ((input[1] & 0x0F) << 2) | (input[2] >> 6) ], + n<3 ? '=' : Base64Table[ input[2] & 0x3F ] + }; + ret.append(output, output+4); + } + } + else // use hex + { + ret.resize(len*2+2); + ret[0] = '0'; + ret[1] = 'x'; + for(int i=0;i>4); + int b = (((const unsigned char*)data)[i])&15; + if(a>9) a += 'A'-10; + else a += '0'; + if(b>9) b += 'A'-10; + else b += '0'; + ret[2+i*2] = a; + ret[2+i*2+1] = b; + } + } + return ret; +} + +///returns -1 if this is not a hex string +int HexStringToBytesLength(const std::string& str) +{ + if(str.size()>2 && str[0] == '0' && toupper(str[1]) == 'X') + return str.size()/2-1; + else return -1; +} + +int Base64StringToBytesLength(const std::string& str) +{ + if(str.size() < 7 || (str.size()-7) % 4 || str.substr(0,7) != "base64:") return -1; + + size_t c = ((str.size() - 7) / 4) * 3; + if(str[str.size()-1] == '=') { --c; + if(str[str.size()-2] == '=') --c; } + return c; +} + +///parses a string in the same format as BytesToString +///returns true if success. +bool StringToBytes(const std::string& str, void* data, int len) +{ + if(str.substr(0,7) == "base64:") + { + // base64 + unsigned char* tgt = (unsigned char*)data; + for(size_t pos = 7; pos < str.size() && len > 0; ) + { + unsigned char input[4], converted[4]; + for(int i=0; i<4; ++i) + { + if(pos >= str.size() && i > 0) return false; // invalid data + input[i] = str[pos++]; + if(input[i] & 0x80) return false; // illegal character + converted[i] = Base64Table[input[i]^0x80]; + if(converted[i] & 0x80) return false; // illegal character + } + unsigned char outpacket[3] = + { + (converted[0] << 2) | (converted[1] >> 4), + (converted[1] << 4) | (converted[2] >> 2), + (converted[2] << 6) | (converted[3]) + }; + int outlen = (input[2] == '=') ? 1 : (input[3] == '=' ? 2 : 3); + if(outlen > len) outlen = len; + memcpy(tgt, outpacket, outlen); + tgt += outlen; + len -= outlen; + } + return true; + } + if(str.size()>2 && str[0] == '0' && toupper(str[1]) == 'X') + { + // hex + int amt = len; + int bytesAvailable = str.size()/2; + if(bytesAvailable < amt) + amt = bytesAvailable; + const char* cstr = str.c_str()+2; + for(int i=0;i='A') a=a-'A'+10; + else a-='0'; + if(b>='A') b=b-'A'+10; + else b-='0'; + unsigned char val = ((unsigned char)a<<4)|(unsigned char)b; + ((unsigned char*)data)[i] = val; + } + return true; + } + + if(len==1) { + int x = atoi(str.c_str()); + *(unsigned char*)data = x; + return true; + } else if(len==2) { + int x = atoi(str.c_str()); + *(unsigned short*)data = x; + return true; + } else if(len==4) { + int x = atoi(str.c_str()); + *(unsigned int*)data = x; + return true; + } + //we can't handle it + return false; +} + +#include +#include +/// \brief convert input string into vector of string tokens +/// +/// \note consecutive delimiters will be treated as single delimiter +/// \note delimiters are _not_ included in return data +/// +/// \param input string to be parsed +/// \param delims list of delimiters. + +std::vector tokenize_str(const std::string & str, + const std::string & delims=", \t") +{ + using namespace std; + // Skip delims at beginning, find start of first token + string::size_type lastPos = str.find_first_not_of(delims, 0); + // Find next delimiter @ end of token + string::size_type pos = str.find_first_of(delims, lastPos); + + // output vector + vector tokens; + + while (string::npos != pos || string::npos != lastPos) + { + // Found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delims. Note the "not_of". this is beginning of token + lastPos = str.find_first_not_of(delims, pos); + // Find next delimiter at end of token. + pos = str.find_first_of(delims, lastPos); + } + + return tokens; +} + +//this code was taken from WINE (LGPL) +//http://google.com/codesearch?hl=en&q=+lang:c+splitpath+show:CPvw9Z-euls:_RSotQzmLeU:KGzljMEYFbY&sa=N&cd=9&ct=rc&cs_p=http://gentoo.osuosl.org/distfiles/Wine-20050524.tar.gz&cs_f=wine-20050524/programs/winefile/splitpath.c +void splitpath(const char* path, char* drv, char* dir, char* name, char* ext) +{ + const char* end; /* end of processed string */ + const char* p; /* search pointer */ + const char* s; /* copy pointer */ + + /* extract drive name */ + if (path[0] && path[1]==':') { + if (drv) { + *drv++ = *path++; + *drv++ = *path++; + *drv = '\0'; + } else path+=2; + } else if (drv) + *drv = '\0'; + + /* search for end of string or stream separator */ + for(end=path; *end && *end!=':'; ) + end++; + + /* search for begin of file extension */ + for(p=end; p>path && *--p!='\\' && *p!='/'; ) + if (*p == '.') { + end = p; + break; + } + + if (ext) + for(s=end; (*ext=*s++); ) + ext++; + else + for(s=end; *s++; ) {} + + /* search for end of directory name */ + for(p=end; p>path; ) + if (*--p=='\\' || *p=='/') { + p++; + break; + } + + if (name) { + for(s=p; s= '0' && s[i] <= '9') + { + v+=s[i]-'0'; + } + else if(s[i] >= 'a' && s[i] <= 'f') + { + v+=s[i]-'a'+10; + } + else if(s[i] >= 'A' && s[i] <= 'F') + { + v+=s[i]-'A'+10; + } + else + { + valid = false; + return 0xFFFF; + } + } + valid = true; + return v; +} + +char *U8ToDecStr(uint8 a) +{ + TempArray[0] = '0' + a/100; + TempArray[1] = '0' + (a%100)/10; + TempArray[2] = '0' + (a%10); + TempArray[3] = 0; + return TempArray; +} + +char *U16ToDecStr(uint16 a) +{ + TempArray[0] = '0' + a/10000; + TempArray[1] = '0' + (a%10000)/1000; + TempArray[2] = '0' + (a%1000)/100; + TempArray[3] = '0' + (a%100)/10; + TempArray[4] = '0' + (a%10); + TempArray[5] = 0; + return TempArray; +} + +char *U32ToDecStr(char* buf, uint32 a) +{ + buf[0] = '0' + a/1000000000; + buf[1] = '0' + (a%1000000000)/100000000; + buf[2] = '0' + (a%100000000)/10000000; + buf[3] = '0' + (a%10000000)/1000000; + buf[4] = '0' + (a%1000000)/100000; + buf[5] = '0' + (a%100000)/10000; + buf[6] = '0' + (a%10000)/1000; + buf[7] = '0' + (a%1000)/100; + buf[8] = '0' + (a%100)/10; + buf[9] = '0' + (a%10); + buf[10] = 0; + return buf; +} +char *U32ToDecStr(uint32 a) +{ + return U32ToDecStr(TempArray,a); +} + +char *U16ToHexStr(uint16 a) +{ + TempArray[0] = a/4096 > 9?'A'+a/4096-10:'0' + a/4096; + TempArray[1] = (a%4096)/256 > 9?'A'+(a%4096)/256 - 10:'0' + (a%4096)/256; + TempArray[2] = (a%256)/16 > 9?'A'+(a%256)/16 - 10:'0' + (a%256)/16; + TempArray[3] = a%16 > 9?'A'+(a%16) - 10:'0' + (a%16); + TempArray[4] = 0; + return TempArray; +} + +char *U8ToHexStr(uint8 a) +{ + TempArray[0] = a/16 > 9?'A'+a/16 - 10:'0' + a/16; + TempArray[1] = a%16 > 9?'A'+(a%16) - 10:'0' + (a%16); + TempArray[2] = 0; + return TempArray; +} + +std::string stditoa(int n) +{ + char tempbuf[16]; + sprintf(tempbuf, "%d", n); + return tempbuf; +} + + +std::string readNullTerminatedAscii(std::istream* is) +{ + std::string ret; + ret.reserve(50); + for(;;) + { + int c = is->get(); + if(c == 0) break; + else ret += (char)c; + } + return ret; +} + +// replace all instances of victim with replacement +std::string mass_replace(const std::string &source, const std::string &victim, const std::string &replacement) +{ + std::string answer = source; + std::string::size_type j = 0; + while ((j = answer.find(victim, j)) != std::string::npos ) + answer.replace(j, victim.length(), replacement); + return answer; +} + +//http://www.codeproject.com/KB/string/UtfConverter.aspx +#include "ConvertUTF.h" +namespace UtfConverter +{ + std::wstring FromUtf8(const std::string& utf8string) + { + size_t widesize = utf8string.length(); + if (sizeof(wchar_t) == 2) + { + wchar_t* widestringnative = new wchar_t[widesize+1]; + const UTF8* sourcestart = reinterpret_cast(utf8string.c_str()); + const UTF8* sourceend = sourcestart + widesize; + UTF16* targetstart = reinterpret_cast(widestringnative); + UTF16* targetend = targetstart + widesize+1; + ConversionResult res = ConvertUTF8toUTF16(&sourcestart, sourceend, &targetstart, targetend, strictConversion); + if (res != conversionOK) + { + delete [] widestringnative; + throw std::exception(); + } + *targetstart = 0; + std::wstring resultstring(widestringnative); + delete [] widestringnative; + return resultstring; + } + else if (sizeof(wchar_t) == 4) + { + wchar_t* widestringnative = new wchar_t[widesize]; + const UTF8* sourcestart = reinterpret_cast(utf8string.c_str()); + const UTF8* sourceend = sourcestart + widesize; + UTF32* targetstart = reinterpret_cast(widestringnative); + UTF32* targetend = targetstart + widesize; + ConversionResult res = ConvertUTF8toUTF32(&sourcestart, sourceend, &targetstart, targetend, strictConversion); + if (res != conversionOK) + { + delete [] widestringnative; + throw std::exception(); + } + *targetstart = 0; + std::wstring resultstring(widestringnative); + delete [] widestringnative; + return resultstring; + } + else + { + throw std::exception(); + } + return L""; + } + + std::string ToUtf8(const std::wstring& widestring) + { + size_t widesize = widestring.length(); + + if (sizeof(wchar_t) == 2) + { + size_t utf8size = 3 * widesize + 1; + char* utf8stringnative = new char[utf8size]; + const UTF16* sourcestart = reinterpret_cast(widestring.c_str()); + const UTF16* sourceend = sourcestart + widesize; + UTF8* targetstart = reinterpret_cast(utf8stringnative); + UTF8* targetend = targetstart + utf8size; + ConversionResult res = ConvertUTF16toUTF8(&sourcestart, sourceend, &targetstart, targetend, strictConversion); + if (res != conversionOK) + { + delete [] utf8stringnative; + throw std::exception(); + } + *targetstart = 0; + std::string resultstring(utf8stringnative); + delete [] utf8stringnative; + return resultstring; + } + else if (sizeof(wchar_t) == 4) + { + size_t utf8size = 4 * widesize + 1; + char* utf8stringnative = new char[utf8size]; + const UTF32* sourcestart = reinterpret_cast(widestring.c_str()); + const UTF32* sourceend = sourcestart + widesize; + UTF8* targetstart = reinterpret_cast(utf8stringnative); + UTF8* targetend = targetstart + utf8size; + ConversionResult res = ConvertUTF32toUTF8(&sourcestart, sourceend, &targetstart, targetend, strictConversion); + if (res != conversionOK) + { + delete [] utf8stringnative; + throw std::exception(); + } + *targetstart = 0; + std::string resultstring(utf8stringnative); + delete [] utf8stringnative; + return resultstring; + } + else + { + throw std::exception(); + } + return ""; + } +} + +//convert a std::string to std::wstring +std::wstring mbstowcs(std::string str) +{ + try { + return UtfConverter::FromUtf8(str); + } catch(std::exception) { + return L"(failed UTF-8 conversion)"; + } +} + +std::string wcstombs(std::wstring str) +{ + return UtfConverter::ToUtf8(str); +} + + +//TODO - dont we already have another function that can do this +std::string getExtension(const char* input) { + char buf[1024]; + strcpy(buf,input); + char* dot=strrchr(buf,'.'); + if(!dot) + return ""; + char ext [512]; + strcpy(ext, dot+1); + int k, extlen=strlen(ext); + for(k=0;k +#include +#include +#include +#include + +#include "types.h" + + +//definitions for str_strip() flags +#define STRIP_SP 0x01 // space +#define STRIP_TAB 0x02 // tab +#define STRIP_CR 0x04 // carriage return +#define STRIP_LF 0x08 // line feed + + +int str_ucase(char *str); +int str_lcase(char *str); +int str_ltrim(char *str, int flags); +int str_rtrim(char *str, int flags); +int str_strip(char *str, int flags); +int chr_replace(char *str, char search, char replace); +int str_replace(char *str, char *search, char *replace); + +int HexStringToBytesLength(const std::string& str); +int Base64StringToBytesLength(const std::string& str); +std::string BytesToString(const void* data, int len); +bool StringToBytes(const std::string& str, void* data, int len); + +std::vector tokenize_str(const std::string & str,const std::string & delims); +void splitpath(const char* path, char* drv, char* dir, char* name, char* ext); + +uint16 FastStrToU16(char* s, bool& valid); +char *U16ToDecStr(uint16 a); +char *U32ToDecStr(uint32 a); +char *U32ToDecStr(char* buf, uint32 a); +char *U8ToDecStr(uint8 a); +char *U8ToHexStr(uint8 a); +char *U16ToHexStr(uint16 a); + +std::string stditoa(int n); + +std::string readNullTerminatedAscii(std::istream* is); + +//extracts a decimal uint from an istream +template T templateIntegerDecFromIstream(std::istream* is) +{ + unsigned int ret = 0; + bool pre = true; + + for(;;) + { + int c = is->get(); + if(c == -1) return ret; + int d = c - '0'; + if((d<0 || d>9)) + { + if(!pre) + break; + } + else + { + pre = false; + ret *= 10; + ret += d; + } + } + is->unget(); + return ret; +} + +inline u32 u32DecFromIstream(std::istream* is) { return templateIntegerDecFromIstream(is); } +inline u64 u64DecFromIstream(std::istream* is) { return templateIntegerDecFromIstream(is); } + +//puts an optionally 0-padded decimal integer of type T into the ostream (0-padding is quicker) +template void putdec(std::ostream* os, T dec) +{ + char temp[DIGITS]; + int ctr = 0; + for(int i=0;iwrite(temp+DIGITS-ctr-1,ctr+1); + else + os->write(temp,DIGITS); +} + +std::string mass_replace(const std::string &source, const std::string &victim, const std::string &replacement); + +std::wstring mbstowcs(std::string str); +std::string wcstombs(std::wstring str); + + + +//TODO - dont we already have another function that can do this +std::string getExtension(const char* input); + + +#endif diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index 24546c4d7..745c1abf1 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -58,9 +58,11 @@ ExceptionHandling="1" BufferSecurityCheck="false" EnableEnhancedInstructionSet="0" + WarningLevel="1" DebugInformationFormat="4" CallingConvention="0" CompileAs="0" + DisableSpecificWarnings="4244" /> + + + + + + + + + + + + + + + + + + + + @@ -1011,6 +1053,14 @@ RelativePath="..\MMU.h" > + + + + diff --git a/desmume/src/windows/inputdx.cpp b/desmume/src/windows/inputdx.cpp index 8c880918e..2b089ef38 100644 --- a/desmume/src/windows/inputdx.cpp +++ b/desmume/src/windows/inputdx.cpp @@ -29,6 +29,7 @@ #include "..\MMU.h" #include "..\common.h" #include "resource.h" +#include "NDSSystem.h" // ==================================================== emu input // ======================================================================= @@ -174,6 +175,21 @@ const char *DIkeysNames[0xEF] = }; const char *DIJoyNames[0x04] = { "JUp", "JDown", "JLeft", "JRight" }; +#define KEY_A 0 +#define KEY_B 1 +#define KEY_SELECT 2 +#define KEY_START 3 +#define KEY_RIGHT 4 +#define KEY_LEFT 5 +#define KEY_UP 6 +#define KEY_DOWN 7 +#define KEY_R 8 +#define KEY_L 9 +#define KEY_X 10 +#define KEY_Y 11 +#define KEY_DEBUG 12 + + char *keyPadNames [MAXKEYPAD] = { "A", "B", "SELECT", "START", "RIGHT", "LEFT", "UP", "DOWN", "R", "L", "X", "Y", "DEBUG", "FOLD", "POWER" }; @@ -386,30 +402,21 @@ void NDS_inputPost(BOOL paused, LPSTR buf) { if (paused) return; - u16 pad = (0 | - ((~buf[keyPad[0]] & 0x80) >> 7) | - ((~buf[keyPad[1]] & 0x80) >> 6) | - ((~buf[keyPad[2]] & 0x80) >> 5) | - ((~buf[keyPad[3]] & 0x80) >> 4) | - ((~buf[keyPad[4]] & 0x80) >> 3) | - ((~buf[keyPad[5]] & 0x80) >> 2) | - ((~buf[keyPad[6]] & 0x80) >> 1) | - ((~buf[keyPad[7]] & 0x80)) | - ((~buf[keyPad[8]] & 0x80) << 1) | - ((~buf[keyPad[9]] & 0x80) << 2)) ; + bool R = (buf[keyPad[KEY_RIGHT]] & 0x80)!=0; + bool L = (buf[keyPad[KEY_LEFT]] & 0x80)!=0; + bool D = (buf[keyPad[KEY_DOWN]] & 0x80)!=0; + bool U = (buf[keyPad[KEY_UP]] & 0x80)!=0; + bool T = (buf[keyPad[KEY_START]] & 0x80)!=0; + bool S = (buf[keyPad[KEY_SELECT]] & 0x80)!=0; + bool B = (buf[keyPad[KEY_B]] & 0x80)!=0; + bool A = (buf[keyPad[KEY_A]] & 0x80)!=0; + bool Y = (buf[keyPad[KEY_Y]] & 0x80)!=0; + bool X = (buf[keyPad[KEY_X]] & 0x80)!=0; + bool W = (buf[keyPad[KEY_L]] & 0x80)!=0; + bool E = (buf[keyPad[KEY_R]] & 0x80)!=0; + bool G = (buf[keyPad[KEY_DEBUG]] & 0x80)!=0; - ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] = (u16)pad; - ((u16 *)MMU.ARM7_REG)[0x130>>1] = (u16)pad; - - u16 padExt = (((u16 *)MMU.ARM7_REG)[0x136>>1] & 0x00F0) | - ((~buf[keyPad[10]] & 0x80) >> 7) | - ((~buf[keyPad[11]] & 0x80) >> 6) | - ((~buf[keyPad[12]] & 0x80) >> 4) | - 0x0034; - - ((u16 *)MMU.ARM7_REG)[0x136>>1] = (u16)padExt; - - // TODO: low power IRQ + NDS_setPad( R, L, D, U, T, S, B, A, Y, X, W, E, G); } // TODO diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 8714b2b13..4256fb3ae 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -1,119 +1,122 @@ -/* Copyright (C) 2006 yopyop - yopyop156@ifrance.com - yopyop156.ifrance.com - - Copyright 2006 Theo Berkau - - This file is part of DeSmuME - - DeSmuME is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - DeSmuME is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with DeSmuME; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "windriver.h" -#include -#include -#include -#include -#include -#include +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + Copyright 2006 Theo Berkau + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "windriver.h" +#include +#include +#include +#include +#include +#include #include #include -#include "CWindow.h" -#include "../MMU.h" -#include "../armcpu.h" -#include "../NDSSystem.h" -#include "../debug.h" -#include "../saves.h" -#include "../cflash.h" -#include "resource.h" -#include "memView.h" -#include "disView.h" -#include "ginfo.h" -#include "IORegView.h" -#include "palView.h" -#include "tileView.h" -#include "oamView.h" -#include "mapview.h" -#include "matrixview.h" -#include "lightview.h" -#include "inputdx.h" -#include "FirmConfig.h" -#include "AboutBox.h" -#include "OGLRender.h" -#include "../gfx3d.h" -#include "../render3D.h" -#include "../gdbstub.h" -#include "colorctrl.h" -#include "console.h" -#include "throttle.h" - +#include "CWindow.h" +#include "../MMU.h" +#include "../armcpu.h" +#include "../NDSSystem.h" +#include "../debug.h" +#include "../saves.h" +#include "../cflash.h" +#include "resource.h" +#include "memView.h" +#include "disView.h" +#include "ginfo.h" +#include "IORegView.h" +#include "palView.h" +#include "tileView.h" +#include "oamView.h" +#include "mapview.h" +#include "matrixview.h" +#include "lightview.h" +#include "inputdx.h" +#include "FirmConfig.h" +#include "AboutBox.h" +#include "OGLRender.h" +#include "../gfx3d.h" +#include "../render3D.h" +#include "../gdbstub.h" +#include "colorctrl.h" +#include "console.h" +#include "throttle.h" + #include "../common.h" -#include "snddx.h" - -#include "directx/ddraw.h" - -#define GPU3D_NULL 0 -#define GPU3D_OPENGL 1 +#include "snddx.h" + +#include "directx/ddraw.h" + +#define GPU3D_NULL 0 +#define GPU3D_OPENGL 1 //------todo move these into a generic driver api bool DRV_AviBegin(const char* fname); void DRV_AviEnd(); void DRV_AviSoundUpdate(void* soundData, int soundLen); bool DRV_AviIsRecording(); -void DRV_AviVideoUpdate(const u16* buffer); -//------ - -CRITICAL_SECTION win_sync; -volatile int win_sound_samplecounter = 0; - -//===================== DirectDraw vars -LPDIRECTDRAW7 lpDDraw=NULL; -LPDIRECTDRAWSURFACE7 lpPrimarySurface=NULL; -LPDIRECTDRAWSURFACE7 lpBackSurface=NULL; -DDSURFACEDESC2 ddsd; -LPDIRECTDRAWCLIPPER lpDDClipPrimary=NULL; -LPDIRECTDRAWCLIPPER lpDDClipBack=NULL; - -//===================== Input vars -INPUTCLASS *input = NULL; - -/* The compact flash disk image file */ -static const char *bad_glob_cflash_disk_image_file; -static char cflash_filename_buffer[512]; - -/* Declare Windows procedure */ -LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); - -/* Make the class name into a global variable */ -char SavName[MAX_PATH] = ""; -char ImportSavName[MAX_PATH] = ""; -char szClassName[ ] = "DeSmuME"; -int romnum = 0; - -DWORD threadID; - +void DRV_AviVideoUpdate(const u16* buffer); +//------ + +CRITICAL_SECTION win_sync; +volatile int win_sound_samplecounter = 0; + +Lock::Lock() { EnterCriticalSection(&win_sync); } +Lock::~Lock() { LeaveCriticalSection(&win_sync); } + +//===================== DirectDraw vars +LPDIRECTDRAW7 lpDDraw=NULL; +LPDIRECTDRAWSURFACE7 lpPrimarySurface=NULL; +LPDIRECTDRAWSURFACE7 lpBackSurface=NULL; +DDSURFACEDESC2 ddsd; +LPDIRECTDRAWCLIPPER lpDDClipPrimary=NULL; +LPDIRECTDRAWCLIPPER lpDDClipBack=NULL; + +//===================== Input vars +INPUTCLASS *input = NULL; + +/* The compact flash disk image file */ +static const char *bad_glob_cflash_disk_image_file; +static char cflash_filename_buffer[512]; + +/* Declare Windows procedure */ +LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); + +/* Make the class name into a global variable */ +char SavName[MAX_PATH] = ""; +char ImportSavName[MAX_PATH] = ""; +char szClassName[ ] = "DeSmuME"; +int romnum = 0; + +DWORD threadID; + WINCLASS *MainWindow=NULL; //HWND hwnd; //HDC hdc; -HACCEL hAccel; +HACCEL hAccel; HINSTANCE hAppInst; -RECT MainWindowRect; +RECT MainWindowRect; int WndX = 0; int WndY = 0; - + //=========================== view tools TOOLSCLASS *ViewDisasm_ARM7 = NULL; TOOLSCLASS *ViewDisasm_ARM9 = NULL; @@ -128,342 +131,340 @@ TOOLSCLASS *ViewMatrices = NULL; TOOLSCLASS *ViewLights = NULL; -volatile BOOL execute = FALSE; -volatile BOOL paused = TRUE; -u32 glock = 0; - -BOOL click = FALSE; - -BOOL finished = FALSE; -BOOL romloaded = FALSE; - +volatile BOOL execute = FALSE; +volatile BOOL paused = TRUE; +u32 glock = 0; + +BOOL click = FALSE; + +BOOL finished = FALSE; +BOOL romloaded = FALSE; + void SetRotate(HWND hwnd, int rot); - -BOOL ForceRatio = TRUE; -float DefaultWidth; -float DefaultHeight; -float widthTradeOff; -float heightTradeOff; - -HMENU menu; -HANDLE runthread_ready=INVALID_HANDLE_VALUE; -HANDLE runthread=INVALID_HANDLE_VALUE; - + +BOOL ForceRatio = TRUE; +float DefaultWidth; +float DefaultHeight; +float widthTradeOff; +float heightTradeOff; + +HMENU menu; + //static char IniName[MAX_PATH]; -int sndcoretype=SNDCORE_DIRECTX; -int sndbuffersize=735*4; -int sndvolume=100; - -SoundInterface_struct *SNDCoreList[] = { -&SNDDummy, -&SNDFile, -&SNDDIRECTX, -NULL -}; - -GPU3DInterface *core3DList[] = { -&gpu3DNull, -&gpu3Dgl, -}; - -int autoframeskipenab=1; -int frameskiprate=0; -int emu_paused = 0; -static int backupmemorytype=MC_TYPE_AUTODETECT; -static u32 backupmemorysize=1; -unsigned int frameCounter=0; -bool frameAdvance = false; -bool frameCounterDisplay = false; +int sndcoretype=SNDCORE_DIRECTX; +int sndbuffersize=735*4; +int sndvolume=100; + +SoundInterface_struct *SNDCoreList[] = { +&SNDDummy, +&SNDFile, +&SNDDIRECTX, +NULL +}; + +GPU3DInterface *core3DList[] = { +&gpu3DNull, +&gpu3Dgl, +}; + +int autoframeskipenab=1; +int frameskiprate=0; +int emu_paused = 0; +static int backupmemorytype=MC_TYPE_AUTODETECT; +static u32 backupmemorysize=1; +unsigned int frameCounter=0; +bool frameAdvance = false; +bool frameCounterDisplay = false; bool FpsDisplay = false; -unsigned short windowSize = 0; - +unsigned short windowSize = 0; + unsigned int lastSaveState = 0; //Keeps track of last savestate used for quick save/load functions std::stringstream MessageToDisplay; //temp variable to store message that will be displayed via DisplayMessage function int displayMessageCounter = 0; //Counter to keep track with how long to display messages on screen -/* the firmware settings */ -struct NDS_fw_config_data win_fw_config; - - -LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam); - -struct configured_features { - u16 arm9_gdb_port; - u16 arm7_gdb_port; - - const char *cflash_disk_image_file; -}; - -static void -init_configured_features( struct configured_features *config) { - config->arm9_gdb_port = 0; - config->arm7_gdb_port = 0; - - config->cflash_disk_image_file = NULL; -} - - -static int -fill_configured_features( struct configured_features *config, LPSTR lpszArgument) { - int good_args = 0; - LPTSTR cmd_line; - LPWSTR *argv; - int argc; - - argv = CommandLineToArgvW( GetCommandLineW(), &argc); - - if ( argv != NULL) { - int i; - good_args = 1; - for ( i = 1; i < argc && good_args; i++) { - if ( wcsncmp( argv[i], L"--arm9gdb=", 10) == 0) { - wchar_t *end_char; - unsigned long port_num = wcstoul( &argv[i][10], &end_char, 10); - - if ( port_num > 0 && port_num < 65536) { - config->arm9_gdb_port = port_num; - } - else { - MessageBox(NULL,"ARM9 GDB stub port must be in the range 1 to 65535","Error",MB_OK); - good_args = 0; - } - } - else if ( wcsncmp( argv[i], L"--arm7gdb=", 10) == 0) { - wchar_t *end_char; - unsigned long port_num = wcstoul( &argv[i][10], &end_char, 10); - - if ( port_num > 0 && port_num < 65536) { - config->arm7_gdb_port = port_num; - } - else { - MessageBox(NULL,"ARM9 GDB stub port must be in the range 1 to 65535","Error",MB_OK); - good_args = 0; - } - } - else if ( wcsncmp( argv[i], L"--cflash=", 9) == 0) { - if ( config->cflash_disk_image_file == NULL) { - size_t convert_count = wcstombs( &cflash_filename_buffer[0], &argv[i][9], 512); - if ( convert_count > 0) { - config->cflash_disk_image_file = cflash_filename_buffer; - } - } - else { - MessageBox(NULL,"CFlash disk image file already set","Error",MB_OK); - good_args = 0; - } - } - } - LocalFree( argv); - } - - return good_args; -} - -// Rotation definitions -short GPU_rotation = 0; -DWORD GPU_width = 256; -DWORD GPU_height = 192*2; -DWORD rotationstartscan = 192; -DWORD rotationscanlines = 192*2; - -void SetWindowClientSize(HWND hwnd, int cx, int cy) //found at: http://blogs.msdn.com/oldnewthing/archive/2003/09/11/54885.aspx -{ - HMENU hmenu = GetMenu(hwnd); - RECT rcWindow = { 0, 0, cx, cy }; - - /* - * First convert the client rectangle to a window rectangle the - * menu-wrap-agnostic way. - */ - AdjustWindowRect(&rcWindow, WS_CAPTION| WS_SYSMENU |WS_MINIMIZEBOX | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, hmenu != NULL); - - /* - * If there is a menu, then check how much wrapping occurs - * when we set a window to the width specified by AdjustWindowRect - * and an infinite amount of height. An infinite height allows - * us to see every single menu wrap. - */ - if (hmenu) { - RECT rcTemp = rcWindow; - rcTemp.bottom = 0x7FFF; /* "Infinite" height */ - SendMessage(hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rcTemp); - - /* - * Adjust our previous calculation to compensate for menu - * wrapping. - */ - rcWindow.bottom += rcTemp.top; - } +/* the firmware settings */ +struct NDS_fw_config_data win_fw_config; + + +LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, + LPARAM lParam); + +struct configured_features { + u16 arm9_gdb_port; + u16 arm7_gdb_port; + + const char *cflash_disk_image_file; +}; + +static void +init_configured_features( struct configured_features *config) { + config->arm9_gdb_port = 0; + config->arm7_gdb_port = 0; + + config->cflash_disk_image_file = NULL; +} + + +static int +fill_configured_features( struct configured_features *config, LPSTR lpszArgument) { + int good_args = 0; + LPTSTR cmd_line; + LPWSTR *argv; + int argc; + + argv = CommandLineToArgvW( GetCommandLineW(), &argc); + + if ( argv != NULL) { + int i; + good_args = 1; + for ( i = 1; i < argc && good_args; i++) { + if ( wcsncmp( argv[i], L"--arm9gdb=", 10) == 0) { + wchar_t *end_char; + unsigned long port_num = wcstoul( &argv[i][10], &end_char, 10); + + if ( port_num > 0 && port_num < 65536) { + config->arm9_gdb_port = port_num; + } + else { + MessageBox(NULL,"ARM9 GDB stub port must be in the range 1 to 65535","Error",MB_OK); + good_args = 0; + } + } + else if ( wcsncmp( argv[i], L"--arm7gdb=", 10) == 0) { + wchar_t *end_char; + unsigned long port_num = wcstoul( &argv[i][10], &end_char, 10); + + if ( port_num > 0 && port_num < 65536) { + config->arm7_gdb_port = port_num; + } + else { + MessageBox(NULL,"ARM9 GDB stub port must be in the range 1 to 65535","Error",MB_OK); + good_args = 0; + } + } + else if ( wcsncmp( argv[i], L"--cflash=", 9) == 0) { + if ( config->cflash_disk_image_file == NULL) { + size_t convert_count = wcstombs( &cflash_filename_buffer[0], &argv[i][9], 512); + if ( convert_count > 0) { + config->cflash_disk_image_file = cflash_filename_buffer; + } + } + else { + MessageBox(NULL,"CFlash disk image file already set","Error",MB_OK); + good_args = 0; + } + } + } + LocalFree( argv); + } + + return good_args; +} + +// Rotation definitions +short GPU_rotation = 0; +DWORD GPU_width = 256; +DWORD GPU_height = 192*2; +DWORD rotationstartscan = 192; +DWORD rotationscanlines = 192*2; + +void SetWindowClientSize(HWND hwnd, int cx, int cy) //found at: http://blogs.msdn.com/oldnewthing/archive/2003/09/11/54885.aspx +{ + HMENU hmenu = GetMenu(hwnd); + RECT rcWindow = { 0, 0, cx, cy }; + + /* + * First convert the client rectangle to a window rectangle the + * menu-wrap-agnostic way. + */ + AdjustWindowRect(&rcWindow, WS_CAPTION| WS_SYSMENU |WS_MINIMIZEBOX | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, hmenu != NULL); + + /* + * If there is a menu, then check how much wrapping occurs + * when we set a window to the width specified by AdjustWindowRect + * and an infinite amount of height. An infinite height allows + * us to see every single menu wrap. + */ + if (hmenu) { + RECT rcTemp = rcWindow; + rcTemp.bottom = 0x7FFF; /* "Infinite" height */ + SendMessage(hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rcTemp); + + /* + * Adjust our previous calculation to compensate for menu + * wrapping. + */ + rcWindow.bottom += rcTemp.top; + } SetWindowPos(hwnd, NULL, WndX, WndY, rcWindow.right - rcWindow.left, - rcWindow.bottom - rcWindow.top, SWP_NOMOVE | SWP_NOZORDER); - - if (lpBackSurface!=NULL) - { - IDirectDrawSurface7_Release(lpBackSurface); - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - ddsd.dwWidth = cx; - ddsd.dwHeight = cy; - - IDirectDraw7_CreateSurface(lpDDraw, &ddsd, &lpBackSurface, NULL); - } -} - -void ResizingLimit(int wParam, RECT *rc) -{ - u32 width = (rc->right - rc->left); - u32 height = (rc->bottom - rc->top); - - u32 minX = 256; - u32 minY = 414; - - //printlog("width=%i; height=%i\n", width, height); - - if (GPU_rotation == 90 || GPU_rotation == 270) - { - minX = 390; - minY = 272; - } - switch (wParam) - { - case WMSZ_LEFT: - { - if (widthleft=rc->left+(width-minX); - return; - } - - case WMSZ_RIGHT: - { - if (widthright=rc->left+minX; - return; - } - - case WMSZ_TOP: - { - if (heighttop=rc->top+(height-minY); - return; - } - - case WMSZ_BOTTOM: - { - if (heightbottom=rc->top+minY; - return; - } - - case WMSZ_TOPLEFT: - { - if (heighttop=rc->top+(height-minY); - if (widthleft=rc->left+(width-minX); - return; - } - case WMSZ_BOTTOMLEFT: - { - if (heightbottom=rc->top+minY; - if (widthleft=rc->left+(width-minX); - return; - } - - case WMSZ_TOPRIGHT: - { - if (heighttop=rc->top+(height-minY); - if (widthright=rc->left+minX; - return; - } - - case WMSZ_BOTTOMRIGHT: - { - if (heightbottom=rc->top+minY; - if (widthright=rc->left+minX; - return; - } - } - -} - -void ScallingScreen(HWND hwnd, int wParam, RECT *rc) -{ - float aspect; - u32 width; - u32 height; - u32 width2; - u32 height2; - - width = (rc->right - rc->left - widthTradeOff); - height = (rc->bottom - rc->top - heightTradeOff); - - if (width == height) return; - - if (GPU_rotation == 0 || GPU_rotation == 180) - { - aspect = DefaultWidth / DefaultHeight; - } - else - { - aspect = DefaultHeight / DefaultWidth; - } - - switch (wParam) - { - case WMSZ_LEFT: - case WMSZ_RIGHT: - { - height = (int)(width / aspect); - rc->bottom=rc->top+height+heightTradeOff; - return; - } - - case WMSZ_TOP: - case WMSZ_BOTTOM: - { - width = (int)(height * aspect); - rc->right=rc->left+width+widthTradeOff; - return; - } - - case WMSZ_TOPLEFT: - { - width = (int)(height * aspect); - rc->left=rc->right-width-widthTradeOff; - return; - } - case WMSZ_BOTTOMLEFT: - { - height = (int)(width / aspect); - rc->bottom=rc->top + height + heightTradeOff; - return; - } - - case WMSZ_TOPRIGHT: - case WMSZ_BOTTOMRIGHT: - { - width = (int)(height * aspect); - rc->right=rc->left+width+widthTradeOff; - return; - } - } -} - -void ScaleScreen(HWND hwnd, float factor) -{ - - if ((GPU_rotation==0)||(GPU_rotation==180)) - { + rcWindow.bottom - rcWindow.top, SWP_NOMOVE | SWP_NOZORDER); + + if (lpBackSurface!=NULL) + { + IDirectDrawSurface7_Release(lpBackSurface); + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + ddsd.dwWidth = cx; + ddsd.dwHeight = cy; + + IDirectDraw7_CreateSurface(lpDDraw, &ddsd, &lpBackSurface, NULL); + } +} + +void ResizingLimit(int wParam, RECT *rc) +{ + u32 width = (rc->right - rc->left); + u32 height = (rc->bottom - rc->top); + + u32 minX = 256; + u32 minY = 414; + + //printlog("width=%i; height=%i\n", width, height); + + if (GPU_rotation == 90 || GPU_rotation == 270) + { + minX = 390; + minY = 272; + } + switch (wParam) + { + case WMSZ_LEFT: + { + if (widthleft=rc->left+(width-minX); + return; + } + + case WMSZ_RIGHT: + { + if (widthright=rc->left+minX; + return; + } + + case WMSZ_TOP: + { + if (heighttop=rc->top+(height-minY); + return; + } + + case WMSZ_BOTTOM: + { + if (heightbottom=rc->top+minY; + return; + } + + case WMSZ_TOPLEFT: + { + if (heighttop=rc->top+(height-minY); + if (widthleft=rc->left+(width-minX); + return; + } + case WMSZ_BOTTOMLEFT: + { + if (heightbottom=rc->top+minY; + if (widthleft=rc->left+(width-minX); + return; + } + + case WMSZ_TOPRIGHT: + { + if (heighttop=rc->top+(height-minY); + if (widthright=rc->left+minX; + return; + } + + case WMSZ_BOTTOMRIGHT: + { + if (heightbottom=rc->top+minY; + if (widthright=rc->left+minX; + return; + } + } + +} + +void ScaleScreen(HWND hwnd, int wParam, RECT *rc) +{ + float aspect; + u32 width; + u32 height; + u32 width2; + u32 height2; + + width = (rc->right - rc->left - widthTradeOff); + height = (rc->bottom - rc->top - heightTradeOff); + + if (width == height) return; + + if (GPU_rotation == 0 || GPU_rotation == 180) + { + aspect = DefaultWidth / DefaultHeight; + } + else + { + aspect = DefaultHeight / DefaultWidth; + } + + switch (wParam) + { + case WMSZ_LEFT: + case WMSZ_RIGHT: + { + height = (int)(width / aspect); + rc->bottom=rc->top+height+heightTradeOff; + return; + } + + case WMSZ_TOP: + case WMSZ_BOTTOM: + { + width = (int)(height * aspect); + rc->right=rc->left+width+widthTradeOff; + return; + } + + case WMSZ_TOPLEFT: + { + width = (int)(height * aspect); + rc->left=rc->right-width-widthTradeOff; + return; + } + case WMSZ_BOTTOMLEFT: + { + height = (int)(width / aspect); + rc->bottom=rc->top + height + heightTradeOff; + return; + } + + case WMSZ_TOPRIGHT: + case WMSZ_BOTTOMRIGHT: + { + width = (int)(height * aspect); + rc->right=rc->left+width+widthTradeOff; + return; + } + } +} + +void ScaleScreen(HWND hwnd, float factor) +{ + + if ((GPU_rotation==0)||(GPU_rotation==180)) + { SetWindowPos(hwnd, NULL, WndX, WndY, widthTradeOff + DefaultWidth * factor, - heightTradeOff + DefaultHeight * factor, SWP_NOMOVE | SWP_NOZORDER); - } - else - if ((GPU_rotation==90)||(GPU_rotation==270)) - { + heightTradeOff + DefaultHeight * factor, SWP_NOMOVE | SWP_NOZORDER); + } + else + if ((GPU_rotation==90)||(GPU_rotation==270)) + { SetWindowPos(hwnd, NULL, WndX, WndY, heightTradeOff + DefaultHeight * factor, - widthTradeOff + DefaultWidth * factor, SWP_NOMOVE | SWP_NOZORDER); - } -} - + widthTradeOff + DefaultWidth * factor, SWP_NOMOVE | SWP_NOZORDER); + } +} + void translateXY(s32& x, s32& y) -{ +{ s32 tx=x, ty=y; switch(GPU_rotation) { @@ -481,164 +482,164 @@ void translateXY(s32& x, s32& y) y = (tx-192); break; } -} - - // END Rotation definitions - -int CreateDDrawBuffers() -{ - if (lpDDClipPrimary!=NULL) IDirectDraw7_Release(lpDDClipPrimary); - if (lpPrimarySurface != NULL) IDirectDraw7_Release(lpPrimarySurface); - if (lpBackSurface != NULL) IDirectDraw7_Release(lpBackSurface); - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - ddsd.dwFlags = DDSD_CAPS; - if (IDirectDraw7_CreateSurface(lpDDraw, &ddsd, &lpPrimarySurface, NULL) != DD_OK) return -1; - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - - if ( (GPU_rotation == 0) || (GPU_rotation == 180) ) - { - ddsd.dwWidth = 256; - ddsd.dwHeight = 384; - } - else - if ( (GPU_rotation == 90) || (GPU_rotation == 270) ) - { - ddsd.dwWidth = 384; - ddsd.dwHeight = 256; - } - - if (IDirectDraw7_CreateSurface(lpDDraw, &ddsd, &lpBackSurface, NULL) != DD_OK) return -2; - - if (IDirectDraw7_CreateClipper(lpDDraw, 0, &lpDDClipPrimary, NULL) != DD_OK) return -3; - +} + + // END Rotation definitions + +int CreateDDrawBuffers() +{ + if (lpDDClipPrimary!=NULL) IDirectDraw7_Release(lpDDClipPrimary); + if (lpPrimarySurface != NULL) IDirectDraw7_Release(lpPrimarySurface); + if (lpBackSurface != NULL) IDirectDraw7_Release(lpBackSurface); + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + ddsd.dwFlags = DDSD_CAPS; + if (IDirectDraw7_CreateSurface(lpDDraw, &ddsd, &lpPrimarySurface, NULL) != DD_OK) return -1; + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + + if ( (GPU_rotation == 0) || (GPU_rotation == 180) ) + { + ddsd.dwWidth = 256; + ddsd.dwHeight = 384; + } + else + if ( (GPU_rotation == 90) || (GPU_rotation == 270) ) + { + ddsd.dwWidth = 384; + ddsd.dwHeight = 256; + } + + if (IDirectDraw7_CreateSurface(lpDDraw, &ddsd, &lpBackSurface, NULL) != DD_OK) return -2; + + if (IDirectDraw7_CreateClipper(lpDDraw, 0, &lpDDClipPrimary, NULL) != DD_OK) return -3; + if (IDirectDrawClipper_SetHWnd(lpDDClipPrimary, 0, MainWindow->getHWnd()) != DD_OK) return -4; - if (IDirectDrawSurface7_SetClipper(lpPrimarySurface, lpDDClipPrimary) != DD_OK) return -5; - - return 1; -} - - -void Display() -{ - int res; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - ddsd.dwFlags=DDSD_ALL; - res=IDirectDrawSurface7_Lock(lpBackSurface,NULL,&ddsd,DDLOCK_WAIT, NULL); - - if (res == DD_OK) - { - char* buffer = (char*)ddsd.lpSurface; - - int i, j, sz=256*sizeof(u32); - if (ddsd.ddpfPixelFormat.dwRGBBitCount>16) - { - u16 *tmpGPU_Screen_src=(u16*)GPU_screen; - u32 tmpGPU_screen[98304]; - for(i=0; i<98304; i++) - tmpGPU_screen[i]= (((tmpGPU_Screen_src[i]>>10)&0x1F)<<3)| - (((tmpGPU_Screen_src[i]>>5)&0x1F)<<11)| - (((tmpGPU_Screen_src[i])&0x1F)<<19); - switch (GPU_rotation) - { - case 0: - { - for (i = 0; i < 98304; i+=256) //384*256 - { - memcpy(buffer,tmpGPU_screen+i,sz); - buffer += ddsd.lPitch; - } - break; - } - case 90: - { - u32 start; - for (j=0; j<256; j++) - { - start=98304+j; - for (i=0; i<384; i++) - { - start-=256; - ((u32*)buffer)[i]=((u32 *)tmpGPU_screen)[start]; - } - buffer += ddsd.lPitch; - } - break; - } - case 180: - { - u32 start=98300; - for (j=0; j<384; j++) - { - for (i=0; i<256; i++, --start) - ((u32*)buffer)[i]=((u32 *)tmpGPU_screen)[start]; - buffer += ddsd.lPitch; - } - break; - } - case 270: - { - u32 start; - for (j=0; j<256; j++) - { - start=256-j; - for (i=0; i<384; i++) - { - ((u32*)buffer)[i]=((u32 *)tmpGPU_screen)[start]; - start+=256; - } - buffer += ddsd.lPitch; - } - break; - } - } - } - else - printlog("16bit depth color not supported"); - IDirectDrawSurface7_Unlock(lpBackSurface,(LPRECT)ddsd.lpSurface); - - if (IDirectDrawSurface7_Blt(lpPrimarySurface,&MainWindowRect,lpBackSurface,0, DDBLT_WAIT,0)==DDERR_SURFACELOST) - { - printlog("DirectDraw buffers is lost\n"); - if (IDirectDrawSurface7_Restore(lpPrimarySurface)==DD_OK) - IDirectDrawSurface7_Restore(lpBackSurface); - } - } - else - { - if (res==DDERR_SURFACELOST) - { - printlog("DirectDraw buffers is lost\n"); - if (IDirectDrawSurface7_Restore(lpPrimarySurface)==DD_OK) - IDirectDrawSurface7_Restore(lpBackSurface); - } - } -} - -void CheckMessages() -{ + if (IDirectDrawSurface7_SetClipper(lpPrimarySurface, lpDDClipPrimary) != DD_OK) return -5; + + return 1; +} + + +void Display() +{ + int res; + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags=DDSD_ALL; + res=IDirectDrawSurface7_Lock(lpBackSurface,NULL,&ddsd,DDLOCK_WAIT, NULL); + + if (res == DD_OK) + { + char* buffer = (char*)ddsd.lpSurface; + + int i, j, sz=256*sizeof(u32); + if (ddsd.ddpfPixelFormat.dwRGBBitCount>16) + { + u16 *tmpGPU_Screen_src=(u16*)GPU_screen; + u32 tmpGPU_screen[98304]; + for(i=0; i<98304; i++) + tmpGPU_screen[i]= (((tmpGPU_Screen_src[i]>>10)&0x1F)<<3)| + (((tmpGPU_Screen_src[i]>>5)&0x1F)<<11)| + (((tmpGPU_Screen_src[i])&0x1F)<<19); + switch (GPU_rotation) + { + case 0: + { + for (i = 0; i < 98304; i+=256) //384*256 + { + memcpy(buffer,tmpGPU_screen+i,sz); + buffer += ddsd.lPitch; + } + break; + } + case 90: + { + u32 start; + for (j=0; j<256; j++) + { + start=98304+j; + for (i=0; i<384; i++) + { + start-=256; + ((u32*)buffer)[i]=((u32 *)tmpGPU_screen)[start]; + } + buffer += ddsd.lPitch; + } + break; + } + case 180: + { + u32 start=98300; + for (j=0; j<384; j++) + { + for (i=0; i<256; i++, --start) + ((u32*)buffer)[i]=((u32 *)tmpGPU_screen)[start]; + buffer += ddsd.lPitch; + } + break; + } + case 270: + { + u32 start; + for (j=0; j<256; j++) + { + start=256-j; + for (i=0; i<384; i++) + { + ((u32*)buffer)[i]=((u32 *)tmpGPU_screen)[start]; + start+=256; + } + buffer += ddsd.lPitch; + } + break; + } + } + } + else + printlog("16bit depth color not supported"); + IDirectDrawSurface7_Unlock(lpBackSurface,(LPRECT)ddsd.lpSurface); + + if (IDirectDrawSurface7_Blt(lpPrimarySurface,&MainWindowRect,lpBackSurface,0, DDBLT_WAIT,0)==DDERR_SURFACELOST) + { + printlog("DirectDraw buffers is lost\n"); + if (IDirectDrawSurface7_Restore(lpPrimarySurface)==DD_OK) + IDirectDrawSurface7_Restore(lpBackSurface); + } + } + else + { + if (res==DDERR_SURFACELOST) + { + printlog("DirectDraw buffers is lost\n"); + if (IDirectDrawSurface7_Restore(lpPrimarySurface)==DD_OK) + IDirectDrawSurface7_Restore(lpBackSurface); + } + } +} + +void CheckMessages() +{ MSG msg; - HWND hwnd = MainWindow->getHWnd(); + HWND hwnd = MainWindow->getHWnd(); while( PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ) ) { if( GetMessage( &msg, 0, 0, 0)>0 ) - { - if(!TranslateAccelerator(hwnd,hAccel,&msg)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - } -} - + { + if(!TranslateAccelerator(hwnd,hAccel,&msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } +} + void DisplayMessage() { if (displayMessageCounter) @@ -648,219 +649,217 @@ void DisplayMessage() osd->addFixed(0, 40, "%s",MessageToDisplay.str().c_str()); } } - -void SaveStateMessages(int slotnum, int whichMessage) -{ - MessageToDisplay.str(""); //Clear previous message - displayMessageCounter = 120; - switch (whichMessage) - { - case 0: //State saved - MessageToDisplay << "State " << slotnum << " saved."; - break; - case 1: //State loaded - MessageToDisplay << "State " << slotnum << " loaded."; - break; - case 2: //Save slot selected - MessageToDisplay << "State " << slotnum << " selected."; - default: - break; - } - //DisplayMessage(); -} - -DWORD WINAPI run( LPVOID lpParameter) -{ - char txt[80]; - u32 cycles = 0; - int wait=0; - u64 freq; - u64 OneFrameTime; - int framestoskip=0; - int framesskipped=0; - int skipnextframe=0; - u64 lastticks=0; - u64 curticks=0; - u64 diffticks=0; - u32 framecount=0; - u64 onesecondticks=0; - int fps=0; - int fpsframecount=0; - u64 fpsticks=0; - int res; + +void SaveStateMessages(int slotnum, int whichMessage) +{ + MessageToDisplay.str(""); //Clear previous message + displayMessageCounter = 120; + switch (whichMessage) + { + case 0: //State saved + MessageToDisplay << "State " << slotnum << " saved."; + break; + case 1: //State loaded + MessageToDisplay << "State " << slotnum << " loaded."; + break; + case 2: //Save slot selected + MessageToDisplay << "State " << slotnum << " selected."; + default: + break; + } + //DisplayMessage(); +} + +DWORD WINAPI run() +{ + char txt[80]; + u32 cycles = 0; + int wait=0; + u64 freq; + u64 OneFrameTime; + int framestoskip=0; + int framesskipped=0; + int skipnextframe=0; + u64 lastticks=0; + u64 curticks=0; + u64 diffticks=0; + u32 framecount=0; + u64 onesecondticks=0; + int fps=0; + int fpsframecount=0; + u64 fpsticks=0; + int res; HWND hwnd = MainWindow->getHWnd(); - - DDCAPS hw_caps, sw_caps; - - InitSpeedThrottle(); - - if (DirectDrawCreateEx(NULL, (LPVOID*)&lpDDraw, IID_IDirectDraw7, NULL) != DD_OK) - { - MessageBox(hwnd,"Unable to initialize DirectDraw","Error",MB_OK); - return -1; - } - - if (IDirectDraw7_SetCooperativeLevel(lpDDraw,hwnd, DDSCL_NORMAL) != DD_OK) - { - MessageBox(hwnd,"Unable to set DirectDraw Cooperative Level","Error",MB_OK); - return -1; - } - - if (CreateDDrawBuffers()<1) - { - MessageBox(hwnd,"Unable to set DirectDraw buffers","Error",MB_OK); - return -1; - } - - NDS_3D_SetDriver (GPU3D_OPENGL); - - if (!gpu3D->NDS_3D_Init ()) - { - MessageBox(hwnd,"Unable to initialize openGL","Error",MB_OK); - return -1; - } - - QueryPerformanceFrequency((LARGE_INTEGER *)&freq); - QueryPerformanceCounter((LARGE_INTEGER *)&lastticks); - OneFrameTime = freq / 60; - - SetEvent(runthread_ready); - - while(!finished) - { - while(execute) - { - EnterCriticalSection(&win_sync); - cycles = NDS_exec((560190<<1)-cycles,FALSE); - win_sound_samplecounter = 735; - LeaveCriticalSection(&win_sync); - - SPU_Emulate_core(); - //avi writing - DRV_AviSoundUpdate(SPU_core->outbuf,spu_core_samples); - DRV_AviVideoUpdate((u16*)GPU_screen); - - if (!skipnextframe) - { - input->process(); - + + DDCAPS hw_caps, sw_caps; + + InitSpeedThrottle(); + + if (DirectDrawCreateEx(NULL, (LPVOID*)&lpDDraw, IID_IDirectDraw7, NULL) != DD_OK) + { + MessageBox(hwnd,"Unable to initialize DirectDraw","Error",MB_OK); + return -1; + } + + if (IDirectDraw7_SetCooperativeLevel(lpDDraw,hwnd, DDSCL_NORMAL) != DD_OK) + { + MessageBox(hwnd,"Unable to set DirectDraw Cooperative Level","Error",MB_OK); + return -1; + } + + if (CreateDDrawBuffers()<1) + { + MessageBox(hwnd,"Unable to set DirectDraw buffers","Error",MB_OK); + return -1; + } + + NDS_3D_SetDriver (GPU3D_OPENGL); + + if (!gpu3D->NDS_3D_Init ()) + { + MessageBox(hwnd,"Unable to initialize openGL","Error",MB_OK); + return -1; + } + + QueryPerformanceFrequency((LARGE_INTEGER *)&freq); + QueryPerformanceCounter((LARGE_INTEGER *)&lastticks); + OneFrameTime = freq / 60; + + while(!finished) + { + while(execute) + { + EnterCriticalSection(&win_sync); + cycles = NDS_exec((560190<<1)-cycles,FALSE); + win_sound_samplecounter = 735; + LeaveCriticalSection(&win_sync); + + SPU_Emulate_core(); + //avi writing + DRV_AviSoundUpdate(SPU_core->outbuf,spu_core_samples); + DRV_AviVideoUpdate((u16*)GPU_screen); + + if (!skipnextframe) + { + input->process(); + if (FpsDisplay) osd->addFixed(0, 5, "%02d Fps", fps); osd->update(); - Display(); - osd->clear(); - - - fpsframecount++; - QueryPerformanceCounter((LARGE_INTEGER *)&curticks); - bool oneSecond = curticks >= fpsticks + freq; - if(oneSecond) // TODO: print fps on screen in DDraw - { - fps = fpsframecount; - fpsframecount = 0; - QueryPerformanceCounter((LARGE_INTEGER *)&fpsticks); - } - - if(nds.idleFrameCounter==0 || oneSecond) - { - //calculate a 16 frame arm9 load average - int load = 0; - for(int i=0;i<16;i++) - load = load/8 + nds.runCycleCollector[(i+nds.idleFrameCounter)&15]*7/8; - load = std::min(100,std::max(0,(int)(load*100/1120380))); - sprintf(txt,"(%02d%%) %s", load, DESMUME_NAME_AND_VERSION); - SetWindowText(hwnd, txt); - } - - framesskipped = 0; - - if (framestoskip > 0) - skipnextframe = 1; - } - else - { - framestoskip--; - - if (framestoskip < 1) - skipnextframe = 0; - else - skipnextframe = 1; - - framesskipped++; - } - - while(SpeedThrottle()) - { - } - - if (autoframeskipenab) - { - framecount++; - - if (framecount > 60) - { - framecount = 1; - onesecondticks = 0; - } - - QueryPerformanceCounter((LARGE_INTEGER *)&curticks); - diffticks = curticks-lastticks; - - if(ThrottleIsBehind() && framesskipped < 9) - { - skipnextframe = 1; - framestoskip = 1; - } - - onesecondticks += diffticks; - lastticks = curticks; - } - else - { - if (framestoskip < 1) - framestoskip += frameskiprate; - } - if (frameAdvance) - { - frameAdvance = false; - execute = FALSE; - SPU_Pause(1); - } - frameCounter++; + Display(); + osd->clear(); + + + fpsframecount++; + QueryPerformanceCounter((LARGE_INTEGER *)&curticks); + bool oneSecond = curticks >= fpsticks + freq; + if(oneSecond) // TODO: print fps on screen in DDraw + { + fps = fpsframecount; + fpsframecount = 0; + QueryPerformanceCounter((LARGE_INTEGER *)&fpsticks); + } + + if(nds.idleFrameCounter==0 || oneSecond) + { + //calculate a 16 frame arm9 load average + int load = 0; + for(int i=0;i<16;i++) + load = load/8 + nds.runCycleCollector[(i+nds.idleFrameCounter)&15]*7/8; + load = std::min(100,std::max(0,(int)(load*100/1120380))); + sprintf(txt,"(%02d%%) %s", load, DESMUME_NAME_AND_VERSION); + SetWindowText(hwnd, txt); + } + + framesskipped = 0; + + if (framestoskip > 0) + skipnextframe = 1; + } + else + { + framestoskip--; + + if (framestoskip < 1) + skipnextframe = 0; + else + skipnextframe = 1; + + framesskipped++; + } + + while(SpeedThrottle()) + { + } + + if (autoframeskipenab) + { + framecount++; + + if (framecount > 60) + { + framecount = 1; + onesecondticks = 0; + } + + QueryPerformanceCounter((LARGE_INTEGER *)&curticks); + diffticks = curticks-lastticks; + + if(ThrottleIsBehind() && framesskipped < 9) + { + skipnextframe = 1; + framestoskip = 1; + } + + onesecondticks += diffticks; + lastticks = curticks; + } + else + { + if (framestoskip < 1) + framestoskip += frameskiprate; + } + if (frameAdvance) + { + frameAdvance = false; + execute = FALSE; + SPU_Pause(1); + } + frameCounter++; if (frameCounterDisplay) osd->addFixed(0, 25, "%d",frameCounter); DisplayMessage(); - CheckMessages(); - } - - paused = TRUE; - CheckMessages(); - Sleep(100); - } - if (lpDDClipPrimary!=NULL) IDirectDraw7_Release(lpDDClipPrimary); - if (lpPrimarySurface != NULL) IDirectDraw7_Release(lpPrimarySurface); - if (lpBackSurface != NULL) IDirectDraw7_Release(lpBackSurface); - if (lpDDraw != NULL) IDirectDraw7_Release(lpDDraw); - return 1; -} - -void NDS_Pause() -{ - execute = FALSE; - paused = TRUE; - SPU_Pause(1); - while (!paused) {} - printlog("Paused\n"); -} - -void NDS_UnPause() -{ - paused = FALSE; - execute = TRUE; - SPU_Pause(0); - printlog("Unpaused\n"); -} - -void StateSaveSlot(int num) -{ + CheckMessages(); + } + + paused = TRUE; + CheckMessages(); + Sleep(100); + } + if (lpDDClipPrimary!=NULL) IDirectDraw7_Release(lpDDClipPrimary); + if (lpPrimarySurface != NULL) IDirectDraw7_Release(lpPrimarySurface); + if (lpBackSurface != NULL) IDirectDraw7_Release(lpBackSurface); + if (lpDDraw != NULL) IDirectDraw7_Release(lpDDraw); + return 1; +} + +void NDS_Pause() +{ + execute = FALSE; + paused = TRUE; + SPU_Pause(1); + while (!paused) {} + printlog("Paused\n"); +} + +void NDS_UnPause() +{ + paused = FALSE; + execute = TRUE; + SPU_Pause(0); + printlog("Unpaused\n"); +} + +void StateSaveSlot(int num) +{ if (!paused) { NDS_Pause(); @@ -872,105 +871,105 @@ void StateSaveSlot(int num) lastSaveState = num; //Set last savestate used SaveStateMessages(num, 0); //Display state loaded message -} - -void StateLoadSlot(int num) -{ - BOOL wasPaused = paused; - NDS_Pause(); +} + +void StateLoadSlot(int num) +{ + BOOL wasPaused = paused; + NDS_Pause(); loadstate_slot(num); //Loadstate lastSaveState = num; //Set last savestate used SaveStateMessages(num, 1); //Display state loaded message - if(!wasPaused) - NDS_UnPause(); - else - Display(); -} - -BOOL LoadROM(char * filename, const char *cflash_disk_image) -{ - NDS_Pause(); - if (strcmp(filename,"")!=0) printlog("Loading ROM: %s\n",filename); - - if (NDS_LoadROM(filename, backupmemorytype, backupmemorysize, cflash_disk_image) > 0) - return TRUE; - - return FALSE; -} - -/* - * The thread handling functions needed by the GDB stub code. - */ -void * -createThread_gdb( void (APIENTRY *thread_function)( void *data), - void *thread_data) { - void *new_thread = CreateThread( NULL, 0, - (LPTHREAD_START_ROUTINE)thread_function, thread_data, - 0, NULL); - - return new_thread; -} - -void -joinThread_gdb( void *thread_handle) { -} - - -void SetLanguage(int langid) -{ - switch(langid) - { - case 1: - // French - SetThreadLocale(MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH), - SORT_DEFAULT)); - break; - case 2: - // Danish - SetThreadLocale(MAKELCID(MAKELANGID(LANG_DANISH, SUBLANG_DEFAULT), - SORT_DEFAULT)); - break; - case 0: - // English - SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - SORT_DEFAULT)); - break; - default: break; - break; - } -} - -void SaveLanguage(int langid) -{ - char text[80]; - - sprintf(text, "%d", langid); - WritePrivateProfileString("General", "Language", text, IniName); -} - -void CheckLanguage(UINT id) -{ - int i; - for (i = IDC_LANGENGLISH; i < IDC_LANGFRENCH+1; i++) + if(!wasPaused) + NDS_UnPause(); + else + Display(); +} + +BOOL LoadROM(char * filename, const char *cflash_disk_image) +{ + NDS_Pause(); + if (strcmp(filename,"")!=0) printlog("Loading ROM: %s\n",filename); + + if (NDS_LoadROM(filename, backupmemorytype, backupmemorysize, cflash_disk_image) > 0) + return TRUE; + + return FALSE; +} + +/* + * The thread handling functions needed by the GDB stub code. + */ +void * +createThread_gdb( void (APIENTRY *thread_function)( void *data), + void *thread_data) { + void *new_thread = CreateThread( NULL, 0, + (LPTHREAD_START_ROUTINE)thread_function, thread_data, + 0, NULL); + + return new_thread; +} + +void +joinThread_gdb( void *thread_handle) { +} + + +void SetLanguage(int langid) +{ + switch(langid) + { + case 1: + // French + SetThreadLocale(MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH), + SORT_DEFAULT)); + break; + case 2: + // Danish + SetThreadLocale(MAKELCID(MAKELANGID(LANG_DANISH, SUBLANG_DEFAULT), + SORT_DEFAULT)); + break; + case 0: + // English + SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + SORT_DEFAULT)); + break; + default: break; + break; + } +} + +void SaveLanguage(int langid) +{ + char text[80]; + + sprintf(text, "%d", langid); + WritePrivateProfileString("General", "Language", text, IniName); +} + +void CheckLanguage(UINT id) +{ + int i; + for (i = IDC_LANGENGLISH; i < IDC_LANGFRENCH+1; i++) MainWindow->checkMenu(i, MF_BYCOMMAND | MF_UNCHECKED); - + MainWindow->checkMenu(id, MF_BYCOMMAND | MF_CHECKED); -} - -void ChangeLanguage(int id) -{ - HMENU newmenu; - - SetLanguage(id); - newmenu = LoadMenu(hAppInst, "MENU_PRINCIPAL"); +} + +void ChangeLanguage(int id) +{ + HMENU newmenu; + + SetLanguage(id); + newmenu = LoadMenu(hAppInst, "MENU_PRINCIPAL"); SetMenu(MainWindow->getHWnd(), newmenu); - DestroyMenu(menu); - menu = newmenu; -} - + DestroyMenu(menu); + menu = newmenu; +} + int RegClass(WNDPROC Proc, LPCTSTR szName) -{ +{ WNDCLASS wc; wc.style = CS_DBLCLKS; @@ -986,50 +985,49 @@ int RegClass(WNDPROC Proc, LPCTSTR szName) wc.cbClsExtra = 0; wc.cbWndExtra = 0; return RegisterClass(&wc); -} - -static void ExitRunLoop() -{ - finished = TRUE; - execute = FALSE; -} - - -int WINAPI WinMain (HINSTANCE hThisInstance, - HINSTANCE hPrevInstance, - LPSTR lpszArgument, - int nFunsterStil) - -{ +} + +static void ExitRunLoop() +{ + finished = TRUE; + execute = FALSE; +} + + +int WINAPI WinMain (HINSTANCE hThisInstance, + HINSTANCE hPrevInstance, + LPSTR lpszArgument, + int nFunsterStil) + +{ InitializeCriticalSection(&win_sync); - -#ifdef GDB_STUB - gdbstub_handle_t arm9_gdb_stub; - gdbstub_handle_t arm7_gdb_stub; - struct armcpu_memory_iface *arm9_memio = &arm9_base_memory_iface; - struct armcpu_memory_iface *arm7_memio = &arm7_base_memory_iface; - struct armcpu_ctrl_iface *arm9_ctrl_iface; - struct armcpu_ctrl_iface *arm7_ctrl_iface; -#endif - struct configured_features my_config; - - extern bool windows_opengl_init(); - oglrender_init = windows_opengl_init; - - - MSG messages; /* Here messages to the application are saved */ - char text[80]; - hAppInst=hThisInstance; - + +#ifdef GDB_STUB + gdbstub_handle_t arm9_gdb_stub; + gdbstub_handle_t arm7_gdb_stub; + struct armcpu_memory_iface *arm9_memio = &arm9_base_memory_iface; + struct armcpu_memory_iface *arm7_memio = &arm7_base_memory_iface; + struct armcpu_ctrl_iface *arm9_ctrl_iface; + struct armcpu_ctrl_iface *arm7_ctrl_iface; +#endif + struct configured_features my_config; + + extern bool windows_opengl_init(); + oglrender_init = windows_opengl_init; + + + char text[80]; + hAppInst=hThisInstance; + init_configured_features( &my_config); if ( !fill_configured_features( &my_config, lpszArgument)) { MessageBox(NULL,"Unable to parse command line arguments","Error",MB_OK); return 0; } ColorCtrl_Register(); - - OpenConsole(); // Init debug console - + + OpenConsole(); // Init debug console + if (!RegClass(WindowProcedure, "DeSmuME")) { MessageBox(NULL, "Error registering windows class", "DeSmuME", MB_OK); @@ -1040,10 +1038,10 @@ int WINAPI WinMain (HINSTANCE hThisInstance, windowSize = GetPrivateProfileInt("Video","Window Size", 0, IniName); GPU_rotation = GetPrivateProfileInt("Video","Window Rotate", 0, IniName); ForceRatio = GetPrivateProfileInt("Video","Window Force Ratio", 1, IniName); - FpsDisplay = GetPrivateProfileInt("Display","Display Fps", 0, IniName); - WndX = GetPrivateProfileInt("Video","WindowPosX", 0, IniName); - WndY = GetPrivateProfileInt("Video","WindowPosY", 0, IniName); - frameCounterDisplay = GetPrivateProfileInt("Display","FrameCounter", 0, IniName); + FpsDisplay = GetPrivateProfileInt("Display","Display Fps", 0, IniName); + WndX = GetPrivateProfileInt("Video","WindowPosX", 0, IniName); + WndY = GetPrivateProfileInt("Video","WindowPosY", 0, IniName); + frameCounterDisplay = GetPrivateProfileInt("Display","FrameCounter", 0, IniName); //sprintf(text, "%s", DESMUME_NAME_AND_VERSION); MainWindow = new WINCLASS(CLASSNAME, hThisInstance); RECT clientRect = {0,0,256,384}; @@ -1058,44 +1056,44 @@ int WINAPI WinMain (HINSTANCE hThisInstance, exit(-1); } - /* default the firmware settings, they may get changed later */ - NDS_FillDefaultFirmwareConfigData( &win_fw_config); - - GetPrivateProfileString("General", "Language", "-1", text, 80, IniName); - SetLanguage(atoi(text)); - - bad_glob_cflash_disk_image_file = my_config.cflash_disk_image_file; - - hAccel = LoadAccelerators(hAppInst, MAKEINTRESOURCE(IDR_MAIN_ACCEL)); - -#ifdef DEBUG - LogStart(); -#endif - + /* default the firmware settings, they may get changed later */ + NDS_FillDefaultFirmwareConfigData( &win_fw_config); + + GetPrivateProfileString("General", "Language", "-1", text, 80, IniName); + SetLanguage(atoi(text)); + + bad_glob_cflash_disk_image_file = my_config.cflash_disk_image_file; + + hAccel = LoadAccelerators(hAppInst, MAKEINTRESOURCE(IDR_MAIN_ACCEL)); + +#ifdef DEBUG + LogStart(); +#endif + if (!MainWindow->setMenu(LoadMenu(hThisInstance, "MENU_PRINCIPAL"))) { MessageBox(NULL, "Error creating main menu", "DeSmuME", MB_OK); delete MainWindow; exit(-1); } - - // menu checks + + // menu checks MainWindow->checkMenu(IDC_FORCERATIO, MF_BYCOMMAND | (ForceRatio==1?MF_CHECKED:MF_UNCHECKED)); - + MainWindow->checkMenu(ID_VIEW_DISPLAYFPS, FpsDisplay ? MF_CHECKED : MF_UNCHECKED); - + MainWindow->checkMenu(IDC_WINDOW1X, MF_BYCOMMAND | ((windowSize==1)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW2X, MF_BYCOMMAND | ((windowSize==2)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW3X, MF_BYCOMMAND | ((windowSize==3)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW4X, MF_BYCOMMAND | ((windowSize==4)?MF_CHECKED:MF_UNCHECKED)); - + MainWindow->checkMenu(IDC_ROTATE0, MF_BYCOMMAND | ((GPU_rotation==0)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_ROTATE90, MF_BYCOMMAND | ((GPU_rotation==90)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_ROTATE180, MF_BYCOMMAND | ((GPU_rotation==180)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_ROTATE270, MF_BYCOMMAND | ((GPU_rotation==270)?MF_CHECKED:MF_UNCHECKED)); - + DragAcceptFiles(MainWindow->getHWnd(), TRUE); - + printlog("Init NDS\n"); input = new INPUTCLASS(); @@ -1118,163 +1116,157 @@ int WINAPI WinMain (HINSTANCE hThisInstance, ViewMatrices = new TOOLSCLASS(hThisInstance, IDD_MATRIX_VIEWER, (DLGPROC) ViewMatricesProc); ViewLights = new TOOLSCLASS(hThisInstance, IDD_LIGHT_VIEWER, (DLGPROC) ViewLightsProc); -#ifdef GDB_STUB - if ( my_config.arm9_gdb_port != 0) { - arm9_gdb_stub = createStub_gdb( my_config.arm9_gdb_port, - &arm9_memio, &arm9_direct_memory_iface); - - if ( arm9_gdb_stub == NULL) { - MessageBox(hwnd,"Failed to create ARM9 gdbstub","Error",MB_OK); - return -1; - } - } - if ( my_config.arm7_gdb_port != 0) { - arm7_gdb_stub = createStub_gdb( my_config.arm7_gdb_port, - &arm7_memio, - &arm7_base_memory_iface); - - if ( arm7_gdb_stub == NULL) { - MessageBox(hwnd,"Failed to create ARM7 gdbstub","Error",MB_OK); - return -1; - } - } - - NDS_Init( arm9_memio, &arm9_ctrl_iface, - arm7_memio, &arm7_ctrl_iface); -#else - NDS_Init (); -#endif - - /* - * Activate the GDB stubs - * This has to come after the NDS_Init where the cpus are set up. - */ -#ifdef GDB_STUB - if ( my_config.arm9_gdb_port != 0) { - activateStub_gdb( arm9_gdb_stub, arm9_ctrl_iface); - } - if ( my_config.arm7_gdb_port != 0) { - activateStub_gdb( arm7_gdb_stub, arm7_ctrl_iface); - } -#endif +#ifdef GDB_STUB + if ( my_config.arm9_gdb_port != 0) { + arm9_gdb_stub = createStub_gdb( my_config.arm9_gdb_port, + &arm9_memio, &arm9_direct_memory_iface); + + if ( arm9_gdb_stub == NULL) { + MessageBox(hwnd,"Failed to create ARM9 gdbstub","Error",MB_OK); + return -1; + } + } + if ( my_config.arm7_gdb_port != 0) { + arm7_gdb_stub = createStub_gdb( my_config.arm7_gdb_port, + &arm7_memio, + &arm7_base_memory_iface); + + if ( arm7_gdb_stub == NULL) { + MessageBox(hwnd,"Failed to create ARM7 gdbstub","Error",MB_OK); + return -1; + } + } + + NDS_Init( arm9_memio, &arm9_ctrl_iface, + arm7_memio, &arm7_ctrl_iface); +#else + NDS_Init (); +#endif + + /* + * Activate the GDB stubs + * This has to come after the NDS_Init where the cpus are set up. + */ +#ifdef GDB_STUB + if ( my_config.arm9_gdb_port != 0) { + activateStub_gdb( arm9_gdb_stub, arm9_ctrl_iface); + } + if ( my_config.arm7_gdb_port != 0) { + activateStub_gdb( arm7_gdb_stub, arm7_ctrl_iface); + } +#endif GetPrivateProfileString("General", "Language", "0", text, 80, IniName); //================================================== ??? - CheckLanguage(IDC_LANGENGLISH+atoi(text)); - - GetPrivateProfileString("Video", "FrameSkip", "AUTO", text, 80, IniName); - - if (strcmp(text, "AUTO") == 0) - { - autoframeskipenab=1; - frameskiprate=0; + CheckLanguage(IDC_LANGENGLISH+atoi(text)); + + GetPrivateProfileString("Video", "FrameSkip", "AUTO", text, 80, IniName); + + if (strcmp(text, "AUTO") == 0) + { + autoframeskipenab=1; + frameskiprate=0; MainWindow->checkMenu(IDC_FRAMESKIPAUTO, MF_BYCOMMAND | MF_CHECKED); - } - else - { - autoframeskipenab=0; - frameskiprate=atoi(text); + } + else + { + autoframeskipenab=0; + frameskiprate=atoi(text); MainWindow->checkMenu(frameskiprate + IDC_FRAMESKIP0, MF_BYCOMMAND | MF_CHECKED); - } - -#ifdef BETA_VERSION - EnableMenuItem (menu, IDM_SUBMITBUGREPORT, MF_GRAYED); -#endif - printlog("Init sound core\n"); - sndcoretype = GetPrivateProfileInt("Sound","SoundCore", SNDCORE_DIRECTX, IniName); - sndbuffersize = GetPrivateProfileInt("Sound","SoundBufferSize", 735 * 4, IniName); - - EnterCriticalSection(&win_sync); - int spu_ret = SPU_ChangeSoundCore(sndcoretype, sndbuffersize); - LeaveCriticalSection(&win_sync); - if(spu_ret != 0) - { + } + +#ifdef BETA_VERSION + EnableMenuItem (menu, IDM_SUBMITBUGREPORT, MF_GRAYED); +#endif + printlog("Init sound core\n"); + sndcoretype = GetPrivateProfileInt("Sound","SoundCore", SNDCORE_DIRECTX, IniName); + sndbuffersize = GetPrivateProfileInt("Sound","SoundBufferSize", 735 * 4, IniName); + + EnterCriticalSection(&win_sync); + int spu_ret = SPU_ChangeSoundCore(sndcoretype, sndbuffersize); + LeaveCriticalSection(&win_sync); + if(spu_ret != 0) + { MessageBox(MainWindow->getHWnd(),"Unable to initialize DirectSound","Error",MB_OK); - return -1; - } - - sndvolume = GetPrivateProfileInt("Sound","Volume",100, IniName); - SPU_SetVolume(sndvolume); - - /* Read the firmware settings from the init file */ - win_fw_config.fav_colour = GetPrivateProfileInt("Firmware","favColor", 10, IniName); - win_fw_config.birth_month = GetPrivateProfileInt("Firmware","bMonth", 7, IniName); - win_fw_config.birth_day = GetPrivateProfileInt("Firmware","bDay", 15, IniName); - win_fw_config.language = GetPrivateProfileInt("Firmware","Language", 1, IniName); - - { - /* - * Read in the nickname and message. - * Convert the strings into Unicode UTF-16 characters. - */ - char temp_str[27]; - int char_index; - GetPrivateProfileString("Firmware","nickName", "yopyop", temp_str, 11, IniName); - win_fw_config.nickname_len = strlen( temp_str); - - if ( win_fw_config.nickname_len == 0) { - strcpy( temp_str, "yopyop"); - win_fw_config.nickname_len = strlen( temp_str); - } - - for ( char_index = 0; char_index < win_fw_config.nickname_len; char_index++) { - win_fw_config.nickname[char_index] = temp_str[char_index]; - } - - GetPrivateProfileString("Firmware","Message", "DeSmuME makes you happy!", temp_str, 27, IniName); - win_fw_config.message_len = strlen( temp_str); - for ( char_index = 0; char_index < win_fw_config.message_len; char_index++) { - win_fw_config.message[char_index] = temp_str[char_index]; - } - } - - /* Create the dummy firmware */ - NDS_CreateDummyFirmware( &win_fw_config); - - //runthread_ready = CreateEvent(NULL,TRUE,FALSE,0); - //runthread = CreateThread(NULL, 0, run, NULL, 0, &threadID); - - //wait for the run thread to signal that it is initialized and ready to run - //WaitForSingleObject(runthread_ready,INFINITE); - - // Make sure any quotes from lpszArgument are removed - if (lpszArgument[0] == '\"') - sscanf(lpszArgument, "\"%[^\"]\"", lpszArgument); - - if(LoadROM(lpszArgument, bad_glob_cflash_disk_image_file)) - { - EnableMenuItem(menu, IDM_EXEC, MF_GRAYED); - EnableMenuItem(menu, IDM_PAUSE, MF_ENABLED); - EnableMenuItem(menu, IDM_RESET, MF_ENABLED); - EnableMenuItem(menu, IDM_GAME_INFO, MF_ENABLED); - EnableMenuItem(menu, IDM_IMPORTBACKUPMEMORY, MF_ENABLED); - romloaded = TRUE; - NDS_UnPause(); - } - else - { - EnableMenuItem(menu, IDM_EXEC, MF_ENABLED); - EnableMenuItem(menu, IDM_PAUSE, MF_GRAYED); - EnableMenuItem(menu, IDM_RESET, MF_GRAYED); - EnableMenuItem(menu, IDM_GAME_INFO, MF_GRAYED); - EnableMenuItem(menu, IDM_IMPORTBACKUPMEMORY, MF_GRAYED); - } - + return -1; + } + + sndvolume = GetPrivateProfileInt("Sound","Volume",100, IniName); + SPU_SetVolume(sndvolume); + + /* Read the firmware settings from the init file */ + win_fw_config.fav_colour = GetPrivateProfileInt("Firmware","favColor", 10, IniName); + win_fw_config.birth_month = GetPrivateProfileInt("Firmware","bMonth", 7, IniName); + win_fw_config.birth_day = GetPrivateProfileInt("Firmware","bDay", 15, IniName); + win_fw_config.language = GetPrivateProfileInt("Firmware","Language", 1, IniName); + + { + /* + * Read in the nickname and message. + * Convert the strings into Unicode UTF-16 characters. + */ + char temp_str[27]; + int char_index; + GetPrivateProfileString("Firmware","nickName", "yopyop", temp_str, 11, IniName); + win_fw_config.nickname_len = strlen( temp_str); + + if ( win_fw_config.nickname_len == 0) { + strcpy( temp_str, "yopyop"); + win_fw_config.nickname_len = strlen( temp_str); + } + + for ( char_index = 0; char_index < win_fw_config.nickname_len; char_index++) { + win_fw_config.nickname[char_index] = temp_str[char_index]; + } + + GetPrivateProfileString("Firmware","Message", "DeSmuME makes you happy!", temp_str, 27, IniName); + win_fw_config.message_len = strlen( temp_str); + for ( char_index = 0; char_index < win_fw_config.message_len; char_index++) { + win_fw_config.message[char_index] = temp_str[char_index]; + } + } + + // Create the dummy firmware + NDS_CreateDummyFirmware( &win_fw_config); + + // Make sure any quotes from lpszArgument are removed + if (lpszArgument[0] == '\"') + sscanf(lpszArgument, "\"%[^\"]\"", lpszArgument); + + if(LoadROM(lpszArgument, bad_glob_cflash_disk_image_file)) + { + EnableMenuItem(menu, IDM_EXEC, MF_GRAYED); + EnableMenuItem(menu, IDM_PAUSE, MF_ENABLED); + EnableMenuItem(menu, IDM_RESET, MF_ENABLED); + EnableMenuItem(menu, IDM_GAME_INFO, MF_ENABLED); + EnableMenuItem(menu, IDM_IMPORTBACKUPMEMORY, MF_ENABLED); + romloaded = TRUE; + NDS_UnPause(); + } + else + { + EnableMenuItem(menu, IDM_EXEC, MF_ENABLED); + EnableMenuItem(menu, IDM_PAUSE, MF_GRAYED); + EnableMenuItem(menu, IDM_RESET, MF_GRAYED); + EnableMenuItem(menu, IDM_GAME_INFO, MF_GRAYED); + EnableMenuItem(menu, IDM_IMPORTBACKUPMEMORY, MF_GRAYED); + } + MainWindow->checkMenu(IDC_SAVETYPE1, MF_BYCOMMAND | MF_CHECKED); MainWindow->checkMenu(IDC_SAVETYPE2, MF_BYCOMMAND | MF_UNCHECKED); MainWindow->checkMenu(IDC_SAVETYPE3, MF_BYCOMMAND | MF_UNCHECKED); MainWindow->checkMenu(IDC_SAVETYPE4, MF_BYCOMMAND | MF_UNCHECKED); MainWindow->checkMenu(IDC_SAVETYPE5, MF_BYCOMMAND | MF_UNCHECKED); MainWindow->checkMenu(IDC_SAVETYPE6, MF_BYCOMMAND | MF_UNCHECKED); - - MainWindow->Show(SW_NORMAL); - run(0); - DRV_AviEnd(); - - //------SHUTDOWN - -#ifdef DEBUG - LogStop(); -#endif - if (input!=NULL) delete input; + + MainWindow->Show(SW_NORMAL); + run(); + DRV_AviEnd(); + + //------SHUTDOWN + +#ifdef DEBUG + LogStop(); +#endif + if (input!=NULL) delete input; if (ViewLights!=NULL) delete ViewLights; if (ViewMatrices!=NULL) delete ViewMatrices; if (ViewOAM!=NULL) delete ViewOAM; @@ -1289,85 +1281,85 @@ int WINAPI WinMain (HINSTANCE hThisInstance, delete MainWindow; - CloseConsole(); - - return 0; -} - -void GetWndRect(HWND hwnd) -{ - POINT ptClient; - RECT rc; - - GetClientRect(hwnd,&rc); - ptClient.x=rc.left; - ptClient.y=rc.top; - ClientToScreen(hwnd,&ptClient); - MainWindowRect.left=ptClient.x; - MainWindowRect.top=ptClient.y; + CloseConsole(); + + return 0; +} + +void GetWndRect(HWND hwnd) +{ + POINT ptClient; + RECT rc; + + GetClientRect(hwnd,&rc); + ptClient.x=rc.left; + ptClient.y=rc.top; + ClientToScreen(hwnd,&ptClient); + MainWindowRect.left=ptClient.x; + MainWindowRect.top=ptClient.y; WndX = ptClient.x; WndY = ptClient.y; - ptClient.x=rc.right; - ptClient.y=rc.bottom; - ClientToScreen(hwnd,&ptClient); - MainWindowRect.right=ptClient.x; - MainWindowRect.bottom=ptClient.y; -} - -//======================================================================================== + ptClient.x=rc.right; + ptClient.y=rc.bottom; + ClientToScreen(hwnd,&ptClient); + MainWindowRect.right=ptClient.x; + MainWindowRect.bottom=ptClient.y; +} + +//======================================================================================== void SetRotate(HWND hwnd, int rot) -{ - GPU_rotation = rot; - - switch (rot) - { - case 0: - GPU_width = 256; - GPU_height = 192*2; - rotationstartscan = 192; - rotationscanlines = 192*2; - break; - - case 90: - GPU_rotation = 90; - GPU_width = 192*2; - GPU_height = 256; - rotationstartscan = 0; - rotationscanlines = 256; - break; - - case 180: - GPU_rotation = 180; - GPU_width = 256; - GPU_height = 192*2; - rotationstartscan = 0; - rotationscanlines = 192*2; - break; - - case 270: - GPU_rotation = 270; - GPU_width = 192*2; - GPU_height = 256; - rotationstartscan = 0; - rotationscanlines = 256; - break; - } - - SetWindowClientSize(hwnd, GPU_width, GPU_height); +{ + GPU_rotation = rot; + + switch (rot) + { + case 0: + GPU_width = 256; + GPU_height = 192*2; + rotationstartscan = 192; + rotationscanlines = 192*2; + break; + + case 90: + GPU_rotation = 90; + GPU_width = 192*2; + GPU_height = 256; + rotationstartscan = 0; + rotationscanlines = 256; + break; + + case 180: + GPU_rotation = 180; + GPU_width = 256; + GPU_height = 192*2; + rotationstartscan = 0; + rotationscanlines = 192*2; + break; + + case 270: + GPU_rotation = 270; + GPU_width = 192*2; + GPU_height = 256; + rotationstartscan = 0; + rotationscanlines = 256; + break; + } + + SetWindowClientSize(hwnd, GPU_width, GPU_height); MainWindow->checkMenu(IDC_ROTATE0, MF_BYCOMMAND | ((GPU_rotation==0)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_ROTATE90, MF_BYCOMMAND | ((GPU_rotation==90)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_ROTATE180, MF_BYCOMMAND | ((GPU_rotation==180)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_ROTATE270, MF_BYCOMMAND | ((GPU_rotation==270)?MF_CHECKED:MF_UNCHECKED)); - WritePrivateProfileInt("Video","Window Rotate",GPU_rotation,IniName); -} - -static void AviEnd() -{ - NDS_Pause(); - DRV_AviEnd(); - NDS_UnPause(); -} - + WritePrivateProfileInt("Video","Window Rotate",GPU_rotation,IniName); +} + +static void AviEnd() +{ + NDS_Pause(); + DRV_AviEnd(); + NDS_UnPause(); +} + //Shows an Open File menu and starts recording an AVI static void AviRecordTo() { @@ -1415,373 +1407,363 @@ static void AviRecordTo() } NDS_UnPause(); -} - -//======================================================================================== -LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - static int tmp_execute; - switch (message) // handle the messages - { - /*case WM_ENTERMENULOOP: // temporally removed it (freezes) - { - if (execute) - { - NDS_Pause(); - tmp_execute=2; - } else tmp_execute=-1; - return 0; - } - case WM_EXITMENULOOP: - { - if (tmp_execute==2) NDS_UnPause(); - return 0; - }*/ - - case WM_CREATE: - { - RECT clientSize, fullSize; - GetClientRect(hwnd, &clientSize); - GetWindowRect(hwnd, &fullSize); - DefaultWidth = clientSize.right - clientSize.left; - DefaultHeight = clientSize.bottom - clientSize.top; - widthTradeOff = (fullSize.right - fullSize.left) - (clientSize.right - clientSize.left); - heightTradeOff = (fullSize.bottom - fullSize.top) - (clientSize.bottom - clientSize.top); - - if ( (windowSize < 1) || (windowSize > 4) ) - { - int w=GetPrivateProfileInt("Video","Window width", 0, IniName); - int h=GetPrivateProfileInt("Video","Window height", 0, IniName); - if (w && h) - { - RECT fullSize = {0, 0, w, h}; - ResizingLimit(WMSZ_RIGHT, &fullSize); - - if (ForceRatio) - ScallingScreen(hwnd, WMSZ_RIGHT, &fullSize); +} + +//======================================================================================== +LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static int tmp_execute; + switch (message) // handle the messages + { + /*case WM_ENTERMENULOOP: // temporally removed it (freezes) + { + if (execute) + { + NDS_Pause(); + tmp_execute=2; + } else tmp_execute=-1; + return 0; + } + case WM_EXITMENULOOP: + { + if (tmp_execute==2) NDS_UnPause(); + return 0; + }*/ + + case WM_CREATE: + { + RECT clientSize, fullSize; + GetClientRect(hwnd, &clientSize); + GetWindowRect(hwnd, &fullSize); + DefaultWidth = clientSize.right - clientSize.left; + DefaultHeight = clientSize.bottom - clientSize.top; + widthTradeOff = (fullSize.right - fullSize.left) - (clientSize.right - clientSize.left); + heightTradeOff = (fullSize.bottom - fullSize.top) - (clientSize.bottom - clientSize.top); + + if ( (windowSize < 1) || (windowSize > 4) ) + { + int w=GetPrivateProfileInt("Video","Window width", 0, IniName); + int h=GetPrivateProfileInt("Video","Window height", 0, IniName); + if (w && h) + { + RECT fullSize = {0, 0, w, h}; + ResizingLimit(WMSZ_RIGHT, &fullSize); + + if (ForceRatio) + ScaleScreen(hwnd, WMSZ_RIGHT, &fullSize); SetWindowPos(hwnd, NULL, WndX, WndY, fullSize.right - fullSize.left, - fullSize.bottom - fullSize.top, SWP_NOMOVE | SWP_NOZORDER); - } - else - windowSize=1; - } - if ( (windowSize > 0) && (windowSize < 5) ) ScaleScreen(hwnd, windowSize); - - return 0; - - } - case WM_DESTROY: - case WM_CLOSE: - { - NDS_Pause(); + fullSize.bottom - fullSize.top, SWP_NOMOVE | SWP_NOZORDER); + } + else + windowSize=1; + } + if ( (windowSize > 0) && (windowSize < 5) ) ScaleScreen(hwnd, windowSize); + + return 0; + + } + case WM_DESTROY: + case WM_CLOSE: + { + NDS_Pause(); //Save window size - WritePrivateProfileInt("Video","Window Size",windowSize,IniName); - if (windowSize==0) - { - WritePrivateProfileInt("Video","Window width",MainWindowRect.right-MainWindowRect.left+widthTradeOff,IniName); - WritePrivateProfileInt("Video","Window height",MainWindowRect.bottom-MainWindowRect.top+heightTradeOff,IniName); - } - - //Save window position - WritePrivateProfileInt("Video", "WindowPosX", WndX/*MainWindowRect.left*/, IniName); - WritePrivateProfileInt("Video", "WindowPosY", WndY/*MainWindowRect.top*/, IniName); - - //Save frame counter status - WritePrivateProfileInt("Display", "FrameCounter", frameCounterDisplay, IniName); - - if (runthread != INVALID_HANDLE_VALUE) - { - if (WaitForSingleObject(runthread,INFINITE) == WAIT_TIMEOUT) - { - // Couldn't close thread cleanly - TerminateThread(runthread,0); - } - CloseHandle(runthread); - } - - NDS_DeInit(); - ExitRunLoop();; - return 0; - } - case WM_MOVE: - GetWndRect(hwnd); - return 0; - case WM_SIZING: - { - RECT *rc=(RECT *)lParam; - - windowSize=0; - ResizingLimit(wParam, rc); - if (ForceRatio) - ScallingScreen(hwnd, wParam, rc); - //printlog("sizing: width=%i; height=%i\n", rc->right - rc->left, rc->bottom - rc->top); - } - break; - case WM_SIZE: - if (ForceRatio) { - if ( windowSize != 0 ) ScaleScreen(hwnd, windowSize); - } - GetWndRect(hwnd); - return 0; - case WM_DROPFILES: - { - char filename[MAX_PATH] = ""; - DragQueryFile((HDROP)wParam,0,filename,MAX_PATH); - DragFinish((HDROP)wParam); - if(LoadROM(filename, bad_glob_cflash_disk_image_file)) - { - EnableMenuItem(menu, IDM_EXEC, MF_GRAYED); - EnableMenuItem(menu, IDM_PAUSE, MF_ENABLED); - EnableMenuItem(menu, IDM_RESET, MF_ENABLED); - EnableMenuItem(menu, IDM_GAME_INFO, MF_ENABLED); - EnableMenuItem(menu, IDM_IMPORTBACKUPMEMORY, MF_ENABLED); - romloaded = TRUE; - NDS_UnPause(); - } - } - return 0; - case WM_MOUSEMOVE: + WritePrivateProfileInt("Video","Window Size",windowSize,IniName); + if (windowSize==0) + { + WritePrivateProfileInt("Video","Window width",MainWindowRect.right-MainWindowRect.left+widthTradeOff,IniName); + WritePrivateProfileInt("Video","Window height",MainWindowRect.bottom-MainWindowRect.top+heightTradeOff,IniName); + } + + //Save window position + WritePrivateProfileInt("Video", "WindowPosX", WndX/*MainWindowRect.left*/, IniName); + WritePrivateProfileInt("Video", "WindowPosY", WndY/*MainWindowRect.top*/, IniName); + + //Save frame counter status + WritePrivateProfileInt("Display", "FrameCounter", frameCounterDisplay, IniName); + + NDS_DeInit(); + ExitRunLoop(); + return 0; + } + case WM_MOVE: + GetWndRect(hwnd); + return 0; + case WM_SIZING: + { + RECT *rc=(RECT *)lParam; + + windowSize=0; + ResizingLimit(wParam, rc); + if (ForceRatio) + ScaleScreen(hwnd, wParam, rc); + //printlog("sizing: width=%i; height=%i\n", rc->right - rc->left, rc->bottom - rc->top); + } + break; + case WM_SIZE: + if (ForceRatio) { + if ( windowSize != 0 ) ScaleScreen(hwnd, windowSize); + } + GetWndRect(hwnd); + return 0; + case WM_DROPFILES: + { + char filename[MAX_PATH] = ""; + DragQueryFile((HDROP)wParam,0,filename,MAX_PATH); + DragFinish((HDROP)wParam); + if(LoadROM(filename, bad_glob_cflash_disk_image_file)) + { + EnableMenuItem(menu, IDM_EXEC, MF_GRAYED); + EnableMenuItem(menu, IDM_PAUSE, MF_ENABLED); + EnableMenuItem(menu, IDM_RESET, MF_ENABLED); + EnableMenuItem(menu, IDM_GAME_INFO, MF_ENABLED); + EnableMenuItem(menu, IDM_IMPORTBACKUPMEMORY, MF_ENABLED); + romloaded = TRUE; + NDS_UnPause(); + } + } + return 0; + case WM_MOUSEMOVE: case WM_LBUTTONDOWN: - if (wParam & MK_LBUTTON) - { - RECT r ; - s32 x = (s32)((s16)LOWORD(lParam)); - s32 y = (s32)((s16)HIWORD(lParam)); - GetClientRect(hwnd,&r) ; + if (wParam & MK_LBUTTON) + { + RECT r ; + s32 x = (s32)((s16)LOWORD(lParam)); + s32 y = (s32)((s16)HIWORD(lParam)); + GetClientRect(hwnd,&r) ; // translate from scaling (screen resolution to 256x384 or 512x192) - switch (GPU_rotation) - { - case 0: - case 180: - x = (x*256) / (r.right - r.left) ; - y = (y*384) / (r.bottom - r.top) ; - break ; - case 90: - case 270: + switch (GPU_rotation) + { + case 0: + case 180: + x = (x*256) / (r.right - r.left) ; + y = (y*384) / (r.bottom - r.top) ; + break ; + case 90: + case 270: x = (x*384) / (r.right - r.left) ; y = (y*256) / (r.bottom - r.top) ; - break ; - } + break ; + } //translate for rotation - if (GPU_rotation != 0) + if (GPU_rotation != 0) translateXY(x,y); - else - y-=192; - if(x<0) x = 0; else if(x>255) x = 255; - if(y<0) y = 0; else if(y>192) y = 192; - NDS_setTouchPos(x, y); - return 0; - } - NDS_releaseTouch(); - return 0; + else + y-=192; + if(x<0) x = 0; else if(x>255) x = 255; + if(y<0) y = 0; else if(y>192) y = 192; + NDS_setTouchPos(x, y); + return 0; + } + NDS_releaseTouch(); + return 0; - case WM_LBUTTONUP: - if(click) - ReleaseCapture(); - NDS_releaseTouch(); - return 0; + case WM_LBUTTONUP: + if(click) + ReleaseCapture(); + NDS_releaseTouch(); + return 0; - case WM_COMMAND: - switch(LOWORD(wParam)) - { + case WM_COMMAND: + switch(LOWORD(wParam)) + { case IDM_QUIT: DestroyWindow(hwnd); return 0; - case IDM_OPEN: - { - int filterSize = 0, i = 0; - OPENFILENAME ofn; - char filename[MAX_PATH] = "", - fileFilter[512]=""; - NDS_Pause(); //Stop emulation while opening new rom - - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - - // To avoid #ifdef hell, we'll do a little trick, as lpstrFilter - // needs 0 terminated string, and standard string library, of course, - // can't help us with string creation: just put a '|' were a string end - // should be, and later transform prior assigning to the OPENFILENAME structure - strncpy (fileFilter, "NDS ROM file (*.nds)|*.nds|NDS/GBA ROM File (*.ds.gba)|*.ds.gba|",512); -#ifdef HAVE_LIBZZIP + case IDM_OPEN: + { + int filterSize = 0, i = 0; + OPENFILENAME ofn; + char filename[MAX_PATH] = "", + fileFilter[512]=""; + NDS_Pause(); //Stop emulation while opening new rom + + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + + // To avoid #ifdef hell, we'll do a little trick, as lpstrFilter + // needs 0 terminated string, and standard string library, of course, + // can't help us with string creation: just put a '|' were a string end + // should be, and later transform prior assigning to the OPENFILENAME structure + strncpy (fileFilter, "NDS ROM file (*.nds)|*.nds|NDS/GBA ROM File (*.ds.gba)|*.ds.gba|",512); +#ifdef HAVE_LIBZZIP strncpy (fileFilter, "All Usable Files (*.nds, *.ds.gba, *.zip, *.gz)|*.nds;*.ds.gba;*.zip;*.gz|",512); #endif #ifdef HAVE_LIBZZIP - strncat (fileFilter, "Zipped NDS ROM file (*.zip)|*.zip|",512 - strlen(fileFilter)); -#endif -#ifdef HAVE_LIBZ - strncat (fileFilter, "GZipped NDS ROM file (*.gz)|*.gz|",512 - strlen(fileFilter)); -#endif - strncat (fileFilter, "Any file (*.*)|*.*||",512 - strlen(fileFilter)); - - filterSize = strlen(fileFilter); - for (i = 0; i < filterSize; i++) - { - if (fileFilter[i] == '|') fileFilter[i] = '\0'; - } - ofn.lpstrFilter = fileFilter; - ofn.nFilterIndex = 1; - ofn.lpstrFile = filename; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrDefExt = "nds"; - - if(!GetOpenFileName(&ofn)) - { - if (romloaded) - NDS_UnPause(); //Restart emulation if no new rom chosen - return 0; - } - - LOG("%s\r\n", filename); - - if(LoadROM(filename, bad_glob_cflash_disk_image_file)) - { - EnableMenuItem(menu, IDM_EXEC, MF_GRAYED); - EnableMenuItem(menu, IDM_PAUSE, MF_ENABLED); - EnableMenuItem(menu, IDM_RESET, MF_ENABLED); - EnableMenuItem(menu, IDM_GAME_INFO, MF_ENABLED); - EnableMenuItem(menu, IDM_IMPORTBACKUPMEMORY, MF_ENABLED); - romloaded = TRUE; - NDS_UnPause(); - } - } - return 0; - case IDM_PRINTSCREEN: - { - OPENFILENAME ofn; - char filename[MAX_PATH] = ""; - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - ofn.lpstrFilter = "Bmp file (*.bmp)\0*.bmp\0Any file (*.*)\0*.*\0\0"; - ofn.nFilterIndex = 1; - ofn.lpstrFile = filename; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrDefExt = "bmp"; - ofn.Flags = OFN_OVERWRITEPROMPT; - GetSaveFileName(&ofn); - NDS_WriteBMP(filename); - } - return 0; - case IDM_QUICK_PRINTSCREEN: - { - NDS_WriteBMP("./printscreen.bmp"); - } - return 0; - case IDM_FILE_RECORDAVI: - AviRecordTo(); - break; - case IDM_FILE_STOPAVI: - AviEnd(); - break; - case IDM_STATE_LOAD: - { - OPENFILENAME ofn; - NDS_Pause(); - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - ofn.lpstrFilter = "DeSmuME Savestate (*.dst)\0*.dst\0\0"; - ofn.nFilterIndex = 1; - ofn.lpstrFile = SavName; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrDefExt = "dst"; - - if(!GetOpenFileName(&ofn)) - { - NDS_UnPause(); - return 0; - } - - savestate_load(SavName); - NDS_UnPause(); - } - return 0; - case IDM_STATE_SAVE: - { - OPENFILENAME ofn; - NDS_Pause(); - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - ofn.lpstrFilter = "DeSmuME Savestate (*.dst)\0*.dst\0\0"; - ofn.nFilterIndex = 1; - ofn.lpstrFile = SavName; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrDefExt = "dst"; - - if(!GetSaveFileName(&ofn)) - { - return 0; - } - - savestate_save(SavName); - NDS_UnPause(); - } - return 0; - case IDM_STATE_SAVE_F1: - StateSaveSlot(1); - return 0; - case IDM_STATE_SAVE_F2: - StateSaveSlot(2); - return 0; - case IDM_STATE_SAVE_F3: - StateSaveSlot(3); - return 0; - case IDM_STATE_SAVE_F4: - StateSaveSlot(4); - return 0; - case IDM_STATE_SAVE_F5: - StateSaveSlot(5); - return 0; - case IDM_STATE_SAVE_F6: - StateSaveSlot(6); - return 0; - case IDM_STATE_SAVE_F7: - StateSaveSlot(7); - return 0; - case IDM_STATE_SAVE_F8: - StateSaveSlot(8); - return 0; - case IDM_STATE_SAVE_F9: - StateSaveSlot(9); - return 0; - case IDM_STATE_SAVE_F10: - StateSaveSlot(10); - return 0; - case IDM_STATE_LOAD_F1: - StateLoadSlot(1); - return 0; - case IDM_STATE_LOAD_F2: - StateLoadSlot(2); - return 0; - case IDM_STATE_LOAD_F3: - StateLoadSlot(3); - return 0; - case IDM_STATE_LOAD_F4: - StateLoadSlot(4); - return 0; - case IDM_STATE_LOAD_F5: - StateLoadSlot(5); - return 0; - case IDM_STATE_LOAD_F6: - StateLoadSlot(6); - return 0; - case IDM_STATE_LOAD_F7: - StateLoadSlot(7); - return 0; - case IDM_STATE_LOAD_F8: - StateLoadSlot(8); - return 0; - case IDM_STATE_LOAD_F9: - StateLoadSlot(9); - return 0; - case IDM_STATE_LOAD_F10: - StateLoadSlot(10); - return 0; + strncat (fileFilter, "Zipped NDS ROM file (*.zip)|*.zip|",512 - strlen(fileFilter)); +#endif +#ifdef HAVE_LIBZ + strncat (fileFilter, "GZipped NDS ROM file (*.gz)|*.gz|",512 - strlen(fileFilter)); +#endif + strncat (fileFilter, "Any file (*.*)|*.*||",512 - strlen(fileFilter)); + + filterSize = strlen(fileFilter); + for (i = 0; i < filterSize; i++) + { + if (fileFilter[i] == '|') fileFilter[i] = '\0'; + } + ofn.lpstrFilter = fileFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = filename; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "nds"; + + if(!GetOpenFileName(&ofn)) + { + if (romloaded) + NDS_UnPause(); //Restart emulation if no new rom chosen + return 0; + } + + LOG("%s\r\n", filename); + + if(LoadROM(filename, bad_glob_cflash_disk_image_file)) + { + EnableMenuItem(menu, IDM_EXEC, MF_GRAYED); + EnableMenuItem(menu, IDM_PAUSE, MF_ENABLED); + EnableMenuItem(menu, IDM_RESET, MF_ENABLED); + EnableMenuItem(menu, IDM_GAME_INFO, MF_ENABLED); + EnableMenuItem(menu, IDM_IMPORTBACKUPMEMORY, MF_ENABLED); + romloaded = TRUE; + NDS_UnPause(); + } + } + return 0; + case IDM_PRINTSCREEN: + { + OPENFILENAME ofn; + char filename[MAX_PATH] = ""; + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = "Bmp file (*.bmp)\0*.bmp\0Any file (*.*)\0*.*\0\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFile = filename; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "bmp"; + ofn.Flags = OFN_OVERWRITEPROMPT; + GetSaveFileName(&ofn); + NDS_WriteBMP(filename); + } + return 0; + case IDM_QUICK_PRINTSCREEN: + { + NDS_WriteBMP("./printscreen.bmp"); + } + return 0; + case IDM_FILE_RECORDAVI: + AviRecordTo(); + break; + case IDM_FILE_STOPAVI: + AviEnd(); + break; + case IDM_STATE_LOAD: + { + OPENFILENAME ofn; + NDS_Pause(); + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = "DeSmuME Savestate (*.dst)\0*.dst\0\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFile = SavName; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "dst"; + + if(!GetOpenFileName(&ofn)) + { + NDS_UnPause(); + return 0; + } + + savestate_load(SavName); + NDS_UnPause(); + } + return 0; + case IDM_STATE_SAVE: + { + OPENFILENAME ofn; + NDS_Pause(); + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = "DeSmuME Savestate (*.dst)\0*.dst\0\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFile = SavName; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "dst"; + + if(!GetSaveFileName(&ofn)) + { + return 0; + } + + savestate_save(SavName); + NDS_UnPause(); + } + return 0; + case IDM_STATE_SAVE_F1: + StateSaveSlot(1); + return 0; + case IDM_STATE_SAVE_F2: + StateSaveSlot(2); + return 0; + case IDM_STATE_SAVE_F3: + StateSaveSlot(3); + return 0; + case IDM_STATE_SAVE_F4: + StateSaveSlot(4); + return 0; + case IDM_STATE_SAVE_F5: + StateSaveSlot(5); + return 0; + case IDM_STATE_SAVE_F6: + StateSaveSlot(6); + return 0; + case IDM_STATE_SAVE_F7: + StateSaveSlot(7); + return 0; + case IDM_STATE_SAVE_F8: + StateSaveSlot(8); + return 0; + case IDM_STATE_SAVE_F9: + StateSaveSlot(9); + return 0; + case IDM_STATE_SAVE_F10: + StateSaveSlot(10); + return 0; + case IDM_STATE_LOAD_F1: + StateLoadSlot(1); + return 0; + case IDM_STATE_LOAD_F2: + StateLoadSlot(2); + return 0; + case IDM_STATE_LOAD_F3: + StateLoadSlot(3); + return 0; + case IDM_STATE_LOAD_F4: + StateLoadSlot(4); + return 0; + case IDM_STATE_LOAD_F5: + StateLoadSlot(5); + return 0; + case IDM_STATE_LOAD_F6: + StateLoadSlot(6); + return 0; + case IDM_STATE_LOAD_F7: + StateLoadSlot(7); + return 0; + case IDM_STATE_LOAD_F8: + StateLoadSlot(8); + return 0; + case IDM_STATE_LOAD_F9: + StateLoadSlot(9); + return 0; + case IDM_STATE_LOAD_F10: + StateLoadSlot(10); + return 0; case ACCEL_I: //Quick Save StateSaveSlot(lastSaveState); return 0; @@ -1827,32 +1809,32 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lastSaveState = 9; SaveStateMessages(9,2); return 0; - case IDM_IMPORTBACKUPMEMORY: - { - OPENFILENAME ofn; - NDS_Pause(); - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - ofn.lpstrFilter = "All supported types\0*.duc;*.sav\0Action Replay DS Save (*.duc)\0*.duc\0DS-Xtreme Save (*.sav)\0*.sav\0\0"; - ofn.nFilterIndex = 1; - ofn.lpstrFile = ImportSavName; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrDefExt = "duc"; - - if(!GetOpenFileName(&ofn)) - { - NDS_UnPause(); - return 0; - } - - if (!NDS_ImportSave(ImportSavName)) - MessageBox(hwnd,"Save was not successfully imported","Error",MB_OK); - NDS_UnPause(); - return 0; - } - case IDM_SOUNDSETTINGS: - { + case IDM_IMPORTBACKUPMEMORY: + { + OPENFILENAME ofn; + NDS_Pause(); + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = "All supported types\0*.duc;*.sav\0Action Replay DS Save (*.duc)\0*.duc\0DS-Xtreme Save (*.sav)\0*.sav\0\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFile = ImportSavName; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "duc"; + + if(!GetOpenFileName(&ofn)) + { + NDS_UnPause(); + return 0; + } + + if (!NDS_ImportSave(ImportSavName)) + MessageBox(hwnd,"Save was not successfully imported","Error",MB_OK); + NDS_UnPause(); + return 0; + } + case IDM_SOUNDSETTINGS: + { bool tpaused=false; if (execute) { @@ -1862,30 +1844,30 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_SOUNDSETTINGS), hwnd, (DLGPROC)SoundSettingsDlgProc); if (tpaused) NDS_UnPause(); - } - return 0; - case IDM_GAME_INFO: - { - CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_GAME_INFO), hwnd, GinfoView_Proc); - } - return 0; + } + return 0; + case IDM_GAME_INFO: + { + CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_GAME_INFO), hwnd, GinfoView_Proc); + } + return 0; //========================================================= Tools - case IDM_PAL: + case IDM_PAL: ViewPalette->open(); return 0; - case IDM_TILE: - { + case IDM_TILE: + { ViewTiles->regClass("TileViewBox", TileViewBoxProc); ViewTiles->regClass("MiniTileViewBox", MiniTileViewBoxProc, true); if (!ViewTiles->open()) ViewTiles->unregClass(); - } - return 0; - case IDM_IOREG: - ViewRegisters->open(); - return 0; - case IDM_MEMORY: + } + return 0; + case IDM_IOREG: + ViewRegisters->open(); + return 0; + case IDM_MEMORY: ViewMem_ARM7->regClass("MemViewBox7", ViewMem_ARM7BoxProc); if (!ViewMem_ARM7->open()) ViewMem_ARM7->unregClass(); @@ -1893,150 +1875,150 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if (!ViewMem_ARM9->open()) ViewMem_ARM9->unregClass(); return 0; - case IDM_DISASSEMBLER: + case IDM_DISASSEMBLER: ViewDisasm_ARM7->regClass("DesViewBox7",ViewDisasm_ARM7BoxProc); if (!ViewDisasm_ARM7->open()) ViewDisasm_ARM7->unregClass(); - + ViewDisasm_ARM9->regClass("DesViewBox9",ViewDisasm_ARM9BoxProc); if (!ViewDisasm_ARM9->open()) ViewDisasm_ARM9->unregClass(); return 0; - case IDM_MAP: + case IDM_MAP: ViewMaps->open(); return 0; - case IDM_OAM: + case IDM_OAM: ViewOAM->regClass("OAMViewBox", ViewOAMBoxProc); if (!ViewOAM->open()) ViewOAM->unregClass(); return 0; - - case IDM_MATRIX_VIEWER: + + case IDM_MATRIX_VIEWER: ViewMatrices->open(); return 0; - - case IDM_LIGHT_VIEWER: + + case IDM_LIGHT_VIEWER: ViewLights->open(); return 0; //========================================================== Tools end - - case IDM_MBG0 : - if(MainScreen.gpu->dispBG[0]) - { - GPU_remove(MainScreen.gpu, 0); + + case IDM_MBG0 : + if(MainScreen.gpu->dispBG[0]) + { + GPU_remove(MainScreen.gpu, 0); MainWindow->checkMenu(IDM_MBG0, MF_BYCOMMAND | MF_UNCHECKED); - } - else - { - GPU_addBack(MainScreen.gpu, 0); + } + else + { + GPU_addBack(MainScreen.gpu, 0); MainWindow->checkMenu(IDM_MBG0, MF_BYCOMMAND | MF_CHECKED); - } - return 0; - case IDM_MBG1 : - if(MainScreen.gpu->dispBG[1]) - { - GPU_remove(MainScreen.gpu, 1); + } + return 0; + case IDM_MBG1 : + if(MainScreen.gpu->dispBG[1]) + { + GPU_remove(MainScreen.gpu, 1); MainWindow->checkMenu(IDM_MBG1, MF_BYCOMMAND | MF_UNCHECKED); - } - else - { - GPU_addBack(MainScreen.gpu, 1); + } + else + { + GPU_addBack(MainScreen.gpu, 1); MainWindow->checkMenu(IDM_MBG1, MF_BYCOMMAND | MF_CHECKED); - } - return 0; - case IDM_MBG2 : - if(MainScreen.gpu->dispBG[2]) - { - GPU_remove(MainScreen.gpu, 2); + } + return 0; + case IDM_MBG2 : + if(MainScreen.gpu->dispBG[2]) + { + GPU_remove(MainScreen.gpu, 2); MainWindow->checkMenu(IDM_MBG2, MF_BYCOMMAND | MF_UNCHECKED); - } - else - { - GPU_addBack(MainScreen.gpu, 2); + } + else + { + GPU_addBack(MainScreen.gpu, 2); MainWindow->checkMenu(IDM_MBG2, MF_BYCOMMAND | MF_CHECKED); - } - return 0; - case IDM_MBG3 : - if(MainScreen.gpu->dispBG[3]) - { - GPU_remove(MainScreen.gpu, 3); + } + return 0; + case IDM_MBG3 : + if(MainScreen.gpu->dispBG[3]) + { + GPU_remove(MainScreen.gpu, 3); MainWindow->checkMenu(IDM_MBG3, MF_BYCOMMAND | MF_UNCHECKED); - } - else - { - GPU_addBack(MainScreen.gpu, 3); + } + else + { + GPU_addBack(MainScreen.gpu, 3); MainWindow->checkMenu(IDM_MBG3, MF_BYCOMMAND | MF_CHECKED); - } - return 0; - case IDM_SBG0 : - if(SubScreen.gpu->dispBG[0]) - { - GPU_remove(SubScreen.gpu, 0); + } + return 0; + case IDM_SBG0 : + if(SubScreen.gpu->dispBG[0]) + { + GPU_remove(SubScreen.gpu, 0); MainWindow->checkMenu(IDM_SBG0, MF_BYCOMMAND | MF_UNCHECKED); - } - else - { - GPU_addBack(SubScreen.gpu, 0); + } + else + { + GPU_addBack(SubScreen.gpu, 0); MainWindow->checkMenu(IDM_SBG0, MF_BYCOMMAND | MF_CHECKED); - } - return 0; - case IDM_SBG1 : - if(SubScreen.gpu->dispBG[1]) - { - GPU_remove(SubScreen.gpu, 1); + } + return 0; + case IDM_SBG1 : + if(SubScreen.gpu->dispBG[1]) + { + GPU_remove(SubScreen.gpu, 1); MainWindow->checkMenu(IDM_SBG1, MF_BYCOMMAND | MF_UNCHECKED); - } - else - { - GPU_addBack(SubScreen.gpu, 1); + } + else + { + GPU_addBack(SubScreen.gpu, 1); MainWindow->checkMenu(IDM_SBG1, MF_BYCOMMAND | MF_CHECKED); - } - return 0; - case IDM_SBG2 : - if(SubScreen.gpu->dispBG[2]) - { - GPU_remove(SubScreen.gpu, 2); + } + return 0; + case IDM_SBG2 : + if(SubScreen.gpu->dispBG[2]) + { + GPU_remove(SubScreen.gpu, 2); MainWindow->checkMenu(IDM_SBG2, MF_BYCOMMAND | MF_UNCHECKED); - } - else - { - GPU_addBack(SubScreen.gpu, 2); + } + else + { + GPU_addBack(SubScreen.gpu, 2); MainWindow->checkMenu(IDM_SBG2, MF_BYCOMMAND | MF_CHECKED); - } - return 0; - case IDM_SBG3 : - if(SubScreen.gpu->dispBG[3]) - { - GPU_remove(SubScreen.gpu, 3); + } + return 0; + case IDM_SBG3 : + if(SubScreen.gpu->dispBG[3]) + { + GPU_remove(SubScreen.gpu, 3); MainWindow->checkMenu(IDM_SBG3, MF_BYCOMMAND | MF_UNCHECKED); - } - else - { - GPU_addBack(SubScreen.gpu, 3); + } + else + { + GPU_addBack(SubScreen.gpu, 3); MainWindow->checkMenu(IDM_SBG3, MF_BYCOMMAND | MF_CHECKED); - } - return 0; - - case ACCEL_SPACEBAR: - case IDM_PAUSE: - if (emu_paused) NDS_UnPause(); - else NDS_Pause(); - emu_paused ^= 1; + } + return 0; + + case ACCEL_SPACEBAR: + case IDM_PAUSE: + if (emu_paused) NDS_UnPause(); + else NDS_Pause(); + emu_paused ^= 1; MainWindow->checkMenu(IDM_PAUSE, emu_paused ? MF_CHECKED : MF_UNCHECKED); - return 0; - - case ACCEL_N: //Frame Advance - frameAdvance = true; - execute = TRUE; - emu_paused = 1; + return 0; + + case ACCEL_N: //Frame Advance + frameAdvance = true; + execute = TRUE; + emu_paused = 1; MainWindow->checkMenu(IDM_PAUSE, emu_paused ? MF_CHECKED : MF_UNCHECKED); - return 0; - - case ID_VIEW_FRAMECOUNTER: - frameCounterDisplay ^= 1; + return 0; + + case ID_VIEW_FRAMECOUNTER: + frameCounterDisplay ^= 1; MainWindow->checkMenu(ID_VIEW_FRAMECOUNTER, frameCounterDisplay ? MF_CHECKED : MF_UNCHECKED); - return 0; - + return 0; + case ID_VIEW_DISPLAYFPS: FpsDisplay ^= 1; MainWindow->checkMenu(ID_VIEW_DISPLAYFPS, FpsDisplay ? MF_CHECKED : MF_UNCHECKED); @@ -2044,45 +2026,45 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM osd->clear(); return 0; - #define saver(one,two,three,four,five, six) \ + #define saver(one,two,three,four,five, six) \ MainWindow->checkMenu(IDC_SAVETYPE1, MF_BYCOMMAND | one); \ MainWindow->checkMenu(IDC_SAVETYPE2, MF_BYCOMMAND | two); \ MainWindow->checkMenu(IDC_SAVETYPE3, MF_BYCOMMAND | three); \ MainWindow->checkMenu(IDC_SAVETYPE4, MF_BYCOMMAND | four); \ MainWindow->checkMenu(IDC_SAVETYPE5, MF_BYCOMMAND | five); \ MainWindow->checkMenu(IDC_SAVETYPE6, MF_BYCOMMAND | six); - - case IDC_SAVETYPE1: - saver(MF_CHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED); - mmu_select_savetype(0,&backupmemorytype,&backupmemorysize); - return 0; - case IDC_SAVETYPE2: - saver(MF_UNCHECKED,MF_CHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED); - mmu_select_savetype(1,&backupmemorytype,&backupmemorysize); - return 0; - case IDC_SAVETYPE3: - saver(MF_UNCHECKED,MF_UNCHECKED,MF_CHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED); - mmu_select_savetype(2,&backupmemorytype,&backupmemorysize); - return 0; - case IDC_SAVETYPE4: - saver(MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_CHECKED,MF_UNCHECKED,MF_UNCHECKED); - mmu_select_savetype(3,&backupmemorytype,&backupmemorysize); - return 0; - case IDC_SAVETYPE5: - saver(MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_CHECKED,MF_UNCHECKED); - mmu_select_savetype(4,&backupmemorytype,&backupmemorysize); - return 0; - case IDC_SAVETYPE6: - saver(MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_CHECKED); - mmu_select_savetype(5,&backupmemorytype,&backupmemorysize); - return 0; - - case IDM_RESET: - NDS_Reset(); - frameCounter=0; - return 0; - case IDM_CONFIG: - { + + case IDC_SAVETYPE1: + saver(MF_CHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED); + mmu_select_savetype(0,&backupmemorytype,&backupmemorysize); + return 0; + case IDC_SAVETYPE2: + saver(MF_UNCHECKED,MF_CHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED); + mmu_select_savetype(1,&backupmemorytype,&backupmemorysize); + return 0; + case IDC_SAVETYPE3: + saver(MF_UNCHECKED,MF_UNCHECKED,MF_CHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED); + mmu_select_savetype(2,&backupmemorytype,&backupmemorysize); + return 0; + case IDC_SAVETYPE4: + saver(MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_CHECKED,MF_UNCHECKED,MF_UNCHECKED); + mmu_select_savetype(3,&backupmemorytype,&backupmemorysize); + return 0; + case IDC_SAVETYPE5: + saver(MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_CHECKED,MF_UNCHECKED); + mmu_select_savetype(4,&backupmemorytype,&backupmemorysize); + return 0; + case IDC_SAVETYPE6: + saver(MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_UNCHECKED,MF_CHECKED); + mmu_select_savetype(5,&backupmemorytype,&backupmemorysize); + return 0; + + case IDM_RESET: + NDS_Reset(); + frameCounter=0; + return 0; + case IDM_CONFIG: + { bool tpaused=false; if (execute) { @@ -2092,9 +2074,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM InputConfig(hwnd); if (tpaused) NDS_UnPause(); - } - return 0; - case IDM_FIRMSETTINGS: + } + return 0; + case IDM_FIRMSETTINGS: { bool tpaused=false; if (execute) @@ -2108,32 +2090,32 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM return 0; } - case IDC_FRAMESKIPAUTO: - case IDC_FRAMESKIP0: - case IDC_FRAMESKIP1: - case IDC_FRAMESKIP2: - case IDC_FRAMESKIP3: - case IDC_FRAMESKIP4: - case IDC_FRAMESKIP5: - case IDC_FRAMESKIP6: - case IDC_FRAMESKIP7: - case IDC_FRAMESKIP8: - case IDC_FRAMESKIP9: - { - if(LOWORD(wParam) == IDC_FRAMESKIPAUTO) - { - autoframeskipenab = 1; - WritePrivateProfileString("Video", "FrameSkip", "AUTO", IniName); - } - else - { - char text[80]; - autoframeskipenab = 0; - frameskiprate = LOWORD(wParam) - IDC_FRAMESKIP0; - sprintf(text, "%d", frameskiprate); - WritePrivateProfileString("Video", "FrameSkip", text, IniName); - } - + case IDC_FRAMESKIPAUTO: + case IDC_FRAMESKIP0: + case IDC_FRAMESKIP1: + case IDC_FRAMESKIP2: + case IDC_FRAMESKIP3: + case IDC_FRAMESKIP4: + case IDC_FRAMESKIP5: + case IDC_FRAMESKIP6: + case IDC_FRAMESKIP7: + case IDC_FRAMESKIP8: + case IDC_FRAMESKIP9: + { + if(LOWORD(wParam) == IDC_FRAMESKIPAUTO) + { + autoframeskipenab = 1; + WritePrivateProfileString("Video", "FrameSkip", "AUTO", IniName); + } + else + { + char text[80]; + autoframeskipenab = 0; + frameskiprate = LOWORD(wParam) - IDC_FRAMESKIP0; + sprintf(text, "%d", frameskiprate); + WritePrivateProfileString("Video", "FrameSkip", text, IniName); + } + MainWindow->checkMenu(IDC_FRAMESKIPAUTO, MF_BYCOMMAND | MF_UNCHECKED); MainWindow->checkMenu(IDC_FRAMESKIP0, MF_BYCOMMAND | MF_UNCHECKED); MainWindow->checkMenu(IDC_FRAMESKIP1, MF_BYCOMMAND | MF_UNCHECKED); @@ -2146,32 +2128,32 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM MainWindow->checkMenu(IDC_FRAMESKIP8, MF_BYCOMMAND | MF_UNCHECKED); MainWindow->checkMenu(IDC_FRAMESKIP9, MF_BYCOMMAND | MF_UNCHECKED); MainWindow->checkMenu(LOWORD(wParam), MF_BYCOMMAND | MF_CHECKED); - } - return 0; - case IDC_LANGENGLISH: - SaveLanguage(0); - ChangeLanguage(0); - CheckLanguage(LOWORD(wParam)); - return 0; - case IDC_LANGFRENCH: - SaveLanguage(1); - ChangeLanguage(1); - CheckLanguage(LOWORD(wParam)); - return 0; - case IDC_LANGDANISH: - SaveLanguage(1); - ChangeLanguage(2); - CheckLanguage(LOWORD(wParam)); - return 0; - case IDM_WEBSITE: - ShellExecute(NULL, "open", "http://desmume.sourceforge.net", NULL, NULL, SW_SHOWNORMAL); - return 0; - - case IDM_FORUM: - ShellExecute(NULL, "open", "http://forums.desmume.org/index.php", NULL, NULL, SW_SHOWNORMAL); - return 0; - - case IDM_ABOUT: + } + return 0; + case IDC_LANGENGLISH: + SaveLanguage(0); + ChangeLanguage(0); + CheckLanguage(LOWORD(wParam)); + return 0; + case IDC_LANGFRENCH: + SaveLanguage(1); + ChangeLanguage(1); + CheckLanguage(LOWORD(wParam)); + return 0; + case IDC_LANGDANISH: + SaveLanguage(1); + ChangeLanguage(2); + CheckLanguage(LOWORD(wParam)); + return 0; + case IDM_WEBSITE: + ShellExecute(NULL, "open", "http://desmume.sourceforge.net", NULL, NULL, SW_SHOWNORMAL); + return 0; + + case IDM_FORUM: + ShellExecute(NULL, "open", "http://forums.desmume.org/index.php", NULL, NULL, SW_SHOWNORMAL); + return 0; + + case IDM_ABOUT: { bool tpaused=false; if (execute) @@ -2185,194 +2167,195 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM return 0; } - -#ifndef BETA_VERSION - case IDM_SUBMITBUGREPORT: - ShellExecute(NULL, "open", "http://sourceforge.net/tracker/?func=add&group_id=164579&atid=832291", NULL, NULL, SW_SHOWNORMAL); - return 0; -#endif - - case IDC_ROTATE0: + +#ifndef BETA_VERSION + case IDM_SUBMITBUGREPORT: + ShellExecute(NULL, "open", "http://sourceforge.net/tracker/?func=add&group_id=164579&atid=832291", NULL, NULL, SW_SHOWNORMAL); + return 0; +#endif + + case IDC_ROTATE0: SetRotate(hwnd, 0); - return 0; - case IDC_ROTATE90: + return 0; + case IDC_ROTATE90: SetRotate(hwnd, 90); - return 0; - case IDC_ROTATE180: + return 0; + case IDC_ROTATE180: SetRotate(hwnd, 180); - return 0; - case IDC_ROTATE270: + return 0; + case IDC_ROTATE270: SetRotate(hwnd, 270); - return 0; - - case IDC_WINDOW1X: - windowSize=1; - ScaleScreen(hwnd, windowSize); - WritePrivateProfileInt("Video","Window Size",windowSize,IniName); - + return 0; + + case IDC_WINDOW1X: + windowSize=1; + ScaleScreen(hwnd, windowSize); + WritePrivateProfileInt("Video","Window Size",windowSize,IniName); + MainWindow->checkMenu(IDC_WINDOW1X, MF_BYCOMMAND | ((windowSize==1)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW2X, MF_BYCOMMAND | ((windowSize==2)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW3X, MF_BYCOMMAND | ((windowSize==3)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW4X, MF_BYCOMMAND | ((windowSize==4)?MF_CHECKED:MF_UNCHECKED)); - break; - case IDC_WINDOW2X: - windowSize=2; - ScaleScreen(hwnd, windowSize); - WritePrivateProfileInt("Video","Window Size",windowSize,IniName); - + break; + case IDC_WINDOW2X: + windowSize=2; + ScaleScreen(hwnd, windowSize); + WritePrivateProfileInt("Video","Window Size",windowSize,IniName); + MainWindow->checkMenu(IDC_WINDOW1X, MF_BYCOMMAND | ((windowSize==1)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW2X, MF_BYCOMMAND | ((windowSize==2)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW3X, MF_BYCOMMAND | ((windowSize==3)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW4X, MF_BYCOMMAND | ((windowSize==4)?MF_CHECKED:MF_UNCHECKED)); - break; - case IDC_WINDOW3X: - windowSize=3; - ScaleScreen(hwnd, windowSize); - WritePrivateProfileInt("Video","Window Size",windowSize,IniName); - + break; + case IDC_WINDOW3X: + windowSize=3; + ScaleScreen(hwnd, windowSize); + WritePrivateProfileInt("Video","Window Size",windowSize,IniName); + MainWindow->checkMenu(IDC_WINDOW1X, MF_BYCOMMAND | ((windowSize==1)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW2X, MF_BYCOMMAND | ((windowSize==2)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW3X, MF_BYCOMMAND | ((windowSize==3)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW4X, MF_BYCOMMAND | ((windowSize==4)?MF_CHECKED:MF_UNCHECKED)); - break; - case IDC_WINDOW4X: - windowSize=4; - ScaleScreen(hwnd, windowSize); - WritePrivateProfileInt("Video","Window Size",windowSize,IniName); - + break; + case IDC_WINDOW4X: + windowSize=4; + ScaleScreen(hwnd, windowSize); + WritePrivateProfileInt("Video","Window Size",windowSize,IniName); + MainWindow->checkMenu(IDC_WINDOW1X, MF_BYCOMMAND | ((windowSize==1)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW2X, MF_BYCOMMAND | ((windowSize==2)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW3X, MF_BYCOMMAND | ((windowSize==3)?MF_CHECKED:MF_UNCHECKED)); MainWindow->checkMenu(IDC_WINDOW4X, MF_BYCOMMAND | ((windowSize==4)?MF_CHECKED:MF_UNCHECKED)); - break; - - case IDC_FORCERATIO: - if (ForceRatio) { + break; + + case IDC_FORCERATIO: + if (ForceRatio) { MainWindow->checkMenu(IDC_FORCERATIO, MF_BYCOMMAND | MF_UNCHECKED); - ForceRatio = FALSE; - WritePrivateProfileInt("Video","Window Force Ratio",0,IniName); - } - else { - RECT fullSize; - GetWindowRect(hwnd, &fullSize); - ScallingScreen(hwnd, WMSZ_RIGHT, &fullSize); + ForceRatio = FALSE; + WritePrivateProfileInt("Video","Window Force Ratio",0,IniName); + } + else { + RECT fullSize; + GetWindowRect(hwnd, &fullSize); + ScaleScreen(hwnd, WMSZ_RIGHT, &fullSize); SetWindowPos(hwnd, NULL, WndX, WndY, fullSize.right - fullSize.left, - fullSize.bottom - fullSize.top, SWP_NOMOVE | SWP_NOZORDER); - //ScaleScreen(hwnd, (fullSize.bottom - fullSize.top - heightTradeOff) / DefaultHeight); + fullSize.bottom - fullSize.top, SWP_NOMOVE | SWP_NOZORDER); + //ScaleScreen(hwnd, (fullSize.bottom - fullSize.top - heightTradeOff) / DefaultHeight); MainWindow->checkMenu(IDC_FORCERATIO, MF_BYCOMMAND | MF_CHECKED); - ForceRatio = TRUE; - WritePrivateProfileInt("Video","Window Force Ratio",1,IniName); - } - break; - - } - return 0; - default: /* for messages that we don't deal with */ - return DefWindowProc (hwnd, message, wParam, lParam); - } - - return 0; -} - -LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam) -{ - static int timerid=0; - switch (uMsg) - { - case WM_INITDIALOG: - { - int i; - char tempstr[MAX_PATH]; - // Setup Sound Core Combo box - SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_RESETCONTENT, 0, 0); - SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_ADDSTRING, 0, (LPARAM)"None"); - - for (i = 1; SNDCoreList[i] != NULL; i++) - SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_ADDSTRING, 0, (LPARAM)SNDCoreList[i]->Name); - - // Set Selected Sound Core - for (i = 0; SNDCoreList[i] != NULL; i++) - { - if (sndcoretype == SNDCoreList[i]->id) - SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_SETCURSEL, i, 0); - } - - // Setup Sound Buffer Size Edit Text - sprintf(tempstr, "%d", sndbuffersize); - SetDlgItemText(hDlg, IDC_SOUNDBUFFERET, tempstr); - - // Setup Volume Slider - SendDlgItemMessage(hDlg, IDC_SLVOLUME, TBM_SETRANGE, 0, MAKELONG(0, 100)); - - // Set Selected Volume - SendDlgItemMessage(hDlg, IDC_SLVOLUME, TBM_SETPOS, TRUE, sndvolume); - - timerid = SetTimer(hDlg, 1, 500, NULL); - return TRUE; - } - case WM_TIMER: - { - if (timerid == wParam) - { - int setting; - setting = SendDlgItemMessage(hDlg, IDC_SLVOLUME, TBM_GETPOS, 0, 0); - SPU_SetVolume(setting); - break; - } - break; - } - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDOK: - { - char tempstr[MAX_PATH]; - - EndDialog(hDlg, TRUE); - - // Write Sound core type - sndcoretype = SNDCoreList[SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_GETCURSEL, 0, 0)]->id; - sprintf(tempstr, "%d", sndcoretype); - WritePrivateProfileString("Sound", "SoundCore", tempstr, IniName); - - // Write Sound Buffer size - GetDlgItemText(hDlg, IDC_SOUNDBUFFERET, tempstr, 6); - sscanf(tempstr, "%d", &sndbuffersize); - WritePrivateProfileString("Sound", "SoundBufferSize", tempstr, IniName); - - EnterCriticalSection(&win_sync); - SPU_ChangeSoundCore(sndcoretype, sndbuffersize); - LeaveCriticalSection(&win_sync); - - // Write Volume - sndvolume = SendDlgItemMessage(hDlg, IDC_SLVOLUME, TBM_GETPOS, 0, 0); - sprintf(tempstr, "%d", sndvolume); - WritePrivateProfileString("Sound", "Volume", tempstr, IniName); - SPU_SetVolume(sndvolume); - - return TRUE; - } - case IDCANCEL: - { - EndDialog(hDlg, FALSE); - return TRUE; - } - default: break; - } - - break; - } - case WM_DESTROY: - { - if (timerid != 0) - KillTimer(hDlg, timerid); - break; - } - } - - return FALSE; -} - - + ForceRatio = TRUE; + WritePrivateProfileInt("Video","Window Force Ratio",1,IniName); + } + break; + + } + return 0; + default: /* for messages that we don't deal with */ + return DefWindowProc (hwnd, message, wParam, lParam); + } + + return 0; +} + +LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, + LPARAM lParam) +{ + static UINT_PTR timerid=0; + switch (uMsg) + { + case WM_INITDIALOG: + { + int i; + char tempstr[MAX_PATH]; + // Setup Sound Core Combo box + SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_RESETCONTENT, 0, 0); + SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_ADDSTRING, 0, (LPARAM)"None"); + + for (i = 1; SNDCoreList[i] != NULL; i++) + SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_ADDSTRING, 0, (LPARAM)SNDCoreList[i]->Name); + + // Set Selected Sound Core + for (i = 0; SNDCoreList[i] != NULL; i++) + { + if (sndcoretype == SNDCoreList[i]->id) + SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_SETCURSEL, i, 0); + } + + // Setup Sound Buffer Size Edit Text + sprintf(tempstr, "%d", sndbuffersize); + SetDlgItemText(hDlg, IDC_SOUNDBUFFERET, tempstr); + + // Setup Volume Slider + SendDlgItemMessage(hDlg, IDC_SLVOLUME, TBM_SETRANGE, 0, MAKELONG(0, 100)); + + // Set Selected Volume + SendDlgItemMessage(hDlg, IDC_SLVOLUME, TBM_SETPOS, TRUE, sndvolume); + + timerid = SetTimer(hDlg, 1, 500, NULL); + return TRUE; + } + case WM_TIMER: + { + if (timerid == wParam) + { + int setting; + setting = SendDlgItemMessage(hDlg, IDC_SLVOLUME, TBM_GETPOS, 0, 0); + SPU_SetVolume(setting); + break; + } + break; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + { + char tempstr[MAX_PATH]; + + EndDialog(hDlg, TRUE); + + // Write Sound core type + sndcoretype = SNDCoreList[SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_GETCURSEL, 0, 0)]->id; + sprintf(tempstr, "%d", sndcoretype); + WritePrivateProfileString("Sound", "SoundCore", tempstr, IniName); + + // Write Sound Buffer size + GetDlgItemText(hDlg, IDC_SOUNDBUFFERET, tempstr, 6); + sscanf(tempstr, "%d", &sndbuffersize); + WritePrivateProfileString("Sound", "SoundBufferSize", tempstr, IniName); + + { + Lock lock; + SPU_ChangeSoundCore(sndcoretype, sndbuffersize); + } + + // Write Volume + sndvolume = SendDlgItemMessage(hDlg, IDC_SLVOLUME, TBM_GETPOS, 0, 0); + sprintf(tempstr, "%d", sndvolume); + WritePrivateProfileString("Sound", "Volume", tempstr, IniName); + SPU_SetVolume(sndvolume); + + return TRUE; + } + case IDCANCEL: + { + EndDialog(hDlg, FALSE); + return TRUE; + } + default: break; + } + + break; + } + case WM_DESTROY: + { + if (timerid != 0) + KillTimer(hDlg, timerid); + break; + } + } + + return FALSE; +} + + diff --git a/desmume/src/windows/snddx.cpp b/desmume/src/windows/snddx.cpp index 6f1026943..0d726f3ed 100755 --- a/desmume/src/windows/snddx.cpp +++ b/desmume/src/windows/snddx.cpp @@ -31,6 +31,7 @@ const char* __stdcall DXGetErrorDescription8A(HRESULT hr); #include "SPU.h" #include "snddx.h" #include "CWindow.h" +#include "windriver.h" int SNDDXInit(int buffersize); void SNDDXDeInit(); @@ -71,11 +72,14 @@ static volatile bool terminated; extern CRITICAL_SECTION win_sync; extern volatile int win_sound_samplecounter; -DWORD WINAPI SNDDXThread( LPVOID lpParameter) +DWORD WINAPI SNDDXThread( LPVOID ) { for(;;) { if(terminate) break; - SPU_Emulate_user(); + { + Lock lock; + SPU_Emulate_user(); + } Sleep(10); } terminated = true; @@ -229,10 +233,13 @@ void SNDDXUpdateAudio(s16 *buffer, u32 num_samples) DWORD buffer1_size, buffer2_size; DWORD status; - EnterCriticalSection(&win_sync); - int samplecounter = win_sound_samplecounter -= num_samples; - LeaveCriticalSection(&win_sync); - bool silence = (samplecounter<-44100*15/60); //behind by more than a quarter second -> silence + int samplecounter; + { + Lock lock; + samplecounter = win_sound_samplecounter -= num_samples; + } + + bool silence = (samplecounter<-44100*15/60); //behind by more than a quarter second -> silence IDirectSoundBuffer8_GetStatus(lpDSB2, &status); diff --git a/desmume/src/windows/windriver.h b/desmume/src/windows/windriver.h index fe3b16119..252db51e9 100644 --- a/desmume/src/windows/windriver.h +++ b/desmume/src/windows/windriver.h @@ -7,4 +7,10 @@ extern WINCLASS *MainWindow; +class Lock { +public: + Lock(); + ~Lock(); +}; + #endif \ No newline at end of file