void translate(char input[512], char output[512]) { int i = 0; while (i < 512 && input[i] != '\0') { output[i] = tchar(input[i]); i++; } output[i] = '\0'; }
//----------------------------------------------------------------------------- // Purpose: Creates a new file and dumps the exception info into it // Input : uStructuredExceptionCode - windows exception code, unused. // pExceptionInfo - call stack. // minidumpType - type of minidump to write. // ptchMinidumpFileNameBuffer - if not-NULL points to a writable tchar buffer // of length at least _MAX_PATH to contain the name // of the written minidump file on return. //----------------------------------------------------------------------------- bool WriteMiniDumpUsingExceptionInfo( unsigned int uStructuredExceptionCode, _EXCEPTION_POINTERS * pExceptionInfo, MINIDUMP_TYPE minidumpType, tchar *ptchMinidumpFileNameBuffer /* = NULL */ ) { if ( ptchMinidumpFileNameBuffer ) { *ptchMinidumpFileNameBuffer = tchar( 0 ); } // get the function pointer directly so that we don't have to include the .lib, and that // we can easily change it to using our own dll when this code is used on win98/ME/2K machines HMODULE hDbgHelpDll = ::LoadLibrary( "DbgHelp.dll" ); if ( !hDbgHelpDll ) return false; bool bReturnValue = false; MINIDUMPWRITEDUMP pfnMiniDumpWrite = (MINIDUMPWRITEDUMP) ::GetProcAddress( hDbgHelpDll, "MiniDumpWriteDump" ); if ( pfnMiniDumpWrite ) { // create a unique filename for the minidump based on the current time and module name time_t currTime = ::time( NULL ); struct tm * pTime = ::localtime( &currTime ); ++g_nMinidumpsWritten; // strip off the rest of the path from the .exe name tchar rgchModuleName[MAX_PATH]; #ifdef TCHAR_IS_WCHAR ::GetModuleFileNameW( NULL, rgchModuleName, sizeof(rgchModuleName) / sizeof(tchar) ); #else ::GetModuleFileName( NULL, rgchModuleName, sizeof(rgchModuleName) / sizeof(tchar) ); #endif tchar *pch = _tcsrchr( rgchModuleName, '.' ); if ( pch ) { *pch = 0; } pch = _tcsrchr( rgchModuleName, '\\' ); if ( pch ) { // move past the last slash pch++; } else { pch = _T("unknown"); } // can't use the normal string functions since we're in tier0 tchar rgchFileName[MAX_PATH]; _sntprintf( rgchFileName, sizeof(rgchFileName) / sizeof(tchar), _T("%s_%s_%d%.2d%2d%.2d%.2d%.2d_%d.mdmp"), pch, g_bWritingNonfatalMinidump ? "assert" : "crash", pTime->tm_year + 1900, /* Year less 2000 */ pTime->tm_mon + 1, /* month (0 - 11 : 0 = January) */ pTime->tm_mday, /* day of month (1 - 31) */ pTime->tm_hour, /* hour (0 - 23) */ pTime->tm_min, /* minutes (0 - 59) */ pTime->tm_sec, /* seconds (0 - 59) */ g_nMinidumpsWritten // ensures the filename is unique ); BOOL bMinidumpResult = FALSE; #ifdef TCHAR_IS_WCHAR HANDLE hFile = ::CreateFileW( rgchFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); #else HANDLE hFile = ::CreateFile( rgchFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); #endif if ( hFile ) { // dump the exception information into the file _MINIDUMP_EXCEPTION_INFORMATION ExInfo; ExInfo.ThreadId = ::GetCurrentThreadId(); ExInfo.ExceptionPointers = pExceptionInfo; ExInfo.ClientPointers = FALSE; bMinidumpResult = (*pfnMiniDumpWrite)( ::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, minidumpType, &ExInfo, NULL, NULL ); ::CloseHandle( hFile ); if ( bMinidumpResult ) { bReturnValue = true; if ( ptchMinidumpFileNameBuffer ) { // Copy the file name from "pSrc = rgchFileName" into "pTgt = ptchMinidumpFileNameBuffer" tchar *pTgt = ptchMinidumpFileNameBuffer; tchar const *pSrc = rgchFileName; while ( ( *( pTgt ++ ) = *( pSrc ++ ) ) != tchar( 0 ) ) continue; } } // fall through to trying again } // mark any failed minidump writes by renaming them if ( !bMinidumpResult ) { tchar rgchFailedFileName[_MAX_PATH]; _sntprintf( rgchFailedFileName, sizeof(rgchFailedFileName) / sizeof(tchar), "(failed)%s", rgchFileName ); rename( rgchFileName, rgchFailedFileName ); } } ::FreeLibrary( hDbgHelpDll ); // call the log flush function if one is registered to try to flush any logs //CallFlushLogFunc(); return bReturnValue; }
int export_map(char *filename, tile ***map, gui guibits, bool qf) { int zslice=levels; // if qf==true then we store zslice in levels else we don't need zslice char string[100]; if(qf) sprintf(string, "yxport: Exporting current zslice to: %s...", filename); else sprintf(string, "Exporting to: %s...", filename); fprintf(stderr, "%s\n", string); console(guibits, 20, string); FILE * fp=fopen(filename, "w"); if(fp==NULL) { fprintf(stderr, "Couldn't open file for writing!\n"); perror("fopen"); colconsole(guibits, 20, "Couldn't open file for writing!", 224, 192, 96); return(2); } else { if(qf) { if(zslice>=groundlevel) fprintf(fp, "#build Generated by DF Designer %hhu.%hhu.%hhu\n", VERSION_MAJ, VERSION_MIN, VERSION_REV); else { colconsole(guibits, 20, "yxport: Underground exports not done yet! Sorry", 224, 160, 96); fclose(fp); return(4); } } else fprintf(fp, "Generated by DF Designer %hhu.%hhu.%hhu\n", VERSION_MAJ, VERSION_MIN, VERSION_REV); int x,y,z; int nx=worldx,ny=worldy,nz=levels,mx=0,my=0,mz=0; bool same[levels]; for(z=qf?zslice:0;qf?z<levels:z==zslice;z++) { if((!qf) && (z>0)) { same[z]=true; for(y=0;(y<worldy) && same[z];y++) { for(x=0;(x<worldx) && same[z];x++) { if(map[z][x][y].data!=map[z-1][x][y].data) same[z]=false; else if((map[z][x][y].data & TILE_OBJECT) && (map[z][x][y].object!=map[z-1][x][y].object)) same[z]=false; } } } else same[z]=false; for(y=0;y<worldy;y++) { for(x=0;x<worldx;x++) { int here=map[z][x][y].data; if(z>groundlevel) { if(here!=0) { nx=min(nx, x); ny=min(ny, y); nz=min(nz, z); mx=max(mx, x); my=max(my, y); mz=max(mz, z); } } else if(z==groundlevel) { if(here&~TILE_GRASS) { nx=min(nx, x); ny=min(ny, y); nz=min(nz, z); mx=max(mx, x); my=max(my, y); mz=max(mz, z); } } else { if(here&~TILE_ROCK) { nx=min(nx, x); ny=min(ny, y); nz=min(nz, z); mx=max(mx, x); my=max(my, y); mz=max(mz, z); } } } } } if(qf) nz=mz=zslice; same[nz]=false; // we need to ensure that we at least get something if(!qf) fputc('\n', fp); bool hitstock=false; for(z=mz;z>=nz;z--) { if(!qf) fprintf(fp, "Z-level %d\n", z-groundlevel); if(!same[z]) { for(y=ny;y<=my;y++) { if(!qf) fputc('\n', fp); for(x=nx;x<=mx;x++) { if(qf) { int here=map[zslice][x][y].data; char *qfbuild; if(here&TILE_ROCK) { qfbuild="Cw"; } else if(here&TILE_FLOOR) { qfbuild="Cf"; } else if(here&TILE_DOOR) { qfbuild="d"; } else if(here&TILE_STAIRS) { disp_tile xtile = tchar(map, x, y, zslice); switch(xtile.v) { case '>': qfbuild="Cd"; break; case '<': qfbuild="Cu"; break; case 'X': qfbuild="Cx"; break; default: fprintf(stderr, "yxport: A staircase could not be properly deduced\n"); colconsole(guibits, 20, "yxport: A staircase could not be properly deduced", 160, 160, 128); qfbuild="Cx"; break; } } else if(here&TILE_FORTS) { qfbuild="CF"; } else if(here&TILE_OBJECT) { switch(map[zslice][x][y].object) { case OBJECT_BED: qfbuild="b"; break; case OBJECT_CHAIR: qfbuild="c"; break; case OBJECT_TABLE: qfbuild="t"; break; case OBJECT_STATUE: qfbuild="s"; break; case OBJECT_STKPILE: qfbuild="`"; if(!hitstock) { fprintf(stderr, "yxport: stockpiles not yet supported (ignored)\n"); colconsole(guibits, 20, "yxport: stockpiles not yet supported (ignored)", 160, 160, 128); } hitstock=true; break; default: qfbuild="`"; fprintf(stderr, "yxport: unrecognised object %d (ignored)\n", map[zslice][x][y].object); colconsole(guibits, 20, "yxport: unrecognised object (ignored)", 160, 160, 128); break; } } else { qfbuild="`"; } fprintf(fp, "%s,", qfbuild); } else { disp_tile xtile = tchar(map, x, y, z); if(xtile.v>127) fprintf(fp, "%s", xatiles[xtile.v-128]); else fputc(xtile.v, fp); } } if(qf) fprintf(fp, "#\n"); } if(!qf) { fputc('\n', fp); fputc('\n', fp); } } } fclose(fp); if(qf) colconsole(guibits, 20, "yxport: Exported successfully!", 96, 32, 96); else colconsole(guibits, 20, "Exported successfully!", 96, 32, 96); } return(0); }