From 12ef22e52300f4926d381310a8336821d963ad4d Mon Sep 17 00:00:00 2001 From: Mark Cannon Date: Tue, 7 Apr 2009 08:50:18 +0000 Subject: [PATCH] Fixed unbuffered write regression in RageFileDriverDirect, removed PREFSMAN from InputHandlers, force LightsDriver_External to always load, various M-mod fixes. git-svn-id: https://openitg.svn.sourceforge.net/svnroot/openitg@600 83fadc84-e282-4d84-a09a-c4228d6ae7e5 --- changelog.txt | 9 +++++- src/GameCommand.cpp | 3 +- src/Player.cpp | 35 ++++++++++++++++++--- src/PlayerOptions.cpp | 14 +++++++++ src/RageFileDriverCrypt_ITG2.cpp | 3 -- src/RageFileDriverDirect.cpp | 49 ++++++++++++++++++++---------- src/RageFileDriverDirect.h | 4 +++ src/StepMania.cpp | 14 +++++---- src/ThemeManager.cpp | 12 ++++++++ src/arch/InputHandler/InputHandler_Iow.cpp | 6 ---- src/arch/arch.cpp | 9 +++--- 11 files changed, 115 insertions(+), 43 deletions(-) diff --git a/changelog.txt b/changelog.txt index 3db42214..08d310b4 100755 --- a/changelog.txt +++ b/changelog.txt @@ -7,10 +7,12 @@ OpenITG, beta 1 (almost done) -New LUA bindings: Song: "IsLong", "IsMarathon", "IsCustomSong", "GetGroupName", and "MusicLengthSeconds" RageUtil: "SecondsToMMSS", "SecondsToHHMMSS", "SecondsToMSSMsMs" + ThemeManager: "GetCurLanguage", "GetCurThemeName", "GetThemeNames" -New LUA global: "OPENITG_VERSION" - returns a 3-digit token for version information (xyy - x is build type, yy is version; also in Win32 "Properties") --New Screen: +-New Screens: + "ScreenAddSongs" - allows addition of game data through operator menu (temp. disabled) "ScreenPlayLights" - plays music, can run actors for cabinet/game lights -New InputHandler: "MK3" - controls the Andamiro MK3 and MK5 ISA boards, for the heck of it @@ -40,17 +42,22 @@ OpenITG, beta 1 (almost done) -Fixed cross-platform bugs: M-mods crashed on marathons M-mod code choked on some BPM gimmicks + M-mod code didn't adjust to songs or courses with hidden BPMs Crash when changing from Intense to Normal-only courses or vice versa "Disqualification" display showed for unjoined players on music rate Sensor reading problems with PIUIO Patched OGG songs circumvented Long/Marathon song limits No-timeout warning flood on custom song loading Crash on Edit-only songs (not a bug, but...) + Tentative fix for strange crashes on "theme" GameCommand -Misc. changes: + M-mods disqualify on songs with hidden BPMs + (because it makes it easier to select an easy modifier) Re-backported input debounce, except it works this time. :) Record service credits separately in MachineProfile and Coins.xml Load USB profile songs into memory, instead of onto the disk Complete crypto rewrite - should be much more flexible + LightsDriver_External always loaded, to prevent arcade I/O problems OpenITG, prebeta (November 25th, 2008) -------------------------------------- diff --git a/src/GameCommand.cpp b/src/GameCommand.cpp index 009fa187..4fdddd9c 100755 --- a/src/GameCommand.cpp +++ b/src/GameCommand.cpp @@ -741,7 +741,8 @@ void GameCommand::ApplySelf( const vector &vpns ) const if( m_sTheme != "" && m_sTheme != THEME->GetCurThemeName() ) { THEME->SwitchThemeAndLanguage( m_sTheme, THEME->GetCurLanguage() ); - SONGMAN->LoadGroupColors(); + SONGMAN->LoadGroupColors(); // XXX: is this necessary with ApplyGraphicOptions() set? + ApplyGraphicOptions(); } /* This demonstrates a non-trivial error in the LUA subsystem, diff --git a/src/Player.cpp b/src/Player.cpp index 70a8757e..d122a946 100755 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -194,12 +194,11 @@ void Player::Init( } // calculate M-mod speed here, so we can adjust properly on a per-song basis. - - // EXPERIMENTAL: derive this entirely off the display BPMs and don't use actual BPMs. - // if this works, we'll use it, but it could get messy. we'll see what happens... + // XXX: can we find a better location for this? if( GAMESTATE->m_pPlayerState[pn]->m_StoredPlayerOptions.m_fMaxScrollBPM != 0 ) { DisplayBpms bpms; + if( GAMESTATE->IsCourseMode() ) { ASSERT( GAMESTATE->m_pCurTrail[pn] ); @@ -211,9 +210,35 @@ void Player::Init( GAMESTATE->m_pCurSong->GetDisplayBpms( bpms ); } - // get the maximum listed value for the song or course - float fMaxBPM = bpms.GetMax(); + float fThrowAway, fMaxBPM = 0; + + if( !bpms.IsSecret() ) + { + // all BPMs are listed and available, so we can use the displayed BPMs. + // get the maximum listed value for the song or course + fMaxBPM = bpms.GetMax(); + } + else + { + // we can't rely on the displayed BPMs, so manually calculate. + if( GAMESTATE->IsCourseMode() ) + { + FOREACH_CONST( TrailEntry, GAMESTATE->m_pCurTrail[pn]->m_vEntries, e ) + { + float fMaxForEntry; + e->pSong->m_Timing.GetActualBPM( fThrowAway, fMaxForEntry ); + fMaxBPM = max( fMaxForEntry, fMaxBPM ); + } + } + else + { + GAMESTATE->m_pCurSong->m_Timing.GetActualBPM( fThrowAway, fMaxBPM ); + } + } + + ASSERT( fMaxBPM > 0 ); + // set an X-mod equal to Mnum / fMaxBPM (e.g. M600 with 150 becomes 4x) GAMESTATE->m_pPlayerState[pn]->m_StoredPlayerOptions.m_fScrollSpeed = ( GAMESTATE->m_pPlayerState[pn]->m_StoredPlayerOptions.m_fMaxScrollBPM / fMaxBPM ); } diff --git a/src/PlayerOptions.cpp b/src/PlayerOptions.cpp index 1ea46058..a65ced96 100755 --- a/src/PlayerOptions.cpp +++ b/src/PlayerOptions.cpp @@ -617,6 +617,20 @@ bool PlayerOptions::IsEasierForSongAndSteps( Song* pSong, Steps* pSteps ) // This makes songs with sparse notes easier. if( m_bTransforms[TRANSFORM_ECHO] ) return true; + + // M-mods make songs with indefinite BPMs easier because + // they ensure that the song has a scrollable speed. + if( m_fMaxScrollBPM != 0 ) + { + if( pSong->m_DisplayBPMType == Song::DISPLAY_RANDOM ) + return true; + + float fThrowAway, fMaxBPM; + pSong->m_Timing.GetActualBPM( fThrowAway, fMaxBPM ); + + if( fMaxBPM == 0 ) + return true; + } if( m_fCover ) return true; return false; diff --git a/src/RageFileDriverCrypt_ITG2.cpp b/src/RageFileDriverCrypt_ITG2.cpp index ab5a0c1b..550d84ad 100644 --- a/src/RageFileDriverCrypt_ITG2.cpp +++ b/src/RageFileDriverCrypt_ITG2.cpp @@ -255,9 +255,6 @@ int RageFileObjCrypt_ITG2::ReadInternal( void *buffer, size_t bytes ) delete[] crbuf; delete[] dcbuf; - if( bufsize > 96 ) - for( int i = 0; i < 2; i++ ); - return bytes; } diff --git a/src/RageFileDriverDirect.cpp b/src/RageFileDriverDirect.cpp index 3984a7d5..1f8108cc 100755 --- a/src/RageFileDriverDirect.cpp +++ b/src/RageFileDriverDirect.cpp @@ -22,6 +22,9 @@ REGISTER_FILE_DRIVER( Direct, "DIR" ); +// 64 KB buffer +static const unsigned int BUFFER_SIZE = 1024*64; + RageFileDriverDirect::RageFileDriverDirect( const CString &sRoot ): RageFileDriver( new DirectFilenameDB(sRoot) ) { @@ -304,32 +307,46 @@ static int RetriedWrite( int iFD, const void *pBuf, size_t iCount ) int RageFileObjDirect::FlushInternal() { - if( WriteFailed() ) + if( !m_sWriteBuf.size() ) + return 0; + + int iRet = RetriedWrite( m_iFD, m_sWriteBuf.data(), m_sWriteBuf.size() ); + if( iRet == -1 ) { - SetError( "previous write failed" ); - return -1; + LOG->Warn("Error writing %s: %s", this->m_sPath.c_str(), strerror(errno) ); + SetError( strerror(errno) ); } - return 0; + m_sWriteBuf.erase(); + m_sWriteBuf.reserve( BUFFER_SIZE ); + return iRet; } int RageFileObjDirect::WriteInternal( const void *pBuf, size_t iBytes ) { - if( WriteFailed() ) + if( m_sWriteBuf.size()+iBytes > BUFFER_SIZE ) { - SetError( "previous write failed" ); - return -1; - } + if( Flush() == -1 ) + return -1; - /* The buffer is cleared. If we still don't have space, it's bigger than - * the buffer size, so just write it directly. */ - int iRet = RetriedWrite( m_iFD, pBuf, iBytes ); - if( iRet == -1 ) - { - SetError( strerror(errno) ); - m_bWriteFailed = true; - return -1; + ASSERT( !m_sWriteBuf.size() ); + + /* The buffer is cleared. If we still don't have space, it's bigger than + * the buffer size, so just write it directly. */ + if( iBytes >= BUFFER_SIZE ) + { + int iRet = RetriedWrite( m_iFD, pBuf, iBytes ); + if( iRet == -1 ) + { + LOG->Warn("Error writing %s: %s", this->m_sPath.c_str(), strerror(errno) ); + SetError( strerror(errno) ); + return -1; + } + return iBytes; + } } + + m_sWriteBuf.append( (const char *) pBuf, (const char *) pBuf+iBytes ); return iBytes; } diff --git a/src/RageFileDriverDirect.h b/src/RageFileDriverDirect.h index d9370aa0..4b536ec2 100755 --- a/src/RageFileDriverDirect.h +++ b/src/RageFileDriverDirect.h @@ -28,8 +28,12 @@ public: protected: int m_iFD; int m_iMode; + CString m_sPath; /* for Copy */ + /* TODO: finish backporting from SM4 so we can buffer with RageFileBasic. */ + CString m_sWriteBuf; + private: bool FinalFlush(); diff --git a/src/StepMania.cpp b/src/StepMania.cpp index d330fadf..6344c9e4 100755 --- a/src/StepMania.cpp +++ b/src/StepMania.cpp @@ -69,7 +69,9 @@ #include "MessageManager.h" #include "StatsManager.h" #include "TournamentManager.h" -#include "io/ITGIO.h" // for I/O error reporting + +// XXX: for I/O error reports +#include "io/ITGIO.h" #if defined(XBOX) #include "Archutils/Xbox/VirtualMemory.h" @@ -1597,7 +1599,6 @@ static void CheckSkips( float fDeltaTime ) static void GameLoop() { RageTimer timer; - CString sLastInputError; while(!g_bQuitting) { @@ -1606,12 +1607,13 @@ static void GameLoop() * Update */ - /* XXX: sLastInputError factors into this, but I'm too - * tired to figure it out at this point in time. -- Vyhd */ - if( ITGIO::m_sInputError != "" ) + // XXX: the Iow InputHandler acts as a singleton removed from + // the game loop. It needs an external error monitor because + // it waits until reconnecting to continue...can we improve this? + if( !ITGIO::m_sInputError.empty() ) { SCREENMAN->SystemMessage( ITGIO::m_sInputError ); - ITGIO::m_sInputError = ""; + ITGIO::m_sInputError.clear(); } float fDeltaTime = timer.GetDeltaTime(); diff --git a/src/ThemeManager.cpp b/src/ThemeManager.cpp index e8f00903..97f6ac64 100755 --- a/src/ThemeManager.cpp +++ b/src/ThemeManager.cpp @@ -955,11 +955,23 @@ public: static int GetMetric( T* p, lua_State *L ) { lua_pushstring(L, p->GetMetric(SArg(1),SArg(2)) ); return 1; } static int GetPath( T* p, lua_State *L ) { lua_pushstring(L, p->GetPath((ElementCategory)IArg(1),SArg(2),SArg(3)) ); return 1; } + static int GetCurLanguage( T* p, lua_State *L ) { lua_pushstring(L, p->GetCurLanguage()); return 1; } + static int GetCurThemeName( T* p, lua_State *L ) { lua_pushstring(L, p->GetCurThemeName()); return 1; } + static int GetThemeNames( T* p, lua_State *L ) + { + vector sNames; + p->GetThemeNames( sNames ); + LuaHelpers::CreateTableFromArray( sNames, L ); + return 1; + } static void Register(lua_State *L) { ADD_METHOD( GetMetric ) ADD_METHOD( GetPath ) + ADD_METHOD( GetCurThemeName ) + ADD_METHOD( GetCurLanguage ) + ADD_METHOD( GetThemeNames ) Luna::Register( L ); diff --git a/src/arch/InputHandler/InputHandler_Iow.cpp b/src/arch/InputHandler/InputHandler_Iow.cpp index 0f9539e0..ab340505 100644 --- a/src/arch/InputHandler/InputHandler_Iow.cpp +++ b/src/arch/InputHandler/InputHandler_Iow.cpp @@ -2,8 +2,6 @@ #include "RageLog.h" #include "RageUtil.h" #include "DiagnosticsUtil.h" - -#include "PrefsManager.h" // for m_bDebugUSBInput #include "LightsManager.h" #include "arch/Lights/LightsDriver_External.h" @@ -33,10 +31,6 @@ InputHandler_Iow::InputHandler_Iow() LOG->Trace( "Opened ITGIO board." ); m_bFoundDevice = true; - /* warn if "ext" isn't enabled */ - if( PREFSMAN->GetLightsDriver().Find("ext") == -1 ) - LOG->Warn( "\"ext\" is not an enabled LightsDriver. The I/O board cannot run lights." ); - // set any alternate lights mappings, if they exist SetLightsMappings(); diff --git a/src/arch/arch.cpp b/src/arch/arch.cpp index fc02078c..d444f9c8 100755 --- a/src/arch/arch.cpp +++ b/src/arch/arch.cpp @@ -84,10 +84,6 @@ void MakeLightsDrivers(CString drivers, vector &Add) LOG->Trace( "Initializing lights driver: %s", s->c_str() ); LightsDriver *ret = NULL; -#ifdef USE_LIGHTS_DRIVER_EXTERNAL - if( !s->CompareNoCase("Ext") ) - ret = new LightsDriver_External; -#endif #ifdef USE_LIGHTS_DRIVER_PACDRIVE if( !s->CompareNoCase("PacDrive") ) ret = new LightsDriver_PacDrive; @@ -115,8 +111,11 @@ void MakeLightsDrivers(CString drivers, vector &Add) Add.push_back( ret ); } - // always add system message + // always add system message, for lights debug Add.push_back( new LightsDriver_SystemMessage ); + + // always add ext, so we never need to worry about I/O lights not working + Add.push_back( new LightsDriver_External ); } #include "LoadingWindow/Selector_LoadingWindow.h" -- 2.11.0