speed up editor beat bar drawing (frame rate is not 3x as fast!)

fixed inaccurate 2k/xp video card detection
This commit is contained in:
Chris Danford
2003-02-22 00:22:27 +00:00
parent 5a4d403daf
commit 294144575c
13 changed files with 149 additions and 165 deletions
Binary file not shown.
Binary file not shown.
+3 -3
View File
@@ -144,11 +144,11 @@ void Actor::BeginDraw() // set the world matrix and calculate actor properties
DISPLAY->Scale( m_temp.scale.x, m_temp.scale.y, m_temp.scale.z ); DISPLAY->Scale( m_temp.scale.x, m_temp.scale.y, m_temp.scale.z );
// if( m_temp.rotation.x != 0 ) if( m_temp.rotation.x != 0 )
DISPLAY->RotateX( m_temp.rotation.x ); DISPLAY->RotateX( m_temp.rotation.x );
// if( m_temp.rotation.y != 0 ) if( m_temp.rotation.y != 0 )
DISPLAY->RotateY( m_temp.rotation.y ); DISPLAY->RotateY( m_temp.rotation.y );
// if( m_temp.rotation.z != 0 ) if( m_temp.rotation.z != 0 )
DISPLAY->RotateZ( m_temp.rotation.z ); DISPLAY->RotateZ( m_temp.rotation.z );
} }
+29 -33
View File
@@ -38,6 +38,9 @@ NoteField::NoteField()
m_rectMarkerBar.TurnShadowOff(); m_rectMarkerBar.TurnShadowOff();
m_rectMarkerBar.SetEffectDiffuseShift( 2, RageColor(1,1,1,0.5f), RageColor(0.5f,0.5f,0.5f,0.5f) ); m_rectMarkerBar.SetEffectDiffuseShift( 2, RageColor(1,1,1,0.5f), RageColor(0.5f,0.5f,0.5f,0.5f) );
m_sprBars.Load( THEME->GetPathTo("Graphics","edit bars") );
m_sprBars.StopAnimating();
m_fBeginMarker = m_fEndMarker = -1; m_fBeginMarker = m_fEndMarker = -1;
m_fPercentFadeToFail = -1; m_fPercentFadeToFail = -1;
@@ -91,48 +94,41 @@ void NoteField::DrawBeatBar( const float fBeat )
NoteType nt = BeatToNoteType( fBeat ); NoteType nt = BeatToNoteType( fBeat );
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat ); const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
float fAlpha;
int iState;
RageVertex v[4]; // upper-left, upper-right, lower-right, lower-left if( bIsMeasure )
memset( v, 0, sizeof(v) );
int iSegWidth;
int iSpaceWidth;
float fBrightness;
float fScrollSpeed = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fScrollSpeed;
switch( nt )
{ {
default: ASSERT(0); fAlpha = 1;
case NOTE_TYPE_4TH: iSegWidth = 16; iSpaceWidth = 0; fBrightness = 1; break; iState = 0;
case NOTE_TYPE_8TH: iSegWidth = 12; iSpaceWidth = 4; fBrightness = SCALE(fScrollSpeed,1.f,2.f,0.f,1.f); break; }
case NOTE_TYPE_16TH:iSegWidth = 4; iSpaceWidth = 4; fBrightness = SCALE(fScrollSpeed,2.f,4.f,0.f,1.f); break; else
{
float fScrollSpeed = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fScrollSpeed;
switch( nt )
{
default: ASSERT(0);
case NOTE_TYPE_4TH: fAlpha = 1; iState = 1; break;
case NOTE_TYPE_8TH: fAlpha = SCALE(fScrollSpeed,1.f,2.f,0.f,1.f); iState = 2; break;
case NOTE_TYPE_16TH:fAlpha = SCALE(fScrollSpeed,2.f,4.f,0.f,1.f); iState = 3; break;
}
CLAMP( fAlpha, 0, 1 );
} }
CLAMP( fBrightness, 0, 1 );
DISPLAY->SetTexture( NULL );
DISPLAY->SetTextureModeModulate();
DISPLAY->SetBlendModeNormal();
float fWidth = GetWidth(); float fWidth = GetWidth();
for( float f=-fWidth/2; f<+fWidth/2; ) float fFrameWidth = m_sprBars.GetUnzoomedWidth();
{
v[0].c = v[1].c = v[2].c = v[3].c = RageColor(1,1,1,0.5f*fBrightness);
float fLeft = f; m_sprBars.SetX( 0 );
float fRight = f+iSegWidth; m_sprBars.SetY( fYPos );
float fHeight = bIsMeasure ? 6.f : 3.f; m_sprBars.SetDiffuse( RageColor(1,1,1,fAlpha) );
v[0].p = RageVector3( fLeft, fYPos-fHeight/2, 0 ); // upper-left m_sprBars.SetState( iState );
v[1].p = RageVector3( fRight, fYPos-fHeight/2, 0 ); // upper-right m_sprBars.SetCustomTextureRect( RectF(0,SCALE(iState,0.f,4.f,0.f,1.f), fWidth/fFrameWidth, SCALE(iState+1,0.f,4.f,0.f,1.f)) );
v[2].p = RageVector3( fRight, fYPos+fHeight/2, 0 ); // lower-right m_sprBars.SetZoomX( fWidth/m_sprBars.GetUnzoomedWidth() );
v[3].p = RageVector3( fLeft, fYPos+fHeight/2, 0 ); // lower-left m_sprBars.Draw();
DISPLAY->DrawQuad( v );
f += iSegWidth + iSpaceWidth;
}
if( bIsMeasure ) if( bIsMeasure )
{ {
+1
View File
@@ -60,6 +60,7 @@ protected:
NoteDisplay m_NoteDisplay[MAX_NOTE_TRACKS]; NoteDisplay m_NoteDisplay[MAX_NOTE_TRACKS];
// used in MODE_EDIT // used in MODE_EDIT
Sprite m_sprBars; // 4 frames: Measure, 4th, 8th, 16th
BitmapText m_textMeasureNumber; BitmapText m_textMeasureNumber;
Quad m_rectMarkerBar; Quad m_rectMarkerBar;
Quad m_rectAreaHighlight; Quad m_rectAreaHighlight;
+5
View File
@@ -102,6 +102,8 @@ PrefsManager::PrefsManager()
m_sSoundDrivers = DEFAULT_SOUND_DRIVER_LIST; m_sSoundDrivers = DEFAULT_SOUND_DRIVER_LIST;
m_fSoundVolume = DEFAULT_SOUND_VOLUME; m_fSoundVolume = DEFAULT_SOUND_VOLUME;
m_bAllowSoftwareRenderer = false;
m_sDefaultNoteSkin = "default"; m_sDefaultNoteSkin = "default";
ReadGlobalPrefsFromDisk( true ); ReadGlobalPrefsFromDisk( true );
@@ -173,6 +175,7 @@ void PrefsManager::ReadGlobalPrefsFromDisk( bool bSwitchToLastPlayedGame )
ini.GetValueF( "Options", "MarathonVerSeconds", m_fMarathonVerSongSeconds ); ini.GetValueF( "Options", "MarathonVerSeconds", m_fMarathonVerSongSeconds );
ini.GetValueB( "Options", "ShowSongOptions", m_bShowSongOptions ); ini.GetValueB( "Options", "ShowSongOptions", m_bShowSongOptions );
ini.GetValueI( "Options", "DefaultFailType", (int&)m_DefaultFailType ); ini.GetValueI( "Options", "DefaultFailType", (int&)m_DefaultFailType );
ini.GetValueB( "Options", "bAllowSoftwareRenderer", m_bAllowSoftwareRenderer );
ini.GetValueB( "Options", "DDRExtremeDifficultySelect", m_bDDRExtremeDifficultySelect ); ini.GetValueB( "Options", "DDRExtremeDifficultySelect", m_bDDRExtremeDifficultySelect );
@@ -247,8 +250,10 @@ void PrefsManager::SaveGlobalPrefsToDisk()
ini.SetValueF( "Options", "MarathonVerSeconds", m_fMarathonVerSongSeconds ); ini.SetValueF( "Options", "MarathonVerSeconds", m_fMarathonVerSongSeconds );
ini.SetValueB( "Options", "ShowSongOptions", m_bShowSongOptions ); ini.SetValueB( "Options", "ShowSongOptions", m_bShowSongOptions );
ini.SetValueI( "Options", "DefaultFailType", (int&)m_DefaultFailType ); ini.SetValueI( "Options", "DefaultFailType", (int&)m_DefaultFailType );
ini.SetValueB( "Options", "bAllowSoftwareRenderer", m_bAllowSoftwareRenderer );
ini.SetValueB( "Options", "DDRExtremeDifficultySelect", m_bDDRExtremeDifficultySelect ); ini.SetValueB( "Options", "DDRExtremeDifficultySelect", m_bDDRExtremeDifficultySelect );
/* Only write these if they aren't the default. This ensures that we can change /* Only write these if they aren't the default. This ensures that we can change
* the default and have it take effect for everyone (except people who * the default and have it take effect for everyone (except people who
* tweaked this value). */ * tweaked this value). */
+1
View File
@@ -82,6 +82,7 @@ public:
CString m_sSoundDrivers; CString m_sSoundDrivers;
float m_fSoundVolume; float m_fSoundVolume;
bool m_bAllowSoftwareRenderer;
/* Game-specific prefs: */ /* Game-specific prefs: */
CString m_sDefaultNoteSkin; CString m_sDefaultNoteSkin;
+8 -29
View File
@@ -338,18 +338,8 @@ void ScreenEdit::Update( float fDeltaTime )
GAMESTATE->m_PlayerOptions[PLAYER_1].m_fScrollSpeed += fToMove; GAMESTATE->m_PlayerOptions[PLAYER_1].m_fScrollSpeed += fToMove;
} }
if(m_soundMusic.IsPlaying())
float fPositionSeconds = m_soundMusic.GetPositionSeconds(); GAMESTATE->UpdateSongPosition(m_soundMusic.GetPositionSeconds());
float fSongBeat, fBPS;
bool bFreeze;
m_pSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS, bFreeze );
// update the global music statistics for other classes to access
GAMESTATE->m_fMusicSeconds = fPositionSeconds;
GAMESTATE->m_fCurBPS = fBPS;
GAMESTATE->m_bFreeze = bFreeze;
if( m_EditMode == MODE_RECORDING ) if( m_EditMode == MODE_RECORDING )
{ {
@@ -381,7 +371,7 @@ void ScreenEdit::Update( float fDeltaTime )
if( m_EditMode == MODE_RECORDING || m_EditMode == MODE_PLAYING ) if( m_EditMode == MODE_RECORDING || m_EditMode == MODE_PLAYING )
{ {
GAMESTATE->m_fSongBeat = fSongBeat; // GAMESTATE->m_fSongBeat = fSongBeat;
if( GAMESTATE->m_fSongBeat > m_NoteFieldEdit.m_fEndMarker + 4 ) // give a one measure lead out if( GAMESTATE->m_fSongBeat > m_NoteFieldEdit.m_fEndMarker + 4 ) // give a one measure lead out
{ {
@@ -624,7 +614,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
m_fDestinationScrollSpeed = 2; m_fDestinationScrollSpeed = 2;
m_soundMarker.Play(); m_soundMarker.Play();
} }
else // if( m_fDestinationScrollSpeed == 2 ) else if( m_fDestinationScrollSpeed == 2 )
{ {
m_fDestinationScrollSpeed = 1; m_fDestinationScrollSpeed = 1;
m_soundMarker.Play(); m_soundMarker.Play();
@@ -638,7 +628,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
m_fDestinationScrollSpeed = 4; m_fDestinationScrollSpeed = 4;
m_soundMarker.Play(); m_soundMarker.Play();
} }
else //if( m_fDestinationScrollSpeed == 1 ) else if( m_fDestinationScrollSpeed == 1 )
{ {
m_fDestinationScrollSpeed = 2; m_fDestinationScrollSpeed = 2;
m_soundMarker.Play(); m_soundMarker.Play();
@@ -753,20 +743,8 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
} }
else // both markers are laid else // both markers are laid
{ {
if( GAMESTATE->m_fSongBeat == m_NoteFieldEdit.m_fBeginMarker ) m_NoteFieldEdit.m_fBeginMarker = GAMESTATE->m_fSongBeat;
{ m_NoteFieldEdit.m_fEndMarker = -1;
m_NoteFieldEdit.m_fBeginMarker = m_NoteFieldEdit.m_fEndMarker;
m_NoteFieldEdit.m_fEndMarker = -1;
}
else if( GAMESTATE->m_fSongBeat == m_NoteFieldEdit.m_fEndMarker )
{
m_NoteFieldEdit.m_fEndMarker = -1;
}
else
{
m_NoteFieldEdit.m_fBeginMarker = GAMESTATE->m_fSongBeat;
m_NoteFieldEdit.m_fEndMarker = -1;
}
} }
m_soundMarker.Play(); m_soundMarker.Play();
break; break;
@@ -1294,6 +1272,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
case quick: NoteDataUtil::Quick( m_Clipboard ); break; case quick: NoteDataUtil::Quick( m_Clipboard ); break;
case left: NoteDataUtil::Turn( m_Clipboard, NoteDataUtil::left ); break; case left: NoteDataUtil::Turn( m_Clipboard, NoteDataUtil::left ); break;
case right: NoteDataUtil::Turn( m_Clipboard, NoteDataUtil::right ); break; case right: NoteDataUtil::Turn( m_Clipboard, NoteDataUtil::right ); break;
case mirror: NoteDataUtil::Turn( m_Clipboard, NoteDataUtil::mirror ); break;
case shuffle: NoteDataUtil::Turn( m_Clipboard, NoteDataUtil::shuffle ); break; case shuffle: NoteDataUtil::Turn( m_Clipboard, NoteDataUtil::shuffle ); break;
case super_shuffle: NoteDataUtil::Turn( m_Clipboard, NoteDataUtil::super_shuffle ); break; case super_shuffle: NoteDataUtil::Turn( m_Clipboard, NoteDataUtil::super_shuffle ); break;
case backwards: NoteDataUtil::Backwards( m_Clipboard ); break; case backwards: NoteDataUtil::Backwards( m_Clipboard ); break;
+4 -11
View File
@@ -660,15 +660,9 @@ bool ScreenGameplay::IsTimeToPlayTicks() const
// Sound cards have a latency between when a sample is Play()ed and when the sound // Sound cards have a latency between when a sample is Play()ed and when the sound
// will start coming out the speaker. Compensate for this by boosting // will start coming out the speaker. Compensate for this by boosting
// fPositionSeconds ahead // fPositionSeconds ahead
if( GAMESTATE->m_SongOptions.m_AssistType != SongOptions::ASSIST_TICK )
return false;
float fPositionSeconds = GAMESTATE->m_fMusicSeconds; float fPositionSeconds = GAMESTATE->m_fMusicSeconds;
// HACK: Play the sound a little bit early to account for the fact that the middle of the tick sounds occurs 0.015 seconds into playing.
fPositionSeconds += (SOUNDMAN->GetPlayLatency()+g_fTickEarlySecondsCache) * m_soundMusic.GetPlaybackRate(); fPositionSeconds += (SOUNDMAN->GetPlayLatency()+g_fTickEarlySecondsCache) * m_soundMusic.GetPlaybackRate();
float fSongBeat=GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds ); float fSongBeat = GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds );
int iRowNow = BeatToNoteRowNotRounded( fSongBeat ); int iRowNow = BeatToNoteRowNotRounded( fSongBeat );
iRowNow = max( 0, iRowNow ); iRowNow = max( 0, iRowNow );
@@ -701,7 +695,6 @@ void ScreenGameplay::Update( float fDeltaTime )
* If you don't do this first, the classes are all acting on old * If you don't do this first, the classes are all acting on old
* information and will lag. -Chris */ * information and will lag. -Chris */
// update the global music statistics for other classes to access
/* If ScreenJukebox is changing screens, it'll stop m_soundMusic to tell /* If ScreenJukebox is changing screens, it'll stop m_soundMusic to tell
* us not to update the time here. (In that case, we've already created * us not to update the time here. (In that case, we've already created
* a new ScreenJukebox and reset music statistics, and if we do this then * a new ScreenJukebox and reset music statistics, and if we do this then
@@ -709,7 +702,6 @@ void ScreenGameplay::Update( float fDeltaTime )
if(m_soundMusic.IsPlaying()) if(m_soundMusic.IsPlaying())
GAMESTATE->UpdateSongPosition(m_soundMusic.GetPositionSeconds()); GAMESTATE->UpdateSongPosition(m_soundMusic.GetPositionSeconds());
Screen::Update( fDeltaTime ); Screen::Update( fDeltaTime );
@@ -850,8 +842,9 @@ void ScreenGameplay::Update( float fDeltaTime )
m_iRowLastCrossed = iRowNow; m_iRowLastCrossed = iRowNow;
} }
if(IsTimeToPlayTicks()) if( GAMESTATE->m_SongOptions.m_AssistType == SongOptions::ASSIST_TICK )
m_soundAssistTick.Play(); if( IsTimeToPlayTicks() )
m_soundAssistTick.Play();
} }
-2
View File
@@ -107,7 +107,6 @@ void ScreenSongOptions::ExportOptions()
void ScreenSongOptions::GoToPrevState() void ScreenSongOptions::GoToPrevState()
{ {
SOUNDMAN->StopMusic();
if( GAMESTATE->m_bEditing ) if( GAMESTATE->m_bEditing )
SCREENMAN->PopTopScreen( SM_None ); SCREENMAN->PopTopScreen( SM_None );
else else
@@ -116,7 +115,6 @@ void ScreenSongOptions::GoToPrevState()
void ScreenSongOptions::GoToNextState() void ScreenSongOptions::GoToNextState()
{ {
SOUNDMAN->StopMusic();
if( GAMESTATE->m_bEditing ) if( GAMESTATE->m_bEditing )
SCREENMAN->PopTopScreen(); SCREENMAN->PopTopScreen();
else else
+20 -21
View File
@@ -138,33 +138,32 @@ BEGIN
CTEXT "line3",IDC_STATIC_MESSAGE3,0,65,310,10,SS_CENTERIMAGE CTEXT "line3",IDC_STATIC_MESSAGE3,0,65,310,10,SS_CENTERIMAGE
END END
IDD_DISASM_CRASH DIALOGEX 0, 0, 399, 286 IDD_DISASM_CRASH DIALOG DISCARDABLE 0, 0, 399, 271
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "StepMania Error" CAPTION "StepMania Error"
FONT 8, "MS Sans Serif", 0, 0, 0x1 FONT 8, "MS Sans Serif"
BEGIN BEGIN
DEFPUSHBUTTON "OK",IDOK,348,270,50,15 DEFPUSHBUTTON "Close",IDC_BUTTON_CLOSE,348,255,50,15
LISTBOX IDC_ASMBOX,7,58,279,100,LBS_OWNERDRAWVARIABLE | LTEXT "crash reason: programmer needs good whack on head",
IDC_STATIC_BOMBREASON,8,240,219,8
PUSHBUTTON "View Log",IDC_VIEW_LOG,1,255,70,15
PUSHBUTTON "View crash dump",IDC_CRASH_SAVE,75,255,70,15
PUSHBUTTON "Report the Error",IDC_BUTTON_REPORT,210,255,76,15
PUSHBUTTON "Restart",IDC_BUTTON_RESTART,348,238,50,15
CONTROL 121,IDC_STATIC,"Static",SS_BITMAP,1,2,396,36
LTEXT "StepMania has crashed due to a program error. Diagnostic information has been saved to a file called ""crashinfo.txt"" in the StepMania program directory. Hit ""View crash dump"" to view it. Please include this file in all bug reports.",
IDC_STATIC,8,41,382,19
LTEXT "Program disassembly",IDC_STATIC,7,64,66,8
LISTBOX IDC_ASMBOX,7,76,279,101,LBS_OWNERDRAWVARIABLE |
LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | LBS_NODATA | LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT | LBS_NODATA |
LBS_NOSEL | WS_VSCROLL | WS_TABSTOP LBS_NOSEL | WS_VSCROLL | WS_TABSTOP
LTEXT "crash reason: programmer needs good whack on head", LISTBOX IDC_CALL_STACK,7,196,279,38,LBS_NOINTEGRALHEIGHT |
IDC_STATIC_BOMBREASON,8,222,219,8 WS_VSCROLL | WS_TABSTOP
LISTBOX IDC_REGDUMP,291,58,101,158,NOT LBS_NOTIFY | LTEXT "CPU registers",IDC_STATIC,292,64,44,8
LISTBOX IDC_REGDUMP,291,76,101,158,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
WS_HSCROLL | WS_TABSTOP WS_HSCROLL | WS_TABSTOP
LTEXT "Program disassembly",IDC_STATIC,7,46,66,8 LTEXT "Estimated call stack",IDC_STATIC,7,184,64,8
LTEXT "CPU registers",IDC_STATIC,292,46,44,8
LTEXT "StepMania has crashed due to a program error. Diagnostic information has been saved to a file called ""crashinfo.txt"" in the StepMania program directory. Hit ""View crash dump"" to view it. Please include this file in all bug reports.",
IDC_STATIC,7,238,319,25
PUSHBUTTON "View crash dump",IDC_CRASH_SAVE,76,270,70,15
LISTBOX IDC_CALL_STACK,7,178,279,38,LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
LTEXT "Estimated call stack",IDC_STATIC,7,167,64,8
CONTROL 121,IDC_STATIC,"Static",SS_BITMAP,1,2,396,36
PUSHBUTTON "View Log",IDC_VIEW_LOG,1,270,70,15
PUSHBUTTON "Restart",IDC_BUTTON_RESTART,348,254,50,15
PUSHBUTTON "Report the Error",IDC_BUTTON_REPORT,207,270,76,15
PUSHBUTTON "Close",IDC_BUTTON_CLOSE,348,238,50,15
END END
@@ -189,7 +188,7 @@ BEGIN
LEFTMARGIN, 1 LEFTMARGIN, 1
RIGHTMARGIN, 398 RIGHTMARGIN, 398
VERTGUIDE, 286 VERTGUIDE, 286
BOTTOMMARGIN, 285 BOTTOMMARGIN, 270
END END
END END
#endif // APSTUDIO_INVOKED #endif // APSTUDIO_INVOKED
+1 -1
View File
@@ -325,7 +325,7 @@ int main(int argc, char* argv[])
BoostAppPri(); BoostAppPri();
ResetGame(); ResetGame();
if( DISPLAY->IsSoftwareRenderer() ) if( DISPLAY->IsSoftwareRenderer() && !PREFSMAN->m_bAllowSoftwareRenderer )
SCREENMAN->Prompt( SCREENMAN->Prompt(
SM_None, SM_None,
"OpenGL hardware acceleration\n" "OpenGL hardware acceleration\n"
+75 -63
View File
@@ -14,6 +14,17 @@ struct VideoDriverInfo
CString sDeviceID; CString sDeviceID;
}; };
void LogVideoDriverInfo( VideoDriverInfo info )
{
LOG->Info("Video Driver Information:");
LOG->Info("%-15s:\t%s", "Provider", info.sProvider.GetString());
LOG->Info("%-15s:\t%s", "Description", info.sDescription.GetString());
LOG->Info("%-15s:\t%s", "Version", info.sVersion.GetString());
LOG->Info("%-15s:\t%s", "Date", info.sDate.GetString());
LOG->Info("%-15s:\t%s", "DeviceID", info.sDeviceID.GetString());
}
CString GetRegValue( HKEY hKey, CString sName ) CString GetRegValue( HKEY hKey, CString sName )
{ {
char szBuffer[MAX_PATH]; char szBuffer[MAX_PATH];
@@ -24,10 +35,11 @@ CString GetRegValue( HKEY hKey, CString sName )
return ""; return "";
} }
bool GetDebugInfoWin9x( VideoDriverInfo& infoOut ) bool GetVideoDriverInfo9x( int iIndex, VideoDriverInfo& infoOut )
{ {
HKEY hkey; HKEY hkey;
if (RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Class\\Display\\0000", &hkey) != ERROR_SUCCESS) CString sKey = ssprintf("SYSTEM\\CurrentControlSet\\Services\\Class\\Display\\%04d",iIndex);
if (RegOpenKey(HKEY_LOCAL_MACHINE, sKey, &hkey) != ERROR_SUCCESS)
return false; return false;
infoOut.sDate = GetRegValue( hkey, "DriverDate"); infoOut.sDate = GetRegValue( hkey, "DriverDate");
@@ -41,10 +53,11 @@ bool GetDebugInfoWin9x( VideoDriverInfo& infoOut )
} }
bool GetDebugInfoWinNT( VideoDriverInfo& infoOut ) bool GetVideoDriverInfo2k( int iIndex, VideoDriverInfo& infoOut )
{ {
HKEY hkey; HKEY hkey;
if (RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000", &hkey) != ERROR_SUCCESS) CString sKey = ssprintf("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\%04d",iIndex);
if (RegOpenKey(HKEY_LOCAL_MACHINE, sKey, &hkey) != ERROR_SUCCESS)
return false; return false;
infoOut.sDate = GetRegValue( hkey, "DriverDate"); infoOut.sDate = GetRegValue( hkey, "DriverDate");
@@ -57,79 +70,78 @@ bool GetDebugInfoWinNT( VideoDriverInfo& infoOut )
return true; return true;
} }
void HandleKnownTerribleDriver( VideoDriverInfo info )
{
struct ProblemAndBookmark
{
char szProblemProvider[1024];
char szProblemDescription[1024];
char szReadMeBookmark[64];
};
ProblemAndBookmark ENTRIES[] =
{
// Hacked around the bug in the V3 driver. -Chris
// {"3dfx Interactive, Inc. (Optimized by Amigamerlin)", "Voodoo3 PCI", "Voodoo3"},
{"blah", "blah", "Voodoo3"},
};
const int NUM_ENTRIES = sizeof(ENTRIES) / sizeof(ENTRIES[0]);
for( int i=0; i<NUM_ENTRIES; i++ ) CString GetPrimaryVideoName9xAnd2k() // this will not work on 95 and NT b/c of EnumDisplayDevices
{
typedef BOOL (WINAPI* pfnEnumDisplayDevices)(PVOID,DWORD,PDISPLAY_DEVICE,DWORD);
pfnEnumDisplayDevices EnumDisplayDevices;
HINSTANCE hInstUser32;
hInstUser32 = LoadLibrary("User32.DLL");
if( !hInstUser32 )
return "";
// VC6 don't have a stub to static link with, so link dynamically.
EnumDisplayDevices = (pfnEnumDisplayDevices)GetProcAddress(hInstUser32,"EnumDisplayDevicesA");
if( EnumDisplayDevices == NULL )
{ {
if( info.sProvider == ENTRIES[i].szProblemProvider && FreeLibrary(hInstUser32);
info.sDescription == ENTRIES[i].szProblemDescription ) return "";
}
CString sPrimaryDeviceName;
for( DWORD i=0; true; i++ )
{
DISPLAY_DEVICE dd;
ZERO( dd );
dd.cb = sizeof(dd);
if( !EnumDisplayDevices(NULL, i, &dd, 0) )
break;
if( dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE )
{ {
CString sQuestion = ssprintf( sPrimaryDeviceName = (char*)dd.DeviceString;
"Video Driver Information:\n\n" break;
"Provider: %s\n"
"Description: %s\n"
"Version: %s\n"
"Date: %s\n"
"DeviceID: %s\n"
"\n"
"This video driver is known to have bugs that make StepMania unplayable.\n"
"Click OK to see information on where to find a newer driver.\n"
"Click Cancel to dismiss this warning and continue playing.",
info.sProvider.GetString(),
info.sDescription.GetString(),
info.sVersion.GetString(),
info.sDate.GetString(),
info.sDeviceID.GetString() );
if( IDOK == MessageBox(NULL, sQuestion, "Known problem driver", MB_ICONHAND|MB_OKCANCEL) )
{
char szBuffer[MAX_PATH];
GetCurrentDirectory( MAX_PATH, szBuffer );
GotoURL( ssprintf("%s/README-FIRST.html#%s", szBuffer, ENTRIES[i].szReadMeBookmark) );
exit(1); // Is there a better way to clean up? -Chris
}
else
return;
} }
} }
FreeLibrary(hInstUser32);
return sPrimaryDeviceName;
} }
static void GetDisplayDriverDebugInfo() static void GetDisplayDriverDebugInfo()
{ {
VideoDriverInfo info; CString sPrimaryDeviceName = GetPrimaryVideoName9xAnd2k();
if( GetDebugInfoWin9x(info) ) if( sPrimaryDeviceName == "" )
goto got_debug_info; LOG->Info( "Primary display driver could not be determined." );
if( GetDebugInfoWinNT(info) ) else
goto got_debug_info; LOG->Info( "Primary display driver: %s", sPrimaryDeviceName.GetString() );
LOG->Warn( "Failed to get video card driver info." ); OSVERSIONINFO version;
return; version.dwOSVersionInfoSize=sizeof(version);
GetVersionEx(&version);
bool bIsWin9x = version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS;
got_debug_info: for( int i=0; true; i++ )
{
VideoDriverInfo info;
if( ! (bIsWin9x ? GetVideoDriverInfo9x : GetVideoDriverInfo2k)(i,info) )
break;
LOG->Info("Video Driver Information:"); if( sPrimaryDeviceName == "" ) // failed to get primary disaply name (NT4)
LOG->Info("%-15s:\t%s", "Provider", info.sProvider.GetString()); {
LOG->Info("%-15s:\t%s", "Description", info.sDescription.GetString()); LogVideoDriverInfo( info );
LOG->Info("%-15s:\t%s", "Version", info.sVersion.GetString()); }
LOG->Info("%-15s:\t%s", "Date", info.sDate.GetString()); else if( info.sDescription == sPrimaryDeviceName )
LOG->Info("%-15s:\t%s", "DeviceID", info.sDeviceID.GetString()); {
LogVideoDriverInfo( info );
HandleKnownTerribleDriver( info ); break;
}
}
} }
static CString wo_ssprintf( MMRESULT err, const char *fmt, ...) static CString wo_ssprintf( MMRESULT err, const char *fmt, ...)