diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/xbox/vxconsole/bug.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/xbox/vxconsole/bug.cpp')
| -rw-r--r-- | utils/xbox/vxconsole/bug.cpp | 1576 |
1 files changed, 1576 insertions, 0 deletions
diff --git a/utils/xbox/vxconsole/bug.cpp b/utils/xbox/vxconsole/bug.cpp new file mode 100644 index 0000000..1d288eb --- /dev/null +++ b/utils/xbox/vxconsole/bug.cpp @@ -0,0 +1,1576 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// BUG.CPP +// +// Tracker bridge +//=====================================================================================// +#include "vxconsole.h" + +// two bug systems, certain games are tied to a specific system +#define BUG_REPORTER_DLLNAME_1 "bugreporter.dll" +#define BUG_REPORTER_DLLNAME_2 "bugreporter_filequeue.dll" + +#define BUG_REPOSITORY_URL "\\\\fileserver\\bugs" +#define REPOSITORY_VALIDATION_FILE "info.txt" +#define BUG_ERRORTITLE "Bug Error" +#define BUG_COLOR ( RGB( 0,255,255 ) ) + +HWND g_bug_hWnd; +HMODULE g_bug_hBugReporter1; +HMODULE g_bug_hBugReporter2; +IBugReporter *g_bug_pReporter1; +IBugReporter *g_bug_pReporter2; +IBugReporter *g_bug_pReporter; +char g_bug_szTitle[512]; +char g_bug_szDescription[1024]; +char g_bug_szOwner[128]; +char g_bug_szSeverity[128]; +char g_bug_szReportType[128]; +char g_bug_szPriority[128]; +char g_bug_szArea[128]; +char g_bug_szMapNumber[128]; +int g_bug_GameType; +bool g_bug_bActive; +char g_bug_szScreenshot[MAX_PATH]; +char g_bug_szSavegame[MAX_PATH]; +char g_bug_szBSPName[MAX_PATH]; +xrMapInfo_t g_bug_mapInfo; +bool g_bug_bCompressScreenshot; +bool g_bug_bFirstCommand; + +struct GameSystem_t +{ + const char *pFriendlyName; + const char *pGameName; + bool bUsesSystem1; +}; + +GameSystem_t g_Games[] = +{ + { "Half Life 2", "hl2", true }, + { "Episode 1", "episodic", true }, + { "Episode 2", "ep2", true }, + { "Portal", "portal", false }, + { "Team Fortress 2", "tf", false }, +}; + +static const char *GetRepositoryURL( void ) +{ + const char *pURL = g_bug_pReporter->GetRepositoryURL(); + if ( pURL ) + { + return pURL; + } + + return BUG_REPOSITORY_URL; +} + +const char *GetSubmissionURL( int bugid ) +{ + const char *pURL = g_bug_pReporter->GetSubmissionURL(); + if ( pURL ) + { + return pURL; + } + + static char url[MAX_PATH]; + Q_snprintf( url, sizeof(url), "%s/%i", GetRepositoryURL(), bugid ); + + return url; +} + +//----------------------------------------------------------------------------- +// BugReporter_SelectReporter +// +//----------------------------------------------------------------------------- +bool BugReporter_SelectReporter( const char *pGameName ) +{ + int system = -1; + for ( int i = 0; i < ARRAYSIZE( g_Games ); i++ ) + { + if ( pGameName && !V_stricmp( g_Games[i].pGameName, pGameName ) ) + { + system = i; + break; + } + } + + if ( system == -1 ) + { + // not found, slam to first + system = 0; + } + + // games uses different systems + int oldGameType = g_bug_GameType; + g_bug_GameType = system; + if ( g_Games[system].bUsesSystem1 ) + { + g_bug_pReporter = g_bug_pReporter1; + } + else + { + g_bug_pReporter = g_bug_pReporter2; + } + + // force the game area + if ( g_Games[g_bug_GameType].bUsesSystem1 ) + { + strcpy( g_bug_szArea, "XBOX 360" ); + } + else + { + strcpy( g_bug_szArea, g_Games[g_bug_GameType].pFriendlyName ); + } + + bool bChanged = ( oldGameType != g_bug_GameType ); + return bChanged; +} + +//----------------------------------------------------------------------------- +// BugReporter_LoadDLL +// +//----------------------------------------------------------------------------- +IBugReporter *BugReporter_LoadDLL( const char *pDLLName, HMODULE *phModule ) +{ + HMODULE hModule; + IBugReporter *pBugReporter; + + *phModule = NULL; + + hModule = LoadLibrary( pDLLName ); + if ( !hModule ) + { + Sys_MessageBox( BUG_ERRORTITLE, "Could not open '%s'\n", pDLLName ); + return NULL; + } + + FARPROC pCreateInterface = GetProcAddress( hModule, CREATEINTERFACE_PROCNAME ); + if ( !pCreateInterface ) + { + Sys_MessageBox( BUG_ERRORTITLE, "Missing '%s' interface for '%s'\n", CREATEINTERFACE_PROCNAME, pDLLName ); + return NULL; + } + + pBugReporter = (IBugReporter *)((CreateInterfaceFn)pCreateInterface)( INTERFACEVERSION_BUGREPORTER, NULL ); + if ( !pBugReporter ) + { + Sys_MessageBox( BUG_ERRORTITLE, "Missing interface '%s' for '%s'\n", INTERFACEVERSION_BUGREPORTER, pDLLName ); + return NULL; + } + + bool bSuccess = pBugReporter->Init( NULL ); + if ( !bSuccess ) + { + return NULL; + } + + *phModule = hModule; + return pBugReporter; +} + +//----------------------------------------------------------------------------- +// BugReporter_GetInterfaces +// +//----------------------------------------------------------------------------- +bool BugReporter_GetInterfaces() +{ + if ( !g_bug_pReporter1 ) + { + g_bug_pReporter1 = BugReporter_LoadDLL( BUG_REPORTER_DLLNAME_1, &g_bug_hBugReporter1 ); + if ( !g_bug_pReporter1 ) + { + Sys_MessageBox( BUG_ERRORTITLE, "PVCS intialization failed!\n" ); + } + } + + if ( !g_bug_pReporter2 ) + { + g_bug_pReporter2 = BugReporter_LoadDLL( BUG_REPORTER_DLLNAME_2, &g_bug_hBugReporter2 ); + if ( !g_bug_pReporter2 ) + { + Sys_MessageBox( BUG_ERRORTITLE, "BugBait intialization failed!\n" ); + } + } + + if ( g_bug_pReporter1 ) + { + // determine submitter name + ConsoleWindowPrintf( BUG_COLOR, "Bug Reporter: PVCS Username: '%s' Display As: '%s'\n", g_bug_pReporter1->GetUserName(), g_bug_pReporter1->GetUserName_Display() ); + } + if ( g_bug_pReporter2 ) + { + // determine submitter name + ConsoleWindowPrintf( BUG_COLOR, "Bug Reporter: BugBait Username: '%s' Display As: '%s'\n", g_bug_pReporter2->GetUserName(), g_bug_pReporter2->GetUserName_Display() ); + } + + BugReporter_SelectReporter( NULL ); + + // See if we can see the bug repository right now + char fn[MAX_PATH]; + V_snprintf( fn, sizeof( fn ), "%s/%s", GetRepositoryURL(), REPOSITORY_VALIDATION_FILE ); + Sys_NormalizePath( fn, false ); + + FILE *fp = fopen( fn, "rb" ); + if ( fp ) + { + ConsoleWindowPrintf( BUG_COLOR, "PVCS Repository '%s'\n", GetRepositoryURL() ); + fclose( fp ); + } + else + { + Sys_MessageBox( BUG_ERRORTITLE, "Unable to see '%s', check permissions and network connectivity.\n", fn ); + return false; + } + + // success + return true; +} + +//----------------------------------------------------------------------------- +// BugReporter_FreeInterfaces +// +//----------------------------------------------------------------------------- +void BugReporter_FreeInterfaces() +{ + if ( g_bug_pReporter1 ) + { + g_bug_pReporter1->Shutdown(); + g_bug_pReporter1 = NULL; + FreeLibrary( g_bug_hBugReporter1 ); + g_bug_hBugReporter1 = NULL; + } + + if ( g_bug_pReporter2 ) + { + g_bug_pReporter2->Shutdown(); + g_bug_pReporter2 = NULL; + FreeLibrary( g_bug_hBugReporter2 ); + g_bug_hBugReporter2 = NULL; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Expanded data destination object for CUtlBuffer output +//----------------------------------------------------------------------------- +struct JPEGDestinationManager_t +{ + struct jpeg_destination_mgr pub; // public fields + + CUtlBuffer *pBuffer; // target/final buffer + byte *buffer; // start of temp buffer +}; + +// choose an efficiently bufferaable size +#define OUTPUT_BUF_SIZE 4096 + +//----------------------------------------------------------------------------- +// Purpose: Initialize destination --- called by jpeg_start_compress +// before any data is actually written. +//----------------------------------------------------------------------------- +void init_destination( j_compress_ptr cinfo ) +{ + JPEGDestinationManager_t *dest = ( JPEGDestinationManager_t *) cinfo->dest; + + // Allocate the output buffer --- it will be released when done with image + dest->buffer = (byte *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + OUTPUT_BUF_SIZE * sizeof(byte)); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; +} + +//----------------------------------------------------------------------------- +// Purpose: Empty the output buffer --- called whenever buffer fills up. +// Input : boolean - +//----------------------------------------------------------------------------- +boolean empty_output_buffer( j_compress_ptr cinfo ) +{ + JPEGDestinationManager_t *dest = ( JPEGDestinationManager_t * ) cinfo->dest; + + CUtlBuffer *buf = dest->pBuffer; + + // Add some data + buf->Put( dest->buffer, OUTPUT_BUF_SIZE ); + + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + + return TRUE; +} + +//----------------------------------------------------------------------------- +// Purpose: Terminate destination --- called by jpeg_finish_compress +// after all data has been written. Usually needs to flush buffer. +// +// NB: *not* called by jpeg_abort or jpeg_destroy; surrounding +// application must deal with any cleanup that should happen even +// for error exit. +//----------------------------------------------------------------------------- +void term_destination( j_compress_ptr cinfo ) +{ + JPEGDestinationManager_t *dest = (JPEGDestinationManager_t *) cinfo->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + CUtlBuffer *buf = dest->pBuffer; + + /* Write any data remaining in the buffer */ + if (datacount > 0) + { + buf->Put( dest->buffer, datacount ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Set up functions for writing data to a CUtlBuffer instead of FILE * +//----------------------------------------------------------------------------- +void jpeg_UtlBuffer_dest( j_compress_ptr cinfo, CUtlBuffer *pBuffer ) +{ + JPEGDestinationManager_t *dest; + + /* The destination object is made permanent so that multiple JPEG images + * can be written to the same file without re-executing jpeg_stdio_dest. + * This makes it dangerous to use this manager and a different destination + * manager serially with the same JPEG object, because their private object + * sizes may be different. Caveat programmer. + */ + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof(JPEGDestinationManager_t)); + } + + dest = ( JPEGDestinationManager_t * ) cinfo->dest; + + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->pBuffer = pBuffer; +} + +//----------------------------------------------------------------------------- +// BugDlg_CompressScreenshot +// +// Compress .BMP to .JPG, Delete .BMP +//----------------------------------------------------------------------------- +bool BugDlg_CompressScreenshot() +{ + if ( !g_bug_szScreenshot[0] ) + { + return false; + } + + bool bSuccess = false; + HBITMAP hBitmap = NULL; + HDC hDC = NULL; + char *pBMPBits = NULL; + + CUtlBuffer buf( 0, 0 ); + + hBitmap = (HBITMAP)LoadImage( NULL, g_bug_szScreenshot, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE ); + if ( !hBitmap ) + goto cleanUp; + + hDC = CreateCompatibleDC( NULL ); + if ( !hDC ) + goto cleanUp; + + BITMAPINFO bitmapInfo; + ZeroMemory( &bitmapInfo, sizeof( BITMAPINFO ) ); + bitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); + + // populate the bmp info + if ( !GetDIBits( hDC, hBitmap, 0, 0, NULL, &bitmapInfo, DIB_RGB_COLORS ) ) + goto cleanUp; + + pBMPBits = (char *)Sys_Alloc( bitmapInfo.bmiHeader.biSizeImage ); + if ( !pBMPBits ) + goto cleanUp; + + // could be bottom-up or top-down + int nHeight = abs( bitmapInfo.bmiHeader.biHeight ); + + if ( bitmapInfo.bmiHeader.biBitCount != 32 ) + { + // unexpected format + goto cleanUp; + } + + if ( bitmapInfo.bmiHeader.biCompression != BI_RGB && bitmapInfo.bmiHeader.biCompression != BI_BITFIELDS ) + { + // unexpected format + goto cleanUp; + } + + // don't want color masks + bitmapInfo.bmiHeader.biCompression = BI_RGB; + + // get the raw bits + if ( !GetDIBits( hDC, hBitmap, 0, nHeight, pBMPBits, &bitmapInfo, DIB_RGB_COLORS ) ) + goto cleanUp; + + JSAMPROW row_pointer[1]; + + // compression data structure + struct jpeg_compress_struct cinfo; + ZeroMemory( &cinfo, sizeof( jpeg_compress_struct ) ); + + // point at stderr + struct jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error( &jerr ); + + // create compressor + jpeg_create_compress( &cinfo ); + + // Hook CUtlBuffer to compression + jpeg_UtlBuffer_dest( &cinfo, &buf ); + + // image width and height, in pixels + cinfo.image_width = bitmapInfo.bmiHeader.biWidth; + cinfo.image_height = nHeight; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + + // Apply settings + jpeg_set_defaults( &cinfo ); + jpeg_set_quality( &cinfo, 50, TRUE ); + + // Start compressor + jpeg_start_compress( &cinfo, TRUE); + + char *pRowBuffer = (char*)_alloca( bitmapInfo.bmiHeader.biWidth * 3 ); + row_pointer[0] = (JSAMPROW)pRowBuffer; + + // Write scanlines + while ( cinfo.next_scanline < cinfo.image_height ) + { + char *pSrc; + if ( bitmapInfo.bmiHeader.biHeight < 0 ) + { + // top down + pSrc = &pBMPBits[cinfo.next_scanline * bitmapInfo.bmiHeader.biWidth * 4]; + } + else + { + // bottom up + pSrc = &pBMPBits[(nHeight-1 - cinfo.next_scanline) * bitmapInfo.bmiHeader.biWidth * 4]; + } + + // convert to BGR to RGB + char *pDst = pRowBuffer; + for ( int i=0; i<bitmapInfo.bmiHeader.biWidth; i++ ) + { + pDst[0] = pSrc[2]; + pDst[1] = pSrc[1]; + pDst[2] = pSrc[0]; + pSrc += 4; + pDst += 3; + } + jpeg_write_scanlines( &cinfo, row_pointer, 1 ); + } + + // Finalize image + jpeg_finish_compress( &cinfo ); + + char jpgFilename[MAX_PATH]; + Sys_StripExtension( g_bug_szScreenshot, jpgFilename, sizeof( jpgFilename ) ); + Sys_AddExtension( ".jpg", jpgFilename, sizeof( jpgFilename ) ); + if ( !Sys_SaveFile( jpgFilename, buf.Base(), buf.TellMaxPut() ) ) + goto cleanUp; + + // remove the uncompressed version + unlink( g_bug_szScreenshot ); + strcpy( g_bug_szScreenshot, jpgFilename ); + + bSuccess = true; + +cleanUp: + if ( hBitmap ) + DeleteObject( hBitmap ); + if ( hDC ) + DeleteDC( hDC ); + if ( pBMPBits ) + Sys_Free( pBMPBits ); + + return bSuccess; +} + + +//----------------------------------------------------------------------------- +// BugDlg_GetAppData +// +//----------------------------------------------------------------------------- +void BugDlg_GetAppData( HWND hWnd ) +{ + // clear stale data from previous query + memset( &g_bug_mapInfo, 0, sizeof( g_bug_mapInfo ) ); + + SetDlgItemText( hWnd, IDC_BUG_POSITION_LABEL, "" ); + SetDlgItemText( hWnd, IDC_BUG_ORIENTATION_LABEL, "" ); + SetDlgItemText( hWnd, IDC_BUG_MAP_LABEL, "" ); + SetDlgItemText( hWnd, IDC_BUG_BUILD_LABEL, "" ); + + EnableWindow( GetDlgItem( hWnd, IDC_BUG_SAVEGAME ), false ); + EnableWindow( GetDlgItem( hWnd, IDC_BUG_INCLUDEBSP ), false ); + + if ( g_connectedToApp ) + { + // send to app, responds with position info + if ( !g_bug_bFirstCommand ) + { + // first command must send pause and status to be processed correctly + g_bug_bFirstCommand = true; + ProcessCommand( "pause ; status" ); + } + else + { + ProcessCommand( "status" ); + } + } +} + +//----------------------------------------------------------------------------- +// BugDlg_GetDataFileBase +// +//----------------------------------------------------------------------------- +void BugDlg_GetDataFileBase( char const *suffix, bool bLocalPath, char *buf, int bufsize ) +{ + char filepath[MAX_PATH]; + char filename[MAX_PATH]; + + struct tm t; + + time_t ltime; + time( <ime ); + tm *pTime = localtime( <ime ); + memcpy( &t, pTime, sizeof( t ) ); + + char who[128]; + strncpy( who, suffix, sizeof( who ) ); + _strlwr( who ); + + if ( bLocalPath ) + { + // add a qualified local path + // used as a gathering store before uploading to server + strcpy( filepath, g_localPath ); + Sys_AddFileSeperator( filepath, sizeof( filepath ) ); + strcat( filepath, "bug/" ); + Sys_NormalizePath( filepath, false ); + Sys_CreatePath( filepath ); + } + else + { + filepath[0] = '\0'; + } + + sprintf( filename, "%i_%02i_%02i_%s", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, who ); + V_snprintf( buf, bufsize, "%s%s", filepath, filename ); +} + +//----------------------------------------------------------------------------- +// BugDlg_CheckSubmit +// +//----------------------------------------------------------------------------- +bool BugDlg_CheckSubmit( HWND hWnd ) +{ + bool bEnableSubmit = false; + + if ( g_Games[g_bug_GameType].bUsesSystem1 ) + { + if ( g_bug_szTitle[0] && + g_bug_szDescription[0] && + g_bug_szSeverity[0] && + g_bug_szOwner[0] && + g_bug_szReportType[0] && + g_bug_szPriority[0] && + g_bug_szArea[0] ) + { + bEnableSubmit = true; + } + } + else + { + if ( g_bug_szTitle[0] && + g_bug_szDescription[0] && + g_bug_szSeverity[0] && + g_bug_szOwner[0] && + g_bug_szArea[0] && + g_bug_szMapNumber[0] ) + { + bEnableSubmit = true; + } + } + + EnableWindow( GetDlgItem( hWnd, IDC_BUG_SUBMIT ), bEnableSubmit ); + + return bEnableSubmit; +} + +//----------------------------------------------------------------------------- +// BugDlg_GetChanges +// +//----------------------------------------------------------------------------- +bool BugDlg_GetChanges( HWND hWnd ) +{ + int curSel; + + // title + GetDlgItemText( hWnd, IDC_BUG_TITLE, g_bug_szTitle, sizeof( g_bug_szTitle ) ); + + // description + GetDlgItemText( hWnd, IDC_BUG_DESCRIPTION, g_bug_szDescription, sizeof( g_bug_szDescription ) ); + + // owner + curSel = SendDlgItemMessage( hWnd, IDC_BUG_OWNER, CB_GETCURSEL, 0, 0 ); + if ( curSel == CB_ERR ) + { + g_bug_szOwner[0] = '\0'; + } + else + { + strncpy( g_bug_szOwner, g_bug_pReporter->GetDisplayName( curSel ), sizeof( g_bug_szOwner ) ); + g_bug_szOwner[sizeof( g_bug_szOwner )-1] = '\0'; + + if ( V_stristr( g_bug_szOwner, "unassigned" ) ) + { + g_bug_szOwner[0] = '\0'; + } + } + + // severity + curSel = SendDlgItemMessage( hWnd, IDC_BUG_SEVERITY, CB_GETCURSEL, 0, 0 ); + if ( curSel == CB_ERR ) + { + g_bug_szSeverity[0] = '\0'; + } + else + { + V_strncpy( g_bug_szSeverity, g_bug_pReporter->GetSeverity( curSel ), sizeof( g_bug_szSeverity ) ); + } + + // report type + curSel = SendDlgItemMessage( hWnd, IDC_BUG_REPORTTYPE, CB_GETCURSEL, 0, 0 ); + if ( curSel == CB_ERR ) + { + g_bug_szReportType[0] = '\0'; + } + else + { + V_strncpy( g_bug_szReportType, g_bug_pReporter->GetReportType( curSel ), sizeof( g_bug_szReportType ) ); + } + + // priority + curSel = SendDlgItemMessage( hWnd, IDC_BUG_PRIORITY, CB_GETCURSEL, 0, 0 ); + if ( curSel == CB_ERR ) + { + g_bug_szPriority[0] = '\0'; + } + else + { + V_strncpy( g_bug_szPriority, g_bug_pReporter->GetPriority( curSel ), sizeof( g_bug_szPriority ) ); + } + + // area + curSel = SendDlgItemMessage( hWnd, IDC_BUG_AREA, CB_GETCURSEL, 0, 0 ); + int areaIndex = 0; + if ( curSel == CB_ERR ) + { + g_bug_szArea[0] = '\0'; + } + else + { + V_strncpy( g_bug_szArea, g_bug_pReporter->GetArea( curSel ), sizeof( g_bug_szArea ) ); + areaIndex = curSel; + } + + if ( !g_Games[g_bug_GameType].bUsesSystem1 ) + { + // map number + curSel = SendDlgItemMessage( hWnd, IDC_BUG_MAPNUMBER, CB_GETCURSEL, 0, 0 ); + if ( curSel == CB_ERR ) + { + g_bug_szMapNumber[0] = '\0'; + } + else + { + V_strncpy( g_bug_szMapNumber, g_bug_pReporter->GetLevel( areaIndex, curSel ), sizeof( g_bug_szMapNumber ) ); + } + } + + g_bug_bCompressScreenshot = ( IsDlgButtonChecked( hWnd, IDC_BUG_COMPRESS_SCREENSHOT ) != 0 ); + + BugDlg_CheckSubmit( hWnd ); + + // success + return true; +} + +//----------------------------------------------------------------------------- +// BugDlg_UpdateReporter +// +//----------------------------------------------------------------------------- +bool BugDlg_UpdateReporter( HWND hWnd ) +{ + // game + int newGameType; + int curSel = SendDlgItemMessage( hWnd, IDC_BUG_GAME, CB_GETCURSEL, 0, 0 ); + if ( curSel == CB_ERR ) + { + newGameType = 0; + } + else + { + newGameType = curSel; + } + + return BugReporter_SelectReporter( g_Games[newGameType].pGameName ); +} + +//----------------------------------------------------------------------------- +// BugDlg_Populate +// +//----------------------------------------------------------------------------- +void BugDlg_Populate( HWND hWnd ) +{ + int i; + int count; + int curSel; + + g_bug_bActive = false; + + // title + SendDlgItemMessage( hWnd, IDC_BUG_TITLE, EM_LIMITTEXT, sizeof( g_bug_szTitle )-1, 0 ); + SetDlgItemText( hWnd, IDC_BUG_TITLE, g_bug_szTitle ); + + // description + SendDlgItemMessage( hWnd, IDC_BUG_DESCRIPTION, EM_LIMITTEXT, sizeof( g_bug_szDescription )-1, 0 ); + SetDlgItemText( hWnd, IDC_BUG_DESCRIPTION, g_bug_szDescription ); + + // submitter + SetDlgItemText( hWnd, IDC_BUG_SUBMITTER_LABEL, g_bug_pReporter->GetUserName_Display() ); + + // owner + SendDlgItemMessage( hWnd, IDC_BUG_OWNER, CB_RESETCONTENT, 0, 0 ); + count = g_bug_pReporter->GetDisplayNameCount(); + for ( i = 0; i < count; i++ ) + { + SendDlgItemMessage( hWnd, IDC_BUG_OWNER, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)g_bug_pReporter->GetDisplayName( i ) ); + } + if ( count ) + { + curSel = SendDlgItemMessage( hWnd, IDC_BUG_OWNER, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)(LPCSTR)g_bug_szOwner ); + if ( curSel != CB_ERR ) + { + SendDlgItemMessage( hWnd, IDC_BUG_OWNER, CB_SETCURSEL, curSel, 0 ); + } + } + + // severity + SendDlgItemMessage( hWnd, IDC_BUG_SEVERITY, CB_RESETCONTENT, 0, 0 ); + count = g_bug_pReporter->GetSeverityCount(); + for ( i = 0; i < count; i++ ) + { + SendDlgItemMessage( hWnd, IDC_BUG_SEVERITY, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)g_bug_pReporter->GetSeverity( i ) ); + } + if ( count ) + { + curSel = SendDlgItemMessage( hWnd, IDC_BUG_SEVERITY, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)(LPCSTR)g_bug_szSeverity ); + if ( curSel != CB_ERR ) + { + SendDlgItemMessage( hWnd, IDC_BUG_SEVERITY, CB_SETCURSEL, curSel, 0 ); + } + } + + // report type + SendDlgItemMessage( hWnd, IDC_BUG_REPORTTYPE, CB_RESETCONTENT, 0, 0 ); + EnableWindow( GetDlgItem( hWnd, IDC_BUG_REPORTTYPE ), g_Games[g_bug_GameType].bUsesSystem1 ); + if ( g_Games[g_bug_GameType].bUsesSystem1 ) + { + count = g_bug_pReporter->GetReportTypeCount(); + for ( i = 0; i < count; i++ ) + { + SendDlgItemMessage( hWnd, IDC_BUG_REPORTTYPE, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)g_bug_pReporter->GetReportType( i ) ); + } + if ( count ) + { + curSel = SendDlgItemMessage( hWnd, IDC_BUG_REPORTTYPE, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)(LPCSTR)g_bug_szReportType ); + if ( curSel != CB_ERR ) + { + SendDlgItemMessage( hWnd, IDC_BUG_REPORTTYPE, CB_SETCURSEL, curSel, 0 ); + } + } + } + + // priority + SendDlgItemMessage( hWnd, IDC_BUG_PRIORITY, CB_RESETCONTENT, 0, 0 ); + EnableWindow( GetDlgItem( hWnd, IDC_BUG_PRIORITY ), g_Games[g_bug_GameType].bUsesSystem1 ); + if ( g_Games[g_bug_GameType].bUsesSystem1 ) + { + count = g_bug_pReporter->GetPriorityCount(); + for ( i = 0; i < count; i++ ) + { + SendDlgItemMessage( hWnd, IDC_BUG_PRIORITY, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)g_bug_pReporter->GetPriority( i ) ); + } + if ( count ) + { + curSel = SendDlgItemMessage( hWnd, IDC_BUG_PRIORITY, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)(LPCSTR)g_bug_szPriority ); + if ( curSel != CB_ERR ) + { + SendDlgItemMessage( hWnd, IDC_BUG_PRIORITY, CB_SETCURSEL, curSel, 0 ); + } + } + } + + // area + SendDlgItemMessage( hWnd, IDC_BUG_AREA, CB_RESETCONTENT, 0, 0 ); + count = g_bug_pReporter->GetAreaCount(); + int areaIndex = 0; + for ( i = 0; i < count; i++ ) + { + SendDlgItemMessage( hWnd, IDC_BUG_AREA, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)g_bug_pReporter->GetArea( i ) ); + } + if ( count ) + { + curSel = SendDlgItemMessage( hWnd, IDC_BUG_AREA, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)(LPCSTR)g_bug_szArea ); + if ( curSel != CB_ERR ) + { + SendDlgItemMessage( hWnd, IDC_BUG_AREA, CB_SETCURSEL, curSel, 0 ); + areaIndex = curSel; + } + } + + // map name or number + SendDlgItemMessage( hWnd, IDC_BUG_MAPNUMBER, CB_RESETCONTENT, 0, 0 ); + EnableWindow( GetDlgItem( hWnd, IDC_BUG_MAPNUMBER ), g_Games[g_bug_GameType].bUsesSystem1 == false ); + if ( !g_Games[g_bug_GameType].bUsesSystem1 ) + { + // new system has map names + count = g_bug_pReporter->GetLevelCount( areaIndex ); + for ( i = 0; i < count; i++ ) + { + SendDlgItemMessage( hWnd, IDC_BUG_MAPNUMBER, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)g_bug_pReporter->GetLevel( areaIndex, i ) ); + } + } + if ( count ) + { + curSel = SendDlgItemMessage( hWnd, IDC_BUG_MAPNUMBER, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)(LPCSTR)g_bug_szMapNumber ); + if ( curSel != CB_ERR ) + { + SendDlgItemMessage( hWnd, IDC_BUG_MAPNUMBER, CB_SETCURSEL, curSel, 0 ); + } + } + + // game + SendDlgItemMessage( hWnd, IDC_BUG_GAME, CB_RESETCONTENT, 0, 0 ); + count = ARRAYSIZE( g_Games ); + for ( i = 0; i < count; i++ ) + { + SendDlgItemMessage( hWnd, IDC_BUG_GAME, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)g_Games[i].pFriendlyName ); + } + if ( count ) + { + curSel = SendDlgItemMessage( hWnd, IDC_BUG_GAME, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)(LPCSTR)g_Games[g_bug_GameType].pFriendlyName ); + if ( curSel != CB_ERR ) + { + SendDlgItemMessage( hWnd, IDC_BUG_GAME, CB_SETCURSEL, curSel, 0 ); + } + } + + CheckDlgButton( hWnd, IDC_BUG_COMPRESS_SCREENSHOT, g_bug_bCompressScreenshot ? BST_CHECKED : BST_UNCHECKED ); + + SetDlgItemText( hWnd, IDC_BUG_TAKESHOT_LABEL, g_bug_szScreenshot ); + SetDlgItemText( hWnd, IDC_BUG_SAVEGAME_LABEL, g_bug_szSavegame ); + SetDlgItemText( hWnd, IDC_BUG_INCLUDEBSP_LABEL, g_bug_szBSPName ); + SetDlgItemText( hWnd, IDC_BUG_INCLUDEVMF_LABEL, "" ); + + EnableWindow( GetDlgItem( hWnd, IDC_BUG_TAKESHOT ), g_connectedToApp ); + EnableWindow( GetDlgItem( hWnd, IDC_BUG_INCLUDEVMF ), false ); + EnableWindow( GetDlgItem( hWnd, IDC_BUG_UPDATE ), g_connectedToApp ); + + BugDlg_GetAppData( hWnd ); + + BugDlg_CheckSubmit( hWnd ); + + g_bug_bActive = true; +} + +//----------------------------------------------------------------------------- +// BugDlg_TakeScreenshot +// +//----------------------------------------------------------------------------- +void BugDlg_TakeScreenshot( HWND hWnd ) +{ + char buff[1024]; + + SetDlgItemText( hWnd, IDC_BUG_TAKESHOT_LABEL, "Working..." ); + + BugDlg_GetDataFileBase( g_bug_pReporter->GetUserName(), true, g_bug_szScreenshot, sizeof( g_bug_szScreenshot ) ); + strcat( g_bug_szScreenshot, ".bmp" ); + + // remove local version + unlink( g_bug_szScreenshot ); + + sprintf( buff, "*screenshot \"%s\"", g_bug_szScreenshot ); + if ( !ProcessCommand( buff ) ) + { + g_bug_szScreenshot[0] = '\0'; + } + + SetDlgItemText( hWnd, IDC_BUG_TAKESHOT_LABEL, g_bug_szScreenshot ); +} + +//----------------------------------------------------------------------------- +// BugDlg_SaveGame +// +//----------------------------------------------------------------------------- +void BugDlg_SaveGame( HWND hWnd ) +{ + char buff[1024]; + char savename[MAX_PATH]; + char remoteFile[MAX_PATH]; + + if ( !g_bug_mapInfo.savePath[0] ) + { + return; + } + + SetDlgItemText( hWnd, IDC_BUG_SAVEGAME_LABEL, "Working..." ); + + BugDlg_GetDataFileBase( g_bug_pReporter->GetUserName(), true, g_bug_szSavegame, sizeof( g_bug_szSavegame ) ); + Sys_StripPath( g_bug_szSavegame, savename, sizeof( savename ) ); + strcat( g_bug_szSavegame, ".360.sav" ); + + sprintf( remoteFile, "%s\\%s.360.sav", g_bug_mapInfo.savePath, savename ); + + // delete file locally + unlink( g_bug_szSavegame ); + + // delete file remotely + DmDeleteFile( remoteFile, false ); + + // save, and wait to ensure async completes + sprintf( buff, "save \"%s\" notmostrecent wait", savename ); + if ( !ProcessCommand( buff ) ) + { + // failed + g_bug_szSavegame[0] = '\0'; + } + else + { + DM_FILE_ATTRIBUTES fileAttributes; + for (int i=0; i<5; i++) + { + // wait for the save file to appear + HRESULT hr = DmGetFileAttributes( remoteFile, &fileAttributes ); + if ( hr == XBDM_NOERR ) + break; + + // wait for it + Sleep( 1000 ); + } + + HRESULT hr = DmReceiveFile( g_bug_szSavegame, remoteFile ); + if ( hr != XBDM_NOERR ) + { + // failed + g_bug_szSavegame[0] = '\0'; + } + } + + SetDlgItemText( hWnd, IDC_BUG_SAVEGAME_LABEL, g_bug_szSavegame ); +} + +//----------------------------------------------------------------------------- +// BugDlg_IncludeBSP +// +//----------------------------------------------------------------------------- +void BugDlg_IncludeBSP( HWND hWnd ) +{ + if ( !g_bug_mapInfo.mapPath[0] ) + { + return; + } + + SetDlgItemText( hWnd, IDC_BUG_INCLUDEBSP_LABEL, "Working..." ); + + BugDlg_GetDataFileBase( g_bug_pReporter->GetUserName(), true, g_bug_szBSPName, sizeof( g_bug_szBSPName ) ); + strcat( g_bug_szBSPName, ".360.bsp" ); + + // remove local version + unlink( g_bug_szBSPName ); + + // get the file locally + HRESULT hr = DmReceiveFile( g_bug_szBSPName, g_bug_mapInfo.mapPath ); + if ( hr != XBDM_NOERR ) + { + // failed + g_bug_szBSPName[0] = '\0'; + } + + SetDlgItemText( hWnd, IDC_BUG_INCLUDEBSP_LABEL, g_bug_szBSPName ); +} + +//----------------------------------------------------------------------------- +// BugDlg_ResetAndPopulate +// +//----------------------------------------------------------------------------- +void BugDlg_ResetAndPopulate( HWND hWnd, bool bFullReset = true ) +{ + // reset all fields + if ( bFullReset ) + { + g_bug_szTitle[0] = '\0'; + g_bug_szDescription[0] = '\0'; + } + g_bug_szOwner[0] = '\0'; + g_bug_szSeverity[0] = '\0'; + g_bug_szReportType[0] = '\0'; + g_bug_szPriority[0] = '\0'; + g_bug_szMapNumber[0] = '\0'; + + if ( bFullReset ) + { + g_bug_szScreenshot[0] = '\0'; + g_bug_szSavegame[0] = '\0'; + g_bug_szBSPName[0] = '\0'; + } + + g_bug_bCompressScreenshot = true; + + memset( &g_bug_mapInfo, 0, sizeof( g_bug_mapInfo ) ); + + // populate with reset fields + BugDlg_Populate( hWnd ); +} + +//----------------------------------------------------------------------------- +// BugDlg_Setup +// +//----------------------------------------------------------------------------- +void BugDlg_Setup( HWND hWnd ) +{ + g_bug_hWnd = hWnd; + + // clear stale data from app + g_bug_bFirstCommand = false; + memset( &g_bug_mapInfo, 0, sizeof( g_bug_mapInfo ) ); + + // always reset these fields + g_bug_szTitle[0] = '\0'; + g_bug_szDescription[0] = '\0'; + g_bug_szScreenshot[0] = '\0'; + g_bug_szSavegame[0] = '\0'; + g_bug_szBSPName[0] = '\0'; + + g_bug_bCompressScreenshot = true; + + memset( &g_bug_mapInfo, 0, sizeof( g_bug_mapInfo ) ); + + BugDlg_Populate( hWnd ); +} + +//----------------------------------------------------------------------------- +// BugDlg_UploadFile +// +//----------------------------------------------------------------------------- +bool BugDlg_UploadFile( char const *pLocalName, char const *pRemoteName, bool bDeleteLocal ) +{ + FILE *fp; + int len; + void *pLocalData; + + ConsoleWindowPrintf( BUG_COLOR, "Uploading %s to %s\n", pLocalName, pRemoteName ); + + len = Sys_LoadFile( pLocalName, &pLocalData ); + if ( !pLocalData || !len ) + { + ConsoleWindowPrintf( XBX_CLR_RED, "UploadFile: Unable to open local path '%s'\n", pLocalName ); + return false; + } + + Sys_CreatePath( pRemoteName ); + + fp = fopen( pRemoteName, "wb" ); + if ( !fp ) + { + ConsoleWindowPrintf( XBX_CLR_RED, "UploadFile: Unable to open remote path '%s'\n", pRemoteName ); + Sys_Free( pLocalData ); + return false; + } + + fwrite( pLocalData, len, 1, fp ); + + fclose( fp ); + Sys_Free( pLocalData ); + + if ( bDeleteLocal ) + { + unlink( pLocalName ); + } + + return true; +} + +//----------------------------------------------------------------------------- +// BugDlg_UploadBugSubmission +// +// Expects fully qualified source paths +//----------------------------------------------------------------------------- +bool BugDlg_UploadBugSubmission( int bugID, char const *pSavefile, char const *pScreenshot, char const *pBspFile, char const *pVmfFile ) +{ + char szFilename[MAX_PATH]; + char szLocalfile[MAX_PATH]; + char szRemotefile[MAX_PATH]; + bool bSuccess = true; + + if ( pSavefile && pSavefile[0] ) + { + V_snprintf( szLocalfile, sizeof( szLocalfile ), "%s", pSavefile ); + Sys_StripPath( pSavefile, szFilename, sizeof( szFilename ) ); + V_snprintf( szRemotefile, sizeof( szRemotefile ), "%s/%s", GetSubmissionURL( bugID ), szFilename ); + Sys_NormalizePath( szLocalfile, false ); + Sys_NormalizePath( szRemotefile, false ); + + if ( !BugDlg_UploadFile( szLocalfile, szRemotefile, false ) ) + { + bSuccess = false; + } + } + + if ( pScreenshot && pScreenshot[0] ) + { + V_snprintf( szLocalfile, sizeof( szLocalfile ), "%s", pScreenshot ); + Sys_StripPath( pScreenshot, szFilename, sizeof( szFilename ) ); + V_snprintf( szRemotefile, sizeof( szRemotefile ), "%s/%s", GetSubmissionURL( bugID ), szFilename ); + Sys_NormalizePath( szLocalfile, false ); + Sys_NormalizePath( szRemotefile, false ); + + if ( !BugDlg_UploadFile( szLocalfile, szRemotefile, true ) ) + { + bSuccess = false; + } + } + + if ( pBspFile && pBspFile[0] ) + { + V_snprintf( szLocalfile, sizeof( szLocalfile ), "%s", pBspFile ); + Sys_StripPath( pBspFile, szFilename, sizeof( szFilename ) ); + V_snprintf( szRemotefile, sizeof( szRemotefile ), "%s/%s", GetSubmissionURL( bugID ), szFilename ); + Sys_NormalizePath( szLocalfile, false ); + Sys_NormalizePath( szRemotefile, false ); + + if ( !BugDlg_UploadFile( szLocalfile, szRemotefile, true ) ) + { + bSuccess = false; + } + } + + return bSuccess; +} + +//----------------------------------------------------------------------------- +// BugDlg_Submit +// +//----------------------------------------------------------------------------- +bool BugDlg_Submit( HWND hWnd ) +{ + char title[1024]; + char miscInfo[1024]; + char basename[MAX_PATH]; + char filename[MAX_PATH]; + char positionName[MAX_PATH]; + char orientationName[MAX_PATH]; + char buildName[MAX_PATH]; + char mapName[MAX_PATH]; + bool bSuccess = false; + + sprintf( positionName, "%f %f %f", g_bug_mapInfo.position[0], g_bug_mapInfo.position[1], g_bug_mapInfo.position[2] ); + SetDlgItemText( g_bug_hWnd, IDC_BUG_POSITION_LABEL, positionName ); + + sprintf( orientationName, "%f %f %f", g_bug_mapInfo.angle[0], g_bug_mapInfo.angle[1], g_bug_mapInfo.angle[2] ); + SetDlgItemText( g_bug_hWnd, IDC_BUG_ORIENTATION_LABEL, orientationName ); + + sprintf( buildName, "%d", g_bug_mapInfo.build ); + SetDlgItemText( g_bug_hWnd, IDC_BUG_BUILD_LABEL, buildName ); + + V_FileBase( g_bug_mapInfo.mapPath, mapName, sizeof( mapName ) ); + char *pExtension = V_stristr( mapName, ".bsp" ); + if ( pExtension ) + { + *pExtension = '\0'; + } + pExtension = V_stristr( mapName, ".360" ); + if ( pExtension ) + { + *pExtension = '\0'; + } + + V_snprintf( miscInfo, sizeof( miscInfo ), "skill %d", g_bug_mapInfo.skill ); + + // Stuff bug data files up to server + g_bug_pReporter->StartNewBugReport(); + + g_bug_pReporter->SetOwner( g_bug_pReporter->GetUserNameForDisplayName( g_bug_szOwner ) ); + g_bug_pReporter->SetSubmitter( NULL ); + + if ( mapName[0] ) + V_snprintf( title, sizeof( title ), "%s: %s", mapName, g_bug_szTitle ); + else + V_snprintf( title, sizeof( title ), "%s", g_bug_szTitle ); + g_bug_pReporter->SetTitle( title ); + + g_bug_pReporter->SetDescription( g_bug_szDescription ); + g_bug_pReporter->SetLevel( mapName ); + g_bug_pReporter->SetPosition( positionName ); + g_bug_pReporter->SetOrientation( orientationName ); + g_bug_pReporter->SetBuildNumber( buildName ); + + g_bug_pReporter->SetSeverity( g_bug_szSeverity ); + g_bug_pReporter->SetPriority( g_bug_szPriority ); + g_bug_pReporter->SetArea( g_bug_szArea ); + g_bug_pReporter->SetMapNumber( g_bug_szMapNumber ); + g_bug_pReporter->SetReportType( g_bug_szReportType ); + g_bug_pReporter->SetMiscInfo( miscInfo ); + + g_bug_pReporter->SetDriverInfo( "" ); + g_bug_pReporter->SetExeName( "" ); + g_bug_pReporter->SetGameDirectory( "" ); + g_bug_pReporter->SetRAM( 0 ); + g_bug_pReporter->SetCPU( 0 ); + g_bug_pReporter->SetProcessor( "" ); + g_bug_pReporter->SetDXVersion( 0, 0, 0, 0 ); + g_bug_pReporter->SetOSVersion( "" ); + g_bug_pReporter->ResetIncludedFiles(); + g_bug_pReporter->SetZipAttachmentName( "" ); + + if ( g_bug_szScreenshot[0] ) + { + if ( g_bug_bCompressScreenshot ) + { + BugDlg_CompressScreenshot(); + } + + // strip the fully qualified path into filename only + Sys_StripPath( g_bug_szScreenshot, basename, sizeof( basename ) ); + V_snprintf( filename, sizeof( filename ), "%s/BugId/%s", GetRepositoryURL(), basename ); + Sys_NormalizePath( filename, false ); + g_bug_pReporter->SetScreenShot( filename ); + } + + if ( g_bug_szSavegame[0] ) + { + // strip the fully qualified path into filename only + Sys_StripPath( g_bug_szSavegame, basename, sizeof( basename ) ); + V_snprintf( filename, sizeof( filename ), "%s/BugId/%s", GetRepositoryURL(), basename ); + Sys_NormalizePath( filename, false ); + g_bug_pReporter->SetSaveGame( filename ); + } + + if ( g_bug_szBSPName[0] ) + { + // strip the fully qualified path into filename only + Sys_StripPath( g_bug_szBSPName, basename, sizeof( basename ) ); + V_snprintf( filename, sizeof( filename ), "%s/BugId/%s", GetRepositoryURL(), basename ); + Sys_NormalizePath( filename, false ); + g_bug_pReporter->SetBSPName( filename ); + } + + int bugID = -1; + + bSuccess = g_bug_pReporter->CommitBugReport( bugID ); + if ( bSuccess ) + { + if ( !BugDlg_UploadBugSubmission( bugID, g_bug_szSavegame, g_bug_szScreenshot, g_bug_szBSPName, NULL ) ) + { + Sys_MessageBox( BUG_ERRORTITLE, "Unable to upload files to bug repository!\n" ); + bSuccess = false; + } + } + else + { + Sys_MessageBox( BUG_ERRORTITLE, "Unable to post bug report to database!\n" ); + } + + if ( bSuccess ) + { + if ( g_Games[g_bug_GameType].bUsesSystem1 ) + { + ConsoleWindowPrintf( BUG_COLOR, "Bug Reporter: PVCS submission succeeded for bug! (%d)\n", bugID ); + } + else + { + ConsoleWindowPrintf( BUG_COLOR, "Bug Reporter: BugBait submission succeeded for bug!\n" ); + } + } + else + { + ConsoleWindowPrintf( XBX_CLR_RED, "Bug Reporter: Submission failed\n" ); + } + + return bSuccess; +} + +//----------------------------------------------------------------------------- +// BugDlg_Proc +// +//----------------------------------------------------------------------------- +BOOL CALLBACK BugDlg_Proc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) +{ + switch ( message ) + { + case WM_INITDIALOG: + BugDlg_Setup( hwnd ); + return ( TRUE ); + + case WM_COMMAND: + switch ( LOWORD( wParam ) ) + { + case IDC_BUG_TAKESHOT: + BugDlg_TakeScreenshot( hwnd ); + break; + + case IDC_BUG_SAVEGAME: + BugDlg_SaveGame( hwnd ); + break; + + case IDC_BUG_INCLUDEBSP: + BugDlg_IncludeBSP( hwnd ); + break; + + case IDC_BUG_INCLUDEVMF: + // not implemented, no reason to + break; + + case IDC_BUG_CLEARFORM: + BugDlg_ResetAndPopulate( hwnd ); + return TRUE; + + case IDC_BUG_UPDATE: + BugDlg_GetAppData( hwnd ); + return TRUE; + + case IDC_BUG_OWNER: + case IDC_BUG_SEVERITY: + case IDC_BUG_REPORTTYPE: + case IDC_BUG_PRIORITY: + case IDC_BUG_AREA: + case IDC_BUG_MAPNUMBER: + if ( g_bug_bActive && HIWORD( wParam ) == CBN_CLOSEUP ) + { + BugDlg_GetChanges( hwnd ); + return TRUE; + } + break; + + case IDC_BUG_GAME: + if ( HIWORD( wParam ) == CBN_CLOSEUP ) + { + if ( BugDlg_UpdateReporter( hwnd ) ) + { + // reporter changed, clear critical parts of form + BugDlg_ResetAndPopulate( hwnd, false ); + } + return TRUE; + } + break; + + case IDC_BUG_TITLE: + case IDC_BUG_DESCRIPTION: + if ( g_bug_bActive && HIWORD( wParam ) == EN_CHANGE ) + { + BugDlg_GetChanges( hwnd ); + return TRUE; + } + break; + + case IDC_BUG_COMPRESS_SCREENSHOT: + BugDlg_GetChanges( hwnd ); + return TRUE; + + case IDC_BUG_SUBMIT: + if ( !BugDlg_Submit( hwnd ) ) + break; + // fall through + case IDCANCEL: + case IDC_CANCEL: + if ( g_connectedToApp && g_bug_bFirstCommand ) + { + ProcessCommand( "unpause" ); + } + EndDialog( hwnd, wParam ); + return ( TRUE ); + } + break; + } + return ( FALSE ); +} + +//----------------------------------------------------------------------------- +// BugDlg_SaveConfig +// +//----------------------------------------------------------------------------- +void BugDlg_SaveConfig() +{ + Sys_SetRegistryString( "bug_owner", g_bug_szOwner ); + Sys_SetRegistryString( "bug_severity", g_bug_szSeverity ); + Sys_SetRegistryString( "bug_reporttype", g_bug_szReportType ); + Sys_SetRegistryString( "bug_priority", g_bug_szPriority ); + Sys_SetRegistryInteger( "bug_gametype", g_bug_GameType ); +} + +//----------------------------------------------------------------------------- +// BugDlg_LoadConfig +// +//----------------------------------------------------------------------------- +void BugDlg_LoadConfig() +{ + // get our config + Sys_GetRegistryString( "bug_owner", g_bug_szOwner, "", sizeof( g_bug_szOwner ) ); + Sys_GetRegistryString( "bug_severity", g_bug_szSeverity, "", sizeof( g_bug_szSeverity ) ); + Sys_GetRegistryString( "bug_reporttype", g_bug_szReportType, "", sizeof( g_bug_szReportType ) ); + Sys_GetRegistryString( "bug_priority", g_bug_szPriority, "", sizeof( g_bug_szPriority ) ); + Sys_GetRegistryInteger( "bug_gametype", 0, g_bug_GameType ); + + // start with expected reporter + BugReporter_SelectReporter( g_Games[g_bug_GameType].pGameName ); +} + +//----------------------------------------------------------------------------- +// BugDlg_Open +// +//----------------------------------------------------------------------------- +void BugDlg_Open( void ) +{ + int result; + + // need access to bug databases via DLLs + if ( !BugReporter_GetInterfaces() ) + { + return; + } + + BugDlg_LoadConfig(); + + result = DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_BUG ), g_hDlgMain, ( DLGPROC )BugDlg_Proc ); + if ( LOWORD( result ) == IDC_BUG_SUBMIT ) + { + BugDlg_SaveConfig(); + } + + g_bug_hWnd = NULL; +} + +//----------------------------------------------------------------------------- +// BugDlg_Init +// +//----------------------------------------------------------------------------- +bool BugDlg_Init() +{ + return true; +} + +//----------------------------------------------------------------------------- +// rc_MapInfo +// +// Sent from application with bug dialog info +//----------------------------------------------------------------------------- +int rc_MapInfo( char* commandPtr ) +{ + char* cmdToken; + int errCode; + int infoAddr; + int retVal; + int retAddr; + char buff[128]; + + // success + errCode = 0; + + // get address of data + cmdToken = GetToken( &commandPtr ); + if ( !cmdToken[0] ) + goto cleanUp; + sscanf( cmdToken, "%x", &infoAddr ); + + // get retAddr + cmdToken = GetToken( &commandPtr ); + if ( !cmdToken[0] ) + goto cleanUp; + sscanf( cmdToken, "%x", &retAddr ); + + // get the caller's info data + DmGetMemory( ( void* )infoAddr, sizeof( xrMapInfo_t ), &g_bug_mapInfo, NULL ); + + // swap the structure + BigFloat( &g_bug_mapInfo.position[0], &g_bug_mapInfo.position[0] ); + BigFloat( &g_bug_mapInfo.position[1], &g_bug_mapInfo.position[1] ); + BigFloat( &g_bug_mapInfo.position[2], &g_bug_mapInfo.position[2] ); + BigFloat( &g_bug_mapInfo.angle[0], &g_bug_mapInfo.angle[0] ); + BigFloat( &g_bug_mapInfo.angle[1], &g_bug_mapInfo.angle[1] ); + BigFloat( &g_bug_mapInfo.angle[2], &g_bug_mapInfo.angle[2] ); + g_bug_mapInfo.build = BigDWord( g_bug_mapInfo.build ); + g_bug_mapInfo.skill = BigDWord( g_bug_mapInfo.skill ); + + Sys_NormalizePath( g_bug_mapInfo.savePath, false ); + Sys_NormalizePath( g_bug_mapInfo.mapPath, false ); + + if ( g_bug_hWnd ) + { + if ( g_bug_mapInfo.mapPath[0] ) + { + Sys_StripPath( g_bug_mapInfo.mapPath, buff, sizeof( buff ) ); + SetDlgItemText( g_bug_hWnd, IDC_BUG_MAP_LABEL, buff ); + + if ( !g_Games[g_bug_GameType].bUsesSystem1 ) + { + char *pExtension = V_stristr( buff, ".bsp" ); + if ( pExtension ) + { + *pExtension = '\0'; + } + pExtension = V_stristr( buff, ".360" ); + if ( pExtension ) + { + *pExtension = '\0'; + } + V_strncpy( g_bug_szMapNumber, buff, sizeof( g_bug_szMapNumber ) ); + + int curSel = SendDlgItemMessage( g_bug_hWnd, IDC_BUG_MAPNUMBER, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)(LPCSTR)g_bug_szMapNumber ); + if ( curSel == CB_ERR ) + curSel = 0; + SendDlgItemMessage( g_bug_hWnd, IDC_BUG_MAPNUMBER, CB_SETCURSEL, curSel, 0 ); + } + + sprintf( buff, "%.2f %.2f %.2f", g_bug_mapInfo.position[0], g_bug_mapInfo.position[1], g_bug_mapInfo.position[2] ); + SetDlgItemText( g_bug_hWnd, IDC_BUG_POSITION_LABEL, buff ); + + sprintf( buff, "%.2f %.2f %.2f", g_bug_mapInfo.angle[0], g_bug_mapInfo.angle[1], g_bug_mapInfo.angle[2] ); + SetDlgItemText( g_bug_hWnd, IDC_BUG_ORIENTATION_LABEL, buff ); + } + else + { + SetDlgItemText( g_bug_hWnd, IDC_BUG_MAP_LABEL, "" ); + SetDlgItemText( g_bug_hWnd, IDC_BUG_POSITION_LABEL, "" ); + SetDlgItemText( g_bug_hWnd, IDC_BUG_ORIENTATION_LABEL, "" ); + } + + sprintf( buff, "%d", g_bug_mapInfo.build ); + SetDlgItemText( g_bug_hWnd, IDC_BUG_BUILD_LABEL, buff ); + + EnableWindow( GetDlgItem( g_bug_hWnd, IDC_BUG_SAVEGAME ), g_bug_mapInfo.savePath[0] != '\0' && g_bug_mapInfo.mapPath[0] != '\0' ); + EnableWindow( GetDlgItem( g_bug_hWnd, IDC_BUG_INCLUDEBSP ), g_bug_mapInfo.mapPath[0] != '\0' ); + } + + // return the result + retVal = 0; + int xboxRetVal = BigDWord( retVal ); + DmSetMemory( ( void* )retAddr, sizeof( int ), &xboxRetVal, NULL ); + + DebugCommand( "0x%8.8x = MapInfo( 0x%8.8x )\n", retVal, infoAddr ); + +cleanUp: + return errCode; +} + |