From 29ed126829f06a436e37c7ec5c0fbb07efd051d4 Mon Sep 17 00:00:00 2001 From: Brendan Walker Date: Thu, 5 Dec 2002 00:39:35 +0000 Subject: [PATCH] Added Modified version of RageUtil.cpp/.h to smlobby module to eliminate conflictions between MFC's and Stepmania's CString. Also tweeked the project files to get it to compile... --- stepmania/src/smlobby/RageUtil.cpp | 727 +++++++++++++++++++++++++++++ stepmania/src/smlobby/RageUtil.h | 201 ++++++++ stepmania/src/smlobby/smlobby.ncb | Bin 38 -> 82941 bytes stepmania/src/smlobby/smlobby.opt | Bin 53760 -> 49664 bytes stepmania/src/smlobby/socket.h | 6 +- 5 files changed, 931 insertions(+), 3 deletions(-) create mode 100644 stepmania/src/smlobby/RageUtil.cpp create mode 100644 stepmania/src/smlobby/RageUtil.h diff --git a/stepmania/src/smlobby/RageUtil.cpp b/stepmania/src/smlobby/RageUtil.cpp new file mode 100644 index 0000000000..7ae2be31a0 --- /dev/null +++ b/stepmania/src/smlobby/RageUtil.cpp @@ -0,0 +1,727 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: RageUtil + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford + Peter S. May (GetHashForString implementation) +----------------------------------------------------------------------------- +*/ + +#include "./RageUtil.h" + +ULONG randseed = time(NULL); + +#include +#include +#include +#include +#include +#include + +using namespace std; + +bool IsAnInt( const char *s ) +{ + if( s[0] == '\0' ) + return false; + + for( UINT i=0; s[i]; i++ ) + if( s[i] < '0' || s[i] > '9' ) + return false; + + return true; +} + + +//----------------------------------------------------------------------------- +// Name: ssprintf() +// Desc: +//----------------------------------------------------------------------------- +CString ssprintf( const char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + return vssprintf(fmt, va); +} + + +//----------------------------------------------------------------------------- +// Name: vssprintf() +// Desc: +//----------------------------------------------------------------------------- +CString vssprintf( const char *fmt, va_list argList) +{ + CString str; + str.FormatV(fmt, argList); + return str; +} + + + +//----------------------------------------------------------------------------- +// Name: split() +// Desc: +//----------------------------------------------------------------------------- +void split( const CString &Source, const CString &Deliminator, CStringArray& AddIt, const bool bIgnoreEmpty ) +{ + int startpos = 0; + + do { + int pos = Source.Find(Deliminator, startpos); + if ( pos == -1 ) pos=Source.GetLength(); + + CString AddCString = Source.Mid(startpos, pos-startpos); + if( AddCString.IsEmpty() && bIgnoreEmpty ) + ; // do nothing + else + AddIt.Add(AddCString); + + startpos=pos+Deliminator.GetLength(); + } while ( startpos <= Source.GetLength() ); +} + + +void splitpath( bool UsingDirsOnly, const CString &Path, CString& Drive, CString& Dir, CString& FName, CString& Ext ) +{ + int nSecond; + + // Look for a UNC filename. + if (Path.Left(2) == "\\\\") + { + int nFirst = Path.Find("\\",3); + nSecond = Path.Find("\\",nFirst + 1); + if (nSecond == -1) { + Drive = Path; + Dir = ""; + FName = ""; + Ext = ""; + } + else if (nSecond > nFirst) + Drive = Path.Left(nSecond); + } + else if (Path.Mid(1,1) == ":" ) // drive letter + { + nSecond = 2; + Drive = Path.Left(2); + } + else // no UNC or drive letter + { + nSecond = -1; + } + + + if (UsingDirsOnly) { + Dir = Path.Right((Path.GetLength() - nSecond) - 1); + FName = ""; + Ext = ""; + } + else { + int nDirEnd = Path.ReverseFind('\\'); + if (nDirEnd == Path.GetLength()) { + Dir = ""; + FName = ""; + Ext = ""; + } + else { + + Dir = Path.Mid(nSecond + 1, (nDirEnd - nSecond) - 1); + + int nFileEnd = Path.ReverseFind('.'); + if (nFileEnd != -1) { + + if (nDirEnd > nFileEnd) { + FName = Path.Right(Path.GetLength() - nDirEnd); + Ext = ""; + } + else { + FName = Path.Mid(nDirEnd + 1, (nFileEnd - nDirEnd) - 1); + Ext = Path.Right((Path.GetLength() - nFileEnd) - 1); + } + } + else { + FName = Path.Right((Path.GetLength() - nDirEnd) - 1); + Ext = ""; + } + } + } +} + +//----------------------------------------------------------------------------- +// Name: splitpath() +// Desc: +//----------------------------------------------------------------------------- +void splitrelpath( const CString &Path, CString& Dir, CString& FName, CString& Ext ) +{ + /* Find the last slash or backslash. */ + int Last = max(Path.ReverseFind('/'), Path.ReverseFind('\\')); + + /* Set 'Last' to the first character of the filename. If we have + * no directory separators, this is the entire string, so set it + * to 0. */ + if(Last == -1) Last = 0; + else Last++; + + CString sFNameAndExt = Path.Right(Path.GetLength()-Last); + + // subtract the FNameAndExt from Path + Dir = Path.Left( Path.GetLength()-sFNameAndExt.GetLength() ); // don't subtract out the trailing slash + + CStringArray sFNameAndExtBits; + split( sFNameAndExt, ".", sFNameAndExtBits, false ); + + if( sFNameAndExt.GetLength() == 0 ) // no file at the end of this path + { + FName = ""; + Ext = ""; + } + else if( sFNameAndExtBits.GetSize() == 1 ) // file doesn't have extension + { + FName = sFNameAndExtBits[0]; + Ext = ""; + } + else if( sFNameAndExtBits.GetSize() > 1 ) // file has extension and possibly multiple periods + { + Ext = sFNameAndExtBits[ sFNameAndExtBits.GetSize()-1 ]; + + // subtract the Ext and last period from FNameAndExt + FName = sFNameAndExt.Left( sFNameAndExt.GetLength()-Ext.GetLength()-1 ); + } +} + +/* mkdir -p. Doesn't fail if Path already exists and is a directory. */ +bool CreateDirectories( CString Path ) +{ + CStringArray parts; + CString curpath; + Path.Replace("\\", "/"); + split(Path, "/", parts); + + for(unsigned i = 0; i < parts.GetSize(); ++i) + { + curpath += parts[i] + "/"; + if(CreateDirectory( curpath, NULL )) + continue; + + if(GetLastError() != ERROR_ALREADY_EXISTS) + return false; + + /* Make sure it's a directory. */ + if( !IsADirectory(curpath) ) + return false; + } + + return true; +} + +void GetDirListing( CString sPath, CStringArray &AddTo, bool bOnlyDirs, bool bReturnPathToo ) +{ + CString sDir, sThrowAway; + splitrelpath( sPath, sDir, sThrowAway, sThrowAway ); + + /* XXX: We should use Find* to get a file list only, and handle + * wildcard matching ourself. Windows matching is braindead. For + * example, *.dwi matches "foo.dwi~". */ + WIN32_FIND_DATA fd; + HANDLE hFind = ::FindFirstFile( sPath, &fd ); + + if( INVALID_HANDLE_VALUE == hFind ) // no files found + return; + + do + { + if( bOnlyDirs && !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) + continue; // skip + + CString sDirName( fd.cFileName ); + + if( sDirName == "." || sDirName == ".." ) + continue; + + if( bReturnPathToo ) + AddTo.Add( sDir + sDirName ); + else + AddTo.Add( sDirName ); + + + } while( ::FindNextFile( hFind, &fd ) ); + ::FindClose( hFind ); +} + +void GetCwd(CString &s) +{ + char buf[_MAX_PATH]; + bool ret = getcwd(buf, _MAX_PATH) != NULL; + ASSERT(ret); + + s = buf; +} + +/* This is a little big; I'm undecided whether it deserves its own file. + * For now, I'll leave it here, since the interface is extremely simple. + * If it gets more interfaces, I'll move them to members of DirCache and + * give it its own file. -glenn */ + +/* Keep a cache of read directories, with attributes and the extension + * split off, so we don't have to request this from the system every + * time, and so we can do searches by extension quickly. */ +class DirCache { +public: + struct CacheEntry { + CStringArray files; + CStringArray exts; + CArray Attributes; + + CString dir; + }; + + const CacheEntry *SearchDirCache( const CString &sPath ); + + void FlushCache(); + ~DirCache() { FlushCache(); } +private: + CacheEntry *LoadDirCache( const CString &sPath ); + + /* We don't have too many directories ... XXX - glenn */ + CArray directory_cache; +} static DirectoryCache; + +void DirCache::FlushCache() +{ + for(unsigned i = 0; i < directory_cache.GetSize(); ++i) + delete directory_cache[i]; + directory_cache.RemoveAll(); +} + +void FlushDirCache() { DirectoryCache.FlushCache(); } + +/* Read a directory and return a CacheEntry object for it. */ +DirCache::CacheEntry *DirCache::LoadDirCache( const CString &sPath ) +{ + CString sFile, sDir, sThrowAway; + splitrelpath( sPath, sDir, sThrowAway, sThrowAway ); + + CString oldpath; + GetCwd(oldpath); + if(chdir(sDir) == -1) return NULL; + + WIN32_FIND_DATA fd; + HANDLE hFind = ::FindFirstFile( "*", &fd ); + + if( hFind == INVALID_HANDLE_VALUE ) + { + chdir(oldpath); + return NULL; + } + + DirCache::CacheEntry *dir = new DirCache::CacheEntry; + dir->dir = sPath; + + do { + if(!strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, "..")) + continue; + + CString sExt, sThrowAway; + splitrelpath( fd.cFileName, sThrowAway, sThrowAway, sExt ); + + dir->files.Add(fd.cFileName); + dir->exts.Add(sExt); + dir->Attributes.Add(fd.dwFileAttributes); + } while( ::FindNextFile( hFind, &fd ) ); + directory_cache.Add(dir); + + chdir(oldpath); + return dir; +} + +/* Return a CacheEntry object for a directory, reading it if necessary. */ +const DirCache::CacheEntry *DirCache::SearchDirCache( const CString &sPath ) +{ + unsigned i; + for(i = 0; i < directory_cache.GetSize(); ++i) + if(directory_cache[i]->dir == sPath) break; + + if(i == directory_cache.GetSize()) + /* Didn't find it. */ + return LoadDirCache( sPath ); + + return directory_cache[i]; +} + +/* GetExtDirListing(V): + * sPath is a path, which may include a filename. If a filename + * portion is included, return only files which have that as a + * prefix. (If you don't use this, make sure the path ends in a + * backslash, to prevent the last element of the directory from + * looking like a filename.) + * + * Each argument (or each element in the array) is an extension to + * return. If no arguments are provided, return all files. + */ +bool GetExtDirListing( const CString &sPath, CStringArray &AddTo, bool bOnlyDirs, bool bReturnPathToo, ... ) +{ + const char *masks[32]; + unsigned nmasks = 0; + va_list va; + + va_start(va, bReturnPathToo); + while(const char *next = va_arg(va, const char *)) + { + masks[nmasks++] = next; + ASSERT(nmasks+1 < sizeof(masks)/sizeof(*masks)); + } + va_end(va); + masks[nmasks++] = NULL; + + return GetExtDirListingV(sPath, AddTo, bOnlyDirs, bReturnPathToo, masks ); +} + +bool GetExtDirListingV( const CString &sPath, CStringArray &AddTo, bool bOnlyDirs, bool bReturnPathToo, const char *masks[] ) +{ + CString sFile, sDir, sThrowAway; + splitrelpath( sPath, sDir, sFile, sThrowAway ); + + const DirCache::CacheEntry *cache = DirectoryCache.SearchDirCache(sDir); + if(!cache) return false; + + for(unsigned i = 0; i < cache->files.GetSize(); ++i) + { + if( bOnlyDirs && !(cache->Attributes[i] & FILE_ATTRIBUTE_DIRECTORY) ) + continue; // skip + + if(strnicmp(sFile, cache->files[i], sFile.GetLength())) + continue; + + bool matched = false; + for(int j = 0; !matched && masks[j]; ++j) + { + if(stricmp(masks[j], cache->exts[i])) + continue; + matched = true; + } + + if(!matched) continue; + + if( bReturnPathToo ) + AddTo.Add( sDir + cache->files[i] ); + else + AddTo.Add( cache->files[i] ); + } + + return true; +} + +//----------------------------------------------------------------------------- +// Name: GetHashForString( CString s ) +// Desc: This new version of GetHashForString uses a stronger hashing algorithm +// than the former, assuring to a greater degree that two distinct +// strings do not produce the same result. +// The hashing algorithm is a modified CRC-32 (modified in that the +// characters in the CString are recast as unsigned char and that the +// unsigned int result from the hash is recast as a signed int). +//----------------------------------------------------------------------------- +unsigned int GetHashForString ( CString string ) +{ +/* + * RageCRC32.cpp + * + * Original code + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * Code was extracted from IETF Internet Draft + * draft-ietf-tsvwg-sctpcsum-00 at URI + * http://www.ietf.org/proceedings/01dec/I-D/draft-ietf-tsvwg-sctpcsum-00.txt + * + * Adaptation + * Copyright (C) 2002 Peter S. May. + * SourceForge ID: drokulix + * + * - Header file added + * - Name of function changed to GetCrc32 + * - Values in table changed from long int to int + * + * Chris: + * Moved this code out of RageCRC32 since it's not terribly long. Thanks Dro Kulix! + */ + +/* + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * First, the polynomial itself and its table of feedback terms. The + * polynomial is + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1 + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way + * we hand it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to hight-bit; and the result is transmission bit + * by bit from highest- to lowest-order term without requiring any bit + * shuffling on our part. Reception works similarly + * + * The feedback terms table consists of 256, 32-bit entries. Notes + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback + * terms simply represent the results of eight shift/xor opera + * tions for all combinations of data and CRC register values + * + * The values must be right-shifted by eight bits by the "updcrc + * logic; the shift must be unsigned (bring in zeroes). On some + * hardware you could probably optimize the shift in assembler by + * using byte-swap instructions + * polynomial $edb88320 + */ + +static const unsigned int crc32_tab[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d +}; + +/* Return a 32-bit CRC of the contents of the buffer. */ + +//unsigned int +//GetCrc32(const unsigned char *s, unsigned int len) +//{ + const char* s = string; + int len = string.GetLength(); + + unsigned int crc32val = 0; + for( int i=0; i> 8); + + return crc32val; +//} +} + +unsigned int GetHashForFile( CString sPath ) +{ + unsigned int hash = 0; + + hash += GetHashForString( sPath ); + + hash += GetFileSizeInBytes( sPath ); + + struct stat st; + if( stat(LPCTSTR(sPath), &st) != -1) + hash += st.st_mtime; + + return hash; +} + +unsigned int GetHashForDirectory( CString sDir ) +{ + unsigned int hash = 0; + + hash += GetHashForFile( sDir ); + + CStringArray arrayFiles; + GetDirListing( sDir+"\\*.*", arrayFiles, false ); + for( unsigned i=0; iCompareNoCase( LPCTSTR(s2) ) < 0); +} + +int CompareCStringsDesc(const void* str1, const void* str2) +{ + CString* s1 = (CString *)str1; + CString* s2 = (CString *)str2; + + return int(s1->CompareNoCase( LPCTSTR(s2) ) > 0); +} + +void SortCStringArray( CStringArray &arrayCStrings, const bool bSortAscending ) +{ + /*sort( arrayCStrings.begin(), arrayCStrings.end(), + bSortAscending?CompareCStringsAsc:CompareCStringsDesc);*/ + + qsort(arrayCStrings.GetData(), + arrayCStrings.GetSize(), sizeof(CString), + bSortAscending?CompareCStringsAsc:CompareCStringsDesc); + +} + + + +LONG GetRegKey(HKEY key, const char *subkey, LPTSTR retdata) +{ + HKEY hkey; + LONG retval = RegOpenKeyEx(key, subkey, 0, KEY_QUERY_VALUE, &hkey); + + if (retval == ERROR_SUCCESS) { + long datasize = MAX_PATH; + TCHAR data[MAX_PATH]; + RegQueryValue(hkey, NULL, data, &datasize); + lstrcpy(retdata,data); + RegCloseKey(hkey); + } + + return retval; +} + +HINSTANCE GotoURL(const char *url) +{ + TCHAR key[MAX_PATH + MAX_PATH]; + + // First try ShellExecute() + HINSTANCE result = ShellExecute(NULL, _T("open"), url, NULL,NULL, SW_SHOWDEFAULT); + + // If it failed, get the .htm regkey and lookup the program + if ((UINT)result <= HINSTANCE_ERROR) { + + if (GetRegKey(HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS) { + lstrcat(key, _T("\\shell\\open\\command")); + + if (GetRegKey(HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS) { + TCHAR *pos; + pos = _tcsstr(key, _T("\"%1\"")); + if (pos == NULL) { // No quotes found + pos = strstr(key, _T("%1")); // Check for %1, without quotes + if (pos == NULL) // No parameter at all... + pos = key+lstrlen(key)-1; + else + *pos = '\0'; // Remove the parameter + } + else + *pos = '\0'; // Remove the parameter + + lstrcat(pos, _T(" ")); + lstrcat(pos, url); + result = (HINSTANCE) WinExec(key,SW_SHOWDEFAULT); + } + } + } + + return result; +} + +float calc_mean(const float *start, const float *end) +{ + return accumulate(start, end, 0.f) / distance(start, end); +} + +float calc_stddev(const float *start, const float *end) +{ + /* Calculate the mean. */ + float mean = calc_mean(start, end); + + /* Calculate stddev. */ + float dev = 0.0f; + for( const float *i=start; i != end; ++i ) + dev += (*i - mean) * (*i - mean); + dev /= distance(start, end) - 1; + dev = sqrtf(dev); + + return dev; +} + diff --git a/stepmania/src/smlobby/RageUtil.h b/stepmania/src/smlobby/RageUtil.h new file mode 100644 index 0000000000..697e277e41 --- /dev/null +++ b/stepmania/src/smlobby/RageUtil.h @@ -0,0 +1,201 @@ +#ifndef RAGEUTIL_H +#define RAGEUTIL_H + +/* +----------------------------------------------------------------------------- + File: RageUtil + + Desc: Miscellaneous helper macros and functions. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + + +//----------------------------------------------------------------------------- +// SAFE_ Macros +//----------------------------------------------------------------------------- +#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } +#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } +#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } + +#define ZERO(x) memset(&x, 0, sizeof(x)) +#define COPY(a,b) { ASSERT(sizeof(a)==sizeof(b)); memcpy(&a, &b, sizeof(a)); } + +#define RECTWIDTH(rect) ((rect).right - (rect).left) +#define RECTHEIGHT(rect) ((rect).bottom - (rect).top) +inline int RECTCENTERX(RECT rect) { return rect.left + (rect.right-rect.left)/2; } +inline int RECTCENTERY(RECT rect) { return rect.top + (rect.bottom-rect.top)/2; } + +/* Common harmless mismatches. */ +#ifndef min +inline float min(float a, int b) { return a < b? a:b; } +inline float min(int a, float b) { return a < b? a:b; } +#endif + +#ifndef max +inline float max(float a, int b) { return a > b? a:b; } +inline float max(int a, float b) { return a > b? a:b; } +#endif + +/* Traditional defines. Only use this if you absolutely need + * a constant value. */ +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#define clamp(val,low,high) ( max( (low), min((val),(high)) ) ) + +#define PI ((float)3.1415926535897932384626433832795) +#define DegreeToRadian( degree ) ((degree) * (PI / 180.0f)) +#define RadianToDegree( radian ) ((radian) * (180.0f / PI)) +// Scales x so that l1 corresponds to l2 and h1 corresponds to h2. Does not modify x, MUST assign the result to something! +#define SCALE(x, l1, h1, l2, h2) (((x) - (l1)) / ((h1) - (l1)) * ((h2) - (l2)) + (l2)) +// Clamps x +#define CLAMP(x, l, h) {if (x > h) x = h; else if (x < l) x = l;} + + +//----------------------------------------------------------------------------- +// Misc helper functions +//----------------------------------------------------------------------------- + +// Fast random number generators +// Taken from "Numerical Recipes in C" + +extern ULONG randseed; + +inline ULONG Random() +{ + randseed = 1664525L * randseed + 1013904223L; + return randseed; +} + +inline float RandomFloat() +{ + randseed = 1664525L * randseed + 1013904223L; + ULONG itemp = 0x3f800000 | (0x007fffff & randseed); + return (*(float *)&itemp) - 1.0f; +} + +// Returns a float between dLow and dHigh inclusive +inline float RandomFloat(float fLow, float fHigh) +{ + return RandomFloat() * (fHigh - fLow) + fLow; +} + +// Returns an integer between nLow and nHigh inclusive +inline int RandomInt(int nLow, int nHigh) +{ + return ((Random() >> 2) % (nHigh - nLow + 1)) + nLow; +} + +// Debug new for memory leak tracing +//#ifdef _DEBUG +//#define new new(_NORMAL_BLOCK, __FILE__, __LINE__) +//#endif + + +// Simple function for generating random numbers +inline float randomf( const float low=-1.0f, const float high=1.0f ) +{ + return low + ( high - low ) * ( (FLOAT)rand() ) / RAND_MAX; +} + +/* XXX: These are C99 functions (except for the roundf(double) overload); what's + * the C99 define we can test for? */ +inline double trunc( double f ) { return float(int(f)); }; +inline float truncf( float f ) { return float(int(f)); }; +inline float roundf( float f ) { if(f < 0) return truncf(f-0.5f); return truncf(f+0.5f); }; +inline double roundf( double f ){ if(f < 0) return trunc(f-0.5); return trunc(f+0.5); }; +inline float froundf( const float f, const float fRoundInterval ) +{ + return int( (f + fRoundInterval/2)/fRoundInterval ) * fRoundInterval; +} + +bool IsAnInt( const char *s ); +float TimeToSeconds( CString sHMS ); +CString SecondsToTime( float fSecs ); + +CString ssprintf( const char *fmt, ...); +CString vssprintf( const char *fmt, va_list argList ); + + +// Splits a Path into 4 parts (Directory, Drive, Filename, Extention). Supports UNC path names. +// param1: Whether the Supplied Path (PARAM2) contains a directory name only +// or a file name (Reason: some directories will end with "aaa.bbb" +// which is like a file name). +// We should just make sure all pathnames end with a slash, not special case it here. +// -glenn +void splitpath( + bool UsingDirsOnly, + const CString &Path, + CString &Drive, + CString &Dir, + CString &FName, + CString &Ext +); + +void splitrelpath( + const CString &Path, + CString& Dir, + CString& FName, + CString& Ext +); + +// Splits a CString into an CStringArray according the Deliminator. +void split( + const CString &Source, + const CString &Deliminator, + CStringArray& AddIt, + const bool bIgnoreEmpty = true +); + +// Joins a CStringArray to create a CString according the Deliminator. +CString join( + const CString &Deliminator, + const CStringArray& Source +); + +bool CreateDirectories( CString Path ); +void GetDirListing( CString sPath, CStringArray &AddTo, bool bOnlyDirs=false, bool bReturnPathToo=false ); + +bool GetExtDirListing( const CString &sPath, CStringArray &AddTo, bool bOnlyDirs, bool bReturnPathToo, ... ); +bool GetExtDirListingV( const CString &sPath, CStringArray &AddTo, bool bOnlyDirs, bool bReturnPathToo, const char *masks[] ); +void FlushDirCache(); + +unsigned int GetHashForString( CString s ); +unsigned int GetHashForFile( CString sPath ); +unsigned int GetHashForDirectory( CString sDir ); // a hash value that remains the same as long as nothing in the directory has changed + +bool DoesFileExist( const CString &sPath ); +bool IsAFile( const CString &sPath ); +bool IsADirectory( const CString &sPath ); +DWORD GetFileSizeInBytes( const CString &sFilePath ); + +int CompareCStringsAsc(const void* str1, const void* str2); +int CompareCStringsDesc(const void* str1, const void* str2); +void SortCStringArray( CStringArray &AddTo, const bool bSortAcsending = true ); + + +LONG GetRegKey(HKEY key, const char *subkey, LPTSTR retdata); +HINSTANCE GotoURL(const char *url); + +/* Find the mean and standard deviation of all numbers in [start,end). */ +float calc_mean(const float *start, const float *end); +float calc_stddev(const float *start, const float *end); + +/* Fix Windows breakage ... */ +#ifdef WIN32 +#define getcwd _getcwd +#define wgetcwd _wgetcwd +#define chdir _chdir +#define wchdir _wchdir +#define alloca _alloca +#endif + +#endif diff --git a/stepmania/src/smlobby/smlobby.ncb b/stepmania/src/smlobby/smlobby.ncb index 954d0534b5d80900b97be4a9cc747808a6a10c9c..22559c75dd7bf62fd69e952a10669afe4a180c6a 100644 GIT binary patch literal 82941 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 S0!)AjFaajO1eidx1pW=`2qfSD literal 53760 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 T|0p2-pZI_B{NMTe{NKL;StCl3 diff --git a/stepmania/src/smlobby/socket.h b/stepmania/src/smlobby/socket.h index 9d09dedee9..3b3bf81b96 100644 --- a/stepmania/src/smlobby/socket.h +++ b/stepmania/src/smlobby/socket.h @@ -3,10 +3,10 @@ #ifndef SOCKET_H #define SOCKET_H -#pragma comment(lib, "sdl_net/lib/SDL.lib") -#pragma comment(lib, "sdl_net/lib/SDL_net.lib") +#pragma comment(lib, "../SDL-1.2.5/lib/SDL.lib") +#pragma comment(lib, "../SDL_net-1.2.4/lib/SDL_net.lib") -#include "sdl_net/include/SDL_net.h" +#include "../SDL_net-1.2.4/include/SDL_net.h" //HACK: SDL_net doesn't appear to have a way to get the host name // which I need to resolve the machine's ip address