Game Development Community

TGB 1.7.3beta1 Bug - Can't load resources

by Rene Damm · in Torque Game Builder · 05/08/2008 (10:37 am) · 32 replies

Adding resources to a project via "Project -> Resources..." has no effect on project. Resources get added to list, but after exiting the dialog, disappear and no resources are added to the Create tab.

Looking at the log reveals the following:

Unable to open file 'C:/Users/Ren[EACUTE here] Damm/AppData/Roaming/GarageGames/TorqueGameBuilder/RSSCache.cs for writing.
Compiling C:/Program Files/Torque/TorqueGameBuilder-1.7.3/tgb/resources/fishArt/resourceDatabase.cs...
Resource with name  found but invalid resource object contained inside resource!
Compiling C:/Program Files/Torque/TorqueGameBuilder-1.7.3/tgb/resources/fishArt/resourceDatabase.cs...
Resource with name  found but invalid resource object contained inside resource!
Compiling C:/Program Files/Torque/TorqueGameBuilder-1.7.3/tgb/resources/fishArt/resourceDatabase.cs...
Resource with name  found but invalid resource object contained inside resource!
Compiling C:/Program Files/Torque/TorqueGameBuilder-1.7.3/tgb/resources/MoleArt/resourceDatabase.cs...
Resource with name  found but invalid resource object contained inside resource!
Compiling C:/Program Files/Torque/TorqueGameBuilder-1.7.3/tgb/resources/fishArt/resourceDatabase.cs...
Resource with name  found but invalid resource object contained inside resource!
Compiling C:/Program Files/Torque/TorqueGameBuilder-1.7.3/tgb/resources/MoleArt/resourceDatabase.cs...
Resource with name  found but invalid resource object contained inside resource!

OS is Vista.

Hoping to find the time to give this a more thorough look.

PS: Hope this hasn't been reported before. Rather new here. Searching turned up nothing.

-----
Edited: Forum software truncated post after eacute character.

-----
Edit: Patched 1.7.4 binaries available here.
Page «Previous 1 2
#1
05/08/2008 (10:44 am)
By the way, the forum software seems to have a bug. When leaving the eacute character in the log dump above in the post, everything starting with that character got truncated.

Verified this with both IE and FF, so it's not a browser bug.

Have seen other truncated posts before.
#2
05/08/2008 (2:21 pm)
TGB-82. Any additional information on your OS (32 bit, 64 bit, etc?)
#3
05/08/2008 (2:34 pm)
32bit Vista German.
#4
05/09/2008 (7:45 pm)
Okay, got that one pinned. It's the same ANSI/UTF-8 mixup issues I've come across with TGEA a few days ago. Already had that hunch that this eacute was causing trouble again.

What happens is that TGB finds the script source file (assuming it is run from a directory that does not trigger the character conversion issue) and then goes on to compile it. Since, however, the compiled file is stored in the app data dir under the user's home directory, which in my case has that eacute thing, TGB bombs when trying to open the compiled file. Thus the resource script is never executed.

A quick check of the sources revealed that TGB is already doing a better job in winFileio.cpp at using the Win32 API than TGEA used to do, but obviously it still lets ANSI stuff slip through as UTF-8.

Will post the fix soonish...
#5
05/09/2008 (9:06 pm)
Okay, here's the fix. This pertains to far more than just adding resources. Basically, the beta as is won't be able to run from a directory that has problematic characters in its path and there's some more related issues like preferences not getting stored properly and DSO compilation not working.

Sorry for the rather extensive changes, but this really fixes *all* the ANSI/UTF-8 mixup issues I could find.

So, on we go...

---
PS: BTW, rather than patching all this manually, you can also diff against the respective files in TGEA. That's basically what I did since I fixed the very same issues there a few days ago. There's only minor differences.

---
Edit: Don't recommend doing that anymore. There's enough differences.
#6
05/09/2008 (9:06 pm)
platformWin32/platformWin32.h

100,141d99
< //-------------------------------------- Helper Functions
< 
< template< typename T >
< inline void forwardslashT( T *str )
< {
<    while(*str)
<    {
<       if(*str == '\\')
<          *str = '/';
<       str++;
<    }
< }
< 
< inline void forwardslash( char* str )
< {
<    forwardslashT< char >( str );
< }
< inline void forwardslash( WCHAR* str )
< {
<    forwardslashT< WCHAR >( str );
< }
< 
< template< typename T >
< inline void backslashT( T *str )
< {
<    while(*str)
<    {
<       if(*str == '/')
<          *str = '\\';
<       str++;
<    }
< }
< 
< inline void backslash( char* str )
< {
<    backslashT< char >( str );
< }
< inline void backslash( WCHAR* str )
< {
<    backslashT< WCHAR >( str );
< }
<
#7
05/09/2008 (9:07 pm)
platformWin32/winExec.cc

13d12
< #include "util/tempAlloc.h"
15,29c14,15
< //-----------------------------------------------------------------------------
< // Thread for executing in
< //-----------------------------------------------------------------------------
< 
< class ExecuteThread : public Thread
< {
<    // [tom, 12/14/2006] mProcess is only used in the constructor before the thread
<    // is started and in the thread itself so we should be OK without a mutex.
<    HANDLE mProcess;
< 
< public:
<    ExecuteThread(const char *executable, const char *args = NULL, const char *directory = NULL);
< 
<    virtual void run(void *arg = 0);
< };
---
> // Forward Refs
> class ExecuteThread;
31c17
< //-----------------------------------------------------------------------------
---
> //////////////////////////////////////////////////////////////////////////
33c19
< //-----------------------------------------------------------------------------
---
> //////////////////////////////////////////////////////////////////////////
54c40,56
< //-----------------------------------------------------------------------------
---
> //////////////////////////////////////////////////////////////////////////
> // Thread for executing in
> //////////////////////////////////////////////////////////////////////////
> 
> class ExecuteThread : public Thread
> {
>    // [tom, 12/14/2006] mProcess is only used in the constructor before the thread
>    // is started and in the thread itself so we should be OK without a mutex.
>    HANDLE mProcess;
> 
> public:
>    ExecuteThread(const char *executable, const char *args = NULL, const char *directory = NULL);
> 
>    virtual void run(void *arg = 0);
> };
> 
> //////////////////////////////////////////////////////////////////////////
58c60,62
<    SHELLEXECUTEINFO shl;
---
>    #pragma message("Implement UNICODE support for ExecuteThread [12/14/2006 tom]" )
> 
>    SHELLEXECUTEINFOA shl;
67,89c71,74
<    TempAlloc< TCHAR > dirBuf( dStrlen( directory ) + 1 );
< 
< #ifdef UNICODE
<    WCHAR exe[ 1024 ];
<    convertUTF8toUTF16( exeBuf, exe, sizeof( exe ) / sizeof( exe[ 0 ] ) );
< 
<    TempAlloc< WCHAR > argsBuf( dStrlen( args ) + 1 );
< 
<    convertUTF8toUTF16( args, argsBuf, argsBuf.size );
<    convertUTF8toUTF16( directory, dirBuf, dirBuf.size );
< #else
<    char* exe = exeBuf;
<    char* argsBuf = args;
<    dStrpcy( dirBuf, directory );
< #endif
< 
<    backslash( exe );
<    backslash( dirBuf );
<    
<    shl.lpVerb = TEXT( "open" );
<    shl.lpFile = exe;
<    shl.lpParameters = argsBuf;
<    shl.lpDirectory = dirBuf;
---
>    shl.lpVerb = "open";
>    shl.lpFile = exeBuf;
>    shl.lpParameters = args;
>    shl.lpDirectory = directory;
93c78
<    if(ShellExecuteEx(&shl) && shl.hProcess)
---
>    if(ShellExecuteExA(&shl) && shl.hProcess)
105c90
<    DWORD wait = WAIT_OBJECT_0 - 1; // i.e., not WAIT_OBJECT_0
---
>    DWORD wait;
111c96
< //-----------------------------------------------------------------------------
---
> //////////////////////////////////////////////////////////////////////////
113c98
< //-----------------------------------------------------------------------------
---
> //////////////////////////////////////////////////////////////////////////
136,146c121,122
< #ifdef UNICODE
<    WCHAR p[ 1024 ];
<    convertUTF8toUTF16( filePath, p, sizeof( p ) / sizeof( p[ 0 ] ) );
< #else
<    char* p = filePath;
< #endif
< 
<    backslash( p );
< 
<    ::ShellExecute( NULL,TEXT("explore"),p, NULL, NULL, SW_SHOWNORMAL);
< }
---
>    ::ShellExecuteA( NULL,"explore",filePath, NULL, NULL, SW_SHOWNORMAL);
> }
#8
05/09/2008 (9:11 pm)
platformWin32/winFileio.cc

< #include "util/tempAlloc.h"
24,27d22
< //-----------------------------------------------------------------------------
< bool dFileDelete(const char * name)
< {
<    AssertFatal( name != NULL, "dFileDelete - NULL file name" );
29c24,33
<    TempAlloc< TCHAR > buf( dStrlen( name ) + 1 );
---
> //-------------------------------------- Helper Functions
> static void forwardslash(char *str)
> {
>    while(*str)
>    {
>       if(*str == '\')
>          *str = '/';
>       str++;
>    }
> }
31,35c35,43
< #ifdef UNICODE
<    convertUTF8toUTF16( name, buf, buf.size );
< #else
<    dStrcpy( buf, name );
< #endif
---
> static void backslash(char *str)
> {
>    while(*str)
>    {
>       if(*str == '/')
>          *str = '\';
>       str++;
>    }
> }
37,39c45,52
<    backslash( buf );
<    if( Platform::isFile( name ) )
<       return DeleteFile( buf );
---
> //-----------------------------------------------------------------------------
> bool dFileDelete(const char * name)
> {
>    if(!name || (dStrlen(name) >= MAX_PATH))
>       return(false);
>    //return(::DeleteFile(name));
>    if(Platform::isFile(name))
>       return(remove(name) == 0);
41c54
<       return RemoveDirectory( buf );
---
>       return ::RemoveDirectoryA(name) != 0;
46,49c59,60
<    AssertFatal( oldName != NULL && newName != NULL, "dFileRename - NULL file name" );
< 
<    TempAlloc< TCHAR > oldf( dStrlen( oldName ) + 1 );
<    TempAlloc< TCHAR > newf( dStrlen( newName ) + 1 );
---
>    if(oldName == NULL || newName == NULL || dStrlen(oldName) >= MAX_PATH || dStrlen(newName) > MAX_PATH)
>       return false;
51,54c62
< #ifdef UNICODE
<    convertUTF8toUTF16( oldName, oldf, oldf.size );
<    convertUTF8toUTF16( newName, newf, newf.size );
< #else
---
>    char oldf[MAX_PATH], newf[MAX_PATH];
57d64
< #endif
61c68
<    return MoveFile( oldf, newf );
---
>    return rename(oldf, newf) == 0;
66c73,80
<    AssertFatal( name != NULL, "dFileTouch - NULL file name" );
---
>    // change the modified time to the current time (0byte WriteFile fails!)
>    return(utime(name, 0) != -1);
> };
> 
> static S32 QSORT_CALLBACK pathCompare(const void* a,const void* b)
> {
>    const char *aa = *((const char **)a), *ptrA;
>    const char *bb = *((const char **)b), *ptrB;
68c82,85
<    TempAlloc< TCHAR > buf( dStrlen( name ) + 1 );
---
>    while(aa && bb && *aa && *bb)
>    {
>       ptrA = dStrchr(aa, '/');
>       ptrB = dStrchr(bb, '/');
70,74c87,89
< #ifdef UNICODE
<    convertUTF8toUTF16( name, buf, buf.size );
< #else
<    dStrcpy( buf, name );
< #endif
---
>       if(ptrA && ptrB)
>       {
>          ++ptrA; ++ptrB;
76,84c91,95
<    backslash( buf );
<    FILETIME ftime;
<    GetSystemTimeAsFileTime( &ftime );
<    HANDLE handle = CreateFile( buf, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
<       NULL, OPEN_EXISTING, 0, NULL );
<    if( handle == INVALID_HANDLE_VALUE )
<       return false;
<    bool result = SetFileTime( handle, NULL, NULL, &ftime );
<    CloseHandle( handle );
---
>          S32 len = ptrA - aa > ptrB - bb ? ptrA - aa : ptrB - bb;
>          S32 ret = dStrnicmp(aa, bb, len);
>          if(ret != 0)
>             return ret;
>       }
86,87c97,109
<    return result;
< };
---
>       aa = ptrA;
>       bb = ptrB;
>    }
> 
>    if(aa && ! bb)
>       return -1;
>    if(bb && ! aa)
>       return 1;
>    if(aa && bb)
>       return dStricmp(aa, bb);
> 
>    return 0;
> }
91c113,115
<    AssertFatal( fromName != NULL && toName != NULL, "dPathCopy - NULL file name" );
---
>    if(!fromName || (dStrlen(fromName) >= MAX_PATH) ||
>       !toName || (dStrlen(toName) >= MAX_PATH))
>       return(false);
93,94c117,125
<    TempAlloc< TCHAR > from( dStrlen( fromName ) + 1 );
<    TempAlloc< TCHAR > to( dStrlen( toName ) + 1 );
---
>    static char filebuf[2048];
>    dStrcpy(filebuf, fromName);
>    backslash(filebuf);
>    fromName = filebuf;
> 
>    static char filebuf2[2048];
>    dStrcpy(filebuf2, toName);
>    backslash(filebuf2);
>    toName = filebuf2;
95a127,129
>    // Copy File
>    if (Platform::isFile(fromName))
>    {
97,98c131,133
<    convertUTF8toUTF16( fromName, from, from.size );
<    convertUTF8toUTF16( toName, to, to.size );
---
>       UTF16 f[1024], t[1024];
>       convertUTF8toUTF16((UTF8 *)fromName, f, sizeof(f));
>       convertUTF8toUTF16((UTF8 *)toName, t, sizeof(t));
100,101c135,136
<    dStrcpy( from, fromName );
<    dStrcpy( to, toName );
---
#9
05/09/2008 (9:13 pm)
>       char *f = (char*)fromName;
>       char *t = (char*)toName;
102a138,141
>       if(::CopyFile( f, t, nooverwrite))
>       {
>          return true;
>       }
104,105c143,144
<    backslash( from );
<    backslash( to );
---
>       return false;
>    }
107,109d145
<    // Copy File
<    if (Platform::isFile(fromName))
<       return CopyFile( from, to, nooverwrite );
127,128d162
<       TempAlloc< char > tempBuf( to.size * 3 + MAX_PATH * 3 );
< 
132c166
<          const char* fromDir = directoryInfo[i];
---
>          const char* from = directoryInfo[i];
134,138c168,172
<          char* toDir = tempBuf;
<          Platform::makeFullPathName(fromDir + dStrlen(fromName) + (dStricmp(fromDir, fromName) ? 1 : 0), tempBuf, tempBuf.size, toName);
<          if(*(toDir + dStrlen(toDir) - 1) != '/')
<             dStrcat(toDir, "/");
<          forwardslash(toDir);
---
>          char to[1024];
>          Platform::makeFullPathName(from + dStrlen(fromName) + (dStricmp(from, fromName) ? 1 : 0), to, sizeof(to), toName);
>          if(*(to + dStrlen(to) - 1) != '/')
>             dStrcat(to, "/");
>          forwardslash(to);
140c174
<          if (!Platform::createPath(toDir))
---
>          if (!Platform::createPath(to))
142c176
<             //TODO: New directory should be deleted here.
---
>             // New directory should be deleted here.
147,152d180
<       TempAlloc< char > tempBuf1( from.size * 3 + MAX_PATH * 3 );
< #ifdef UNICODE
<       TempAlloc< WCHAR > wtempBuf( tempBuf.size / 3 );
<       TempAlloc< WCHAR > wtempBuf1( tempBuf1.size / 3 );
< #endif
< 
155,156c183,184
<          char* fromFile = tempBuf1;
<          dSprintf( tempBuf1, tempBuf1.size, "%s/%s", fileInfo[i].pFullPath, fileInfo[i].pFileName);
---
>          char from[1024];
>          dSprintf(from, 1024, "%s/%s", fileInfo[i].pFullPath, fileInfo[i].pFileName);
158,161c186,189
<          char* toFile = tempBuf;
<          Platform::makeFullPathName(fileInfo[i].pFullPath + dStrlen(fromName) + (dStricmp(fileInfo[i].pFullPath, fromName) ? 1 : 0), tempBuf, tempBuf.size, toName);
<          dStrcat(toFile, "/");
<          dStrcat(toFile, fileInfo[i].pFileName);
---
>          char to[1024];
>          Platform::makeFullPathName(fileInfo[i].pFullPath + dStrlen(fromName) + (dStricmp(fileInfo[i].pFullPath, fromName) ? 1 : 0), to, sizeof(to), toName);
>          dStrcat(to, "/");
>          dStrcat(to, fileInfo[i].pFileName);
163,164c191,192
<          backslash(fromFile);
<          backslash(toFile);
---
>          backslash(from);
>          backslash(to);
167,170c195,197
<          convertUTF8toUTF16( tempBuf, wtempBuf, wtempBuf.size );
<          convertUTF8toUTF16( tempBuf1, wtempBuf1, wtempBuf1.size );
<          WCHAR* f = wtempBuf1;
<          WCHAR* t = wtempBuf;
---
>          UTF16 f[1024], t[1024];
>          convertUTF8toUTF16((UTF8 *)from, f, sizeof(f));
>          convertUTF8toUTF16((UTF8 *)to, t, sizeof(t));
172,173c199,200
<          char *f = (char*)fromFile;
<          char *t = (char*)toFile;
---
>          char *f = (char*)from;
>          char *t = (char*)to;
230,234c257,259
<    AssertFatal(NULL != filename, "File::open: NULL fname");
<    AssertWarn(INVALID_HANDLE_VALUE == (HANDLE)handle, "File::open: handle already valid");
< 
<    TempAlloc< TCHAR > fname( dStrlen( filename ) + 1 );
< 
---
>    static char filebuf[2048];
>    dStrcpy(filebuf, filename);
>    backslash(filebuf);
236c261,262
<    convertUTF8toUTF16( filename, fname, fname.size );
---
>    UTF16 fname[2048];
>    convertUTF8toUTF16((UTF8 *)filebuf, fname, sizeof(fname));
238c264,265
<    dStrcpy(fname, filename);
---
>    char *fname;
>    fname = filebuf;
240c267,269
<    backslash( fname );
---
> 
>     AssertFatal(NULL != fname, "File::open: NULL fname");
>     AssertWarn(INVALID_HANDLE_VALUE == (HANDLE)handle, "File::open: handle already valid");
352c381
<     if (absolutePos)
---
>     switch (absolutePos)
353a383
>     case true:                                                    // absolute position
361,363c391,392
<     }
<     else
<     {
---
>         break;
>     case false:                                                    // relative position
554a584
>    char buf[1024], fullPath[1024];
557,558c587
<    TempAlloc< char > fullPath( dStrlen( path ) + MAX_PATH * 3 );
<    Platform::makeFullPathName( path, fullPath, fullPath.size );
---
>    Platform::makeFullPathName(path, fullPath, sizeof(fullPath));
560,567c589
<    // [rene, 04/05/2008] Had some weird crashes with dSprintf.  That's why the complicated
<    //    manual concatenation is here.
< 
<    U32 lenFullPath = dStrlen( fullPath );
<    TempAlloc< char > buf( lenFullPath + dStrlen( pattern ) + 2 );
<    dMemcpy( buf, fullPath, lenFullPath );
<    buf[ lenFullPath ] = '/';
<    dStrcpy( &buf[ lenFullPath + 1 ], pattern );
---
>    dSprintf(buf, sizeof(buf), "%s/%s", fullPath, pattern);
570,572c592,593
<    TempAlloc< WCHAR > searchBuf( buf.size );
<    convertUTF8toUTF16( buf, searchBuf, searchBuf.size );
<    WCHAR* search = searchBuf;
---
>    UTF16 search[1024];
>    convertUTF8toUTF16((UTF8 *)buf, search, sizeof(search));
577,578d597
<    backslash( search );
<    
586,587c605,606
<       convertUTF16toUTF8( findData.cFileName, buf, buf.size );
<       char* fnbuf = buf;
---
>       char fnbuf[1024];
>       convertUTF16toUTF8(findData.cFileName, (UTF8 *)fnbuf, sizeof(fnbuf));
599c618
<          if (dStrcmp( findData.cFileName, TEXT( "." ) ) == 0 || dStrcmp( findData.cFileName, TEXT( ".." ) ) == 0)
---
>          if (dStrcmp(fnbuf, ".") == 0 || dStrcmp(fnbuf, "..") == 0)
606,607c625,626
<          dSprintf( fullPath, fullPath.size, "%s/%s", path, fnbuf);
<          char* child = fullPath;
---
>          char child[1024];
>          dSprintf(child, sizeof(child), "%s/%s", path, fnbuf);
627,628d645
<          forwardslash( fnbuf );
< 
646,648d662
< 
<    TempAlloc< TCHAR > fp( dStrlen( filePath ) + 1 );
< 
650c664,665
<    convertUTF8toUTF16( filePath, fp, fp.size );
---
>    UTF16 fp[512];
>    convertUTF8toUTF16((UTF8 *)filePath, fp, sizeof(fp));
652c667
<    dStrcpy( fp, filePath );
---
>    const char *fp = filePath;
655,656d669
<    backslash( fp );
< 
678c691,694
<    TempAlloc< TCHAR > pathbuf( dStrlen( file ) + 1 );
#10
05/09/2008 (9:14 pm)
---
>    char pathbuf[1024];
>    const char *dir;
>    pathbuf[0] = 0;
>    U32 pathLen = 0;
679a696,699
>    while((dir = dStrchr(file, '/')) != NULL)
>    {
>       dStrncpy(pathbuf + pathLen, file, dir - file);
>       pathbuf[pathLen + dir-file] = 0;
681,684c701,703
<    TempAlloc< WCHAR > fileBuf( pathbuf.size );
<    convertUTF8toUTF16( file, fileBuf, fileBuf.size );
<    const WCHAR* fileName = fileBuf;
<    const WCHAR* dir;
---
>       UTF16 b[1024];
>       convertUTF8toUTF16((UTF8 *)pathbuf, b, sizeof(b));
>       bool ret = CreateDirectory(b, NULL);
686,687c705
<    const char* fileName = file;
<    const char* dir;
---
>       bool ret = CreateDirectory(pathbuf, NULL);
689,704c707,709
< 
<    pathbuf[ 0 ] = 0;
<    U32 pathLen = 0;
< 
<    while((dir = dStrchr(fileName, '/')) != NULL)
<    {
<       TCHAR* pathptr = pathbuf;
<       dMemcpy( pathptr + pathLen, fileName, ( dir - fileName ) * sizeof( TCHAR ) );
<       pathbuf[pathLen + dir-fileName] = 0;
<  
<       // ignore return value because we are fine with already existing directory
<       CreateDirectory(pathbuf, NULL);
< 
<       pathLen += dir - fileName;
<       pathbuf[pathLen++] = '\';
<       fileName = dir + 1;
---
>       pathLen += dir - file;
>       pathbuf[pathLen++] = '/';
>       file = dir + 1;
709,710d713
< // [rene, 04/05/2008] Not used currently so did not bother updating.
< #if 0
719c722
<    char fileBuf[1024];
---
>    char fileBuf[256];
732c735
< #if defined (TORQUE_DEBUG) || !defined (TORQUE_SHIPPING)
---
> #if defined (TORQUE_DEBUG) || defined (INTERNAL_RELEASE)
743c746
< #if defined (TORQUE_DEBUG) || !defined (TORQUE_SHIPPING)
---
> #if defined (TORQUE_DEBUG) || defined (INTERNAL_RELEASE)
763d765
< #endif
781,792c783,786
<    TempAlloc< TCHAR > buf( 2048 );
< 
<    GetCurrentDirectory( buf.size, buf );
<    forwardslash( buf );
< 
< #ifdef UNICODE
<    char* utf8 = convertUTF16toUTF8( buf );
<    StringTableEntry result = StringTable->insert( utf8 );
<    return result;
< #else
<    return StringTable->insert( buf );
< #endif
---
>    char cwd_buf[2048];
>    GetCurrentDirectoryA(2047, cwd_buf);
>    forwardslash(cwd_buf);
>    return StringTable->insert(cwd_buf);
797,806c791,796
<    TempAlloc< TCHAR > buf( dStrlen( newDir ) + 2 );
< 
< #ifdef UNICODE
<    convertUTF8toUTF16( newDir, buf, buf.size - 1 );
< #else
<    dStrcpy( buf, newDir );
< #endif
< 
<    backslash( buf );
<    return SetCurrentDirectory( buf );
---
>    StringTableEntry lastDir = Platform::getCurrentDirectory();
>    char cwd_buf[2048];
>    dStrncpy(cwd_buf, newDir, sizeof(cwd_buf)-1);
>    cwd_buf[sizeof(cwd_buf)-1] = 0;
>    backslash(cwd_buf);
>    return SetCurrentDirectoryA(cwd_buf);
809,838d798
< #ifdef UNICODE
< static void getExecutableInfo( StringTableEntry* path, StringTableEntry* exe )
< {
<    static StringTableEntry pathEntry = NULL;
<    static StringTableEntry exeEntry = NULL;
< 
<    if( !pathEntry )
<    {
<       WCHAR cen_buf[ 2048 ];
<       GetModuleFileNameW( NULL, cen_buf, sizeof( cen_buf ) / sizeof( cen_buf[ 0 ] ) );
<       forwardslash( cen_buf );
< 
<       WCHAR* delimiter = dStrrchr( cen_buf, '/' );
<       if( delimiter )
<          *delimiter = '[[62818c2009ef0]]';
< 
<       char* pathBuf = convertUTF16toUTF8( cen_buf );
<       char* exeBuf = convertUTF16toUTF8( delimiter + 1 );
< 
<       pathEntry = StringTable->insert( pathBuf );
<       exeEntry = StringTable->insert( exeBuf );
<    }
< 
<    if( path )
<       *path = pathEntry;
<    if( exe )
<       *exe = exeEntry;
< }
< #endif
< 
841,845d800
< #ifdef UNICODE
<    StringTableEntry exe;
<    getExecutableInfo( NULL, &exe );
<    return exe;
< #else
865d819
< #endif
870,874d823
< #ifdef UNICODE
<    StringTableEntry path;
<    getExecutableInfo( &path, NULL );
<    return path;
< #else
890d838
< #endif
899,900c847,848
<    TempAlloc< TCHAR > buf( dStrlen( pFilePath ) + 1 );
< 
---
>    // Get file info
>    WIN32_FIND_DATA findData;
902c850,852
<    convertUTF8toUTF16( pFilePath, buf, buf.size );
---
>    UTF16 b[512];
>    convertUTF8toUTF16((UTF8 *)pFilePath, b, sizeof(b));
>    HANDLE handle = FindFirstFile(b, &findData);
904c854
<    dStrcpy( buf, pFilePath );
---
>    HANDLE handle = FindFirstFile(pFilePath, &findData);
906,911d855
<    backslash( buf );
< 
<    // Get file info
<    WIN32_FIND_DATA findData;
<    HANDLE handle = FindFirstFile(buf, &findData);
<    FindClose(handle);
912a857,858
>    // [neo, 4/6/2007]
>    // This used to be after the FindClose() call 
915a862,863
>    FindClose(handle);
> 
934,942d881
<    TempAlloc< TCHAR > buf( dStrlen( pFilePath ) + 1 );
< 
< #ifdef UNICODE
<    convertUTF8toUTF16( pFilePath, buf, buf.size );
< #else
<    dStrcpy( buf, pFilePath );
< #endif
<    backslash( buf );
< 
944,945c883,885
<    WIN32_FIND_DATA findData;
<    HANDLE handle = FindFirstFile(buf, &findData);
---
>    WIN32_FIND_DATAA findData;
>    HANDLE handle = FindFirstFileA(pFilePath, &findData);
>    FindClose(handle);
950,951d889
<    FindClose(handle);
< 
961c899
<    return findData.nFileSizeLow;
---
>    return findData.nFileSizeLow;;
971,972c909,910
<    TempAlloc< TCHAR > buf( dStrlen( pDirPath ) + 1 );
< 
---
>    // Get file info
>    WIN32_FIND_DATA findData;
974c912,914
<    convertUTF8toUTF16( pDirPath, buf, buf.size );
---
>    UTF16 b[512];
>    convertUTF8toUTF16((UTF8 *)pDirPath, b, sizeof(b));
>    HANDLE handle = FindFirstFile(b, &findData);
976c916
<    dStrcpy( buf, pDirPath );
---
>    HANDLE handle = FindFirstFile(pDirPath, &findData);
978,982d917
<    backslash( buf );
< 
<    // Get file info
<    WIN32_FIND_DATA findData;
<    HANDLE handle = FindFirstFile(buf, &findData);
1014,1029d948
<    const char* fileName = avar("%s/*", pParent);
< 
<    TempAlloc< TCHAR > file( dStrlen( fileName ) + 1 );
<    TempAlloc< TCHAR > dir( dStrlen( pDir ) + 1 );
< 
< #ifdef UNICODE
<    convertUTF8toUTF16( fileName, file, file.size );
<    convertUTF8toUTF16( pDir, dir, dir.size );
< #else
<    dStrcpy( file, fileName );
<    dStrcpy( dir, pDir );
< #endif
< 
<    backslash( file );
<    backslash( dir );
< 
1032,1033c951,952
<    WIN32_FIND_DATA findData;
<    HANDLE handle = FindFirstFile(file, &findData);
---
>    WIN32_FIND_DATAA findData;
>    HANDLE handle = FindFirstFileA(avar("%s/*", pParent), &findData);
1045,1046d963
<          //FIXME: this has to be dStrcasecmp but there's no implementation for Unicode
< 
1048c965
<          if (dStrcmp(dir, findData.cFileName ) == 0)
---
>          if (dStrcmp(pDir, findData.cFileName ) == 0)
#11
05/09/2008 (9:14 pm)
1055c972
<    }while(FindNextFile(handle, &findData));
---
>    }while(FindNextFileA(handle, &findData));
1131,1132c1048,1049
<          TCHAR lpszVolumeName[ 256 ];
<          TCHAR lpszFileSystem[ 256 ];
---
>          char lpszVolumeName[ 256 ];
>          char lpszFileSystem[ 256 ];
1137,1138c1054,1055
<          dMemset( lpszVolumeName, 0, sizeof( lpszVolumeName ) );
<          dMemset( lpszFileSystem, 0, sizeof( lpszFileSystem ) );
---
>          dMemset( lpszVolumeName, 0, 256 );
>          dMemset( lpszFileSystem, 0, 256 );
1140a1058
> 
1161,1168d1078
< #ifdef UNICODE
<             WCHAR ibuf[ 3 ];
<             ibuf[ 0 ] = ( *i )[ 0 ];
<             ibuf[ 1 ] = ':';
<             ibuf[ 2 ] = '[[62818c2012639]]';
< #else
<             char* ibuf = *i;
< #endif
1170,1177c1080
<             GetVolumeInformation( ibuf, lpszVolumeName, sizeof( lpszVolumeName ) / sizeof( lpszVolumeName[ 0 ] ),
<                &dwSerial, &dwMaxComponentLength, &dwFileSystemFlags, lpszFileSystem,
<                sizeof( lpszFileSystem ) / sizeof( lpszFileSystem[ 0 ] ) );
< 
< #ifdef UNICODE
<             char buf[ sizeof( lpszFileSystem ) / sizeof( lpszFileSystem[ 0 ] ) * 3 + 1 ];
<             convertUTF16toUTF8( lpszFileSystem, buf, sizeof( buf ) / sizeof( buf[ 0 ] ) );
<             info.FileSystem = StringTable->insert( buf );
---
>             GetVolumeInformationA( (*i), lpszVolumeName, 256, &dwSerial, &dwMaxComponentLength, &dwFileSystemFlags, lpszFileSystem, 256 );
1179,1181d1081
<             convertUTF16toUTF8( lpszVolumeName, buf, sizeof( buf ) / sizeof( buf[ 0 ] ) );
<             info.Name = StringTable->insert( buf );
< #else
1184d1083
< #endif
1186,1187c1085
<             // Won't compile on something prior to XP.
<             info.ReadOnly = dwFileSystemFlags & FILE_READ_ONLY_VOLUME;
---
>             info.ReadOnly = false;  // not detected yet - to implement later
1205c1103,1104
<    char searchBuf[1024];
---
>    char search[1024];
>    WIN32_FIND_DATAA findData;
1210c1109
<       dStrcpy( searchBuf, pPath );
---
>       dStrcpy( search, pPath );
1212,1222c1111
<       dSprintf(searchBuf, 1024, "%s/*", pPath );
< 
< #ifdef UNICODE
<    WCHAR buf[ 1024 ];
<    convertUTF8toUTF16( searchBuf, buf, sizeof( buf ) / sizeof( buf[ 0 ] ) );
<    WCHAR* search = buf;
< #else
<    char* search = searchBuf;
< #endif
< 
<    backslash( search );
---
>       dSprintf(search, 1024, "%s/*", pPath );
1225,1226c1114
<    WIN32_FIND_DATA findData;
<    HANDLE handle = FindFirstFile(search, &findData);
---
>    HANDLE handle = FindFirstFileA(search, &findData);
1230d1117
<    bool result = false;
1236c1123
<          if (dStrcmp(findData.cFileName, TEXT( "." ) ) == 0 || dStrcmp(findData.cFileName, TEXT( ".." ) ) == 0)
---
>          if (dStrcmp(findData.cFileName, ".") == 0 || dStrcmp(findData.cFileName, "..") == 0)
1239,1246c1126
< #ifdef UNICODE
<          char fileName[ 1024 ];
<          convertUTF16toUTF8( findData.cFileName, fileName, sizeof( fileName ) / sizeof( fileName[ 0 ] ) );
< #else
<          char* fileName = findData.cFileName;
< #endif
< 
<          if( Platform::isExcludedDirectory( fileName ) )
---
>          if( Platform::isExcludedDirectory( findData.cFileName ) )
1249,1250c1129,1131
<          result = true;
<          break;
---
>          Platform::clearExcludedDirectories();
> 
>          return true;
1253c1134
<    while(FindNextFile(handle, &findData));
---
>    while(FindNextFileA(handle, &findData));
1259c1140
<    return result;
---
>    return false;
1265c1146,1147
<    TempAlloc< char > search( 1024 );
---
>    char search[1024];
>    WIN32_FIND_DATAA findData;
1272c1154,1156
<    char subTrail = subPath ? subPath[ dStrlen(subPath) - 1 ] : '[[62818c2012639]]';
---
>    char subTrail;
>    if( subPath )
>        subTrail = subPath[ dStrlen(subPath) - 1 ];
1280c1164
<             dSprintf(search, search.size, "%s%s*", basePath,subPath );
---
>             dSprintf(search, 1024, "%s%s*", basePath,subPath );
1282c1166
<             dSprintf(search, search.size, "%s%s/*", basePath,subPath );
---
>             dSprintf(search, 1024, "%s%s/*", basePath,subPath );
1285c1169
<          dSprintf( search, search.size, "%s*", basePath );
---
>          dSprintf( search, 1024, "%s*", basePath );
1291c1175
<             dSprintf(search, search.size, "%s%s*", basePath,subPath );
---
>             dSprintf(search, 1024, "%s%s*", basePath,subPath );
1293c1177
<             dSprintf(search, search.size, "%s%s/*", basePath,subPath );
---
>             dSprintf(search, 1024, "%s%s/*", basePath,subPath );
1295c1179
<          dSprintf(search, search.size, "%s/*", basePath );
---
>          dSprintf(search, 1024, "%s/*", basePath );
1298,1306d1181
< #ifdef UNICODE
<    TempAlloc< WCHAR > searchStr( dStrlen( search ) + 1 );
<    convertUTF8toUTF16( search, searchStr, searchStr.size );
< #else
<    char* searchStr = search;
< #endif
< 
<    backslash( searchStr );
< 
1311,1312c1186
<    WIN32_FIND_DATA findData;
<    HANDLE handle = FindFirstFile(searchStr, &findData);
---
>    HANDLE handle = FindFirstFileA(search, &findData);
1349,1352d1222
< #ifdef UNICODE
<    TempAlloc< char > fileName( 1024 );
< #endif
< 
1358c1228
<          if (dStrcmp(findData.cFileName, TEXT( "." )) == 0 || dStrcmp(findData.cFileName, TEXT( ".." )) == 0)
---
>          if (dStrcmp(findData.cFileName, ".") == 0 || dStrcmp(findData.cFileName, "..") == 0)
1361,1366d1230
< #ifdef UNICODE
<          convertUTF16toUTF8( findData.cFileName, fileName, fileName.size );
< #else
<          char* fileName = findData.cFileName;
< #endif
< 
1368c1232
<          if( Platform::isExcludedDirectory( fileName ) )
---
>          if( Platform::isExcludedDirectory( findData.cFileName ) )
1372a1237,1238
>             char child[1024];
> 
1374c1240
<                dSprintf(search, search.size, "%s%s", subPath, fileName);
---
>                dSprintf(child, sizeof(child), "%s%s", subPath, findData.cFileName);
1376,1377c1242
<                dSprintf(search, search.size, "%s/%s", subPath, fileName);
<             char* child = search;
---
>                dSprintf(child, sizeof(child), "%s/%s", subPath, findData.cFileName);
1385c1250,1251
<             char* child;
---
>             char child[1024];
> 
1387c1253
<                child = fileName;
---
>                dStrcpy( child, findData.cFileName );
1389,1392c1255
<             {
<                dSprintf(search, search.size, "/%s", fileName);
<                child = search;
<             }
---
>                dSprintf(child, sizeof(child), "/%s", findData.cFileName);
1399c1262
<    while(FindNextFile(handle, &findData));
---
>    while(FindNextFileA(handle, &findData));
1420,1421c1283
<    TCHAR buf[ 1024 ];
<    DWORD len = GetTempPath( sizeof( buf ), buf );
---
> #pragma message("Implement UNICODE support for osGetTemporaryDirectory [01/23/2007 tom]" )
1423,1428c1285,1286
< #ifdef UNICODE
<    char dir[ 1024 ];
<    convertUTF16toUTF8( buf, dir, sizeof( dir ) );
< #else
<    char* dir = buf;
< #endif
---
>    char buf[512];
>    DWORD len = GetTempPathA(sizeof(buf), buf);
1430c1288
<    dir[len-1] = 0;
---
>    buf[len-1] = 0;
1432,1433c1290,1291
<    forwardslash(dir);
<    return StringTable->insert(dir);
---
>    forwardslash(buf);
>    return StringTable->insert(buf);
#12
05/09/2008 (9:15 pm)
platformWin32/winUser.cc

4d3
< #include "core/unicode.h"
15,17c14,15
<    TCHAR szBuffer[ MAX_PATH + 1 ];
< 
<    if(! SHGetSpecialFolderPath( NULL, szBuffer, CSIDL_APPDATA, true ) )
---
>    char szBuffer[512];
>    if(! SHGetSpecialFolderPathA( NULL, LPSTR( szBuffer ), CSIDL_APPDATA, true ) )
20c18
<    TCHAR *ptr = szBuffer;
---
>    char *ptr = szBuffer;
28,36c26
< #ifdef UNICODE
<    char path[ MAX_PATH * 3 + 1 ];
<    convertUTF16toUTF8( szBuffer, path, sizeof( path ) );
< #else
<    char* path = szBuffer;
< #endif
< 
< 
<    return StringTable->insert( path );
---
>    return StringTable->insert(szBuffer);
41,43c31,33
<    TCHAR szBuffer[ MAX_PATH + 1 ];
<    if(! SHGetSpecialFolderPath( NULL, szBuffer, CSIDL_PERSONAL, false ) )
<       if(! SHGetSpecialFolderPath( NULL, szBuffer, CSIDL_COMMON_DOCUMENTS, false ) )
---
>    char szBuffer[512];
>    if(! SHGetSpecialFolderPathA( NULL, LPSTR( szBuffer ), CSIDL_PERSONAL, false ) )
>       if(! SHGetSpecialFolderPathA( NULL, LPSTR( szBuffer ), CSIDL_COMMON_DOCUMENTS, false ) )
46c36
<    TCHAR *ptr = szBuffer;
---
>    char *ptr = szBuffer;
54,61c44
< #ifdef UNICODE
<    char path[ MAX_PATH * 3 + 1 ];
<    convertUTF16toUTF8( szBuffer, path, sizeof( path ) );
< #else
<    char* path = szBuffer;
< #endif
< 
<    return StringTable->insert( path );
---
>    return StringTable->insert(szBuffer);
#13
05/09/2008 (9:15 pm)
core/unicode.h

102,109d101
< 
< //-----------------------------------------------------------------------------
< /// Scanning for characters in unicode strings
< UTF16* dStrrchr(UTF16* unistring, U32 c);
< const UTF16* dStrrchr(const UTF16* unistring, U32 c);
< 
< UTF16* dStrchr(UTF16* unistring, U32 c);
< const UTF16* dStrchr(const UTF16* unistring, U32 c);
#14
05/09/2008 (9:15 pm)
core/unicode.cc

577,613d576
< const UTF16* dStrrchr(const UTF16* unistring, U32 c)
< {
<    if(!unistring) return NULL;
< 
<    const UTF16* tmp = unistring + dStrlen(unistring);
<    while( tmp >= unistring)
<    { 
<       if(*tmp == c)
<          return tmp;
<       tmp--;
<    }
<    return NULL;
< }
< 
< UTF16* dStrrchr(UTF16* unistring, U32 c)
< {
<    const UTF16* str = unistring;
<    return const_cast<UTF16*>(dStrrchr(str, c));
< }
< 
< const UTF16* dStrchr(const UTF16* unistring, U32 c)
< {
<    if(!unistring) return NULL;
<    const UTF16* tmp = unistring;
<    
<    while ( *tmp  && *tmp != c)
<       tmp++;
< 
<    return  (*tmp == c) ? tmp : NULL;
< }
< 
< UTF16* dStrchr(UTF16* unistring, U32 c)
< {
<    const UTF16* str = unistring;
<    return const_cast<UTF16*>(dStrchr(str, c));
< }
<
#15
05/09/2008 (9:16 pm)
And finally one new file util/tempAlloc.h

//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

#ifndef _TEMPALLOC_H_
#define _TEMPALLOC_H_

#include "platform/platform.h"

template< typename T >
struct TempAlloc
{
   T* ptr;
   U32 size;

   TempAlloc( U32 size )
      : size( size )
   {
      ptr = ( T* ) dMalloc( size * sizeof( T ) );
   }
   ~TempAlloc()
   {
      if( ptr )
         dFree( ptr );
   }
   operator T*()
   {
      return ptr;
   }
};

#endif // _TEMPALLOC_H_
#16
05/09/2008 (9:25 pm)
Ah, one change I forgot. This, however, does two things. One change is necessary for the changes above to work.

The other thing is some nice issue I stumbled across recently. One of the undocumented "features" of the Windows file selection dialog is that it changes the current working directory to where the user had made his/her final selection. Very annoying and since Torque bases some of its file accesses on the CWD, the user will see seemingly unexplicable file access errors after using the file selection dialog.

The following code also makes sure the CWD is preserved.

platformWin32/nativeDialogs/fileDialog.cc

23a24,46
> // Support Functions
> //-----------------------------------------------------------------------------
> static void forwardslash(char *str)
> {
>    while(*str)
>    {
>       if(*str == '\')
>          *str = '/';
>       str++;
>    }
> }
> 
> static void backslash(char *str)
> {
>    while(*str)
>    {
>       if(*str == '/')
>          *str = '\';
>       str++;
>    }
> }
> 
> //-----------------------------------------------------------------------------
330,333d352
<    // Get the current working directory, so we can back up to it once Windows has
<    // done its crazyness and messed with it.
<    StringTableEntry cwd = Platform::getCurrentDirectory();
< 
343,345d361
< 
<    // Restore the working directory.
<    Platform::setCurrentDirectory( cwd );


-----------
EDIT: Hmm, doing some quick tests, it seems that TGB has no problems with the user changing the CWD. Probably better to leave that out especially as it is annoying to the user when having to always start out from the same directory in selection dialogs.
#17
05/10/2008 (9:22 am)
Found two more places with the same issue (after noticing that instance restarting didn't work anymore).

platformWin32/winWindow.cc

180,181c180,181
<    TCHAR cen_buf[2048];
<    GetModuleFileName( NULL, cen_buf, sizeof( cen_buf ));
---
>    char cen_buf[2048];
>    GetModuleFileNameA( NULL, cen_buf, 2047);
182a183,188
> #ifdef UNICODE
>    UTF16 b[512];
>    convertUTF8toUTF16((UTF8 *)cen_buf, b, sizeof(b));
> #else
>    const char* b = cen_buf;
> #endif
184c190
<    if( CreateProcess( cen_buf,
---
>    if( CreateProcess( b,
774c780
<             TCHAR pszTheBuffer[MAX_PATH];
---
>             LPTSTR pszTheBuffer[MAX_PATH];
778,785c784,785
<             DragQueryFile(hTheDrop, nI, pszTheBuffer, sizeof(pszTheBuffer));
< 
< #ifdef UNICODE
<             char fileName[ MAX_PATH * 3 ];
<             convertUTF16toUTF8( pszTheBuffer, fileName, sizeof( fileName ) /sizeof( fileName[ 0 ] ) );
< #else
<             char* fileName = pszTheBuffer;
< #endif
---
>             // FIXME: Deal with Unicode
>             DragQueryFileA(hTheDrop, nI, (LPSTR)pszTheBuffer, sizeof(pszTheBuffer));
788c788
<             if (Platform::isFile( fileName ))
---
>             if (Platform::isFile( (const char*)pszTheBuffer ))
798c798
<                while((hfile = ::CreateFile(pszTheBuffer, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
---
>                while((hfile = ::CreateFileA((const char*)pszTheBuffer, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
808c808
<                Con::executef( 2, "onDropFile", StringTable->insert( fileName ) );
---
>                Con::executef( 2, "onDropFile", StringTable->insert((const char*)pszTheBuffer) );
#18
05/11/2008 (12:49 pm)
Hmm, now ended up with a strange error that I can't yet pinpoint the cause for. TGB deadlocks in Thread::join() after reactivating when the game has finished running. The process run thread correctly terminates yet WaitForSingleObject just blocks ad infinitum. Very odd.
#19
05/11/2008 (1:13 pm)
Okay, reading through the docs a little more thoroughly revealed what's wrong. The current threading code in TGB creates the thread through _beginthread and then later uses WaitForSingleObject. However, _beginthread implies the handle to be automatically closed when the thread function returns. WaitForSingleObject thus waits on an invalid handle.

Here's the fix.

platformWin32/thread/thread.cc

47c47
< static unsigned int __stdcall ThreadRunHandler(void * arg)
---
> static void ThreadRunHandler(void * arg)
59,61d58
< 
<    _endthreadex( 0 );
<    return 0;
103c100
<    mData->mThreadHnd = (HANDLE)_beginthreadex(0, 0, ThreadRunHandler, mData, 0, 0);
---
>    mData->mThreadHnd = (HANDLE)_beginthread(ThreadRunHandler, 0, mData);
111,114c108
<    bool res = ( WaitForSingleObject(mData->mThreadHnd, INFINITE) != WAIT_FAILED );
<    CloseHandle( mData->mThreadHnd );
< 
<    return res;
---
>    return WaitForSingleObject(mData->mThreadHnd, INFINITE) != WAIT_FAILED;

Seems everything's working fine and dandy now. Next up: having a fun time with this awesome program...

--------
Edit: Again, same issue in TGEA...
#20
07/08/2008 (1:11 pm)
Hehe, suppose my lengthy diffs freaked someone out since it's now two releases and the bugs are still in TGB.
Page «Previous 1 2