the various changes that I forgot to commit (cleanup and so forth) into hg,

culminating in syncing with sm-ssc v1.0 public beta 2
This commit is contained in:
AJ Kelly
2010-03-31 17:37:09 -05:00
parent b279635401
commit 642f4b107c
80 changed files with 1200 additions and 918 deletions
+46 -31
View File
@@ -2,7 +2,6 @@
; created by ; created by
; BBF, GlennMaynard, ChrisDanford ; BBF, GlennMaynard, ChrisDanford
; hacked by AJ for sm-ssc ; hacked by AJ for sm-ssc
; I use the following command to create the installer:
; NOTE: this .NSI script is designed for NSIS v2.0+ ; NOTE: this .NSI script is designed for NSIS v2.0+
;-------------------------------- ;--------------------------------
@@ -25,8 +24,8 @@
Name "${PRODUCT_DISPLAY}" Name "${PRODUCT_DISPLAY}"
OutFile "${PRODUCT_DISPLAY}.exe" OutFile "${PRODUCT_DISPLAY}.exe"
Caption "${PRODUCT_DISPLAY}" Caption "${PRODUCT_DISPLAY} | install"
UninstallCaption "${PRODUCT_DISPLAY}" UninstallCaption "${PRODUCT_DISPLAY} | uninstall"
; Some default compiler settings (uncomment and change at will): ; Some default compiler settings (uncomment and change at will):
!ifdef COMPRESS !ifdef COMPRESS
@@ -44,6 +43,7 @@
AutoCloseWindow true ; (can be true for the window go away automatically at end) AutoCloseWindow true ; (can be true for the window go away automatically at end)
; ShowInstDetails hide ; (can be show to have them shown, or nevershow to disable) ; ShowInstDetails hide ; (can be show to have them shown, or nevershow to disable)
SetDateSave on ; (can be on to have files restored to their orginal date) SetDateSave on ; (can be on to have files restored to their orginal date)
; may not be the best idea for vista/7? -aj
InstallDir "$PROGRAMFILES\${PRODUCT_ID}" InstallDir "$PROGRAMFILES\${PRODUCT_ID}"
InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\${PRODUCT_ID}" "" InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\${PRODUCT_ID}" ""
; DirShow show ; (make this hide to not let the user change it) ; DirShow show ; (make this hide to not let the user change it)
@@ -148,7 +148,8 @@
; generate, then include installer strings ; generate, then include installer strings
;!delfile "nsis_strings_temp.inc" ;!delfile "nsis_strings_temp.inc"
!system '"Program\${PRODUCT_FAMILY}.exe" --ExportNsisStrings' ; xxx: hardcoded to StepMania
!system '"Program\StepMania.exe" --ExportNsisStrings'
!include "nsis_strings_temp.inc" !include "nsis_strings_temp.inc"
;-------------------------------- ;--------------------------------
@@ -194,6 +195,11 @@ Section "Main Section" SecMain
; add registry entries ; add registry entries
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\${PRODUCT_ID}" "" "$INSTDIR" WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\${PRODUCT_ID}" "" "$INSTDIR"
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_ID}" "DisplayName" "$(TEXT_IO_REMOVE_ONLY)" WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_ID}" "DisplayName" "$(TEXT_IO_REMOVE_ONLY)"
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_ID}" "DisplayVersion" "$(PRODUCT_VER)"
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_ID}" "Comments" "sm-ssc is a rhythm game simulator (forked from StepMania)."
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_ID}" "Publisher" "the spinal shark collective"
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_ID}" "URLInfoAbout" "http://ssc.ajworld.net/sm-ssc/"
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_ID}" "URLUpdateInfo" "http://code.google.com/p/sm-ssc/"
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_ID}" "UninstallString" '"$INSTDIR\uninstall.exe"' WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_ID}" "UninstallString" '"$INSTDIR\uninstall.exe"'
!endif !endif
@@ -211,8 +217,8 @@ Section "Main Section" SecMain
!ifdef ASSOCIATE_SMZIP !ifdef ASSOCIATE_SMZIP
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Classes\smzipfile" "" "$(TEXT_IO_SMZIP_PACKAGE)" WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Classes\smzipfile" "" "$(TEXT_IO_SMZIP_PACKAGE)"
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Classes\smzipfile\DefaultIcon" "" "$INSTDIR\Program\${PRODUCT_FAMILY}.exe,1" WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Classes\smzipfile\DefaultIcon" "" "$INSTDIR\Program\StepMania.exe,1"
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Classes\smzipfile\shell\open\command" "" '"$INSTDIR\Program\${PRODUCT_FAMILY}.exe" "%1"' WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Classes\smzipfile\shell\open\command" "" '"$INSTDIR\Program\StepMania.exe" "%1"'
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Classes\.smzip" "" "smzipfile" WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Classes\.smzip" "" "smzipfile"
!endif !endif
@@ -232,9 +238,9 @@ Section "Main Section" SecMain
CreateDirectory "$INSTDIR\BackgroundTransitions" CreateDirectory "$INSTDIR\BackgroundTransitions"
File /r /x CVS /x .svn "BackgroundTransitions" File /r /x CVS /x .svn "BackgroundTransitions"
CreateDirectory "$INSTDIR\RandomMovies" ;CreateDirectory "$INSTDIR\RandomMovies"
SetOutPath "$INSTDIR\RandomMovies" ;SetOutPath "$INSTDIR\RandomMovies"
File "RandomMovies\instructions.txt" ;File "RandomMovies\instructions.txt"
; end background/movie related ; end background/movie related
; Nobody should be using this directory anymore. -aj ; Nobody should be using this directory anymore. -aj
@@ -251,10 +257,10 @@ Section "Main Section" SecMain
CreateDirectory "$INSTDIR\Courses" CreateDirectory "$INSTDIR\Courses"
SetOutPath "$INSTDIR\Courses" SetOutPath "$INSTDIR\Courses"
File "Courses\instructions.txt" File "Courses\instructions.txt"
File /r /x CVS /x .svn "Courses\Samples" File /r /x CVS /x .svn "Courses\Default"
CreateDirectory "$INSTDIR\Packages" CreateDirectory "$INSTDIR\Packages"
File "Packages\Instructions.txt" ;File "Packages\Instructions.txt"
; remove old noteskins ; remove old noteskins
RMDir /r "$INSTDIR\NoteSkins\common\default" RMDir /r "$INSTDIR\NoteSkins\common\default"
@@ -296,7 +302,7 @@ Section "Main Section" SecMain
; make songs dir ; make songs dir
CreateDirectory "$INSTDIR\Songs" CreateDirectory "$INSTDIR\Songs"
SetOutPath "$INSTDIR\Songs" SetOutPath "$INSTDIR\Songs"
File "Songs\Instructions.txt" ;File "Songs\Instructions.txt"
; remove and install themes ; remove and install themes
RMDir /r "$INSTDIR\Themes\_fallback" RMDir /r "$INSTDIR\Themes\_fallback"
@@ -304,7 +310,7 @@ Section "Main Section" SecMain
RMDir /r "$INSTDIR\Themes\default" RMDir /r "$INSTDIR\Themes\default"
CreateDirectory "$INSTDIR\Themes" CreateDirectory "$INSTDIR\Themes"
SetOutPath "$INSTDIR\Themes" SetOutPath "$INSTDIR\Themes"
File "Themes\instructions.txt" ;File "Themes\instructions.txt"
File /r /x CVS /x .svn "Themes\_fallback" File /r /x CVS /x .svn "Themes\_fallback"
File /r /x CVS /x .svn "Themes\_portKit-sm4" File /r /x CVS /x .svn "Themes\_portKit-sm4"
File /r /x CVS /x .svn "Themes\default" File /r /x CVS /x .svn "Themes\default"
@@ -322,15 +328,15 @@ Section "Main Section" SecMain
SetOutPath "$INSTDIR\Program" SetOutPath "$INSTDIR\Program"
!ifdef INSTALL_EXECUTABLES !ifdef INSTALL_EXECUTABLES
; normal exec ; normal exec (xxx: hardcoded to StepMania instead of ${PRODUCT_FAMILY})
File "Program\${PRODUCT_FAMILY}.exe" File "Program\StepMania.exe"
File "Program\${PRODUCT_FAMILY}.vdi" File "Program\StepMania.vdi"
; sse2 exec ; sse2 exec
File "Program\${PRODUCT_FAMILY}-SSE2.exe" File "Program\StepMania-SSE2.exe"
File "Program\${PRODUCT_FAMILY}-SSE2.vdi" File "Program\StepMania-SSE2.vdi"
; other programs ; other programs
File "Program\tools.exe"
File "Program\Texture Font Generator.exe" File "Program\Texture Font Generator.exe"
;File "Program\tools.exe" ; to be replaced
!endif !endif
!ifdef ASSOCIATE_SMZIP !ifdef ASSOCIATE_SMZIP
Call RefreshShellIcons Call RefreshShellIcons
@@ -358,10 +364,10 @@ Section "Main Section" SecMain
; documentation ; documentation
CreateDirectory "$INSTDIR\Docs" CreateDirectory "$INSTDIR\Docs"
SetOutPath "$INSTDIR\Docs" SetOutPath "$INSTDIR\Docs"
File "Licenses.txt" File "Docs\Licenses.txt"
File "credits.txt" File "Docs\credits.txt"
File "Changelog_sm-ssc.txt" File "Docs\Changelog_sm-ssc.txt"
File "CommandLineArgs.txt" File "Docs\CommandLineArgs.txt"
CreateDirectory "$INSTDIR\Manual" CreateDirectory "$INSTDIR\Manual"
SetOutPath "$INSTDIR\Manual" SetOutPath "$INSTDIR\Manual"
@@ -370,8 +376,10 @@ Section "Main Section" SecMain
; Create Start Menu icons ; Create Start Menu icons
SetShellVarContext current # 'all' doesn't work on Win9x SetShellVarContext current # 'all' doesn't work on Win9x
CreateDirectory "$SMPROGRAMS\${PRODUCT_ID}\" CreateDirectory "$SMPROGRAMS\${PRODUCT_ID}\"
CreateShortCut "$DESKTOP\$(TEXT_IO_RUN).lnk" "$INSTDIR\Program\${PRODUCT_FAMILY}.exe" ; xxx: StepMania.exe
CreateShortCut "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_RUN).lnk" "$INSTDIR\Program\${PRODUCT_FAMILY}.exe" ; xxx: make desktop shortcut an option
CreateShortCut "$DESKTOP\$(TEXT_IO_RUN).lnk" "$INSTDIR\Program\StepMania.exe"
CreateShortCut "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_RUN).lnk" "$INSTDIR\Program\StepMania.exe"
!ifdef MAKE_OPEN_PROGRAM_FOLDER_SHORTCUT !ifdef MAKE_OPEN_PROGRAM_FOLDER_SHORTCUT
CreateShortCut "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_OPEN_PROGRAM_FOLDER).lnk" "$WINDIR\explorer.exe" "$INSTDIR\" CreateShortCut "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_OPEN_PROGRAM_FOLDER).lnk" "$WINDIR\explorer.exe" "$INSTDIR\"
!endif !endif
@@ -384,7 +392,8 @@ Section "Main Section" SecMain
CreateShortCut "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_CHECK_FOR_UPDATES).lnk" "${UPDATES_URL}" CreateShortCut "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_CHECK_FOR_UPDATES).lnk" "${UPDATES_URL}"
!endif !endif
CreateShortCut "$INSTDIR\${PRODUCT_ID}.lnk" "$INSTDIR\Program\${PRODUCT_FAMILY}.exe" ; xxx: StepMania.exe
CreateShortCut "$INSTDIR\${PRODUCT_ID}.lnk" "$INSTDIR\Program\StepMania.exe"
!endif !endif
IfErrors do_error do_no_error IfErrors do_error do_no_error
@@ -459,7 +468,8 @@ Function LeaveAutorun
GoTo proceed GoTo proceed
play: play:
Exec "$INSTDIR\Program\${PRODUCT_FAMILY}.exe" ; xxx: StepMania.exe
Exec "$INSTDIR\Program\StepMania.exe"
IfErrors play_error IfErrors play_error
quit quit
@@ -543,7 +553,8 @@ Function PreInstall
!endif !endif
!else !else
; Check that full version is installed. ; Check that full version is installed.
IfFileExists "$INSTDIR\Program\${PRODUCT_FAMILY}.exe" proceed_with_patch ; xxx: StepMania.exe
IfFileExists "$INSTDIR\Program\StepMania.exe" proceed_with_patch
MessageBox MB_YESNO|MB_ICONINFORMATION "$(TEXT_IO_FULL_INSTALL_NOT_FOUND)" IDYES proceed_with_patch MessageBox MB_YESNO|MB_ICONINFORMATION "$(TEXT_IO_FULL_INSTALL_NOT_FOUND)" IDYES proceed_with_patch
Abort Abort
proceed_with_patch: proceed_with_patch:
@@ -582,6 +593,7 @@ FunctionEnd
;-------------------------------- ;--------------------------------
;Uninstaller Section ;Uninstaller Section
; todo: update big time
Section "Uninstall" Section "Uninstall"
@@ -619,7 +631,7 @@ Section "Uninstall"
RMDir "$INSTDIR\Packages" RMDir "$INSTDIR\Packages"
Delete "$INSTDIR\Courses\instructions.txt" Delete "$INSTDIR\Courses\instructions.txt"
RMDir /r "$INSTDIR\Courses\Samples" RMDir /r "$INSTDIR\Courses\Default"
RMDir "$INSTDIR\Courses" RMDir "$INSTDIR\Courses"
Delete "$INSTDIR\NoteSkins\instructions.txt" Delete "$INSTDIR\NoteSkins\instructions.txt"
@@ -657,8 +669,11 @@ Section "Uninstall"
!endif !endif
!ifdef INSTALL_EXECUTABLES !ifdef INSTALL_EXECUTABLES
Delete "$INSTDIR\Program\${PRODUCT_FAMILY}.exe" ; xxx: StepMania.exe
Delete "$INSTDIR\Program\${PRODUCT_FAMILY}.vdi" Delete "$INSTDIR\Program\StepMania.exe"
Delete "$INSTDIR\Program\StepMania.vdi"
Delete "$INSTDIR\Program\StepMania-SSE2.exe"
Delete "$INSTDIR\Program\StepMania-SSE2.vdi"
Delete "$INSTDIR\Program\tools.exe" Delete "$INSTDIR\Program\tools.exe"
Delete "$INSTDIR\Program\Texture Font Generator.exe" Delete "$INSTDIR\Program\Texture Font Generator.exe"
!endif !endif
-2
View File
@@ -21,9 +21,7 @@ public:
Actor *GetTarget() { return m_pActorTarget; } Actor *GetTarget() { return m_pActorTarget; }
void SetTarget( Actor *pTarget ) { m_pActorTarget = pTarget; } void SetTarget( Actor *pTarget ) { m_pActorTarget = pTarget; }
//
// Lua // Lua
//
virtual void PushSelf( lua_State *L ); virtual void PushSelf( lua_State *L );
private: private:
+29 -30
View File
@@ -54,23 +54,19 @@ void ArrowEffects::Update()
const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pn]; const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pn];
PerPlayerData &data = g_EffectData[pn]; PerPlayerData &data = g_EffectData[pn];
//
// Update Tornado // Update Tornado
//
for( int iColNum = 0; iColNum < MAX_COLS_PER_PLAYER; ++iColNum ) for( int iColNum = 0; iColNum < MAX_COLS_PER_PLAYER; ++iColNum )
{ {
// TRICKY: Tornado is very unplayable in doubles, so use a smaller // TRICKY: Tornado is very unplayable in doubles, so use a smaller
// tornado width if there are many columns // tornado width if there are many columns
/* /* the below makes an assumption for dance mode.
* the above makes an assumption for dance mode. * perhaps check if we are actually playing on singles without,
* perhaps check if we are actually playing on singles without, say * say more than 6 columns. That would exclude IIDX, pop'n, and
* more than 6 columns. That would exclude IIDX, pop'n, and * techno-8, all of which would be very hectic.
* techno-8, all of which would be clusterfucks. * certain non-singles modes (like halfdoubles 6cols)
* certain non-singles modes like halfdoubles (6cols),
* could possibly have tornado enabled. * could possibly have tornado enabled.
* let's also take default resolution (640x480) into mind. -aj * let's also take default resolution (640x480) into mind. -aj */
*/
bool bWideField = pStyle->m_iColsPerPlayer > 4; bool bWideField = pStyle->m_iColsPerPlayer > 4;
int iTornadoWidth = bWideField ? 2 : 3; int iTornadoWidth = bWideField ? 2 : 3;
@@ -89,9 +85,7 @@ void ArrowEffects::Update()
} }
} }
//
// Update Invert // Update Invert
//
for( int iColNum = 0; iColNum < MAX_COLS_PER_PLAYER; ++iColNum ) for( int iColNum = 0; iColNum < MAX_COLS_PER_PLAYER; ++iColNum )
{ {
const int iNumCols = pStyle->m_iColsPerPlayer; const int iNumCols = pStyle->m_iColsPerPlayer;
@@ -135,9 +129,7 @@ void ArrowEffects::Update()
data.m_fInvertDistance[iColNum] = fNewPixelOffset - fOldPixelOffset; data.m_fInvertDistance[iColNum] = fNewPixelOffset - fOldPixelOffset;
} }
//
// Update Beat // Update Beat
//
do { do {
float fAccelTime = 0.2f, fTotalTime = 0.5f; float fAccelTime = 0.2f, fTotalTime = 0.5f;
float fBeat = GAMESTATE->m_fSongBeatVisible + fAccelTime; float fBeat = GAMESTATE->m_fSongBeatVisible + fAccelTime;
@@ -148,7 +140,7 @@ void ArrowEffects::Update()
if( fBeat < 0 ) if( fBeat < 0 )
break; break;
/* -100.2 -> -0.2 -> 0.2 */ // -100.2 -> -0.2 -> 0.2
fBeat -= truncf( fBeat ); fBeat -= truncf( fBeat );
fBeat += 1; fBeat += 1;
fBeat -= truncf( fBeat ); fBeat -= truncf( fBeat );
@@ -172,15 +164,14 @@ void ArrowEffects::Update()
} }
} }
/* For visibility testing: if bAbsolute is false, random modifiers must return the /* For visibility testing: if bAbsolute is false, random modifiers must return
* minimum possible scroll speed. */ * the minimum possible scroll speed. */
float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float fNoteBeat, float &fPeakYOffsetOut, bool &bIsPastPeakOut, bool bAbsolute ) float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float fNoteBeat, float &fPeakYOffsetOut, bool &bIsPastPeakOut, bool bAbsolute )
{ {
// Default values that are returned if boomerang is off. // Default values that are returned if boomerang is off.
fPeakYOffsetOut = FLT_MAX; fPeakYOffsetOut = FLT_MAX;
bIsPastPeakOut = true; bIsPastPeakOut = true;
float fYOffset = 0; float fYOffset = 0;
/* Usually, fTimeSpacing is 0 or 1, in which case we use entirely beat spacing or /* Usually, fTimeSpacing is 0 or 1, in which case we use entirely beat spacing or
@@ -213,7 +204,6 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
const float* fAccels = pPlayerState->m_PlayerOptions.GetCurrent().m_fAccels; const float* fAccels = pPlayerState->m_PlayerOptions.GetCurrent().m_fAccels;
//const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects; //const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
float fYAdjust = 0; // fill this in depending on PlayerOptions float fYAdjust = 0; // fill this in depending on PlayerOptions
if( fAccels[PlayerOptions::ACCEL_BOOST] != 0 ) if( fAccels[PlayerOptions::ACCEL_BOOST] != 0 )
@@ -240,9 +230,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
fYOffset += fYAdjust; fYOffset += fYAdjust;
//
// Factor in boomerang // Factor in boomerang
//
if( fAccels[PlayerOptions::ACCEL_BOOMERANG] != 0 ) if( fAccels[PlayerOptions::ACCEL_BOOMERANG] != 0 )
{ {
float fPeakAtYOffset = SCREEN_HEIGHT * 0.75f; // zero point of boomerang function float fPeakAtYOffset = SCREEN_HEIGHT * 0.75f; // zero point of boomerang function
@@ -252,13 +240,11 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
fYOffset = (-1*fYOffset*fYOffset/SCREEN_HEIGHT) + 1.5f*fYOffset; fYOffset = (-1*fYOffset*fYOffset/SCREEN_HEIGHT) + 1.5f*fYOffset;
} }
//
// Factor in scroll speed // Factor in scroll speed
//
float fScrollSpeed = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollSpeed; float fScrollSpeed = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollSpeed;
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fRandomSpeed > 0 && !bAbsolute ) if( pPlayerState->m_PlayerOptions.GetCurrent().m_fRandomSpeed > 0 && !bAbsolute )
{ {
/* Generate a deterministically "random" speed for each arrow. */ // Generate a deterministically "random" speed for each arrow.
unsigned seed = GAMESTATE->m_iStageSeed + ( BeatToNoteRow( fNoteBeat ) << 8 ) + (iCol * 100); unsigned seed = GAMESTATE->m_iStageSeed + ( BeatToNoteRow( fNoteBeat ) << 8 ) + (iCol * 100);
for( int i = 0; i < 3; ++i ) for( int i = 0; i < 3; ++i )
@@ -273,7 +259,6 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
1.0f, pPlayerState->m_PlayerOptions.GetCurrent().m_fRandomSpeed + 1.0f ); 1.0f, pPlayerState->m_PlayerOptions.GetCurrent().m_fRandomSpeed + 1.0f );
} }
if( fAccels[PlayerOptions::ACCEL_EXPAND] != 0 ) if( fAccels[PlayerOptions::ACCEL_EXPAND] != 0 )
{ {
float fExpandMultiplier = SCALE( RageFastCos(g_fExpandSeconds*3), -1, 1, 0.75f, 1.75f ); float fExpandMultiplier = SCALE( RageFastCos(g_fExpandSeconds*3), -1, 1, 0.75f, 1.75f );
@@ -288,7 +273,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
static void ArrowGetReverseShiftAndScale( const PlayerState* pPlayerState, int iCol, float fYReverseOffsetPixels, float &fShiftOut, float &fScaleOut ) static void ArrowGetReverseShiftAndScale( const PlayerState* pPlayerState, int iCol, float fYReverseOffsetPixels, float &fShiftOut, float &fScaleOut )
{ {
/* XXX: Hack: we need to scale the reverse shift by the zoom. */ // XXX: Hack: we need to scale the reverse shift by the zoom.
float fTinyPercent = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects[PlayerOptions::EFFECT_TINY]; float fTinyPercent = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects[PlayerOptions::EFFECT_TINY];
float fZoom = 1 - fTinyPercent*0.5f; float fZoom = 1 - fTinyPercent*0.5f;
@@ -321,7 +306,13 @@ float ArrowEffects::GetYPos( const PlayerState* pPlayerState, int iCol, float fY
if( fEffects[PlayerOptions::EFFECT_TIPSY] != 0 ) if( fEffects[PlayerOptions::EFFECT_TIPSY] != 0 )
f += fEffects[PlayerOptions::EFFECT_TIPSY] * ( RageFastCos( RageTimer::GetTimeSinceStartFast()*1.2f + iCol*1.8f) * ARROW_SIZE*0.4f ); f += fEffects[PlayerOptions::EFFECT_TIPSY] * ( RageFastCos( RageTimer::GetTimeSinceStartFast()*1.2f + iCol*1.8f) * ARROW_SIZE*0.4f );
// In beware's DDR Extreme-focused fork of StepMania 3.9, this value is
// floored, making arrows show on integer Y coordinates. Supposedly it makes
// the arrows look better, but testing needs to be done.
// todo: make this a preference -aj
return f; return f;
//return floor(f);
} }
float ArrowEffects::GetYOffsetFromYPos( const PlayerState* pPlayerState, int iCol, float YPos, float fYReverseOffsetPixels ) float ArrowEffects::GetYOffsetFromYPos( const PlayerState* pPlayerState, int iCol, float YPos, float fYReverseOffsetPixels )
@@ -386,11 +377,20 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float
fPixelOffsetFromCenter += fEffects[PlayerOptions::EFFECT_BEAT] * fShift; fPixelOffsetFromCenter += fEffects[PlayerOptions::EFFECT_BEAT] * fShift;
} }
/*
if( fEffects[PlayerOptions::SCROLL_X] != 0 )
{
// Compare pPlayerState->m_PlayerNumber.
// notes will go \ for p1 and / for p2.
// pCols[iColNum] for each column.
}
*/
fPixelOffsetFromCenter += pCols[iColNum].fXOffset; fPixelOffsetFromCenter += pCols[iColNum].fXOffset;
if( fEffects[PlayerOptions::EFFECT_MINI] != 0 ) if( fEffects[PlayerOptions::EFFECT_MINI] != 0 )
{ {
/* Allow Mini to pull tracks together, but not to push them apart. */ // Allow Mini to pull tracks together, but not to push them apart.
float fMiniPercent = fEffects[PlayerOptions::EFFECT_MINI]; float fMiniPercent = fEffects[PlayerOptions::EFFECT_MINI];
fMiniPercent = min( powf(0.5f, fMiniPercent), 1.0f ); fMiniPercent = min( powf(0.5f, fMiniPercent), 1.0f );
fPixelOffsetFromCenter *= fMiniPercent; fPixelOffsetFromCenter *= fMiniPercent;
@@ -450,14 +450,13 @@ float ArrowEffects::ReceptorGetRotation( const PlayerState* pPlayerState )
return fRotation; return fRotation;
} }
#define CENTER_LINE_Y 160 // from fYOffset == 0 #define CENTER_LINE_Y 160 // from fYOffset == 0
#define FADE_DIST_Y 40 #define FADE_DIST_Y 40
static float GetCenterLine( const PlayerState* pPlayerState ) static float GetCenterLine( const PlayerState* pPlayerState )
{ {
/* Another mini hack: if EFFECT_MINI is on, then our center line is at eg. 320, /* Another mini hack: if EFFECT_MINI is on, then our center line is at
* not 160. */ * eg. 320, not 160. */
const float fMiniPercent = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects[PlayerOptions::EFFECT_TINY]; const float fMiniPercent = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects[PlayerOptions::EFFECT_TINY];
const float fZoom = 1 - fMiniPercent*0.5f; const float fZoom = 1 - fMiniPercent*0.5f;
return CENTER_LINE_Y / fZoom; return CENTER_LINE_Y / fZoom;
-1
View File
@@ -28,7 +28,6 @@ public:
// Inverse of ArrowGetYPos (YPos -> fYOffset). // Inverse of ArrowGetYPos (YPos -> fYOffset).
static float GetYOffsetFromYPos( const PlayerState* pPlayerState, int iCol, float YPos, float fYReverseOffsetPixels ); static float GetYOffsetFromYPos( const PlayerState* pPlayerState, int iCol, float YPos, float fYReverseOffsetPixels );
// fRotation is Z rotation of an arrow. This will depend on the column of // fRotation is Z rotation of an arrow. This will depend on the column of
// the arrow and possibly the Arrow effect and the fYOffset (in the case of // the arrow and possibly the Arrow effect and the fYOffset (in the case of
// EFFECT_DIZZY). // EFFECT_DIZZY).
+1 -1
View File
@@ -40,7 +40,7 @@ void AutoActor::Load( const RString &sPath )
Unload(); Unload();
m_pActor = ActorUtil::MakeActor( sPath ); m_pActor = ActorUtil::MakeActor( sPath );
/* If a Condition is false, MakeActor will return NULL. */ // If a Condition is false, MakeActor will return NULL.
if( m_pActor == NULL ) if( m_pActor == NULL )
m_pActor = new Actor; m_pActor = new Actor;
} }
+1 -3
View File
@@ -38,9 +38,7 @@ public:
void DemandGraphics(); void DemandGraphics();
void UndemandGraphics(); void UndemandGraphics();
//
// Lua // Lua
//
void PushSelf( Lua *L ); void PushSelf( Lua *L );
// smart accessor // smart accessor
@@ -48,13 +46,13 @@ public:
RString m_sCharDir; RString m_sCharDir;
RString m_sCharacterID; RString m_sCharacterID;
private: private:
RString m_sDisplayName; RString m_sDisplayName;
RString m_sCardPath; RString m_sCardPath;
RString m_sIconPath; RString m_sIconPath;
public: public:
apActorCommands m_cmdInit; apActorCommands m_cmdInit;
// All the stuff below will be filled in if this character is playable in Rave mode // All the stuff below will be filled in if this character is playable in Rave mode
-2
View File
@@ -32,9 +32,7 @@ public:
virtual ControllerStateDisplay *Copy() const; virtual ControllerStateDisplay *Copy() const;
//
// Lua // Lua
//
virtual void PushSelf( lua_State *L ); virtual void PushSelf( lua_State *L );
protected: protected:
+19
View File
@@ -192,6 +192,7 @@ void Course::Init()
m_sSubTitleTranslit = ""; m_sSubTitleTranslit = "";
m_sBannerPath = ""; m_sBannerPath = "";
m_sBackgroundPath = "";
m_sCDTitlePath = ""; m_sCDTitlePath = "";
m_sGroupName = ""; m_sGroupName = "";
@@ -883,11 +884,27 @@ RString Course::GetBannerPath() const
return Dirname(m_sPath) + m_sBannerPath; return Dirname(m_sPath) + m_sBannerPath;
} }
RString Course::GetBackgroundPath() const
{
if( m_sBackgroundPath.empty() )
return RString();
if( m_sBackgroundPath[0] == '/' )
return m_sBackgroundPath;
// add "-bg" on the end to differentiate the background from the banner.
// This is based on traditional file naming found in most song files. -aj
return Dirname(m_sPath) + m_sBackgroundPath + RString("-bg");
}
bool Course::HasBanner() const bool Course::HasBanner() const
{ {
return GetBannerPath() != "" && IsAFile(GetBannerPath()); return GetBannerPath() != "" && IsAFile(GetBannerPath());
} }
bool Course::HasBackground() const
{
return GetBackgroundPath() != "" && IsAFile(GetBackgroundPath());
}
void Course::UpdateCourseStats( StepsType st ) void Course::UpdateCourseStats( StepsType st )
{ {
m_SortOrder_TotalDifficulty = 0; m_SortOrder_TotalDifficulty = 0;
@@ -1029,6 +1046,7 @@ public:
return 1; return 1;
} }
static int GetBannerPath( T* p, lua_State *L ) { RString s = p->GetBannerPath(); if( s.empty() ) return 0; LuaHelpers::Push(L, s); return 1; } static int GetBannerPath( T* p, lua_State *L ) { RString s = p->GetBannerPath(); if( s.empty() ) return 0; LuaHelpers::Push(L, s); return 1; }
static int GetBackgroundPath( T* p, lua_State *L ) { RString s = p->GetBackgroundPath(); if( s.empty() ) return 0; LuaHelpers::Push(L, s); return 1; }
static int GetGroupName( T* p, lua_State *L ) { lua_pushstring(L, p->m_sGroupName ); return 1; } static int GetGroupName( T* p, lua_State *L ) { lua_pushstring(L, p->m_sGroupName ); return 1; }
static int IsAutogen( T* p, lua_State *L ) { lua_pushboolean(L, p->m_bIsAutogen ); return 1; } static int IsAutogen( T* p, lua_State *L ) { lua_pushboolean(L, p->m_bIsAutogen ); return 1; }
static int GetEstimatedNumStages( T* p, lua_State *L ) { lua_pushnumber(L, p->GetEstimatedNumStages() ); return 1; } static int GetEstimatedNumStages( T* p, lua_State *L ) { lua_pushnumber(L, p->GetEstimatedNumStages() ); return 1; }
@@ -1059,6 +1077,7 @@ public:
ADD_METHOD( GetCourseEntry ); ADD_METHOD( GetCourseEntry );
ADD_METHOD( GetAllTrails ); ADD_METHOD( GetAllTrails );
ADD_METHOD( GetBannerPath ); ADD_METHOD( GetBannerPath );
ADD_METHOD( GetBackgroundPath );
ADD_METHOD( GetGroupName ); ADD_METHOD( GetGroupName );
ADD_METHOD( IsAutogen ); ADD_METHOD( IsAutogen );
ADD_METHOD( GetEstimatedNumStages ); ADD_METHOD( GetEstimatedNumStages );
+4 -1
View File
@@ -85,7 +85,9 @@ public:
Course(); Course();
RString GetBannerPath() const; RString GetBannerPath() const;
RString GetBackgroundPath() const;
bool HasBanner() const; bool HasBanner() const;
bool HasBackground() const;
/* If PREFSMAN->m_bShowNative is off, these are the same as GetTranslit* below. /* If PREFSMAN->m_bShowNative is off, these are the same as GetTranslit* below.
* Otherwise, they return the main titles. */ * Otherwise, they return the main titles. */
@@ -96,7 +98,7 @@ public:
RString GetTranslitMainTitle() const { return m_sMainTitleTranslit.size()? m_sMainTitleTranslit: m_sMainTitle; } RString GetTranslitMainTitle() const { return m_sMainTitleTranslit.size()? m_sMainTitleTranslit: m_sMainTitle; }
RString GetTranslitSubTitle() const { return m_sSubTitleTranslit.size()? m_sSubTitleTranslit: m_sSubTitle; } RString GetTranslitSubTitle() const { return m_sSubTitleTranslit.size()? m_sSubTitleTranslit: m_sSubTitle; }
/* "title subtitle" */ // "title subtitle"
RString GetDisplayFullTitle() const; RString GetDisplayFullTitle() const;
RString GetTranslitFullTitle() const; RString GetTranslitFullTitle() const;
@@ -169,6 +171,7 @@ public:
RString m_sSubTitle, m_sSubTitleTranslit; RString m_sSubTitle, m_sSubTitleTranslit;
RString m_sBannerPath; RString m_sBannerPath;
RString m_sBackgroundPath; // after 9 years yes finally -aj
RString m_sCDTitlePath; RString m_sCDTitlePath;
RString m_sGroupName; RString m_sGroupName;
+8 -8
View File
@@ -99,7 +99,7 @@ int StepsDisplayList::GetCurrentRowIndex( PlayerNumber pn ) const
return 0; return 0;
} }
/* Update m_fY and m_bHidden[]. */ // Update m_fY and m_bHidden[].
void StepsDisplayList::UpdatePositions() void StepsDisplayList::UpdatePositions()
{ {
int iCurrentRow[NUM_PLAYERS]; int iCurrentRow[NUM_PLAYERS];
@@ -111,7 +111,7 @@ void StepsDisplayList::UpdatePositions()
int first_start, first_end, second_start, second_end; int first_start, first_end, second_start, second_end;
/* Choices for each player. If only one player is active, it's the same for both. */ // Choices for each player. If only one player is active, it's the same for both.
int P1Choice = GAMESTATE->IsHumanPlayer(PLAYER_1)? iCurrentRow[PLAYER_1]: GAMESTATE->IsHumanPlayer(PLAYER_2)? iCurrentRow[PLAYER_2]: 0; int P1Choice = GAMESTATE->IsHumanPlayer(PLAYER_1)? iCurrentRow[PLAYER_1]: GAMESTATE->IsHumanPlayer(PLAYER_2)? iCurrentRow[PLAYER_2]: 0;
int P2Choice = GAMESTATE->IsHumanPlayer(PLAYER_2)? iCurrentRow[PLAYER_2]: GAMESTATE->IsHumanPlayer(PLAYER_1)? iCurrentRow[PLAYER_1]: 0; int P2Choice = GAMESTATE->IsHumanPlayer(PLAYER_2)? iCurrentRow[PLAYER_2]: GAMESTATE->IsHumanPlayer(PLAYER_1)? iCurrentRow[PLAYER_1]: 0;
@@ -120,19 +120,19 @@ void StepsDisplayList::UpdatePositions()
const bool BothPlayersActivated = GAMESTATE->IsHumanPlayer(PLAYER_1) && GAMESTATE->IsHumanPlayer(PLAYER_2); const bool BothPlayersActivated = GAMESTATE->IsHumanPlayer(PLAYER_1) && GAMESTATE->IsHumanPlayer(PLAYER_2);
if( !BothPlayersActivated ) if( !BothPlayersActivated )
{ {
/* Simply center the cursor. */ // Simply center the cursor.
first_start = max( P1Choice - halfsize, 0 ); first_start = max( P1Choice - halfsize, 0 );
first_end = first_start + total; first_end = first_start + total;
second_start = second_end = first_end; second_start = second_end = first_end;
} }
else else
{ {
/* First half: */ // First half:
const int earliest = min( P1Choice, P2Choice ); const int earliest = min( P1Choice, P2Choice );
first_start = max( earliest - halfsize/2, 0 ); first_start = max( earliest - halfsize/2, 0 );
first_end = first_start + halfsize; first_end = first_start + halfsize;
/* Second half: */ // Second half:
const int latest = max( P1Choice, P2Choice ); const int latest = max( P1Choice, P2Choice );
second_start = max( latest - halfsize/2, 0 ); second_start = max( latest - halfsize/2, 0 );
@@ -152,19 +152,19 @@ void StepsDisplayList::UpdatePositions()
{ {
const int sum = (first_end - first_start) + (second_end - second_start); const int sum = (first_end - first_start) + (second_end - second_start);
if( sum >= (int) Rows.size() || sum >= total) if( sum >= (int) Rows.size() || sum >= total)
break; /* nothing more to display, or no room */ break; // nothing more to display, or no room
/* First priority: expand the top of the second half until it meets /* First priority: expand the top of the second half until it meets
* the first half. */ * the first half. */
if( second_start > first_end ) if( second_start > first_end )
second_start--; second_start--;
/* Otherwise, expand either end. */ // Otherwise, expand either end.
else if( first_start > 0 ) else if( first_start > 0 )
first_start--; first_start--;
else if( second_end < (int) Rows.size() ) else if( second_end < (int) Rows.size() )
second_end++; second_end++;
else else
ASSERT(0); /* do we have room to grow or don't we? */ ASSERT(0); // do we have room to grow or don't we?
} }
int pos = 0; int pos = 0;
+7 -13
View File
@@ -13,12 +13,10 @@ void DynamicActorScroller::LoadFromNode( const XNode *pNode )
{ {
ActorScroller::LoadFromNode( pNode ); ActorScroller::LoadFromNode( pNode );
/* /* All of our children are identical, since they must be interchangeable.
* All of our children are identical, since they must be interchangeable.
* The <children> node loads only one; we copy the rest. * The <children> node loads only one; we copy the rest.
* *
* Make one extra copy if masking is enabled. * Make one extra copy if masking is enabled. */
*/
if( m_SubActors.size() != 1 ) if( m_SubActors.size() != 1 )
RageException::Throw( "%s: DynamicActorScroller: loaded %i nodes; require exactly one", ActorUtil::GetWhere(pNode).c_str(), (int)m_SubActors.size() ); RageException::Throw( "%s: DynamicActorScroller: loaded %i nodes; require exactly one", ActorUtil::GetWhere(pNode).c_str(), (int)m_SubActors.size() );
@@ -38,7 +36,7 @@ void DynamicActorScroller::LoadFromNode( const XNode *pNode )
LUA->Release(L); LUA->Release(L);
} }
/* Call the expression with line = nil to find out the number of lines. */ // Call the expression with line = nil to find out the number of lines.
{ {
Lua *L = LUA->Get(); Lua *L = LUA->Get();
m_LoadFunction.PushSelf( L ); m_LoadFunction.PushSelf( L );
@@ -55,20 +53,16 @@ void DynamicActorScroller::LoadFromNode( const XNode *pNode )
LUA->Release(L); LUA->Release(L);
} }
/* /* Reconfigure all items, so the loaded actors actually correspond with
* Reconfigure all items, so the loaded actors actually correspond with * m_iFirstSubActorIndex. */
* m_iFirstSubActorIndex.
*/
ShiftSubActors( INT_MAX ); ShiftSubActors( INT_MAX );
} }
/* /* Shift m_SubActors forward by iDist, and then fill in the new entries.
* Shift m_SubActors forward by iDist, and then fill in the new entries.
* *
* Important: under normal scrolling, with or without m_bLoop, at most one * Important: under normal scrolling, with or without m_bLoop, at most one
* object is created per update, and this normally only happens when an * object is created per update, and this normally only happens when an
* object comes on screen. Extra actor updates are avoided for efficiency. * object comes on screen. Extra actor updates are avoided for efficiency. */
*/
void DynamicActorScroller::ShiftSubActors( int iDist ) void DynamicActorScroller::ShiftSubActors( int iDist )
{ {
ActorScroller::ShiftSubActors( iDist ); ActorScroller::ShiftSubActors( iDist );
+49 -52
View File
@@ -29,7 +29,7 @@ void FontPage::Load( const FontPageSettings &cfg )
ASSERT( m_FontPageTextures.m_pTextureMain != NULL ); ASSERT( m_FontPageTextures.m_pTextureMain != NULL );
RageTextureID ID2 = ID1; RageTextureID ID2 = ID1;
/* "arial 20 16x16 [main].png" => "arial 20 16x16 [main-stroke].png" */ // "arial 20 16x16 [main].png" => "arial 20 16x16 [main-stroke].png"
if( ID2.filename.find("]") != string::npos ) if( ID2.filename.find("]") != string::npos )
{ {
ID2.filename.Replace( "]", "-stroke]" ); ID2.filename.Replace( "]", "-stroke]" );
@@ -97,7 +97,7 @@ void FontPage::Load( const FontPageSettings &cfg )
m_iDrawExtraPixelsLeft = cfg.m_iDrawExtraPixelsLeft; m_iDrawExtraPixelsLeft = cfg.m_iDrawExtraPixelsLeft;
m_iDrawExtraPixelsRight = cfg.m_iDrawExtraPixelsRight; m_iDrawExtraPixelsRight = cfg.m_iDrawExtraPixelsRight;
/* Shift the character up so the top will be rendered at the baseline. */ // Shift the character up so the top will be rendered at the baseline.
m_fVshift = (float) -iBaseline; m_fVshift = (float) -iBaseline;
SetTextureCoords( aiFrameWidths, cfg.m_iAdvanceExtraPixels ); SetTextureCoords( aiFrameWidths, cfg.m_iAdvanceExtraPixels );
@@ -119,7 +119,7 @@ void FontPage::SetTextureCoords( const vector<int> &widths, int iAdvanceExtraPix
* of the character (most characters don't take a full block). */ * of the character (most characters don't take a full block). */
g.m_TexRect = *m_FontPageTextures.m_pTextureMain->GetTextureCoordRect(i); g.m_TexRect = *m_FontPageTextures.m_pTextureMain->GetTextureCoordRect(i);
/* Set the width and height to the width and line spacing, respectively. */ // Set the width and height to the width and line spacing, respectively.
g.m_fWidth = float( widths[i] ); g.m_fWidth = float( widths[i] );
g.m_fHeight = float(m_FontPageTextures.m_pTextureMain->GetSourceFrameHeight()); g.m_fHeight = float(m_FontPageTextures.m_pTextureMain->GetSourceFrameHeight());
@@ -158,14 +158,14 @@ void FontPage::SetTextureCoords( const vector<int> &widths, int iAdvanceExtraPix
void FontPage::SetExtraPixels( int iDrawExtraPixelsLeft, int iDrawExtraPixelsRight ) void FontPage::SetExtraPixels( int iDrawExtraPixelsLeft, int iDrawExtraPixelsRight )
{ {
/* Hack: do one more than we were asked to; I think a lot of fonts are one /* Hack: do one more than we were asked to; I think a lot of fonts are one
* too low. */ * too low. (who? -aj; todo: source quote) */
iDrawExtraPixelsRight++; iDrawExtraPixelsRight++;
iDrawExtraPixelsLeft++; iDrawExtraPixelsLeft++;
if( (iDrawExtraPixelsLeft % 2) == 1 ) if( (iDrawExtraPixelsLeft % 2) == 1 )
++iDrawExtraPixelsLeft; ++iDrawExtraPixelsLeft;
/* Adjust for iDrawExtraPixelsLeft and iDrawExtraPixelsRight. */ // Adjust for iDrawExtraPixelsLeft and iDrawExtraPixelsRight.
for( unsigned i = 0; i < m_aGlyphs.size(); ++i ) for( unsigned i = 0; i < m_aGlyphs.size(); ++i )
{ {
int iFrameWidth = m_FontPageTextures.m_pTextureMain->GetSourceFrameWidth(); int iFrameWidth = m_FontPageTextures.m_pTextureMain->GetSourceFrameWidth();
@@ -177,7 +177,7 @@ void FontPage::SetExtraPixels( int iDrawExtraPixelsLeft, int iDrawExtraPixelsRig
float fExtraLeft = min( float(iDrawExtraPixelsLeft), (iFrameWidth-fCharWidth)/2.0f ); float fExtraLeft = min( float(iDrawExtraPixelsLeft), (iFrameWidth-fCharWidth)/2.0f );
float fExtraRight = min( float(iDrawExtraPixelsRight), (iFrameWidth-fCharWidth)/2.0f ); float fExtraRight = min( float(iDrawExtraPixelsRight), (iFrameWidth-fCharWidth)/2.0f );
/* Move left and expand right. */ // Move left and expand right.
m_aGlyphs[i].m_TexRect.left -= fExtraLeft * m_FontPageTextures.m_pTextureMain->GetSourceToTexCoordsRatioX(); m_aGlyphs[i].m_TexRect.left -= fExtraLeft * m_FontPageTextures.m_pTextureMain->GetSourceToTexCoordsRatioX();
m_aGlyphs[i].m_TexRect.right += fExtraRight * m_FontPageTextures.m_pTextureMain->GetSourceToTexCoordsRatioX(); m_aGlyphs[i].m_TexRect.right += fExtraRight * m_FontPageTextures.m_pTextureMain->GetSourceToTexCoordsRatioX();
m_aGlyphs[i].m_fHshift -= fExtraLeft; m_aGlyphs[i].m_fHshift -= fExtraLeft;
@@ -213,7 +213,7 @@ int Font::GetLineHeightInSourcePixels( const wstring &szLine ) const
{ {
int iLineHeight = 0; int iLineHeight = 0;
/* The height of a line is the height of its tallest used font page. */ // The height of a line is the height of its tallest used font page.
for( unsigned i=0; i<szLine.size(); i++ ) for( unsigned i=0; i<szLine.size(); i++ )
iLineHeight = max( iLineHeight, GetGlyph(szLine[i]).m_pPage->m_iHeight ); iLineHeight = max( iLineHeight, GetGlyph(szLine[i]).m_pPage->m_iHeight );
@@ -228,7 +228,7 @@ Font::Font()
m_iRefCount = 1; m_iRefCount = 1;
m_pDefault = NULL; m_pDefault = NULL;
m_bRightToLeft = false; m_bRightToLeft = false;
// don't show strokes by default // [sm-ssc] don't show strokes by default
m_DefaultStrokeColor = RageColor(0,0,0,0); m_DefaultStrokeColor = RageColor(0,0,0,0);
} }
@@ -293,14 +293,14 @@ const glyph &Font::GetGlyph( wchar_t c ) const
{ {
ASSERT(c >= 0 && c <= 0xFFFFFF); ASSERT(c >= 0 && c <= 0xFFFFFF);
/* Fast path: */ // Fast path:
if( c < (int) ARRAYLEN(m_iCharToGlyphCache) && m_iCharToGlyphCache[c] ) if( c < (int) ARRAYLEN(m_iCharToGlyphCache) && m_iCharToGlyphCache[c] )
return *m_iCharToGlyphCache[c]; return *m_iCharToGlyphCache[c];
/* Try the regular character. */ // Try the regular character.
map<wchar_t,glyph*>::const_iterator it = m_iCharToGlyph.find(c); map<wchar_t,glyph*>::const_iterator it = m_iCharToGlyph.find(c);
/* If that's missing, use the default glyph. */ // If that's missing, use the default glyph.
if(it == m_iCharToGlyph.end()) if(it == m_iCharToGlyph.end())
it = m_iCharToGlyph.find(FONT_DEFAULT_GLYPH); it = m_iCharToGlyph.find(FONT_DEFAULT_GLYPH);
@@ -318,7 +318,7 @@ bool Font::FontCompleteForString( const wstring &str ) const
for( unsigned i = 0; i < str.size(); ++i ) for( unsigned i = 0; i < str.size(); ++i )
{ {
/* If the glyph for this character is the default glyph, we're incomplete. */ // If the glyph for this character is the default glyph, we're incomplete.
const glyph &g = GetGlyph( str[i] ); const glyph &g = GetGlyph( str[i] );
if( &g == m_pDefault->second ) if( &g == m_pDefault->second )
return false; return false;
@@ -349,7 +349,7 @@ void Font::SetDefaultGlyph( FontPage *pPage )
} }
/* Given the INI for a font, find all of the texture pages for the font. */ // Given the INI for a font, find all of the texture pages for the font.
void Font::GetFontPaths( const RString &sFontIniPath, vector<RString> &asTexturePathsOut ) void Font::GetFontPaths( const RString &sFontIniPath, vector<RString> &asTexturePathsOut )
{ {
RString sPrefix = SetExtension( sFontIniPath, "" ); RString sPrefix = SetExtension( sFontIniPath, "" );
@@ -384,7 +384,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
{ {
cfg.m_sTexturePath = sTexturePath; cfg.m_sTexturePath = sTexturePath;
/* If we have any characters to map, add them. */ // If we have any characters to map, add them.
for( unsigned n=0; n<sChars.size(); n++ ) for( unsigned n=0; n<sChars.size(); n++ )
{ {
char c = sChars[n]; char c = sChars[n];
@@ -394,6 +394,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
RageTexture::GetFrameDimensionsFromFileName( sTexturePath, &iNumFramesWide, &iNumFramesHigh ); RageTexture::GetFrameDimensionsFromFileName( sTexturePath, &iNumFramesWide, &iNumFramesHigh );
int iNumFrames = iNumFramesWide * iNumFramesHigh; int iNumFrames = iNumFramesWide * iNumFramesHigh;
// Deal with fonts generated by Bitmap Font Builder.
ini.RenameKey("Char Widths", "main"); ini.RenameKey("Char Widths", "main");
// LOG->Trace("Loading font page '%s' settings from page name '%s'", // LOG->Trace("Loading font page '%s' settings from page name '%s'",
@@ -410,7 +411,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
ini.GetValue( sPageName, "AdvanceExtraPixels", cfg.m_iAdvanceExtraPixels ); ini.GetValue( sPageName, "AdvanceExtraPixels", cfg.m_iAdvanceExtraPixels );
ini.GetValue( sPageName, "TextureHints", cfg.m_sTextureHints ); ini.GetValue( sPageName, "TextureHints", cfg.m_sTextureHints );
/* Iterate over all keys. */ // Iterate over all keys.
const XNode* pNode = ini.GetChild( sPageName ); const XNode* pNode = ini.GetChild( sPageName );
if( pNode ) if( pNode )
{ {
@@ -421,18 +422,17 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
sName.MakeUpper(); sName.MakeUpper();
/* If val is an integer, it's a width, eg. "10=27". */ // If val is an integer, it's a width, eg. "10=27".
if( IsAnInt(sName) ) if( IsAnInt(sName) )
{ {
cfg.m_mapGlyphWidths[atoi(sName)] = pValue->GetValue<int>(); cfg.m_mapGlyphWidths[atoi(sName)] = pValue->GetValue<int>();
continue; continue;
} }
/* "map codepoint=frame" maps a char to a frame. */ // "map codepoint=frame" maps a char to a frame.
if( sName.substr(0, 4) == "MAP " ) if( sName.substr(0, 4) == "MAP " )
{ {
/* /* map CODEPOINT=frame. CODEPOINT can be
* map CODEPOINT=frame. CODEPOINT can be
* 1. U+hexval * 1. U+hexval
* 2. an alias ("oq") * 2. an alias ("oq")
* 3. a character in quotes ("X") * 3. a character in quotes ("X")
@@ -440,7 +440,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
* map 1=2 is the same as * map 1=2 is the same as
* range unicode #1-1=2 * range unicode #1-1=2
*/ */
RString sCodepoint = sName.substr(4); /* "CODEPOINT" */ RString sCodepoint = sName.substr(4); // "CODEPOINT"
wchar_t c; wchar_t c;
if( sCodepoint.substr(0, 2) == "U+" && IsHexVal(sCodepoint.substr(2)) ) if( sCodepoint.substr(0, 2) == "U+" && IsHexVal(sCodepoint.substr(2)) )
@@ -467,8 +467,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
if( sName.substr(0, 6) == "RANGE " ) if( sName.substr(0, 6) == "RANGE " )
{ {
/* /* range CODESET=first_frame or
* range CODESET=first_frame or
* range CODESET #start-end=first_frame * range CODESET #start-end=first_frame
* eg * eg
* range CP1252=0 (default for 256-frame fonts) * range CP1252=0 (default for 256-frame fonts)
@@ -487,14 +486,13 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
static Regex parse("^RANGE ([A-Z0-9\\-]+)( ?#([0-9A-F]+)-([0-9A-F]+))?$"); static Regex parse("^RANGE ([A-Z0-9\\-]+)( ?#([0-9A-F]+)-([0-9A-F]+))?$");
bool bMatch = parse.Compare( sName, asMatches ); bool bMatch = parse.Compare( sName, asMatches );
ASSERT( asMatches.size() == 4 ); /* 4 parens */ ASSERT( asMatches.size() == 4 ); // 4 parens
if( !bMatch || asMatches[0].empty() ) if( !bMatch || asMatches[0].empty() )
RageException::Throw( "Font definition \"%s\" has an invalid range \"%s\": parse error.", RageException::Throw( "Font definition \"%s\" has an invalid range \"%s\": parse error.",
ini.GetPath().c_str(), sName.c_str() ); ini.GetPath().c_str(), sName.c_str() );
/* We must have either 1 match (just the codeset) or 4 (the whole thing). */ // We must have either 1 match (just the codeset) or 4 (the whole thing).
int iCount = -1; int iCount = -1;
int iFirst = 0; int iFirst = 0;
if( !asMatches[2].empty() ) if( !asMatches[2].empty() )
@@ -536,7 +534,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
RageException::Throw( "The font definition \"%s\" tries to assign line %i, but the font is only %i characters high.", RageException::Throw( "The font definition \"%s\" tries to assign line %i, but the font is only %i characters high.",
ini.GetPath().c_str(), iFirstFrame, iNumFramesHigh ); ini.GetPath().c_str(), iFirstFrame, iNumFramesHigh );
/* Decode the string. */ // Decode the string.
const wstring wdata( RStringToWstring(pValue->GetValue<RString>()) ); const wstring wdata( RStringToWstring(pValue->GetValue<RString>()) );
if( int(wdata.size()) > iNumFramesWide ) if( int(wdata.size()) > iNumFramesWide )
@@ -550,9 +548,9 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
} }
/* If it's 128 or 256 frames, default to ASCII or CP1252, /* If it's 128 or 256 frames, default to ASCII or CP1252,
* respectively. If it's anything else, we don't know what it * respectively. 5x3 and 4x4 numbers fonts are supported as well.
* is, so don't make any default mappings (the INI needs to do * If it's anything else, we don't know what it is, so don't make
* it itself). */ * any default mappings (the INI needs to do that itself). */
if( sPageName != "common" && cfg.CharToGlyphNo.empty() ) if( sPageName != "common" && cfg.CharToGlyphNo.empty() )
{ {
switch( iNumFrames ) switch( iNumFrames )
@@ -572,7 +570,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
} }
} }
/* If ' ' is set and nbsp is not, set nbsp. */ // If ' ' is set and nbsp is not, set nbsp.
if( cfg.CharToGlyphNo.find(' ') != cfg.CharToGlyphNo.end() ) if( cfg.CharToGlyphNo.find(' ') != cfg.CharToGlyphNo.end() )
cfg.CharToGlyphNo[0x00A0] = cfg.CharToGlyphNo[' ']; cfg.CharToGlyphNo[0x00A0] = cfg.CharToGlyphNo[' '];
} }
@@ -581,14 +579,14 @@ RString FontPageSettings::MapRange( RString sMapping, int iMapOffset, int iGlyph
{ {
if( !sMapping.CompareNoCase("Unicode") ) if( !sMapping.CompareNoCase("Unicode") )
{ {
/* Special case. */ // Special case.
if( iCount == -1 ) if( iCount == -1 )
return "Can't map all of Unicode to one font page"; /* don't do that */ return "Can't map all of Unicode to one font page"; // don't do that
/* What's a practical limit? A 2048x2048 texture could contain 16x16 characters, /* What's a practical limit? A 2048x2048 texture could contain 16x16
* which is 16384 glyphs. (Use a grayscale map and that's only 4 megs.) Let's use * characters, which is 16384 glyphs. (Use a grayscale map and that's
* that as a cap. (We don't want to go crazy if someone says "range Unicode * only 4 megs.) Let's use that as a cap. (We don't want to go crazy
* #0-FFFFFFFF".) */ * if someone says "range Unicode #0-FFFFFFFF".) */
if( iCount > 16384 ) if( iCount > 16384 )
return ssprintf( "Can't map %i glyphs to one font page", iCount ); return ssprintf( "Can't map %i glyphs to one font page", iCount );
@@ -613,9 +611,9 @@ RString FontPageSettings::MapRange( RString sMapping, int iMapOffset, int iGlyph
--iMapOffset; --iMapOffset;
} }
if( iMapOffset ) if( iMapOffset )
return "Map overflow"; /* there aren't enough characters in the map */ return "Map overflow"; // there aren't enough characters in the map
/* If iCount is -1, set it to the number of characters in the map. */ // If iCount is -1, set it to the number of characters in the map.
if( iCount == -1 ) if( iCount == -1 )
for( iCount = 0; pMapping[iCount] != 0; ++iCount ) ; for( iCount = 0; pMapping[iCount] != 0; ++iCount ) ;
@@ -629,15 +627,14 @@ RString FontPageSettings::MapRange( RString sMapping, int iMapOffset, int iGlyph
} }
if( iCount ) if( iCount )
return "Map overflow"; /* there aren't enough characters in the map */ return "Map overflow"; // there aren't enough characters in the map
return RString(); return RString();
} }
static vector<RString> LoadStack; static vector<RString> LoadStack;
/* /* A font set is a set of files, eg:
* A font set is a set of files, eg:
* *
* Normal 16x16.png * Normal 16x16.png
* Normal [other] 16x16.png * Normal [other] 16x16.png
@@ -651,6 +648,7 @@ static vector<RString> LoadStack;
* *
* If a file has no characters and sChars is not set, it will receive a default * If a file has no characters and sChars is not set, it will receive a default
* mapping of ASCII or ISO-8859-1 if the font has exactly 128 or 256 frames. * mapping of ASCII or ISO-8859-1 if the font has exactly 128 or 256 frames.
* 5x3 (15 frames) and 4x4 (16 frames) numbers sheets are also supported.
* However, if it doesn't, we don't know what it is and the font will receive * However, if it doesn't, we don't know what it is and the font will receive
* no default mapping. A font isn't useful with no characters mapped. * no default mapping. A font isn't useful with no characters mapped.
*/ */
@@ -658,7 +656,7 @@ void Font::Load( const RString &sIniPath, RString sChars )
{ {
ASSERT_M( !GetExtension(sIniPath).CompareNoCase("ini"), sIniPath ); ASSERT_M( !GetExtension(sIniPath).CompareNoCase("ini"), sIniPath );
/* Check for recursion (recursive imports). */ // Check for recursion (recursive imports).
for( unsigned i = 0; i < LoadStack.size(); ++i ) for( unsigned i = 0; i < LoadStack.size(); ++i )
{ {
if( LoadStack[i] == sIniPath ) if( LoadStack[i] == sIniPath )
@@ -670,20 +668,19 @@ void Font::Load( const RString &sIniPath, RString sChars )
} }
LoadStack.push_back( sIniPath ); LoadStack.push_back( sIniPath );
/* The font is not already loaded. Figure out what we have. */ // The font is not already loaded. Figure out what we have.
CHECKPOINT_M( ssprintf("Font::Load(\"%s\",\"%s\").", sIniPath.c_str(), m_sChars.c_str()) ); CHECKPOINT_M( ssprintf("Font::Load(\"%s\",\"%s\").", sIniPath.c_str(), m_sChars.c_str()) );
path = sIniPath; path = sIniPath;
m_sChars = sChars; m_sChars = sChars;
/* Get the filenames associated with this font. */ // Get the filenames associated with this font.
vector<RString> asTexturePaths; vector<RString> asTexturePaths;
GetFontPaths( sIniPath, asTexturePaths ); GetFontPaths( sIniPath, asTexturePaths );
bool bCapitalsOnly = false; bool bCapitalsOnly = false;
/* If we have an INI, load it. */ // If we have an INI, load it.
IniFile ini; IniFile ini;
if( !sIniPath.empty() ) if( !sIniPath.empty() )
{ {
@@ -701,7 +698,7 @@ void Font::Load( const RString &sIniPath, RString sChars )
bool bIsTopLevelFont = LoadStack.size() == 1; bool bIsTopLevelFont = LoadStack.size() == 1;
/* If this is a top-level font (not a subfont), load the default font first. */ // If this is a top-level font (not a subfont), load the default font first.
if( bIsTopLevelFont ) if( bIsTopLevelFont )
ImportList.push_back("Common default"); ImportList.push_back("Common default");
@@ -734,26 +731,26 @@ void Font::Load( const RString &sIniPath, RString sChars )
} }
} }
/* Load each font page. */ // Load each font page.
for( unsigned i = 0; i < asTexturePaths.size(); ++i ) for( unsigned i = 0; i < asTexturePaths.size(); ++i )
{ {
const RString &sTexturePath = asTexturePaths[i]; const RString &sTexturePath = asTexturePaths[i];
FontPage *pPage = new FontPage; FontPage *pPage = new FontPage;
/* Grab the page name, eg "foo" from "Normal [foo].png". */ // Grab the page name, eg "foo" from "Normal [foo].png".
RString sPagename = GetPageNameFromFileName( sTexturePath ); RString sPagename = GetPageNameFromFileName( sTexturePath );
// Ignore stroke textures // Ignore stroke textures
if( sTexturePath.find("-stroke") != string::npos ) if( sTexturePath.find("-stroke") != string::npos )
continue; continue;
/* Load settings for this page from the INI. */ // Load settings for this page from the INI.
FontPageSettings cfg; FontPageSettings cfg;
LoadFontPageSettings( cfg, ini, sTexturePath, "common", sChars ); LoadFontPageSettings( cfg, ini, sTexturePath, "common", sChars );
LoadFontPageSettings( cfg, ini, sTexturePath, sPagename, sChars ); LoadFontPageSettings( cfg, ini, sTexturePath, sPagename, sChars );
/* Go. */ // Load.
pPage->Load( cfg ); pPage->Load( cfg );
/* Expect at least as many frames as we have premapped characters. */ /* Expect at least as many frames as we have premapped characters. */
@@ -789,7 +786,7 @@ void Font::Load( const RString &sIniPath, RString sChars )
if( LoadStack.empty() ) if( LoadStack.empty() )
{ {
/* Cache ASCII glyphs. */ // Cache ASCII glyphs.
ZERO( m_iCharToGlyphCache ); ZERO( m_iCharToGlyphCache );
map<wchar_t,glyph*>::iterator it; map<wchar_t,glyph*>::iterator it;
for( it = m_iCharToGlyph.begin(); it != m_iCharToGlyph.end(); ++it ) for( it = m_iCharToGlyph.begin(); it != m_iCharToGlyph.end(); ++it )
+19 -17
View File
@@ -15,7 +15,9 @@ class IniFile;
struct FontPageTextures struct FontPageTextures
{ {
RageTexture *m_pTextureMain; RageTexture *m_pTextureMain;
RageTexture *m_pTextureStroke; /* an optional texture drawn underneath Main that can help to acheive complicated layer styles */ /* an optional texture drawn underneath Main that can help to acheive
* complicated layer styles. */
RageTexture *m_pTextureStroke;
FontPageTextures() FontPageTextures()
{ {
@@ -30,16 +32,16 @@ struct glyph
FontPageTextures m_FontPageTextures; FontPageTextures m_FontPageTextures;
FontPageTextures *GetFontPageTextures() const { return const_cast<FontPageTextures *>(&m_FontPageTextures); } FontPageTextures *GetFontPageTextures() const { return const_cast<FontPageTextures *>(&m_FontPageTextures); }
/* Number of pixels to advance horizontally after drawing this character. */ // Number of pixels to advance horizontally after drawing this character.
int m_iHadvance; int m_iHadvance;
/* Size of the actual rendered character. */ // Size of the actual rendered character.
float m_fWidth, m_fHeight; float m_fWidth, m_fHeight;
/* Number of pixels to offset this character when rendering. */ // Number of pixels to offset this character when rendering.
float m_fHshift; // , vshift; float m_fHshift; // , m_fVshift;
/* Texture coordinate rect. */ // Texture coordinate rect.
RectF m_TexRect; RectF m_TexRect;
}; };
@@ -59,7 +61,7 @@ struct FontPageSettings
RString m_sTextureHints; RString m_sTextureHints;
map<wchar_t,int> CharToGlyphNo; map<wchar_t,int> CharToGlyphNo;
/* If a value is missing, the width of the texture frame is used. */ // If a value is missing, the width of the texture frame is used.
map<int,int> m_mapGlyphWidths; map<int,int> m_mapGlyphWidths;
FontPageSettings(): FontPageSettings():
@@ -87,21 +89,21 @@ public:
void Load( const FontPageSettings &cfg ); void Load( const FontPageSettings &cfg );
/* Page-global properties. */ // Page-global properties.
int m_iHeight; int m_iHeight;
int m_iLineSpacing; int m_iLineSpacing;
float m_fVshift; float m_fVshift;
int GetCenter() const { return m_iHeight/2; } int GetCenter() const { return m_iHeight/2; }
/* Remember these only for GetLineWidthInSourcePixels. */ // Remember these only for GetLineWidthInSourcePixels.
int m_iDrawExtraPixelsLeft, m_iDrawExtraPixelsRight; int m_iDrawExtraPixelsLeft, m_iDrawExtraPixelsRight;
FontPageTextures m_FontPageTextures; FontPageTextures m_FontPageTextures;
// XXX remove? // XXX: remove?
RString m_sTexturePath; RString m_sTexturePath;
/* All glyphs in this list will point to m_pTexture. */ // All glyphs in this list will point to m_pTexture.
vector<glyph> m_aGlyphs; vector<glyph> m_aGlyphs;
map<wchar_t,int> m_iCharToGlyphNo; map<wchar_t,int> m_iCharToGlyphNo;
@@ -127,17 +129,17 @@ public:
bool FontCompleteForString( const wstring &str ) const; bool FontCompleteForString( const wstring &str ) const;
/* Add a FontPage to this font. */ // Add a FontPage to this font.
void AddPage(FontPage *fp); void AddPage(FontPage *fp);
/* Steal all of a font's pages. */ // Steal all of a font's pages.
void MergeFont(Font &f); void MergeFont(Font &f);
void Load(const RString &sFontOrTextureFilePath, RString sChars); void Load(const RString &sFontOrTextureFilePath, RString sChars);
void Unload(); void Unload();
void Reload(); void Reload();
/* Load font-wide settings. */ // Load font-wide settings.
void CapsOnly(); void CapsOnly();
int GetHeight() const { return m_pDefault->m_iHeight; } int GetHeight() const { return m_pDefault->m_iHeight; }
@@ -150,14 +152,14 @@ public:
const RageColor &GetDefaultStrokeColor() const { return m_DefaultStrokeColor; }; const RageColor &GetDefaultStrokeColor() const { return m_DefaultStrokeColor; };
private: private:
/* List of pages and fonts that we use (and are responsible for freeing). */ // List of pages and fonts that we use (and are responsible for freeing).
vector<FontPage *> m_apPages; vector<FontPage *> m_apPages;
/* This is the primary fontpage of this font; font-wide height, center, /* This is the primary fontpage of this font; font-wide height, center,
* etc. is pulled from it. (This is one of pages[].) */ * etc. is pulled from it. (This is one of pages[].) */
FontPage *m_pDefault; FontPage *m_pDefault;
/* Map from characters to glyphs. (Each glyph* is part of one of pages[].) */ // Map from characters to glyphs. (Each glyph* is part of one of pages[].)
map<wchar_t,glyph*> m_iCharToGlyph; map<wchar_t,glyph*> m_iCharToGlyph;
glyph *m_iCharToGlyphCache[128]; glyph *m_iCharToGlyphCache[128];
@@ -168,7 +170,7 @@ private:
RageColor m_DefaultStrokeColor; RageColor m_DefaultStrokeColor;
/* We keep this around only for reloading. */ // We keep this around only for reloading.
RString m_sChars; RString m_sChars;
void LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RString &sTexturePath, const RString &PageName, RString sChars ); void LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RString &sTexturePath, const RString &PageName, RString sChars );
+21 -15
View File
@@ -6,7 +6,7 @@
#include <map> #include <map>
/* Map from "&foo;" to a UTF-8 string. */ // Map from "&foo;" to a UTF-8 string.
typedef map<RString, wchar_t, StdString::StdStringLessNoCase> aliasmap; typedef map<RString, wchar_t, StdString::StdStringLessNoCase> aliasmap;
static aliasmap CharAliases; static aliasmap CharAliases;
static map<RString,RString> CharAliasRepl; static map<RString,RString> CharAliasRepl;
@@ -31,6 +31,12 @@ static map<RString,RString> CharAliasRepl;
* write &these; to SMs, due to format limitations. * write &these; to SMs, due to format limitations.
*/ */
// the above comment sounds old, look at the "kakumei1", which reminds me of the
// old SPiGuMuS kanji font hack.
// a more modern implementation would likely involve a Lua file in Data for the
// base character aliases, and any alias not encountered in the list would be
// added at the next possible code point. -aj
/* Here's a copy-and-paste for a basic Japanese font page: /* Here's a copy-and-paste for a basic Japanese font page:
 、。〃〄々〆〇〈〉《》「」『』  、。〃〄々〆〇〈〉《》「」『』
@@ -67,17 +73,17 @@ static void InitCharAliases()
if(!CharAliases.empty()) if(!CharAliases.empty())
return; return;
CharAliases["default"] = FONT_DEFAULT_GLYPH; /* ? */ CharAliases["default"] = FONT_DEFAULT_GLYPH; // ?
CharAliases["invalid"] = INVALID_CHAR; /* 0xFFFD */ CharAliases["invalid"] = INVALID_CHAR; // 0xFFFD
/* The comments here are UTF-8; they won't show up in VC6 (use a later // The comments here are UTF-8; they won't show up in VC6
* version of visual studio then, you old fart). -aj edited this */ // (use a better editor then -aj)
#define INTERNAL 0xE000 #define INTERNAL 0xE000
// todo: convert this into a vector? that way we can dynamically add // todo: convert this into a vector? that way we can dynamically add
// to the list easier. // to the list easier. -aj(?)
/* Hiragana: */ // Hiragana:
struct alias { struct alias {
const char *str; const char *str;
wchar_t chr; wchar_t chr;
@@ -168,7 +174,7 @@ static void InitCharAliases()
{ "hyos", 0x3087 }, /* ょ */ { "hyos", 0x3087 }, /* ょ */
{ "hwas", 0x308e }, /* ゎ */ { "hwas", 0x308e }, /* ゎ */
/* Katakana: */ // Katakana:
{ "hq", 0x3063 }, /* っ */ { "hq", 0x3063 }, /* っ */
{ "ka", 0x30a2 }, /* ア */ { "ka", 0x30a2 }, /* ア */
{ "ki", 0x30a4 }, /* イ */ { "ki", 0x30a4 }, /* イ */
@@ -263,7 +269,7 @@ static void InitCharAliases()
{ "nbsp", 0x00a0 }, /* Non-breaking space */ { "nbsp", 0x00a0 }, /* Non-breaking space */
/* Symbols: */ // Symbols:
{ "delta", 0x0394 }, /* Δ */ { "delta", 0x0394 }, /* Δ */
{ "sigma", 0x03a3 }, /* Σ */ { "sigma", 0x03a3 }, /* Σ */
{ "omega", 0x03a9 }, /* Ω */ { "omega", 0x03a9 }, /* Ω */
@@ -309,7 +315,7 @@ static void InitCharAliases()
{ "ok", INTERNAL }, { "ok", INTERNAL },
{ "nextrow", INTERNAL }, { "nextrow", INTERNAL },
{ "select", INTERNAL }, { "select", INTERNAL },
/* PlayStation-style controller */ // PlayStation-style controller
{ "auxx", INTERNAL }, { "auxx", INTERNAL },
{ "auxtriangle",INTERNAL }, { "auxtriangle",INTERNAL },
{ "auxsquare", INTERNAL }, { "auxsquare", INTERNAL },
@@ -322,17 +328,17 @@ static void InitCharAliases()
{ "auxr3", INTERNAL }, { "auxr3", INTERNAL },
{ "auxselect", INTERNAL }, { "auxselect", INTERNAL },
{ "auxstart", INTERNAL }, { "auxstart", INTERNAL },
/* various other controllers (SNES, Saturn, Dreamcast stick styles) */ // various other controllers (SNES, Saturn, Dreamcast stick styles)
{ "auxa", INTERNAL }, { "auxa", INTERNAL },
{ "auxb", INTERNAL }, { "auxb", INTERNAL },
{ "auxc", INTERNAL }, { "auxc", INTERNAL },
{ "auxd", INTERNAL }, { "auxd", INTERNAL },
/* auxx is handled above */ // auxx is handled above
{ "auxy", INTERNAL }, { "auxy", INTERNAL },
{ "auxz", INTERNAL }, { "auxz", INTERNAL },
{ "auxl", INTERNAL }, { "auxl", INTERNAL },
{ "auxr", INTERNAL }, { "auxr", INTERNAL },
/* Xbox (original, 360)-style controllers */ // Xbox (original, 360)-style controllers
{ "auxwhite", INTERNAL }, { "auxwhite", INTERNAL },
{ "auxblack", INTERNAL }, { "auxblack", INTERNAL },
{ "auxlb", INTERNAL }, { "auxlb", INTERNAL },
@@ -362,7 +368,7 @@ static void InitCharAliases()
} }
} }
/* Replace all &markers; and &#NNNN;s with UTF-8. */ // Replace all &markers; and &#NNNN;s with UTF-8.
void FontCharAliases::ReplaceMarkers( RString &sText ) void FontCharAliases::ReplaceMarkers( RString &sText )
{ {
InitCharAliases(); InitCharAliases();
@@ -370,7 +376,7 @@ void FontCharAliases::ReplaceMarkers( RString &sText )
Replace_Unicode_Markers(sText); Replace_Unicode_Markers(sText);
} }
/* Replace all &markers; and &#NNNN;s with UTF-8. */ // Replace all &markers; and &#NNNN;s with UTF-8.
bool FontCharAliases::GetChar( RString &codepoint, wchar_t &ch ) bool FontCharAliases::GetChar( RString &codepoint, wchar_t &ch )
{ {
InitCharAliases(); InitCharAliases();
+1 -1
View File
@@ -195,7 +195,7 @@ static const wchar_t map_korean_jamo[] =
0 0
}; };
/* Numbers. "0123456789%. :x" */ /* 5x3 Numbers. "0123456789%. :x" */
static const wchar_t map_numbers[] = { static const wchar_t map_numbers[] = {
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034,
0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039,
+4 -2
View File
@@ -316,9 +316,9 @@ StringToX( StageAward );
LuaFunction( StageAwardToLocalizedString, StageAwardToLocalizedString(Enum::Check<StageAward>(L, 1)) ); LuaFunction( StageAwardToLocalizedString, StageAwardToLocalizedString(Enum::Check<StageAward>(L, 1)) );
LuaXType( StageAward ); LuaXType( StageAward );
// Numbers are intentially not at the front of these strings so that the // Numbers are intentionally not at the front of these strings so that the
// strings can be used as XML entity names. // strings can be used as XML entity names.
// Numbers are intentially not at the back so that "1000" and "10000" don't // Numbers are intentionally not at the back so that "1000" and "10000" don't
// conflict when searching for theme elements. // conflict when searching for theme elements.
static const char *PeakComboAwardNames[] = { static const char *PeakComboAwardNames[] = {
"1000", "1000",
@@ -415,7 +415,9 @@ LuaXType( EditMode );
static const char *SampleMusicPreviewModeNames[] = { static const char *SampleMusicPreviewModeNames[] = {
"Normal", "Normal",
//"StartToPreview",
"ScreenMusic", "ScreenMusic",
//"LastSong"
}; };
XToString( SampleMusicPreviewMode ); XToString( SampleMusicPreviewMode );
StringToX( SampleMusicPreviewMode ); StringToX( SampleMusicPreviewMode );
+3 -18
View File
@@ -282,8 +282,6 @@ RankingCategory AverageMeterToRankingCategory( int iAverageMeter );
extern const RString GROUP_ALL; extern const RString GROUP_ALL;
//
//
// //
enum PlayerController enum PlayerController
{ {
@@ -316,9 +314,7 @@ enum StageResult
}; };
//
// Battle stuff // Battle stuff
//
const int NUM_INVENTORY_SLOTS = 3; const int NUM_INVENTORY_SLOTS = 3;
enum AttackLevel enum AttackLevel
{ {
@@ -331,11 +327,7 @@ const int NUM_ATTACKS_PER_LEVEL = 3;
const int ITEM_NONE = -1; const int ITEM_NONE = -1;
//
// Coin stuff // Coin stuff
//
enum CoinMode enum CoinMode
{ {
CoinMode_Home, CoinMode_Home,
@@ -348,9 +340,7 @@ const RString& CoinModeToString( CoinMode cm );
LuaDeclareType( CoinMode ); LuaDeclareType( CoinMode );
//
// Premium // Premium
//
enum Premium enum Premium
{ {
Premium_Off, Premium_Off,
@@ -364,10 +354,7 @@ const RString& PremiumToLocalizedString( Premium p );
LuaDeclareType( Premium ); LuaDeclareType( Premium );
//
// Award stuff // Award stuff
//
enum StageAward enum StageAward
{ {
StageAward_FullComboW3, StageAward_FullComboW3,
@@ -460,7 +447,6 @@ const RString& EditModeToString( EditMode em );
EditMode StringToEditMode( const RString& s ); EditMode StringToEditMode( const RString& s );
LuaDeclareType( EditMode ); LuaDeclareType( EditMode );
// I wish this didn't have to be here, but for it to be a metric, it has to. -aj
/* /*
original options from ScreenEz2SelectMusic: original options from ScreenEz2SelectMusic:
(if no confirm type is mentioned, there is none.) (if no confirm type is mentioned, there is none.)
@@ -468,16 +454,15 @@ original options from ScreenEz2SelectMusic:
0 = play music as you select; SampleMusicPreviewMode_Normal 0 = play music as you select; SampleMusicPreviewMode_Normal
1 = no music plays, select 1x to play preview music, select again to confirm 1 = no music plays, select 1x to play preview music, select again to confirm
2 = no music plays at all (SampleMusicPreviewMode_ScreenMusic + redir to silent) 2 = no music plays at all (SampleMusicPreviewMode_ScreenMusic + redir to silent)
3 = play music as select, 2x to confirm 3 = play music as select, 2x to confirm (SampleMusicPreviewMode_Normal + [SSMusic] TwoPartConfirmsOnly)
4 = screen music plays; SampleMusicPreviewMode_ScreenMusic 4 = screen music plays; SampleMusicPreviewMode_ScreenMusic
Options 1 and 3 need to behave well with TWO_PART_SELECTION, and are not
currently represented because of this.
*/ */
enum SampleMusicPreviewMode enum SampleMusicPreviewMode
{ {
SampleMusicPreviewMode_Normal, SampleMusicPreviewMode_Normal,
//SampleMusicPreviewMode_StartToPreview,
SampleMusicPreviewMode_ScreenMusic, SampleMusicPreviewMode_ScreenMusic,
//SampleMusicPreviewMode_LastSong, // continue playing the last song
NUM_SampleMusicPreviewMode, NUM_SampleMusicPreviewMode,
SampleMusicPreviewMode_Invalid, SampleMusicPreviewMode_Invalid,
}; };
+19 -9
View File
@@ -62,6 +62,7 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
#define GAME_BUTTON_NEXT GAME_BUTTON_CUSTOM_01 #define GAME_BUTTON_NEXT GAME_BUTTON_CUSTOM_01
// dance
#define DANCE_BUTTON_LEFT GAME_BUTTON_CUSTOM_01 #define DANCE_BUTTON_LEFT GAME_BUTTON_CUSTOM_01
#define DANCE_BUTTON_RIGHT GAME_BUTTON_CUSTOM_02 #define DANCE_BUTTON_RIGHT GAME_BUTTON_CUSTOM_02
#define DANCE_BUTTON_UP GAME_BUTTON_CUSTOM_03 #define DANCE_BUTTON_UP GAME_BUTTON_CUSTOM_03
@@ -69,14 +70,14 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
#define DANCE_BUTTON_UPLEFT GAME_BUTTON_CUSTOM_05 #define DANCE_BUTTON_UPLEFT GAME_BUTTON_CUSTOM_05
#define DANCE_BUTTON_UPRIGHT GAME_BUTTON_CUSTOM_06 #define DANCE_BUTTON_UPRIGHT GAME_BUTTON_CUSTOM_06
#define NUM_DANCE_BUTTONS GAME_BUTTON_CUSTOM_07 #define NUM_DANCE_BUTTONS GAME_BUTTON_CUSTOM_07
// pump
#define PUMP_BUTTON_UPLEFT GAME_BUTTON_CUSTOM_01 #define PUMP_BUTTON_UPLEFT GAME_BUTTON_CUSTOM_01
#define PUMP_BUTTON_UPRIGHT GAME_BUTTON_CUSTOM_02 #define PUMP_BUTTON_UPRIGHT GAME_BUTTON_CUSTOM_02
#define PUMP_BUTTON_CENTER GAME_BUTTON_CUSTOM_03 #define PUMP_BUTTON_CENTER GAME_BUTTON_CUSTOM_03
#define PUMP_BUTTON_DOWNLEFT GAME_BUTTON_CUSTOM_04 #define PUMP_BUTTON_DOWNLEFT GAME_BUTTON_CUSTOM_04
#define PUMP_BUTTON_DOWNRIGHT GAME_BUTTON_CUSTOM_05 #define PUMP_BUTTON_DOWNRIGHT GAME_BUTTON_CUSTOM_05
#define NUM_PUMP_BUTTONS GAME_BUTTON_CUSTOM_06 #define NUM_PUMP_BUTTONS GAME_BUTTON_CUSTOM_06
// kb7
#define KB7_BUTTON_KEY1 GAME_BUTTON_CUSTOM_01 #define KB7_BUTTON_KEY1 GAME_BUTTON_CUSTOM_01
#define KB7_BUTTON_KEY2 GAME_BUTTON_CUSTOM_02 #define KB7_BUTTON_KEY2 GAME_BUTTON_CUSTOM_02
#define KB7_BUTTON_KEY3 GAME_BUTTON_CUSTOM_03 #define KB7_BUTTON_KEY3 GAME_BUTTON_CUSTOM_03
@@ -84,7 +85,7 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
#define KB7_BUTTON_KEY5 GAME_BUTTON_CUSTOM_05 #define KB7_BUTTON_KEY5 GAME_BUTTON_CUSTOM_05
#define KB7_BUTTON_KEY6 GAME_BUTTON_CUSTOM_06 #define KB7_BUTTON_KEY6 GAME_BUTTON_CUSTOM_06
#define NUM_KB7_BUTTONS GAME_BUTTON_CUSTOM_07 #define NUM_KB7_BUTTONS GAME_BUTTON_CUSTOM_07
// ez2(dancer)
#define EZ2_BUTTON_FOOTUPLEFT GAME_BUTTON_CUSTOM_01 #define EZ2_BUTTON_FOOTUPLEFT GAME_BUTTON_CUSTOM_01
#define EZ2_BUTTON_FOOTUPRIGHT GAME_BUTTON_CUSTOM_02 #define EZ2_BUTTON_FOOTUPRIGHT GAME_BUTTON_CUSTOM_02
#define EZ2_BUTTON_FOOTDOWN GAME_BUTTON_CUSTOM_03 #define EZ2_BUTTON_FOOTDOWN GAME_BUTTON_CUSTOM_03
@@ -93,14 +94,14 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
#define EZ2_BUTTON_HANDLRLEFT GAME_BUTTON_CUSTOM_06 #define EZ2_BUTTON_HANDLRLEFT GAME_BUTTON_CUSTOM_06
#define EZ2_BUTTON_HANDLRRIGHT GAME_BUTTON_CUSTOM_07 #define EZ2_BUTTON_HANDLRRIGHT GAME_BUTTON_CUSTOM_07
#define NUM_EZ2_BUTTONS GAME_BUTTON_CUSTOM_08 #define NUM_EZ2_BUTTONS GAME_BUTTON_CUSTOM_08
// para
#define PARA_BUTTON_LEFT GAME_BUTTON_CUSTOM_01 #define PARA_BUTTON_LEFT GAME_BUTTON_CUSTOM_01
#define PARA_BUTTON_UPLEFT GAME_BUTTON_CUSTOM_02 #define PARA_BUTTON_UPLEFT GAME_BUTTON_CUSTOM_02
#define PARA_BUTTON_UP GAME_BUTTON_CUSTOM_03 #define PARA_BUTTON_UP GAME_BUTTON_CUSTOM_03
#define PARA_BUTTON_UPRIGHT GAME_BUTTON_CUSTOM_04 #define PARA_BUTTON_UPRIGHT GAME_BUTTON_CUSTOM_04
#define PARA_BUTTON_RIGHT GAME_BUTTON_CUSTOM_05 #define PARA_BUTTON_RIGHT GAME_BUTTON_CUSTOM_05
#define NUM_PARA_BUTTONS GAME_BUTTON_CUSTOM_06 #define NUM_PARA_BUTTONS GAME_BUTTON_CUSTOM_06
// ds3ddx
#define DS3DDX_BUTTON_HANDLEFT GAME_BUTTON_CUSTOM_01 #define DS3DDX_BUTTON_HANDLEFT GAME_BUTTON_CUSTOM_01
#define DS3DDX_BUTTON_FOOTDOWNLEFT GAME_BUTTON_CUSTOM_02 #define DS3DDX_BUTTON_FOOTDOWNLEFT GAME_BUTTON_CUSTOM_02
#define DS3DDX_BUTTON_FOOTUPLEFT GAME_BUTTON_CUSTOM_03 #define DS3DDX_BUTTON_FOOTUPLEFT GAME_BUTTON_CUSTOM_03
@@ -110,7 +111,7 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
#define DS3DDX_BUTTON_FOOTDOWNRIGHT GAME_BUTTON_CUSTOM_07 #define DS3DDX_BUTTON_FOOTDOWNRIGHT GAME_BUTTON_CUSTOM_07
#define DS3DDX_BUTTON_HANDRIGHT GAME_BUTTON_CUSTOM_08 #define DS3DDX_BUTTON_HANDRIGHT GAME_BUTTON_CUSTOM_08
#define NUM_DS3DDX_BUTTONS GAME_BUTTON_CUSTOM_09 #define NUM_DS3DDX_BUTTONS GAME_BUTTON_CUSTOM_09
// beat
#define BEAT_BUTTON_KEY1 GAME_BUTTON_CUSTOM_01 #define BEAT_BUTTON_KEY1 GAME_BUTTON_CUSTOM_01
#define BEAT_BUTTON_KEY2 GAME_BUTTON_CUSTOM_02 #define BEAT_BUTTON_KEY2 GAME_BUTTON_CUSTOM_02
#define BEAT_BUTTON_KEY3 GAME_BUTTON_CUSTOM_03 #define BEAT_BUTTON_KEY3 GAME_BUTTON_CUSTOM_03
@@ -121,13 +122,13 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
#define BEAT_BUTTON_SCRATCHUP GAME_BUTTON_CUSTOM_08 #define BEAT_BUTTON_SCRATCHUP GAME_BUTTON_CUSTOM_08
#define BEAT_BUTTON_SCRATCHDOWN GAME_BUTTON_CUSTOM_09 #define BEAT_BUTTON_SCRATCHDOWN GAME_BUTTON_CUSTOM_09
#define NUM_BEAT_BUTTONS GAME_BUTTON_CUSTOM_10 #define NUM_BEAT_BUTTONS GAME_BUTTON_CUSTOM_10
// maniax
#define MANIAX_BUTTON_HANDUPLEFT GAME_BUTTON_CUSTOM_01 #define MANIAX_BUTTON_HANDUPLEFT GAME_BUTTON_CUSTOM_01
#define MANIAX_BUTTON_HANDUPRIGHT GAME_BUTTON_CUSTOM_02 #define MANIAX_BUTTON_HANDUPRIGHT GAME_BUTTON_CUSTOM_02
#define MANIAX_BUTTON_HANDLRLEFT GAME_BUTTON_CUSTOM_03 #define MANIAX_BUTTON_HANDLRLEFT GAME_BUTTON_CUSTOM_03
#define MANIAX_BUTTON_HANDLRRIGHT GAME_BUTTON_CUSTOM_04 #define MANIAX_BUTTON_HANDLRRIGHT GAME_BUTTON_CUSTOM_04
#define NUM_MANIAX_BUTTONS GAME_BUTTON_CUSTOM_05 #define NUM_MANIAX_BUTTONS GAME_BUTTON_CUSTOM_05
// techno
#define TECHNO_BUTTON_LEFT GAME_BUTTON_CUSTOM_01 #define TECHNO_BUTTON_LEFT GAME_BUTTON_CUSTOM_01
#define TECHNO_BUTTON_RIGHT GAME_BUTTON_CUSTOM_02 #define TECHNO_BUTTON_RIGHT GAME_BUTTON_CUSTOM_02
#define TECHNO_BUTTON_UP GAME_BUTTON_CUSTOM_03 #define TECHNO_BUTTON_UP GAME_BUTTON_CUSTOM_03
@@ -138,7 +139,7 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
#define TECHNO_BUTTON_DOWNLEFT GAME_BUTTON_CUSTOM_08 #define TECHNO_BUTTON_DOWNLEFT GAME_BUTTON_CUSTOM_08
#define TECHNO_BUTTON_DOWNRIGHT GAME_BUTTON_CUSTOM_09 #define TECHNO_BUTTON_DOWNRIGHT GAME_BUTTON_CUSTOM_09
#define NUM_TECHNO_BUTTONS GAME_BUTTON_CUSTOM_10 #define NUM_TECHNO_BUTTONS GAME_BUTTON_CUSTOM_10
// popn
#define POPN_BUTTON_LEFT_WHITE GAME_BUTTON_CUSTOM_01 #define POPN_BUTTON_LEFT_WHITE GAME_BUTTON_CUSTOM_01
#define POPN_BUTTON_LEFT_YELLOW GAME_BUTTON_CUSTOM_02 #define POPN_BUTTON_LEFT_YELLOW GAME_BUTTON_CUSTOM_02
#define POPN_BUTTON_LEFT_GREEN GAME_BUTTON_CUSTOM_03 #define POPN_BUTTON_LEFT_GREEN GAME_BUTTON_CUSTOM_03
@@ -149,6 +150,15 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
#define POPN_BUTTON_RIGHT_YELLOW GAME_BUTTON_CUSTOM_08 #define POPN_BUTTON_RIGHT_YELLOW GAME_BUTTON_CUSTOM_08
#define POPN_BUTTON_RIGHT_WHITE GAME_BUTTON_CUSTOM_09 #define POPN_BUTTON_RIGHT_WHITE GAME_BUTTON_CUSTOM_09
#define NUM_POPN_BUTTONS GAME_BUTTON_CUSTOM_10 #define NUM_POPN_BUTTONS GAME_BUTTON_CUSTOM_10
// guitar
#define GUITAR_BUTTON_FRET1 GAME_BUTTON_CUSTOM_01
#define GUITAR_BUTTON_FRET2 GAME_BUTTON_CUSTOM_02
#define GUITAR_BUTTON_FRET3 GAME_BUTTON_CUSTOM_03
#define GUITAR_BUTTON_FRET4 GAME_BUTTON_CUSTOM_04
#define GUITAR_BUTTON_FRET5 GAME_BUTTON_CUSTOM_05
#define GUITAR_BUTTON_STRUM_UP GAME_BUTTON_CUSTOM_06
#define GUITAR_BUTTON_STRUM_DOWN GAME_BUTTON_CUSTOM_07
#define NUM_GUITAR_BUTTONS GAME_BUTTON_CUSTOM_08
#define KARAOKE_BUTTON_LEFT GAME_BUTTON_CUSTOM_01 #define KARAOKE_BUTTON_LEFT GAME_BUTTON_CUSTOM_01
#define NUM_KARAOKE_BUTTONS GAME_BUTTON_CUSTOM_02 #define NUM_KARAOKE_BUTTONS GAME_BUTTON_CUSTOM_02
+46 -20
View File
@@ -2548,8 +2548,8 @@ static const Game g_Game_Popn =
/** Guitar5 ******************************************************************/ /** Guitar5 ******************************************************************/
//ThemeMetric<int> GUITAR5_COL_SPACING ("ColumnSpacing","Guitar5"); //ThemeMetric<int> GUITAR5_COL_SPACING ("ColumnSpacing","Guitar5");
static const int GUITAR5_COL_SPACING = 32; static const int GUITAR5_COL_SPACING = 48; // todo: get a proper value? -aj
/*
static const Style g_Style_Guitar_Five = static const Style g_Style_Guitar_Five =
{ // STYLE_GUITAR_FIVE { // STYLE_GUITAR_FIVE
true, // m_bUsedForGameplay true, // m_bUsedForGameplay
@@ -2577,8 +2577,8 @@ static const Style g_Style_Guitar_Five =
}, },
}, },
{ // m_iInputColumn[NUM_GameController][NUM_GameButton] { // m_iInputColumn[NUM_GameController][NUM_GameButton]
{ 0, 4, 3, 2, 1, Style::END_MAPPING }, { 0, 1, 2, 3, 4, Style::END_MAPPING },
{ 0, 4, 3, 2, 1, Style::END_MAPPING }, { 0, 1, 2, 3, 4, Style::END_MAPPING },
}, },
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER]; { // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
0,1,2,3,4 0,1,2,3,4
@@ -2595,39 +2595,64 @@ static const Style *g_apGame_Guitar_Styles[] =
}; };
// auto keymappings // auto keymappings
static const AutoMappings g_AutoKeyMappings_Guitar = AutoMappings (
"",
"",
"",
// p1
AutoMappingEntry( 0, KEY_Cz, GUITAR_BUTTON_FRET1, false ),
AutoMappingEntry( 0, KEY_Cx, GUITAR_BUTTON_FRET2, false ),
AutoMappingEntry( 0, KEY_Cc, GUITAR_BUTTON_FRET3, false ),
AutoMappingEntry( 0, KEY_Cv, GUITAR_BUTTON_FRET4, false ),
AutoMappingEntry( 0, KEY_Cb, GUITAR_BUTTON_FRET5, false ),
AutoMappingEntry( 0, KEY_UP, GUITAR_BUTTON_STRUM_UP, false ),
AutoMappingEntry( 0, KEY_DOWN, GUITAR_BUTTON_STRUM_DOWN,false ),
// p2
AutoMappingEntry( 0, KEY_Cy, GUITAR_BUTTON_FRET1, true ),
AutoMappingEntry( 0, KEY_Cu, GUITAR_BUTTON_FRET2, true ),
AutoMappingEntry( 0, KEY_Ci, GUITAR_BUTTON_FRET3, true ),
AutoMappingEntry( 0, KEY_Co, GUITAR_BUTTON_FRET4, true ),
AutoMappingEntry( 0, KEY_Cp, GUITAR_BUTTON_FRET5, true ),
AutoMappingEntry( 0, KEY_KP_C8, GUITAR_BUTTON_STRUM_UP, true ),
AutoMappingEntry( 0, KEY_KP_C5, GUITAR_BUTTON_STRUM_DOWN,true )
);
static const Game g_Game_Guitar = static const Game g_Game_Guitar =
{ {
"guitar", // m_szName "guitar", // m_szName
g_apGame_Guitar_Styles, // m_apStyles g_apGame_Guitar_Styles, // m_apStyles
true, // m_bCountNotesSeparately false, // m_bCountNotesSeparately (false stops crashes and failing)
true, // m_bAllowHopos true, // m_bAllowHopos
{ // m_InputScheme { // m_InputScheme
"guitar", // m_szName "guitar", // m_szName
NUM_GUITAR_BUTTONS, // m_iButtonsPerController NUM_GUITAR_BUTTONS, // m_iButtonsPerController
{ // m_szButtonNames { // m_szButtonNames
{ "Button Name", GameButton_Invalid }, { "Fret1", GAME_BUTTON_START },
{ "Fret2", GAME_BUTTON_BACK },
{ "Fret3", GameButton_Invalid },
{ "Fret4", GameButton_Invalid },
{ "Fret5", GameButton_Invalid },
{ "StrumUp", GAME_BUTTON_UP },
{ "StrumDown", GAME_BUTTON_DOWN },
}, },
&g_AutoKeyMappings_Guitar &g_AutoKeyMappings_Guitar
}, },
{ {
{ GameButtonType_Step }, { GameButtonType_Fret }, // Green
{ GameButtonType_Step }, { GameButtonType_Fret }, // Red
{ GameButtonType_Step }, { GameButtonType_Fret }, // Yellow
{ GameButtonType_Step }, { GameButtonType_Fret }, // Blue
{ GameButtonType_Step }, { GameButtonType_Fret }, // Orange
{ GameButtonType_Step }, { GameButtonType_Strum },
{ GameButtonType_Step }, { GameButtonType_Strum },
{ GameButtonType_Step },
{ GameButtonType_Step },
}, },
TNS_W1, // m_mapW1To TNS_W1, // m_mapW1To
TNS_W1, // m_mapW2To TNS_W2, // m_mapW2To
TNS_W1, // m_mapW3To TNS_W3, // m_mapW3To
TNS_W1, // m_mapW4To TNS_W4, // m_mapW4To
TNS_Miss, // m_mapW5To TNS_W5, // m_mapW5To
}; };
*/
/** Karaoke ******************************************************************/ /** Karaoke ******************************************************************/
static const Style g_Style_Karaoke_Single = static const Style g_Style_Karaoke_Single =
@@ -2813,6 +2838,7 @@ static const Game *g_Games[] =
&g_Game_Maniax, &g_Game_Maniax,
&g_Game_Techno, &g_Game_Techno,
&g_Game_Popn, &g_Game_Popn,
//&g_Game_Guitar, // nope, still broken. -aj
&g_Game_Karaoke, &g_Game_Karaoke,
&g_Game_Lights, &g_Game_Lights,
}; };
+3 -3
View File
@@ -49,12 +49,12 @@ struct MusicPlaying
bool m_bTimingDelayed; bool m_bTimingDelayed;
bool m_bHasTiming; bool m_bHasTiming;
bool m_bApplyMusicRate; bool m_bApplyMusicRate;
/* The timing data that we're currently using. */ // The timing data that we're currently using.
TimingData m_Timing; TimingData m_Timing;
NoteData m_Lights; NoteData m_Lights;
/* If m_bTimingDelayed is true, this will be the timing data for the song that's starting. /* If m_bTimingDelayed is true, this will be the timing data for the
* We'll copy it to m_Timing once sound is heard. */ * song that's starting. We'll copy it to m_Timing once sound is heard. */
TimingData m_NewTiming; TimingData m_NewTiming;
RageSound *m_Music; RageSound *m_Music;
MusicPlaying( RageSound *Music ) MusicPlaying( RageSound *Music )
+46 -7
View File
@@ -205,7 +205,7 @@ void GameState::ApplyGameCommand( const RString &sCommand, PlayerNumber pn )
void GameState::ApplyCmdline() void GameState::ApplyCmdline()
{ {
/* We need to join players before we can set the style. */ // We need to join players before we can set the style.
RString sPlayer; RString sPlayer;
for( int i = 0; GetCommandlineArgument( "player", &sPlayer, i ); ++i ) for( int i = 0; GetCommandlineArgument( "player", &sPlayer, i ); ++i )
{ {
@@ -240,6 +240,7 @@ void GameState::ResetPlayer( PlayerNumber pn )
m_pPlayerState[pn]->m_PlayerOptions.Assign( ModsLevel_Preferred, po ); m_pPlayerState[pn]->m_PlayerOptions.Assign( ModsLevel_Preferred, po );
} }
//static Preference<bool> g_bMultiplayer( "Multiplayer", false );
void GameState::Reset() void GameState::Reset()
{ {
m_MasterPlayerNumber = PLAYER_INVALID; // must initialize for UnjoinPlayer m_MasterPlayerNumber = PLAYER_INVALID; // must initialize for UnjoinPlayer
@@ -346,7 +347,7 @@ void GameState::JoinPlayer( PlayerNumber pn )
if( GetNumSidesJoined() == 1 ) if( GetNumSidesJoined() == 1 )
BeginGame(); BeginGame();
/* Count each player join as a play. */ // Count each player join as a play.
{ {
Profile* pMachineProfile = PROFILEMAN->GetMachineProfile(); Profile* pMachineProfile = PROFILEMAN->GetMachineProfile();
pMachineProfile->m_iTotalSessions++; pMachineProfile->m_iTotalSessions++;
@@ -889,11 +890,14 @@ void GameState::ResetMusicStatistics()
//m_bStop = false; //m_bStop = false;
m_bFreeze = false; m_bFreeze = false;
m_bDelay = false; m_bDelay = false;
/*
m_iWarpToRow = -1; // Set to -1 because some song may want to warp to row 0. -aj
m_iWarpFromRow = -1; // Set when a warp is encountered. also see above. -aj
*/
m_fMusicSecondsVisible = 0; m_fMusicSecondsVisible = 0;
m_fSongBeatVisible = 0; m_fSongBeatVisible = 0;
Actor::SetBGMTime( 0, 0, 0, 0 ); Actor::SetBGMTime( 0, 0, 0, 0 );
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
m_pPlayerState[p]->ClearHopoState(); m_pPlayerState[p]->ClearHopoState();
} }
@@ -935,17 +939,35 @@ void GameState::ResetStageStatistics()
} }
static Preference<float> g_fVisualDelaySeconds( "VisualDelaySeconds", 0.0f ); static Preference<float> g_fVisualDelaySeconds( "VisualDelaySeconds", 0.0f );
// todo: modify for warps -aj
// m_iWarpToRow
void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer &timestamp ) void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer &timestamp )
{ {
if( !timestamp.IsZero() ) if( !timestamp.IsZero() )
m_LastBeatUpdate = timestamp; m_LastBeatUpdate = timestamp;
else else
m_LastBeatUpdate.Touch(); m_LastBeatUpdate.Touch();
/*
// xxx testing: only do this on monotune survivor
if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" )
LOG->Trace( ssprintf("[GameState::UpdateSongPosition] cur BPS = %f, fPositionSeconds = %f",m_fCurBPS,fPositionSeconds) );
*/
timing.GetBeatAndBPSFromElapsedTime( fPositionSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze, m_bDelay ); timing.GetBeatAndBPSFromElapsedTime( fPositionSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze, m_bDelay );
// "Crash reason : -243478.890625 -48695.773438" // "Crash reason : -243478.890625 -48695.773438"
ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds", m_fSongBeat, fPositionSeconds) ); ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds", m_fSongBeat, fPositionSeconds) );
/*
// xxx testing: only do this on monotune survivor
if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" )
LOG->Trace( ssprintf("[GameState::UpdateSongPosition] m_fMusicSeconds before = %f",m_fMusicSeconds) );
*/
m_fMusicSeconds = fPositionSeconds; m_fMusicSeconds = fPositionSeconds;
/*
// xxx testing: only do this on monotune survivor
if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" )
LOG->Trace( ssprintf("[GameState::UpdateSongPosition] m_fMusicSeconds after = %f",m_fMusicSeconds) );
*/
m_fLightSongBeat = timing.GetBeatFromElapsedTime( fPositionSeconds + g_fLightsAheadSeconds ); m_fLightSongBeat = timing.GetBeatFromElapsedTime( fPositionSeconds + g_fLightsAheadSeconds );
m_fSongBeatNoOffset = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds ); m_fSongBeatNoOffset = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds );
@@ -955,6 +977,25 @@ void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &ti
bool bThrowAway; bool bThrowAway;
timing.GetBeatAndBPSFromElapsedTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fThrowAway, bThrowAway, bThrowAway ); timing.GetBeatAndBPSFromElapsedTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fThrowAway, bThrowAway, bThrowAway );
/*
// xxx testing: only do this on monotune survivor
if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" )
{
// and only do it in the known negative bpm region. HACKITY HACK
if(m_fSongBeat >= 445.490f && m_fSongBeat <= 453.72f)
{
LOG->Trace( ssprintf("fPositionSeconds = %f",fPositionSeconds) );
LOG->Trace( ssprintf("Song beat: %f (%f seconds), BPS = %f (%f BPM)",m_fSongBeat,m_fMusicSecondsVisible,m_fCurBPS,m_fCurBPS*60.0f) );
//LOG->Trace( ssprintf("Music seconds visible %f = fPositionSeconds %f - g_fVisualDelaySeconds %f", m_fMusicSecondsVisible,fPositionSeconds,g_fVisualDelaySeconds.Get()) );
}
else if(m_fSongBeat == 445.500f)
{
LOG->Trace( ssprintf("[beat 445.500] fPositionSeconds = %f",fPositionSeconds) );
LOG->Trace( ssprintf("Song beat: %f (%f seconds), BPS = %f (%f BPM)",m_fSongBeat,m_fMusicSecondsVisible,m_fCurBPS,m_fCurBPS*60.0f) );
}
}
*/
Actor::SetBGMTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fPositionSeconds, m_fSongBeatNoOffset ); Actor::SetBGMTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fPositionSeconds, m_fSongBeatNoOffset );
// LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f, m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze ); // LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f, m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze );
} }
@@ -965,7 +1006,7 @@ update player position code goes here
float GameState::GetSongPercent( float beat ) const float GameState::GetSongPercent( float beat ) const
{ {
/* 0 = first step; 1 = last step */ // 0 = first step; 1 = last step
return (beat - m_pCurSong->m_fFirstBeat) / m_pCurSong->m_fLastBeat; return (beat - m_pCurSong->m_fFirstBeat) / m_pCurSong->m_fLastBeat;
} }
@@ -1482,7 +1523,7 @@ PlayerOptions::FailType GameState::GetPlayerFailType( const PlayerState *pPlayer
if( !IsEventMode() ) if( !IsEventMode() )
bFirstStage |= m_iPlayerStageTokens[pPlayerState->m_PlayerNumber] == PREFSMAN->m_iSongsPerPlay-1; // HACK; -1 because this is called during gameplay bFirstStage |= m_iPlayerStageTokens[pPlayerState->m_PlayerNumber] == PREFSMAN->m_iSongsPerPlay-1; // HACK; -1 because this is called during gameplay
/* Easy and beginner are never harder than FAIL_IMMEDIATE_CONTINUE. */ // Easy and beginner are never harder than FAIL_IMMEDIATE_CONTINUE.
if( dc <= Difficulty_Easy ) if( dc <= Difficulty_Easy )
setmax( ft, PlayerOptions::FAIL_IMMEDIATE_CONTINUE ); setmax( ft, PlayerOptions::FAIL_IMMEDIATE_CONTINUE );
@@ -1535,11 +1576,9 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
StepsType st = GetCurrentStyle()->m_StepsType; StepsType st = GetCurrentStyle()->m_StepsType;
//
// Find unique Song and Steps combinations that were played. // Find unique Song and Steps combinations that were played.
// We must keep only the unique combination or else we'll double-count // We must keep only the unique combination or else we'll double-count
// high score markers. // high score markers.
//
vector<SongAndSteps> vSongAndSteps; vector<SongAndSteps> vSongAndSteps;
for( unsigned i=0; i<STATSMAN->m_vPlayedStageStats.size(); i++ ) for( unsigned i=0; i<STATSMAN->m_vPlayedStageStats.size(); i++ )
+1
View File
@@ -184,6 +184,7 @@ public:
//bool m_bStop; // in the middle of a stop (freeze or delay) //bool m_bStop; // in the middle of a stop (freeze or delay)
bool m_bFreeze; // in the middle of a freeze bool m_bFreeze; // in the middle of a freeze
bool m_bDelay; // in the middle of a delay bool m_bDelay; // in the middle of a delay
//int m_iWarpToRow, m_iWarpFromRow; // used for warping
RageTimer m_LastBeatUpdate; // time of last m_fSongBeat, etc. update RageTimer m_LastBeatUpdate; // time of last m_fSongBeat, etc. update
BroadcastOnChange<bool> m_bGameplayLeadIn; BroadcastOnChange<bool> m_bGameplayLeadIn;
-4
View File
@@ -174,9 +174,7 @@ void GraphDisplay::Set( const StageStats &ss, const PlayerStageStats &pss )
UpdateVerts(); UpdateVerts();
//
// Show song boundaries // Show song boundaries
//
float fSec = 0; float fSec = 0;
FOREACH_CONST( Song*, ss.m_vpPossibleSongs, song ) FOREACH_CONST( Song*, ss.m_vpPossibleSongs, song )
{ {
@@ -193,9 +191,7 @@ void GraphDisplay::Set( const StageStats &ss, const PlayerStageStats &pss )
if( !pss.m_bFailed ) if( !pss.m_bFailed )
{ {
//
// Search for the min life record to show "Just Barely!" // Search for the min life record to show "Just Barely!"
//
float fMinLifeSoFar = 1.0f; float fMinLifeSoFar = 1.0f;
int iMinLifeSoFarAt = 0; int iMinLifeSoFarAt = 0;
-2
View File
@@ -18,9 +18,7 @@ public:
void Load( RString sMetricsGroup ); void Load( RString sMetricsGroup );
void Set( const StageStats &ss, const PlayerStageStats &s ); void Set( const StageStats &ss, const PlayerStageStats &s );
//
// Lua // Lua
//
virtual void PushSelf( lua_State *L ); virtual void PushSelf( lua_State *L );
private: private:
+2 -1
View File
@@ -44,7 +44,7 @@ static SortOrder ForceAppropriateSort( PlayMode pm, SortOrder so )
case PLAY_MODE_ENDLESS: return SORT_ENDLESS_COURSES; case PLAY_MODE_ENDLESS: return SORT_ENDLESS_COURSES;
} }
/* If we're not in a course mode, don't start in a course sort. */ // If we're not in a course mode, don't start in a course sort.
switch( so ) switch( so )
{ {
case SORT_ONI_COURSES: case SORT_ONI_COURSES:
@@ -576,6 +576,7 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
{ {
if( SHOW_ROULETTE ) if( SHOW_ROULETTE )
arrayWheelItemDatas.push_back( new MusicWheelItemData(TYPE_ROULETTE, NULL, "", NULL, RageColor(1,0,0,1), 0) ); arrayWheelItemDatas.push_back( new MusicWheelItemData(TYPE_ROULETTE, NULL, "", NULL, RageColor(1,0,0,1), 0) );
// Only add TYPE_PORTAL if there's at least one song on the list. // Only add TYPE_PORTAL if there's at least one song on the list.
bool bFoundAnySong = false; bool bFoundAnySong = false;
for( unsigned i=0; !bFoundAnySong && i < arrayWheelItemDatas.size(); i++ ) for( unsigned i=0; !bFoundAnySong && i < arrayWheelItemDatas.size(); i++ )
+6 -28
View File
@@ -379,7 +379,7 @@ void NoteField::DrawAreaHighlight( int iStartBeat, int iEndBeat )
m_rectAreaHighlight.Draw(); m_rectAreaHighlight.Draw();
} }
// todo: add DrawWarpAreaBG? -aj
void NoteField::DrawBPMText( const float fBeat, const float fBPM ) void NoteField::DrawBPMText( const float fBeat, const float fBPM )
{ {
@@ -494,11 +494,9 @@ float FindFirstDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistance
float FindLastDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceBeforeTargetsPixels ) float FindLastDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceBeforeTargetsPixels )
{ {
//
// Probe for last note to draw. // Probe for last note to draw.
// worst case is 0.25x + boost. Adjust search distance to // worst case is 0.25x + boost. Adjust search distance to
// so that notes don't pop onto the screen. // so that notes don't pop onto the screen.
//
float fSearchDistance = 10; float fSearchDistance = 10;
float fLastBeatToDraw = GAMESTATE->m_fSongBeat+fSearchDistance; float fLastBeatToDraw = GAMESTATE->m_fSongBeat+fSearchDistance;
@@ -547,7 +545,7 @@ void NoteField::DrawPrimitives()
{ {
//LOG->Trace( "NoteField::DrawPrimitives()" ); //LOG->Trace( "NoteField::DrawPrimitives()" );
/* This should be filled in on the first update. */ // This should be filled in on the first update.
ASSERT( m_pCurDisplay != NULL ); ASSERT( m_pCurDisplay != NULL );
ArrowEffects::Update(); ArrowEffects::Update();
@@ -556,9 +554,7 @@ void NoteField::DrawPrimitives()
const PlayerOptions &current_po = m_pPlayerState->m_PlayerOptions.GetCurrent(); const PlayerOptions &current_po = m_pPlayerState->m_PlayerOptions.GetCurrent();
//
// Adjust draw range depending on some effects // Adjust draw range depending on some effects
//
int iDrawDistanceAfterTargetsPixels = m_iDrawDistanceAfterTargetsPixels; int iDrawDistanceAfterTargetsPixels = m_iDrawDistanceAfterTargetsPixels;
// HACK: if boomerang and centered are on, then we want to draw much // HACK: if boomerang and centered are on, then we want to draw much
// earlier to that the notes don't pop on screen. // earlier to that the notes don't pop on screen.
@@ -590,24 +586,18 @@ void NoteField::DrawPrimitives()
#define IS_ON_SCREEN( fBeat ) IsOnScreen( fBeat, 0, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels ) #define IS_ON_SCREEN( fBeat ) IsOnScreen( fBeat, 0, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels )
//
// Draw board // Draw board
//
if( SHOW_BOARD ) if( SHOW_BOARD )
{ {
DrawBoard( iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels ); DrawBoard( iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels );
} }
//
// Draw Receptors // Draw Receptors
//
{ {
cur->m_ReceptorArrowRow.Draw(); cur->m_ReceptorArrowRow.Draw();
} }
//
// Draw beat bars // Draw beat bars
//
if( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) if( GAMESTATE->IsEditing() || SHOW_BEAT_BARS )
{ {
const vector<TimeSignatureSegment> &vTimeSignatureSegments = GAMESTATE->m_pCurSong->m_Timing.m_vTimeSignatureSegments; const vector<TimeSignatureSegment> &vTimeSignatureSegments = GAMESTATE->m_pCurSong->m_Timing.m_vTimeSignatureSegments;
@@ -692,7 +682,7 @@ void NoteField::DrawPrimitives()
} }
} }
// todo: add warp text // todo: add warp text -aj
// Course mods text // Course mods text
const Course *pCourse = GAMESTATE->m_pCurCourse; const Course *pCourse = GAMESTATE->m_pCurCourse;
@@ -715,9 +705,7 @@ void NoteField::DrawPrimitives()
} }
} }
//
// BGChange text // BGChange text
//
switch( GAMESTATE->m_EditMode ) switch( GAMESTATE->m_EditMode )
{ {
case EditMode_Home: case EditMode_Home:
@@ -783,9 +771,7 @@ void NoteField::DrawPrimitives()
ASSERT(0); ASSERT(0);
} }
//
// Draw marker bars // Draw marker bars
//
if( m_iBeginMarker != -1 && m_iEndMarker != -1 ) if( m_iBeginMarker != -1 && m_iEndMarker != -1 )
{ {
int iBegin = m_iBeginMarker; int iBegin = m_iBeginMarker;
@@ -809,12 +795,9 @@ void NoteField::DrawPrimitives()
} }
//
// Optimization is very important here because there are so many arrows to draw. // Optimization is very important here because there are so many arrows to draw.
// Draw the arrows in order of column. This minimize texture switches and let us // Draw the arrows in order of column. This minimize texture switches and let us
// draw in big batches. // draw in big batches.
//
float fSelectedRangeGlow = SCALE( RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f ); float fSelectedRangeGlow = SCALE( RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f );
@@ -827,9 +810,7 @@ void NoteField::DrawPrimitives()
bool bAnyUpcomingInThisCol = false; bool bAnyUpcomingInThisCol = false;
//
// Draw all HoldNotes in this column (so that they appear under the tap notes) // Draw all HoldNotes in this column (so that they appear under the tap notes)
//
{ {
NoteData::TrackMap::const_iterator begin, end; NoteData::TrackMap::const_iterator begin, end;
m_pNoteData->GetTapNoteRangeInclusive( c, iFirstRowToDraw, iLastRowToDraw+1, begin, end ); m_pNoteData->GetTapNoteRangeInclusive( c, iFirstRowToDraw, iLastRowToDraw+1, begin, end );
@@ -889,10 +870,7 @@ void NoteField::DrawPrimitives()
} }
} }
//
// Draw all TapNotes in this column // Draw all TapNotes in this column
//
// draw notes from furthest to closest // draw notes from furthest to closest
@@ -909,7 +887,7 @@ void NoteField::DrawPrimitives()
continue; // skip continue; // skip
} }
/* Don't draw hidden (fully judged) steps. */ // Don't draw hidden (fully judged) steps.
if( tn.result.bHidden ) if( tn.result.bHidden )
continue; continue;
@@ -922,8 +900,8 @@ void NoteField::DrawPrimitives()
ASSERT_M( NoteRowToBeat(i) > -2000, ssprintf("%i %i %i, %f %f", i, iLastRowToDraw, iFirstRowToDraw, GAMESTATE->m_fSongBeat, GAMESTATE->m_fMusicSeconds) ); ASSERT_M( NoteRowToBeat(i) > -2000, ssprintf("%i %i %i, %f %f", i, iLastRowToDraw, iFirstRowToDraw, GAMESTATE->m_fSongBeat, GAMESTATE->m_fMusicSeconds) );
// See if there is a hold step that begins on this index. Only do this // See if there is a hold step that begins on this index.
// if the note skin cares. // Only do this if the noteskin cares.
bool bHoldNoteBeginsOnThisBeat = false; bool bHoldNoteBeginsOnThisBeat = false;
if( m_pCurDisplay->display[c].DrawHoldHeadForTapsOnSameRow() ) if( m_pCurDisplay->display[c].DrawHoldHeadForTapsOnSameRow() )
{ {
+92 -13
View File
@@ -88,6 +88,9 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
out.m_fBeat0OffsetInSeconds = 0; out.m_fBeat0OffsetInSeconds = 0;
out.m_BPMSegments.clear(); out.m_BPMSegments.clear();
out.m_StopSegments.clear(); out.m_StopSegments.clear();
//out.m_WarpSegments.clear();
//vector<WarpSegment> arrayWarpsFromNegativeBPMs;
for( unsigned i=0; i<msd.GetNumValues(); i++ ) for( unsigned i=0; i<msd.GetNumValues(); i++ )
{ {
@@ -174,11 +177,59 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
const float fBeat = StringToFloat( arrayBPMChangeValues[0] ); const float fBeat = StringToFloat( arrayBPMChangeValues[0] );
const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] );
// todo: convert negative BPMs into Warp segments // convert negative BPMs into Warp segments
/*
if( fNewBPM < 0.0f )
{
vector<RString> arrayNextBPMChangeValues;
// get next bpm in sequence
if((b+1) < arrayBPMChangeExpressions.size())
{
split( arrayBPMChangeExpressions[b+1], "=", arrayNextBPMChangeValues );
const float fNextPositiveBeat = StringToFloat( arrayNextBPMChangeValues[0] );
const float fNextPositiveBPM = StringToFloat( arrayNextBPMChangeValues[1] );
//LOG->Trace( ssprintf("String (%s) vs. BPM (%f)",arrayNextBPMChangeValues[1].c_str(),fNextPositiveBPM) );
// tJumpPos = (tPosBPS-abs(negBPS)) + (gPosBPMPosition - fNegPosition)
float fDeltaBeat = ((fNextPositiveBPM/60.0f)-abs(fNewBPM/60.0f)) + (fNextPositiveBeat-fBeat);
float fWarpToBeat = fNextPositiveBeat + fDeltaBeat;
WarpSegment wsTemp(BeatToNoteRow(fBeat),BeatToNoteRow(fWarpToBeat));
arrayWarpsFromNegativeBPMs.push_back(wsTemp);
*/
/*
LOG->Trace( ssprintf("==NotesLoSM negbpm==\nfnextposbeat = %f, fnextposbpm = %f,\nfdelta = %f, fwarpto = %f",
fNextPositiveBeat,
fNextPositiveBPM,
fDeltaBeat,
fWarpToBeat
) );
*/
/*
LOG->Trace( ssprintf("==Negative/Subtractive BPM in NotesLoader==\nNegBPM has noterow = %i, BPM = %f\nNextBPM @ noterow %i\nDelta value = %i noterows\nThis warp will have us end up at noterow %i",
BeatToNoteRow(fBeat), fNewBPM,
BeatToNoteRow(fNextPositiveBeat),
BeatToNoteRow(fDeltaBeat),
BeatToNoteRow(fWarpToBeat))
);
*/
//float fDeltaBeat = ((fNextPositiveBPM/60.0f)-abs(fNewBPM/60.0f)) + (fNextPositiveBeat-fBeat);
/*
LOG->Trace( ssprintf("==NotesLoader Delta as NoteRows==\nfDeltaBeat = %f (beat)\nfDeltaBeat = (NextBPMSeg %f - abs(fBPS %f)) + (nextStartRow %i - thisRow %i)",
fDeltaBeat,(fNextPositiveBPM/60.0f),abs(fNewBPM/60.0f),BeatToNoteRow(fNextPositiveBeat),BeatToNoteRow(fBeat))
);
*/
/*
}
else
{
// last BPM is a negative one? ugh. -aj (MAX_NOTE_ROW exists btw)
}
}
*/
if( PREFSMAN->m_bQuirksMode ) if( PREFSMAN->m_bQuirksMode )
{ {
// in quirks mode, accept all BPMs, not just positives. // in quirks mode, accept all BPMs, not just positives.
// xxx: make this work for decent simfiles only? -aj // xxx: make this work for decent simfiles only? (lol) -aj
out.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); out.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) );
} }
else else
@@ -257,12 +308,36 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
const float fWarpAt = StringToFloat( arrayWarpValues[0] ); const float fWarpAt = StringToFloat( arrayWarpValues[0] );
const float fWarpTo = StringToFloat( arrayWarpValues[1] ); const float fWarpTo = StringToFloat( arrayWarpValues[1] );
if( fWarpAt > 0.0f && fWarpTo > 0.0f )
{
WarpSegment new_seg( BeatToNoteRow(fWarpAt), BeatToNoteRow(fWarpTo) ); WarpSegment new_seg( BeatToNoteRow(fWarpAt), BeatToNoteRow(fWarpTo) );
// LOG->Trace( "Adding a warp segment: starts at %f, jumps to %f", new_seg.m_iStartRow, new_seg.m_iEndRow ); // LOG->Trace( "Adding a warp segment: starts at %f, jumps to %f", new_seg.m_iStartRow, new_seg.m_iEndRow );
out.AddWarpSegment( new_seg ); out.AddWarpSegment( new_seg );
} }
else
{
// Disallow negative warps, to prevent the same kind of
// problem that happened when Negative/Subtractive BPMs
// arrived on the StepMania scene. -aj
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid warp: from beat %f to beat %f.", fWarpAt, fWarpTo );
}
}
}
// We should not support files that contain both Negative BPMs & Warps.
// If Warps have been populated from Negative BPMs, then go through that
// instead of using the data in the Warps tag. This should be above,
// but it breaks compiling so...
{
if(arrayWarpsFromNegativeBPMs.size() > 0)
{
// zomg we already have some warps...
for( unsigned i=0; i<arrayWarpsFromNegativeBPMs.size(); i++ )
{
out.AddWarpSegment( arrayWarpsFromNegativeBPMs[i] );
}
// sorting will need to take place somewhere.
}
} }
*/ */
@@ -389,7 +464,7 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache
else if( sValueName=="BACKGROUND" ) else if( sValueName=="BACKGROUND" )
out.m_sBackgroundFile = sParams[1]; out.m_sBackgroundFile = sParams[1];
/* Save "#LYRICS" for later, so we can add an internal lyrics tag. */ // Save "#LYRICS" for later, so we can add an internal lyrics tag.
else if( sValueName=="LYRICSPATH" ) else if( sValueName=="LYRICSPATH" )
out.m_sLyricsFile = sParams[1]; out.m_sLyricsFile = sParams[1];
@@ -463,6 +538,10 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache
else if( sValueName=="SAMPLELENGTH" ) else if( sValueName=="SAMPLELENGTH" )
out.m_fMusicSampleLengthSeconds = HHMMSSToSeconds( sParams[1] ); out.m_fMusicSampleLengthSeconds = HHMMSSToSeconds( sParams[1] );
// SamplePath is used when the song has a separate preview clip. -aj
//else if( sValueName=="SAMPLEPATH" )
//out.m_sMusicSamplePath = sParams[1];
else if( sValueName=="DISPLAYBPM" ) else if( sValueName=="DISPLAYBPM" )
{ {
// #DISPLAYBPM:[xxx][xxx:xxx]|[*]; // #DISPLAYBPM:[xxx][xxx:xxx]|[*];
@@ -489,8 +568,8 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache
// (Why was it removed?) // (Why was it removed?)
else if(!stricmp(sParams[1],"ROULETTE")) else if(!stricmp(sParams[1],"ROULETTE"))
out.m_SelectionDisplay = out.SHOW_ALWAYS; out.m_SelectionDisplay = out.SHOW_ALWAYS;
/* The following two cases are just fixes to make sure simfiles that used 3.9+ features /* The following two cases are just fixes to make sure simfiles that
* are not excluded here */ * used 3.9+ features are not excluded here */
else if(!stricmp(sParams[1],"ES") || !stricmp(sParams[1],"OMES")) else if(!stricmp(sParams[1],"ES") || !stricmp(sParams[1],"OMES"))
out.m_SelectionDisplay = out.SHOW_ALWAYS; out.m_SelectionDisplay = out.SHOW_ALWAYS;
else if( atoi(sParams[1]) > 0 ) else if( atoi(sParams[1]) > 0 )
@@ -897,20 +976,20 @@ void SMLoader::TidyUpData( Song &song, bool bFromCache )
} }
} }
/* If there's no -nosongbg- tag, add the song BG. */ // If there's no -nosongbg- tag, add the song BG.
if( !bHasNoSongBgTag ) do if( !bHasNoSongBgTag ) do
{ {
/* If we're loading cache, -nosongbg- should always be in there. We must /* If we're loading cache, -nosongbg- should always be in there. We
* not call IsAFile(song.GetBackgroundPath()) when loading cache. */ * must not call IsAFile(song.GetBackgroundPath()) when loading cache. */
if( bFromCache ) if( bFromCache )
break; break;
/* If BGChanges already exist after the last beat, don't add the background /* If BGChanges already exist after the last beat, don't add the
* in the middle. */ * background in the middle. */
if( !bg.empty() && bg.back().m_fStartBeat-0.0001f >= song.m_fLastBeat ) if( !bg.empty() && bg.back().m_fStartBeat-0.0001f >= song.m_fLastBeat )
break; break;
/* If the last BGA is already the song BGA, don't add a duplicate. */ // If the last BGA is already the song BGA, don't add a duplicate.
if( !bg.empty() && !bg.back().m_def.m_sFile1.CompareNoCase(song.m_sBackgroundFile) ) if( !bg.empty() && !bg.back().m_def.m_sFile1.CompareNoCase(song.m_sBackgroundFile) )
break; break;
+19 -2
View File
@@ -71,8 +71,9 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
f.PutLine( ssprintf("#LASTBEATHINT:%.3f;", out.m_fSpecifiedLastBeat) ); f.PutLine( ssprintf("#LASTBEATHINT:%.3f;", out.m_fSpecifiedLastBeat) );
f.Write( "#SELECTABLE:" ); f.Write( "#SELECTABLE:" );
switch(out.m_SelectionDisplay) { switch(out.m_SelectionDisplay)
default: ASSERT(0); /* fallthrough */ {
default: ASSERT(0); // fall through
case Song::SHOW_ALWAYS: f.Write( "YES" ); break; case Song::SHOW_ALWAYS: f.Write( "YES" ); break;
case Song::SHOW_NEVER: f.Write( "NO" ); break; case Song::SHOW_NEVER: f.Write( "NO" ); break;
} }
@@ -134,6 +135,22 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
} }
f.PutLine( ";" ); f.PutLine( ";" );
/*
f.Write( "#WARPS:" );
for( unsigned i=0; i<out.m_Timing.m_WarpSegments.size(); i++ )
{
const WarpSegment &fs = out.m_Timing.m_WarpSegments[i];
if( fs.m_bDelay )
{
f.PutLine( ssprintf( "%.3f=%.3f", NoteRowToBeat(fs.m_iStartRow), fs.m_fStopSeconds ) );
if( i != out.m_Timing.m_StopSegments.size()-1 )
f.Write( "," );
}
}
f.PutLine( ";" );
*/
ASSERT( !out.m_Timing.m_vTimeSignatureSegments.empty() ); ASSERT( !out.m_Timing.m_vTimeSignatureSegments.empty() );
f.Write( "#TIMESIGNATURES:" ); f.Write( "#TIMESIGNATURES:" );
FOREACH_CONST( TimeSignatureSegment, out.m_Timing.m_vTimeSignatureSegments, iter ) FOREACH_CONST( TimeSignatureSegment, out.m_Timing.m_vTimeSignatureSegments, iter )
+4
View File
@@ -25,6 +25,7 @@ static const char *PaneCategoryNames[] = {
"Rolls", "Rolls",
"Mines", "Mines",
"Hands", "Hands",
//"Lifts",
"MachineHighScore", "MachineHighScore",
"MachineHighName", "MachineHighName",
"ProfileHighScore", "ProfileHighScore",
@@ -48,6 +49,7 @@ static const Content_t g_Contents[NUM_PaneCategory] =
{ NEED_NOTES, "count" }, { NEED_NOTES, "count" },
{ NEED_NOTES, "count" }, { NEED_NOTES, "count" },
{ NEED_NOTES, "count" }, { NEED_NOTES, "count" },
//{ NEED_NOTES, "count" },
{ NEED_NOTES, "score" }, { NEED_NOTES, "score" },
{ NEED_NOTES, "name" }, { NEED_NOTES, "name" },
{ NEED_NOTES|NEED_PROFILE, "score" }, { NEED_NOTES|NEED_PROFILE, "score" },
@@ -158,6 +160,7 @@ void PaneDisplay::SetContent( PaneCategory c )
case PaneCategory_Rolls: val = rv[RadarCategory_Rolls]; break; case PaneCategory_Rolls: val = rv[RadarCategory_Rolls]; break;
case PaneCategory_Mines: val = rv[RadarCategory_Mines]; break; case PaneCategory_Mines: val = rv[RadarCategory_Mines]; break;
case PaneCategory_Hands: val = rv[RadarCategory_Hands]; break; case PaneCategory_Hands: val = rv[RadarCategory_Hands]; break;
//case PaneCategory_Lifts: val = rv[RadarCategory_Lifts]; break;
case PaneCategory_ProfileHighScore: case PaneCategory_ProfileHighScore:
case PaneCategory_MachineHighName: /* set val for color */ case PaneCategory_MachineHighName: /* set val for color */
case PaneCategory_MachineHighScore: case PaneCategory_MachineHighScore:
@@ -196,6 +199,7 @@ void PaneDisplay::SetContent( PaneCategory c )
case PaneCategory_Rolls: case PaneCategory_Rolls:
case PaneCategory_Mines: case PaneCategory_Mines:
case PaneCategory_Hands: case PaneCategory_Hands:
//case PaneCategory_Lifts:
str = ssprintf( COUNT_FORMAT.GetValue(), val ); str = ssprintf( COUNT_FORMAT.GetValue(), val );
} }
} }
+1
View File
@@ -23,6 +23,7 @@ enum PaneCategory
PaneCategory_Rolls, PaneCategory_Rolls,
PaneCategory_Mines, PaneCategory_Mines,
PaneCategory_Hands, PaneCategory_Hands,
//PaneCategory_Lifts,
PaneCategory_MachineHighScore, PaneCategory_MachineHighScore,
PaneCategory_MachineHighName, PaneCategory_MachineHighName,
PaneCategory_ProfileHighScore, PaneCategory_ProfileHighScore,
+1 -1
View File
@@ -3019,7 +3019,7 @@ void Player::SetCombo( int iCombo, int iMisses )
if( b1000Milestone ) if( b1000Milestone )
this->PlayCommand( "ThousandMilestone" ); this->PlayCommand( "ThousandMilestone" );
// don't show a colored combo until the specified point in the metrics. // don't show a colored combo until 1/4 of the way through the song
bool bPastBeginning = (!GAMESTATE->IsCourseMode() || GAMESTATE->GetCourseSongIndex()>0) && bool bPastBeginning = (!GAMESTATE->IsCourseMode() || GAMESTATE->GetCourseSongIndex()>0) &&
GAMESTATE->m_fMusicSeconds > GAMESTATE->m_pCurSong->m_fMusicLengthSeconds * PERCENT_UNTIL_COLOR_COMBO; GAMESTATE->m_fMusicSeconds > GAMESTATE->m_pCurSong->m_fMusicLengthSeconds * PERCENT_UNTIL_COLOR_COMBO;
+12
View File
@@ -163,6 +163,7 @@ void PlayerOptions::GetMods( vector<RString> &AddTo, bool bForceNoteSkin ) const
AddPart( AddTo, m_fScrolls[SCROLL_ALTERNATE], "Alternate" ); AddPart( AddTo, m_fScrolls[SCROLL_ALTERNATE], "Alternate" );
AddPart( AddTo, m_fScrolls[SCROLL_CROSS], "Cross" ); AddPart( AddTo, m_fScrolls[SCROLL_CROSS], "Cross" );
AddPart( AddTo, m_fScrolls[SCROLL_CENTERED], "Centered" ); AddPart( AddTo, m_fScrolls[SCROLL_CENTERED], "Centered" );
//AddPart( AddTo, m_fScrolls[SCROLL_X], "XMode" );
AddPart( AddTo, m_fDark, "Dark" ); AddPart( AddTo, m_fDark, "Dark" );
@@ -327,6 +328,16 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
SET_FLOAT( fTimeSpacing ) SET_FLOAT( fTimeSpacing )
m_fTimeSpacing = 1; m_fTimeSpacing = 1;
} }
/* Port M-Mod's from OpenITG, starting from r537 */
// Midiman
else if( sscanf( sBit, "m%f", &level ) == 1 )
{
if( !isfinite(level) || level <= 0.0f )
level = 200.0f; // Just pick some value.
SET_FLOAT( fScrollBPM )
SET_FLOAT( fTimeSpacing )
m_fTimeSpacing = 1;
}
else if( sBit == "clearall" ) Init(); else if( sBit == "clearall" ) Init();
else if( sBit == "boost" ) SET_FLOAT( fAccels[ACCEL_BOOST] ) else if( sBit == "boost" ) SET_FLOAT( fAccels[ACCEL_BOOST] )
else if( sBit == "brake" || sBit == "land" ) SET_FLOAT( fAccels[ACCEL_BRAKE] ) else if( sBit == "brake" || sBit == "land" ) SET_FLOAT( fAccels[ACCEL_BRAKE] )
@@ -380,6 +391,7 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
else if( sBit == "alternate" ) SET_FLOAT( fScrolls[SCROLL_ALTERNATE] ) else if( sBit == "alternate" ) SET_FLOAT( fScrolls[SCROLL_ALTERNATE] )
else if( sBit == "cross" ) SET_FLOAT( fScrolls[SCROLL_CROSS] ) else if( sBit == "cross" ) SET_FLOAT( fScrolls[SCROLL_CROSS] )
else if( sBit == "centered" ) SET_FLOAT( fScrolls[SCROLL_CENTERED] ) else if( sBit == "centered" ) SET_FLOAT( fScrolls[SCROLL_CENTERED] )
//else if( sBit == "xmode" ) SET_FLOAT( fScrolls[SCROLL_X] )
else if( sBit == "noholds" ) m_bTransforms[TRANSFORM_NOHOLDS] = on; else if( sBit == "noholds" ) m_bTransforms[TRANSFORM_NOHOLDS] = on;
else if( sBit == "norolls" ) m_bTransforms[TRANSFORM_NOROLLS] = on; else if( sBit == "norolls" ) m_bTransforms[TRANSFORM_NOROLLS] = on;
else if( sBit == "nomines" ) m_bTransforms[TRANSFORM_NOMINES] = on; else if( sBit == "nomines" ) m_bTransforms[TRANSFORM_NOMINES] = on;
+1
View File
@@ -110,6 +110,7 @@ public:
SCROLL_ALTERNATE, SCROLL_ALTERNATE,
SCROLL_CROSS, SCROLL_CROSS,
SCROLL_CENTERED, SCROLL_CENTERED,
//SCROLL_X,
NUM_SCROLLS NUM_SCROLLS
}; };
enum ScoreDisplay { enum ScoreDisplay {
+13 -15
View File
@@ -117,8 +117,8 @@ void PlayerStageStats::AddStats( const PlayerStageStats& other )
m_ComboList.push_back( newcombo ); m_ComboList.push_back( newcombo );
} }
/* Merge identical combos. This normally only happens in course mode, when a combo /* Merge identical combos. This normally only happens in course mode, when
* continues between songs. */ * a combo continues between songs. */
for( unsigned i=1; i<m_ComboList.size(); ++i ) for( unsigned i=1; i<m_ComboList.size(); ++i )
{ {
Combo_t &prevcombo = m_ComboList[i-1]; Combo_t &prevcombo = m_ComboList[i-1];
@@ -128,7 +128,7 @@ void PlayerStageStats::AddStats( const PlayerStageStats& other )
if( fabsf(PrevComboEnd - ThisComboStart) > 0.001 ) if( fabsf(PrevComboEnd - ThisComboStart) > 0.001 )
continue; continue;
/* These are really the same combo. */ // These are really the same combo.
prevcombo.m_fSizeSeconds += combo.m_fSizeSeconds; prevcombo.m_fSizeSeconds += combo.m_fSizeSeconds;
prevcombo.m_cnt += combo.m_cnt; prevcombo.m_cnt += combo.m_cnt;
m_ComboList.erase( m_ComboList.begin()+i ); m_ComboList.erase( m_ComboList.begin()+i );
@@ -222,7 +222,7 @@ float PlayerStageStats::MakePercentScore( int iActual, int iPossible )
if( iActual == iPossible ) if( iActual == iPossible )
return 1; // correct for rounding error return 1; // correct for rounding error
/* This can happen in battle, with transform attacks. */ // This can happen in battle, with transform attacks.
//ASSERT_M( iActual <= iPossible, ssprintf("%i/%i", iActual, iPossible) ); //ASSERT_M( iActual <= iPossible, ssprintf("%i/%i", iActual, iPossible) );
float fPercent = iActual / (float)iPossible; float fPercent = iActual / (float)iPossible;
@@ -232,12 +232,12 @@ float PlayerStageStats::MakePercentScore( int iActual, int iPossible )
int iPercentTotalDigits = 3 + CommonMetrics::PERCENT_SCORE_DECIMAL_PLACES; // "100" + "." + "00" int iPercentTotalDigits = 3 + CommonMetrics::PERCENT_SCORE_DECIMAL_PLACES; // "100" + "." + "00"
// TRICKY: printf will round, but we want to truncate. Otherwise, we may display a percent // TRICKY: printf will round, but we want to truncate. therwise, we may display
// score that's too high and doesn't match up with the calculated grade. // a percent score that's too high and doesn't match up with the calculated grade.
float fTruncInterval = powf( 0.1f, (float)iPercentTotalDigits-1 ); float fTruncInterval = powf( 0.1f, (float)iPercentTotalDigits-1 );
// TRICKY: ftruncf is rounding 1.0000000 to 0.99990004. Give a little boost to // TRICKY: ftruncf is rounding 1.0000000 to 0.99990004. Give a little boost
// fPercentDancePoints to correct for this. // to fPercentDancePoints to correct for this.
fPercent += 0.000001f; fPercent += 0.000001f;
fPercent = ftruncf( fPercent, fTruncInterval ); fPercent = ftruncf( fPercent, fTruncInterval );
@@ -346,13 +346,11 @@ void PlayerStageStats::SetLifeRecordAt( float fLife, float fStepsSecond )
MESSAGEMAN->Broadcast( Message_LifeMeterChangedP1 ); MESSAGEMAN->Broadcast( Message_LifeMeterChangedP1 );
//
// Memory optimization: // Memory optimization:
// If we have three consecutive records A, B, and C all with the same fLife, // If we have three consecutive records A, B, and C all with the same fLife,
// we can eliminate record B without losing data. Only check the last three // we can eliminate record B without losing data. Only check the last three
// records in the map since we're only inserting at the end, and we know all // records in the map since we're only inserting at the end, and we know all
// earlier redundant records have already been removed. // earlier redundant records have already been removed.
//
map<float,float>::iterator C = m_fLifeRecord.end(); map<float,float>::iterator C = m_fLifeRecord.end();
--C; --C;
if( C == m_fLifeRecord.begin() ) // no earlier records left if( C == m_fLifeRecord.begin() ) // no earlier records left
@@ -375,10 +373,10 @@ float PlayerStageStats::GetLifeRecordAt( float fStepsSecond ) const
if( m_fLifeRecord.empty() ) if( m_fLifeRecord.empty() )
return 0; return 0;
/* Find the first element whose key is greater than k. */ // Find the first element whose key is greater than k.
map<float,float>::const_iterator it = m_fLifeRecord.upper_bound( fStepsSecond ); map<float,float>::const_iterator it = m_fLifeRecord.upper_bound( fStepsSecond );
/* Find the last element whose key is less than or equal to k. */ // Find the last element whose key is less than or equal to k.
if( it != m_fLifeRecord.begin() ) if( it != m_fLifeRecord.begin() )
--it; --it;
@@ -391,10 +389,10 @@ float PlayerStageStats::GetLifeRecordLerpAt( float fStepsSecond ) const
if( m_fLifeRecord.empty() ) if( m_fLifeRecord.empty() )
return 0; return 0;
/* Find the first element whose key is greater than k. */ // Find the first element whose key is greater than k.
map<float,float>::const_iterator later = m_fLifeRecord.upper_bound( fStepsSecond ); map<float,float>::const_iterator later = m_fLifeRecord.upper_bound( fStepsSecond );
/* Find the last element whose key is less than or equal to k. */ // Find the last element whose key is less than or equal to k.
map<float,float>::const_iterator earlier = later; map<float,float>::const_iterator earlier = later;
if( earlier != m_fLifeRecord.begin() ) if( earlier != m_fLifeRecord.begin() )
--earlier; --earlier;
@@ -405,7 +403,7 @@ float PlayerStageStats::GetLifeRecordLerpAt( float fStepsSecond ) const
if( earlier->first == later->first ) // two samples from the same time. Don't divide by zero in SCALE if( earlier->first == later->first ) // two samples from the same time. Don't divide by zero in SCALE
return earlier->second; return earlier->second;
/* earlier <= pos <= later */ // earlier <= pos <= later
return SCALE( fStepsSecond, earlier->first, later->first, earlier->second, later->second ); return SCALE( fStepsSecond, earlier->first, later->first, earlier->second, later->second );
} }
+3 -3
View File
@@ -82,7 +82,7 @@ static const char *BannerCacheModeNames[] = {
XToString( BannerCacheMode ); XToString( BannerCacheMode );
StringToX( BannerCacheMode ); StringToX( BannerCacheMode );
LuaXType( BannerCacheMode ); LuaXType( BannerCacheMode );
/*
static const char *BackgroundCacheModeNames[] = { static const char *BackgroundCacheModeNames[] = {
"Off", "Off",
"LowResPreload", "LowResPreload",
@@ -92,7 +92,7 @@ static const char *BackgroundCacheModeNames[] = {
XToString( BackgroundCacheMode ); XToString( BackgroundCacheMode );
StringToX( BackgroundCacheMode ); StringToX( BackgroundCacheMode );
LuaXType( BackgroundCacheMode ); LuaXType( BackgroundCacheMode );
*/
static const char *HighResolutionTexturesNames[] = { static const char *HighResolutionTexturesNames[] = {
"Auto", "Auto",
"ForceOff", "ForceOff",
@@ -181,7 +181,7 @@ PrefsManager::PrefsManager() :
m_bDelayedTextureDelete ( "DelayedTextureDelete", false ), m_bDelayedTextureDelete ( "DelayedTextureDelete", false ),
m_bDelayedModelDelete ( "DelayedModelDelete", false ), m_bDelayedModelDelete ( "DelayedModelDelete", false ),
m_BannerCache ( "BannerCache", BNCACHE_LOW_RES_PRELOAD ), m_BannerCache ( "BannerCache", BNCACHE_LOW_RES_PRELOAD ),
m_BackgroundCache ( "BackgroundCache", BGCACHE_LOW_RES_PRELOAD ), //m_BackgroundCache ( "BackgroundCache", BGCACHE_LOW_RES_PRELOAD ),
m_bFastLoad ( "FastLoad", false ), m_bFastLoad ( "FastLoad", false ),
m_bFastLoadAdditionalSongs ( "FastLoadAdditionalSongs", false ), m_bFastLoadAdditionalSongs ( "FastLoadAdditionalSongs", false ),
+3 -1
View File
@@ -66,6 +66,7 @@ enum BannerCacheMode
NUM_BannerCacheMode, NUM_BannerCacheMode,
BannerCacheMode_Invalid BannerCacheMode_Invalid
}; };
/*
enum BackgroundCacheMode enum BackgroundCacheMode
{ {
BGCACHE_OFF, BGCACHE_OFF,
@@ -75,6 +76,7 @@ enum BackgroundCacheMode
NUM_BackgroundCacheMode, NUM_BackgroundCacheMode,
BackgroundCacheMode_Invalid BackgroundCacheMode_Invalid
}; };
*/
enum HighResolutionTextures enum HighResolutionTextures
{ {
HighResolutionTextures_Auto, HighResolutionTextures_Auto,
@@ -167,7 +169,7 @@ public:
Preference<bool> m_bDelayedTextureDelete; Preference<bool> m_bDelayedTextureDelete;
Preference<bool> m_bDelayedModelDelete; Preference<bool> m_bDelayedModelDelete;
Preference<BannerCacheMode> m_BannerCache; Preference<BannerCacheMode> m_BannerCache;
Preference<BackgroundCacheMode> m_BackgroundCache; //Preference<BackgroundCacheMode> m_BackgroundCache;
Preference<bool> m_bFastLoad; Preference<bool> m_bFastLoad;
Preference<bool> m_bFastLoadAdditionalSongs; Preference<bool> m_bFastLoadAdditionalSongs;
+1 -1
View File
@@ -23,7 +23,7 @@
* "v0.0": Final Releases * "v0.0": Final Releases
*/ */
#ifndef PRODUCT_VER_BARE #ifndef PRODUCT_VER_BARE
#define PRODUCT_VER_BARE v1.0 beta 1 #define PRODUCT_VER_BARE v1.0 beta 2
#endif #endif
// A unique ID for a build of an application. This is used in crash reports and in the network code's version handling // A unique ID for a build of an application. This is used in crash reports and in the network code's version handling
+2 -2
View File
@@ -5,9 +5,9 @@
; see ProductInfo.h for use descriptions ; see ProductInfo.h for use descriptions
!define PRODUCT_ID "sm-ssc" !define PRODUCT_ID "sm-ssc"
!define PRODUCT_VER "v1.0 beta 1" !define PRODUCT_VER "v1.0 beta 2"
!define PRODUCT_DISPLAY "${PRODUCT_ID} ${PRODUCT_VER}" !define PRODUCT_DISPLAY "${PRODUCT_ID} ${PRODUCT_VER}"
!define PRODUCT_BITMAP "sm4" !define PRODUCT_BITMAP "ssc"
!define PRODUCT_URL "http://ssc.ajworld.net/sm-ssc/" !define PRODUCT_URL "http://ssc.ajworld.net/sm-ssc/"
!define UPDATES_URL "http://ssc.ajworld.net/sm-ssc/" !define UPDATES_URL "http://ssc.ajworld.net/sm-ssc/"
-9
View File
@@ -417,10 +417,8 @@ bool ProfileManager::CreateLocalProfile( RString sName, RString &sProfileIDOut )
{ {
ASSERT( !sName.empty() ); ASSERT( !sName.empty() );
//
// Find a directory directory name that's a number greater than all // Find a directory directory name that's a number greater than all
// existing numbers. This preserves the "order by create date". // existing numbers. This preserves the "order by create date".
//
int iMaxProfileNumber = -1; int iMaxProfileNumber = -1;
vector<RString> vs; vector<RString> vs;
GetLocalProfileIDs( vs ); GetLocalProfileIDs( vs );
@@ -430,16 +428,12 @@ bool ProfileManager::CreateLocalProfile( RString sName, RString &sProfileIDOut )
int iProfileNumber = iMaxProfileNumber + 1; int iProfileNumber = iMaxProfileNumber + 1;
RString sProfileID = ssprintf( "%08d", iProfileNumber ); RString sProfileID = ssprintf( "%08d", iProfileNumber );
//
// Create the new profile. // Create the new profile.
//
Profile *pProfile = new Profile; Profile *pProfile = new Profile;
pProfile->m_sDisplayName = sName; pProfile->m_sDisplayName = sName;
pProfile->m_sCharacterID = CHARMAN->GetRandomCharacter()->m_sCharacterID; pProfile->m_sCharacterID = CHARMAN->GetRandomCharacter()->m_sCharacterID;
//
// Save it to disk. // Save it to disk.
//
RString sProfileDir = LocalProfileIDToDir( sProfileID ); RString sProfileDir = LocalProfileIDToDir( sProfileID );
if( !pProfile->SaveAllToDir(sProfileDir, PREFSMAN->m_bSignProfileData) ) if( !pProfile->SaveAllToDir(sProfileDir, PREFSMAN->m_bSignProfileData) )
{ {
@@ -500,7 +494,6 @@ bool ProfileManager::DeleteLocalProfile( RString sProfileID )
if( (*i)->Get() == sProfileID ) if( (*i)->Get() == sProfileID )
(*i)->Set( "" ); (*i)->Set( "" );
} }
return true; return true;
} }
else else
@@ -510,8 +503,6 @@ bool ProfileManager::DeleteLocalProfile( RString sProfileID )
} }
} }
LOG->Warn( "DeleteLocalProfile: ProfileID '%s' doesn't exist", sProfileID.c_str() ); LOG->Warn( "DeleteLocalProfile: ProfileID '%s' doesn't exist", sProfileID.c_str() );
return false; return false;
} }
+16 -16
View File
@@ -174,10 +174,10 @@ void RageBitmapTexture::Create()
pImg = pGrayscale; pImg = pGrayscale;
} }
/* Figure out which texture format we want the renderer to use. */ // Figure out which texture format we want the renderer to use.
PixelFormat pixfmt; PixelFormat pixfmt;
/* If the source is palleted, always load as paletted if supported. */ // If the source is palleted, always load as paletted if supported.
if( pImg->format->BitsPerPixel == 8 && DISPLAY->SupportsTextureFormat(PixelFormat_PAL) ) if( pImg->format->BitsPerPixel == 8 && DISPLAY->SupportsTextureFormat(PixelFormat_PAL) )
{ {
pixfmt = PixelFormat_PAL; pixfmt = PixelFormat_PAL;
@@ -189,10 +189,10 @@ void RageBitmapTexture::Create()
{ {
case 16: case 16:
{ {
/* Bits of alpha in the source: */ // Bits of alpha in the source:
int iSourceAlphaBits = 8 - pImg->format->Loss[3]; int iSourceAlphaBits = 8 - pImg->format->Loss[3];
/* Don't use more than we were hinted to. */ // Don't use more than we were hinted to.
iSourceAlphaBits = min( actualID.iAlphaBits, iSourceAlphaBits ); iSourceAlphaBits = min( actualID.iAlphaBits, iSourceAlphaBits );
switch( iSourceAlphaBits ) switch( iSourceAlphaBits )
@@ -214,7 +214,7 @@ void RageBitmapTexture::Create()
} }
} }
/* Make we're using a supported format. Every card supports either RGBA8 or RGBA4. */ // Make we're using a supported format. Every card supports either RGBA8 or RGBA4.
if( !DISPLAY->SupportsTextureFormat(pixfmt) ) if( !DISPLAY->SupportsTextureFormat(pixfmt) )
{ {
pixfmt = PixelFormat_RGBA8; pixfmt = PixelFormat_RGBA8;
@@ -222,14 +222,15 @@ void RageBitmapTexture::Create()
pixfmt = PixelFormat_RGBA4; pixfmt = PixelFormat_RGBA4;
} }
/* Dither if appropriate. XXX: This is a special case: don't bother dithering to /* Dither if appropriate.
* RGBA8888. We actually want to dither only if the destination has greater color * XXX: This is a special case: don't bother dithering to RGBA8888.
* depth on at least one color channel than the source. For example, it doesn't * We actually want to dither only if the destination has greater color depth
* on at least one color channel than the source. For example, it doesn't
* make sense to do this when pixfmt is RGBA5551 if the image is only RGBA555. */ * make sense to do this when pixfmt is RGBA5551 if the image is only RGBA555. */
if( actualID.bDither && if( actualID.bDither &&
(pixfmt==PixelFormat_RGBA4 || pixfmt==PixelFormat_RGB5A1) ) (pixfmt==PixelFormat_RGBA4 || pixfmt==PixelFormat_RGB5A1) )
{ {
/* Dither down to the destination format. */ // Dither down to the destination format.
const RageDisplay::PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt); const RageDisplay::PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt);
RageSurface *dst = CreateSurface( pImg->w, pImg->h, pfd->bpp, RageSurface *dst = CreateSurface( pImg->w, pImg->h, pfd->bpp,
pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] );
@@ -254,10 +255,8 @@ void RageBitmapTexture::Create()
{ {
// // Enforce frames in the image have even dimensions.
// Enforce frames in the image have even dimensions. Otherwise, // Otherwise, pixel/texel alignment will be off.
// pixel/texel alignment will be off.
//
int iDimensionMultiple = 2; int iDimensionMultiple = 2;
if( sHintString.find("doubleres") != string::npos ) if( sHintString.find("doubleres") != string::npos )
@@ -304,11 +303,12 @@ void RageBitmapTexture::Create()
delete pImg; delete pImg;
/* Check for hints that override the apparent "size". */ // Check for hints that override the apparent "size".
GetResolutionFromFileName( actualID.filename, m_iSourceWidth, m_iSourceHeight ); GetResolutionFromFileName( actualID.filename, m_iSourceWidth, m_iSourceHeight );
/* if "doubleres" (high resolution) then we want the image to appear in-game with dimensions 1/2 of the source. /* if "doubleres" (high resolution) then we want the image to appear in-game
* So, cut down the source dimension here after everythign above is finished operating with the real image * with dimensions 1/2 of the source. So, cut down the source dimension here
* after everything above is finished operating with the real image
* source dimensions. */ * source dimensions. */
if( sHintString.find("doubleres") != string::npos ) if( sHintString.find("doubleres") != string::npos )
{ {
+12 -18
View File
@@ -137,7 +137,7 @@ struct RenderTargetParam
{ {
} }
/* The dimensions of the actual render target, analogous to a window size: */ // The dimensions of the actual render target, analogous to a window size:
int iWidth, iHeight; int iWidth, iHeight;
bool bWithDepthBuffer; bool bWithDepthBuffer;
@@ -184,7 +184,7 @@ public:
// Return true if device was re-created and we need to reload textures. // Return true if device was re-created and we need to reload textures.
RString SetVideoMode( VideoModeParams p, bool &bNeedReloadTextures ); RString SetVideoMode( VideoModeParams p, bool &bNeedReloadTextures );
/* Call this when the resolution has been changed externally: */ // Call this when the resolution has been changed externally:
virtual void ResolutionChanged(); virtual void ResolutionChanged();
virtual bool BeginFrame(); virtual bool BeginFrame();
@@ -198,8 +198,8 @@ public:
virtual bool SupportsThreadedRendering() { return false; } virtual bool SupportsThreadedRendering() { return false; }
virtual bool SupportsPerVertexMatrixScale() = 0; virtual bool SupportsPerVertexMatrixScale() = 0;
// If threaded rendering is supported, these will be called from the rendering // If threaded rendering is supported, these will be called from the
// thread before and after rendering. // rendering thread before and after rendering.
virtual void BeginConcurrentRenderingMainThread() { } virtual void BeginConcurrentRenderingMainThread() { }
virtual void EndConcurrentRenderingMainThread() { } virtual void EndConcurrentRenderingMainThread() { }
virtual void BeginConcurrentRendering(); virtual void BeginConcurrentRendering();
@@ -233,16 +233,14 @@ public:
bool SupportsRenderToTexture() const { return false; } bool SupportsRenderToTexture() const { return false; }
/* /* Create a render target, returning a texture handle. In addition to normal
* Create a render target, returning a texture handle. In addition to normal
* texture functions, this can be passed to SetRenderTarget. Delete with * texture functions, this can be passed to SetRenderTarget. Delete with
* DeleteTexture. (UpdateTexture is not permitted.) Returns 0 if render-to- * DeleteTexture. (UpdateTexture is not permitted.) Returns 0 if render-to-
* texture is unsupported. * texture is unsupported.
*/ */
virtual unsigned CreateRenderTarget( const RenderTargetParam &param, int &iTextureWidthOut, int &iTextureHeightOut ) { return 0; } virtual unsigned CreateRenderTarget( const RenderTargetParam &param, int &iTextureWidthOut, int &iTextureHeightOut ) { return 0; }
/* /* Set the render target, or 0 to resume rendering to the framebuffer. An active render
* Set the render target, or 0 to resume rendering to the framebuffer. An active render
* target may not be used as a texture. If bPreserveTexture is true, the contents * target may not be used as a texture. If bPreserveTexture is true, the contents
* of the texture will be preserved from the previous call; otherwise, cleared. If * of the texture will be preserved from the previous call; otherwise, cleared. If
* bPreserveTexture is true the first time a render target is used, behave as if * bPreserveTexture is true the first time a render target is used, behave as if
@@ -335,16 +333,16 @@ protected:
void SetDefaultRenderStates(); void SetDefaultRenderStates();
public: public:
/* Statistics */ // Statistics
int GetFPS() const; int GetFPS() const;
int GetVPF() const; int GetVPF() const;
int GetCumFPS() const; /* average FPS since last reset */ int GetCumFPS() const; // average FPS since last reset
virtual void ResetStats(); virtual void ResetStats();
virtual void ProcessStatsOnFlip(); virtual void ProcessStatsOnFlip();
virtual RString GetStats() const; virtual RString GetStats() const;
void StatsAddVerts( int iNumVertsRendered ); void StatsAddVerts( int iNumVertsRendered );
/* World matrix stack functions. */ // World matrix stack functions.
void PushMatrix(); void PushMatrix();
void PopMatrix(); void PopMatrix();
void Translate( float x, float y, float z ); void Translate( float x, float y, float z );
@@ -360,19 +358,19 @@ public:
void PreMultMatrix( const RageMatrix &f ); void PreMultMatrix( const RageMatrix &f );
void LoadIdentity(); void LoadIdentity();
/* Texture matrix functions */ // Texture matrix functions
void TexturePushMatrix(); void TexturePushMatrix();
void TexturePopMatrix(); void TexturePopMatrix();
void TextureTranslate( float x, float y ); void TextureTranslate( float x, float y );
void TextureTranslate( const RageVector2 &v ) { this->TextureTranslate( v.x, v.y ); } void TextureTranslate( const RageVector2 &v ) { this->TextureTranslate( v.x, v.y ); }
/* Projection and View matrix stack functions. */ // Projection and View matrix stack functions.
void CameraPushMatrix(); void CameraPushMatrix();
void CameraPopMatrix(); void CameraPopMatrix();
void LoadMenuPerspective( float fFOVDegrees, float fWidth, float fHeight, float fVanishPointX, float fVanishPointY ); void LoadMenuPerspective( float fFOVDegrees, float fWidth, float fHeight, float fVanishPointX, float fVanishPointY );
void LoadLookAt( float fov, const RageVector3 &Eye, const RageVector3 &At, const RageVector3 &Up ); void LoadLookAt( float fov, const RageVector3 &Eye, const RageVector3 &At, const RageVector3 &Up );
/* Centering matrix */ // Centering matrix
void CenteringPushMatrix(); void CenteringPushMatrix();
void CenteringPopMatrix(); void CenteringPopMatrix();
void ChangeCentering( int trans_x, int trans_y, int add_width, int add_height ); void ChangeCentering( int trans_x, int trans_y, int add_width, int add_height );
@@ -390,9 +388,7 @@ protected:
virtual RageMatrix GetOrthoMatrix( float l, float r, float b, float t, float zn, float zf ); virtual RageMatrix GetOrthoMatrix( float l, float r, float b, float t, float zn, float zf );
virtual RageMatrix GetFrustumMatrix( float l, float r, float b, float t, float zn, float zf ); virtual RageMatrix GetFrustumMatrix( float l, float r, float b, float t, float zn, float zf );
//
// Matrix that adjusts position and scale of image on the screen // Matrix that adjusts position and scale of image on the screen
//
RageMatrix GetCenteringMatrix( float fTranslateX, float fTranslateY, float fAddWidth, float fAddHeight ) const; RageMatrix GetCenteringMatrix( float fTranslateX, float fTranslateY, float fAddWidth, float fAddHeight ) const;
void UpdateCentering(); void UpdateCentering();
@@ -403,10 +399,8 @@ protected:
const RageMatrix* GetWorldTop() const; const RageMatrix* GetWorldTop() const;
const RageMatrix* GetTextureTop() const; const RageMatrix* GetTextureTop() const;
//
// To limit the framerate, call FrameLimitBeforeVsync before waiting // To limit the framerate, call FrameLimitBeforeVsync before waiting
// for vsync and FrameLimitAfterVsync after. // for vsync and FrameLimitAfterVsync after.
//
void FrameLimitBeforeVsync( int iFPS ); void FrameLimitBeforeVsync( int iFPS );
void FrameLimitAfterVsync(); void FrameLimitAfterVsync();
}; };
+10 -12
View File
@@ -340,21 +340,19 @@ RageFileObjDirect::~RageFileObjDirect()
if( !(m_iMode & RageFile::WRITE) || (m_iMode & RageFile::STREAMED) ) if( !(m_iMode & RageFile::WRITE) || (m_iMode & RageFile::STREAMED) )
return; return;
/* We now have path written to MakeTempFilename(m_sPath). Rename the temporary /* We now have path written to MakeTempFilename(m_sPath).
* file over the real path. */ * Rename the temporary file over the real path. */
do do
{ {
if( bFailed || WriteFailed() ) if( bFailed || WriteFailed() )
break; break;
/* /* We now have path written to MakeTempFilename(m_sPath). Rename the
* We now have path written to MakeTempFilename(m_sPath). Rename the temporary * temporary file over the real path. This should be an atomic operation
* file over the real path. This should be an atomic operation with a journalling * with a journalling filesystem. That is, there should be no
* filesystem. That is, there should be no intermediate state a JFS might restore * intermediate state a JFS might restore the file we're writing (in the
* the file we're writing (in the case of a crash/powerdown) to an empty or partial * case of a crash/powerdown) to an empty or partial file. */
* file.
*/
RString sOldPath = MakeTempFilename(m_sPath); RString sOldPath = MakeTempFilename(m_sPath);
RString sNewPath = m_sPath; RString sNewPath = m_sPath;
@@ -389,12 +387,12 @@ RageFileObjDirect::~RageFileObjDirect()
} }
} }
/* Success. */ // Success.
return; return;
#endif #endif
} while(0); } while(0);
/* The write or the rename failed. Delete the incomplete temporary file. */ // The write or the rename failed. Delete the incomplete temporary file.
DoRemove( MakeTempFilename(m_sPath) ); DoRemove( MakeTempFilename(m_sPath) );
} }
@@ -410,7 +408,7 @@ int RageFileObjDirect::ReadInternal( void *pBuf, size_t iBytes )
return iRet; return iRet;
} }
/* write(), but retry a couple times on EINTR. */ // write(), but retry a couple times on EINTR.
static int RetriedWrite( int iFD, const void *pBuf, size_t iCount ) static int RetriedWrite( int iFD, const void *pBuf, size_t iCount )
{ {
int iTries = 3, iRet; int iTries = 3, iRet;
+5 -8
View File
@@ -1,5 +1,4 @@
/* /* Handle loading and decoding of sounds.
* Handle loading and decoding of sounds.
* *
* For small files, pre-decode the entire file into a regular buffer. We * For small files, pre-decode the entire file into a regular buffer. We
* might want to play many samples at once, and we don't want to have to decode * might want to play many samples at once, and we don't want to have to decode
@@ -92,8 +91,8 @@ RageSound &RageSound::operator=( const RageSound &cpy )
{ {
LockMut(cpy.m_Mutex); LockMut(cpy.m_Mutex);
/* If m_bDeleteWhenFinished, then nobody that has a reference to the sound should /* If m_bDeleteWhenFinished, then nobody that has a reference to the sound
* be making copies. */ * should be making copies. */
ASSERT( !cpy.m_bDeleteWhenFinished ); ASSERT( !cpy.m_bDeleteWhenFinished );
m_Param = cpy.m_Param; m_Param = cpy.m_Param;
@@ -455,7 +454,6 @@ bool RageSound::Pause( bool bPause )
return SOUNDMAN->Pause( this, bPause ); return SOUNDMAN->Pause( this, bPause );
} }
float RageSound::GetLengthSeconds() float RageSound::GetLengthSeconds()
{ {
if( m_pSource == NULL ) if( m_pSource == NULL )
@@ -472,7 +470,7 @@ float RageSound::GetLengthSeconds()
return -1; return -1;
} }
return iLength / 1000.f; /* ms -> secs */ return iLength / 1000.f; // ms -> secs
} }
int RageSound::GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bApproximate ) const int RageSound::GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bApproximate ) const
@@ -490,8 +488,7 @@ int RageSound::GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bA
return (int) iSourceFrame; return (int) iSourceFrame;
} }
/* /* If non-NULL, approximate is set to true if the returned time is approximated because of
* If non-NULL, approximate is set to true if the returned time is approximated because of
* underrun, the sound not having started (after Play()) or finished (after EOF) yet. * underrun, the sound not having started (after Play()) or finished (after EOF) yet.
* *
* If non-NULL, Timestamp is set to the real clock time associated with the returned sound * If non-NULL, Timestamp is set to the real clock time associated with the returned sound
+22 -28
View File
@@ -28,30 +28,29 @@ struct RageSoundParams
{ {
RageSoundParams(); RageSoundParams();
/* The amount of data to play (or loop): */ // The amount of data to play (or loop):
float m_StartSecond; float m_StartSecond;
float m_LengthSeconds; float m_LengthSeconds;
/* Number of seconds to spend fading in. */ // Number of seconds to spend fading in.
float m_fFadeInSeconds; float m_fFadeInSeconds;
/* Number of seconds to spend fading out. */ // Number of seconds to spend fading out.
float m_fFadeOutSeconds; float m_fFadeOutSeconds;
float m_Volume; // multiplies with SOUNDMAN->GetMixVolume() float m_Volume; // multiplies with SOUNDMAN->GetMixVolume()
float m_fAttractVolume; // multiplies with m_Volume float m_fAttractVolume; // multiplies with m_Volume
/* Number of samples input and output when changing speed. Currently, /* Number of samples input and output when changing speed.
* this is either 1/1, 5/4 or 4/5. */ * Currently, this is either 1/1, 5/4 or 4/5. */
float m_fPitch; float m_fPitch;
float m_fSpeed; float m_fSpeed;
/* Optional driver feature: time to actually start playing sounds. If zero, or if not /* Optional driver feature: time to actually start playing sounds.
* supported, the sound will start immediately. */ * If zero, or if not supported, the sound will start immediately. */
RageTimer m_StartTime; RageTimer m_StartTime;
/* /* M_STOP stops the sound at the end.
* M_STOP stops the sound at the end.
* M_LOOP restarts. * M_LOOP restarts.
* M_CONTINUE feeds silence, which is useful to continue timing longer than the actual sound. * M_CONTINUE feeds silence, which is useful to continue timing longer than the actual sound.
* M_AUTO (default) stops, obeying filename hints. * M_AUTO (default) stops, obeying filename hints.
@@ -74,7 +73,7 @@ struct RageSoundLoadParams
* small memory penalty if not used. */ * small memory penalty if not used. */
bool m_bSupportRateChanging; bool m_bSupportRateChanging;
/* If true, panning will be supported for this sound. */ // If true, panning will be supported for this sound.
bool m_bSupportPan; bool m_bSupportPan;
}; };
@@ -86,8 +85,7 @@ public:
RageSound( const RageSound &cpy ); RageSound( const RageSound &cpy );
RageSound &operator=( const RageSound &cpy ); RageSound &operator=( const RageSound &cpy );
/* /* If bPrecache == true, we'll preload the entire file into memory if
* If bPrecache == true, we'll preload the entire file into memory if
* small enough. If this is done, a large number of copies of the sound * small enough. If this is done, a large number of copies of the sound
* can be played without much performance penalty. This is useful for * can be played without much performance penalty. This is useful for
* efficiently playing keyed sounds, and for rapidly-repeating sound * efficiently playing keyed sounds, and for rapidly-repeating sound
@@ -103,17 +101,15 @@ public:
*/ */
bool Load( RString sFile, bool bPrecache, const RageSoundLoadParams *pParams = NULL ); bool Load( RString sFile, bool bPrecache, const RageSoundLoadParams *pParams = NULL );
/* /* Using this version means the "don't care" about caching. Currently,
* Using this version means the "don't care" about caching. Currently, * this always will not cache the sound; this may become a preference. */
* this always will not cache the sound; this may become a preference.
*/
bool Load( RString sFile ); bool Load( RString sFile );
/* Load a RageSoundReader that you've set up yourself. Sample rate conversion will /* Load a RageSoundReader that you've set up yourself. Sample rate conversion
* be set up only if needed. Doesn't fail. */ * will be set up only if needed. Doesn't fail. */
void LoadSoundReader( RageSoundReader *pSound ); void LoadSoundReader( RageSoundReader *pSound );
/* Get the loaded RageSoundReader. While playing, only properties can be set. */ // Get the loaded RageSoundReader. While playing, only properties can be set.
RageSoundReader *GetSoundReader() { return m_pSource; } RageSoundReader *GetSoundReader() { return m_pSource; }
void Unload(); void Unload();
@@ -145,9 +141,7 @@ public:
bool SetProperty( const RString &sProperty, float fValue ); bool SetProperty( const RString &sProperty, float fValue );
void SetStopModeFromString( const RString &sStopMode ); void SetStopModeFromString( const RString &sStopMode );
//
// Lua // Lua
//
virtual void PushSelf( lua_State *L ); virtual void PushSelf( lua_State *L );
private: private:
@@ -155,7 +149,7 @@ private:
RageSoundReader *m_pSource; RageSoundReader *m_pSource;
/* We keep track of sound blocks we've sent out recently through GetDataToPlay. */ // We keep track of sound blocks we've sent out recently through GetDataToPlay.
pos_map_queue m_HardwareToStreamMap; pos_map_queue m_HardwareToStreamMap;
pos_map_queue m_StreamToSourceMap; pos_map_queue m_StreamToSourceMap;
@@ -183,17 +177,17 @@ private:
int GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bApproximate = NULL ) const; int GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bApproximate = NULL ) const;
bool SetPositionFrames( int frames = -1 ); bool SetPositionFrames( int frames = -1 );
RageSoundParams::StopMode_t GetStopMode() const; /* resolves M_AUTO */ RageSoundParams::StopMode_t GetStopMode() const; // resolves M_AUTO
void SoundIsFinishedPlaying(); // called by sound drivers void SoundIsFinishedPlaying(); // called by sound drivers
public: public:
/* These functions are called only by sound drivers. */ // These functions are called only by sound drivers.
/* Returns the number of bytes actually put into pBuffer. If 0 is returned, it /* Returns the number of bytes actually put into pBuffer. If 0 is returned,
* signals the stream to stop; once it's flushed, SoundStopped will be called. * it signals the stream to stop; once it's flushed, SoundStopped will be
* Until then, SOUNDMAN->GetPosition can still be called; the sound is still * called. Until then, SOUNDMAN->GetPosition can still be called; the sound
* playing. */ * is still playing. */
int GetDataToPlay( float *pBuffer, int iSize, int64_t &iStreamFrame, int &iBytesRead ); int GetDataToPlay( float *pBuffer, int iSize, int64_t &iStreamFrame, int &iBytesRead );
void CommitPlayingPosition( int64_t iHardwareFrame, int64_t iStreamFrame, int iGotFrames ); void CommitPlayingPosition( int64_t iHardwareFrame, int64_t iStreamFrame, int iGotFrames );
}; };
+33 -36
View File
@@ -6,8 +6,7 @@
#define DitherMatDim 4 #define DitherMatDim 4
// Fractions, 0/16 to 15/16:
/* Fractions, 0/16 to 15/16: */
static const int DitherMat[DitherMatDim][DitherMatDim] = static const int DitherMat[DitherMatDim][DitherMatDim] =
{ {
{ 0, 8, 2, 10 }, { 0, 8, 2, 10 },
@@ -18,10 +17,10 @@ static const int DitherMat[DitherMatDim][DitherMatDim] =
static int DitherMatCalc[DitherMatDim][DitherMatDim]; static int DitherMatCalc[DitherMatDim][DitherMatDim];
/* conv is the ratio from the input to the output. */ // conv is the ratio from the input to the output.
static uint8_t DitherPixel(int x, int y, int intensity, int conv) static uint8_t DitherPixel(int x, int y, int intensity, int conv)
{ {
/* The intensity matrix wraps. This assumes the matrix dims are a power of 2. */ // The intensity matrix wraps. This assumes the matrix dims are a power of 2.
x &= DitherMatDim-1; x &= DitherMatDim-1;
y &= DitherMatDim-1; y &= DitherMatDim-1;
@@ -35,13 +34,13 @@ static uint8_t DitherPixel(int x, int y, int intensity, int conv)
* up to 7. So, a proportion of pixels gets rounded up based on how close * up to 7. So, a proportion of pixels gets rounded up based on how close
* the number is to the next value. */ * the number is to the next value. */
/* Convert the number to the destination range. */ // Convert the number to the destination range.
int out_intensity = intensity * conv; int out_intensity = intensity * conv;
/* Add bias. */ // Add bias.
out_intensity += DitherMatCalc[y][x]; out_intensity += DitherMatCalc[y][x];
/* Truncate, and add e to make sure a value of 14.999998 -> 15. */ // Truncate, and add e to make sure a value of 14.999998 -> 15.
return uint8_t((out_intensity + 1) >> 16); return uint8_t((out_intensity + 1) >> 16);
} }
@@ -64,45 +63,45 @@ void RageSurfaceUtils::OrderedDither( const RageSurface *src, RageSurface *dst )
DitherMatCalc_initted = true; DitherMatCalc_initted = true;
} }
/* We can't dither to paletted surfaces. */ // We can't dither to paletted surfaces.
ASSERT( dst->format->BytesPerPixel > 1 ); ASSERT( dst->format->BytesPerPixel > 1 );
uint32_t src_cbits[4], dst_cbits[4]; uint32_t src_cbits[4], dst_cbits[4];
RageSurfaceUtils::GetBitsPerChannel( src->format, src_cbits ); RageSurfaceUtils::GetBitsPerChannel( src->format, src_cbits );
RageSurfaceUtils::GetBitsPerChannel( dst->format, dst_cbits ); RageSurfaceUtils::GetBitsPerChannel( dst->format, dst_cbits );
/* Calculate the ratio from the old bit depth to the new for each color channel. */ // Calculate the ratio from the old bit depth to the new for each color channel.
int conv[4]; int conv[4];
for( int i = 0; i < 4; ++i ) for( int i = 0; i < 4; ++i )
{ {
int MaxInputIntensity = (1 << src_cbits[i])-1; int MaxInputIntensity = (1 << src_cbits[i])-1;
int MaxOutputIntensity = (1 << dst_cbits[i])-1; int MaxOutputIntensity = (1 << dst_cbits[i])-1;
/* If the source is missing the channel, avoid div/0. */ // If the source is missing the channel, avoid div/0.
if( MaxInputIntensity == 0 ) if( MaxInputIntensity == 0 )
conv[i] = 0; conv[i] = 0;
else else
conv[i] = MaxOutputIntensity * 65536 / MaxInputIntensity; conv[i] = MaxOutputIntensity * 65536 / MaxInputIntensity;
} }
/* Max alpha value; used when there's no alpha source. */ // Max alpha value; used when there's no alpha source.
const uint8_t alpha_max = uint8_t((1 << dst_cbits[3]) - 1); const uint8_t alpha_max = uint8_t((1 << dst_cbits[3]) - 1);
/* For each row: */ // For each row:
for( int row = 0; row < src->h; ++row ) for( int row = 0; row < src->h; ++row )
{ {
const uint8_t *srcp = src->pixels + row * src->pitch; const uint8_t *srcp = src->pixels + row * src->pitch;
uint8_t *dstp = dst->pixels + row * dst->pitch; uint8_t *dstp = dst->pixels + row * dst->pitch;
/* For each pixel: */ // For each pixel:
for( int col = 0; col < src->w; ++col ) for( int col = 0; col < src->w; ++col )
{ {
uint8_t colors[4]; uint8_t colors[4];
RageSurfaceUtils::GetRawRGBAV( srcp, src->fmt, colors ); RageSurfaceUtils::GetRawRGBAV( srcp, src->fmt, colors );
/* Note that we don't dither the alpha channel. */ // Note that we don't dither the alpha channel.
for( int c = 0; c < 3; ++c ) for( int c = 0; c < 3; ++c )
{ {
/* If the destination has less bits, dither: */ // If the destination has less bits, dither:
colors[c] = DitherPixel( col, row, colors[c], conv[c] ); colors[c] = DitherPixel( col, row, colors[c], conv[c] );
} }
@@ -113,15 +112,15 @@ void RageSurfaceUtils::OrderedDither( const RageSurface *src, RageSurface *dst )
{ {
colors[3] = alpha_max; colors[3] = alpha_max;
} else { } else {
/* Same as DitherPixel, except it doesn't actually dither; dithering /* Same as DitherPixel, except it doesn't actually dither;
* looks bad on the alpha channel. */ * dithering looks bad on the alpha channel. */
int out_intensity = colors[3] * conv[3]; int out_intensity = colors[3] * conv[3];
/* Round: */ // Round:
colors[3] = uint8_t((out_intensity + 32767) >> 16); colors[3] = uint8_t((out_intensity + 32767) >> 16);
} }
/* Raw value -> int -> pixel */ // Raw value -> int -> pixel
RageSurfaceUtils::SetRawRGBAV(dstp, dst, colors); RageSurfaceUtils::SetRawRGBAV(dstp, dst, colors);
srcp += src->format->BytesPerPixel; srcp += src->format->BytesPerPixel;
@@ -133,13 +132,13 @@ void RageSurfaceUtils::OrderedDither( const RageSurface *src, RageSurface *dst )
static uint8_t EDDitherPixel( int x, int y, int intensity, int conv, int32_t &accumError ) static uint8_t EDDitherPixel( int x, int y, int intensity, int conv, int32_t &accumError )
{ {
/* Convert the number to the destination range. */ // Convert the number to the destination range.
int out_intensity = intensity * conv; int out_intensity = intensity * conv;
/* Add e to make sure a value of 14.999998 -> 15. */ // Add e to make sure a value of 14.999998 -> 15.
++out_intensity; ++out_intensity;
/* Add bias. */ // Add bias.
out_intensity += accumError; out_intensity += accumError;
/* out_intensity is now what we actually want this component to be. /* out_intensity is now what we actually want this component to be.
@@ -149,7 +148,7 @@ static uint8_t EDDitherPixel( int x, int y, int intensity, int conv, int32_t &ac
int clamped_intensity = clamp( out_intensity, 0, 0xFFFFFF ); int clamped_intensity = clamp( out_intensity, 0, 0xFFFFFF );
clamped_intensity &= 0xFF0000; clamped_intensity &= 0xFF0000;
/* Truncate. */ // Truncate.
uint8_t ret = uint8_t(clamped_intensity >> 16); uint8_t ret = uint8_t(clamped_intensity >> 16);
accumError = out_intensity - clamped_intensity; accumError = out_intensity - clamped_intensity;
@@ -160,40 +159,38 @@ static uint8_t EDDitherPixel( int x, int y, int intensity, int conv, int32_t &ac
return ret; return ret;
} }
/* /* This is very similar to OrderedDither, except instead of using a matrix
* This is very similar to OrderedDither, except instead of using a matrix
* containing rounding values, we truncate and then add the resulting error for * containing rounding values, we truncate and then add the resulting error for
* each pixel to the next pixel on the same line. (Maybe we could do both?) * each pixel to the next pixel on the same line. (Maybe we could do both?)
* *
* http://www.gamasutra.com/features/19990521/pixel_conversion_03.htm * http://www.gamasutra.com/features/19990521/pixel_conversion_03.htm */
*/
void RageSurfaceUtils::ErrorDiffusionDither( const RageSurface *src, RageSurface *dst ) void RageSurfaceUtils::ErrorDiffusionDither( const RageSurface *src, RageSurface *dst )
{ {
/* We can't dither to paletted surfaces. */ // We can't dither to paletted surfaces.
ASSERT( dst->format->BytesPerPixel > 1 ); ASSERT( dst->format->BytesPerPixel > 1 );
uint32_t src_cbits[4], dst_cbits[4]; uint32_t src_cbits[4], dst_cbits[4];
RageSurfaceUtils::GetBitsPerChannel( src->format, src_cbits ); RageSurfaceUtils::GetBitsPerChannel( src->format, src_cbits );
RageSurfaceUtils::GetBitsPerChannel( dst->format, dst_cbits ); RageSurfaceUtils::GetBitsPerChannel( dst->format, dst_cbits );
/* Calculate the ratio from the old bit depth to the new for each color channel. */ // Calculate the ratio from the old bit depth to the new for each color channel.
int conv[4]; int conv[4];
for( int i = 0; i < 4; ++i ) for( int i = 0; i < 4; ++i )
{ {
int MaxInputIntensity = (1 << src_cbits[i])-1; int MaxInputIntensity = (1 << src_cbits[i])-1;
int MaxOutputIntensity = (1 << dst_cbits[i])-1; int MaxOutputIntensity = (1 << dst_cbits[i])-1;
/* If the source is missing the channel, avoid div/0. */ // If the source is missing the channel, avoid div/0.
if( MaxInputIntensity == 0 ) if( MaxInputIntensity == 0 )
conv[i] = 0; conv[i] = 0;
else else
conv[i] = MaxOutputIntensity * 65536 / MaxInputIntensity; conv[i] = MaxOutputIntensity * 65536 / MaxInputIntensity;
} }
/* Max alpha value; used when there's no alpha source. */ // Max alpha value; used when there's no alpha source.
const uint8_t alpha_max = uint8_t((1 << dst_cbits[3]) - 1); const uint8_t alpha_max = uint8_t((1 << dst_cbits[3]) - 1);
/* For each row: */ // For each row:
for(int row = 0; row < src->h; ++row) for(int row = 0; row < src->h; ++row)
{ {
int32_t accumError[4] = { 0, 0, 0, 0 }; // accum error values are reset every row int32_t accumError[4] = { 0, 0, 0, 0 }; // accum error values are reset every row
@@ -201,7 +198,7 @@ void RageSurfaceUtils::ErrorDiffusionDither( const RageSurface *src, RageSurface
const uint8_t *srcp = src->pixels + row * src->pitch; const uint8_t *srcp = src->pixels + row * src->pitch;
uint8_t *dstp = dst->pixels + row * dst->pitch; uint8_t *dstp = dst->pixels + row * dst->pitch;
/* For each pixel in row: */ // For each pixel in row:
for( int col = 0; col < src->w; ++col ) for( int col = 0; col < src->w; ++col )
{ {
uint8_t colors[4]; uint8_t colors[4];
@@ -219,11 +216,11 @@ void RageSurfaceUtils::ErrorDiffusionDither( const RageSurface *src, RageSurface
{ {
colors[3] = alpha_max; colors[3] = alpha_max;
} else { } else {
/* Same as DitherPixel, except it doesn't actually dither; dithering /* Same as DitherPixel, except it doesn't actually dither;
* looks bad on the alpha channel. */ * dithering looks bad on the alpha channel. */
int out_intensity = colors[3] * conv[3]; int out_intensity = colors[3] * conv[3];
/* Round: */ // Round:
colors[3] = uint8_t((out_intensity + 32767) >> 16); colors[3] = uint8_t((out_intensity + 32767) >> 16);
} }
+34 -46
View File
@@ -106,20 +106,18 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
acolorhist_item *acolormap=NULL; acolorhist_item *acolormap=NULL;
int newcolors = 0; int newcolors = 0;
/* "apixel", etc. make assumptions about byte order. */ // "apixel", etc. make assumptions about byte order.
RageSurfaceUtils::ConvertSurface( pImg, pImg->w, pImg->h, 32, RageSurfaceUtils::ConvertSurface( pImg, pImg->w, pImg->h, 32,
Swap32BE(0xFF000000), Swap32BE(0x00FF0000), Swap32BE(0x0000FF00), Swap32BE(0x000000FF)); Swap32BE(0xFF000000), Swap32BE(0x00FF0000), Swap32BE(0x0000FF00), Swap32BE(0x000000FF));
pixval maxval = 255; pixval maxval = 255;
{ {
/* /* Attempt to make a histogram of the colors, unclustered.
* Attempt to make a histogram of the colors, unclustered.
* If at first we don't succeed, lower maxval to increase color * If at first we don't succeed, lower maxval to increase color
* coherence and try again. This will eventually terminate, with * coherence and try again. This will eventually terminate, with
* maxval at worst 15, since 32^3 is approximately MAXCOLORS. * maxval at worst 15, since 32^3 is approximately MAXCOLORS.
* [GRR POSSIBLE BUG: what about 32^4 ?] * [GRR POSSIBLE BUG: what about 32^4 ?] */
*/
acolorhist_item *achv; acolorhist_item *achv;
int colors; int colors;
while(1) while(1)
@@ -143,7 +141,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
} }
newcolors = min( colors, iColors ); newcolors = min( colors, iColors );
/* Apply median-cut to histogram, making the new acolormap. */ // Apply median-cut to histogram, making the new acolormap.
acolormap = mediancut( achv, colors, pImg->h * pImg->w, maxval, newcolors ); acolormap = mediancut( achv, colors, pImg->h * pImg->w, maxval, newcolors );
pam_freeacolorhist( achv ); pam_freeacolorhist( achv );
} }
@@ -151,12 +149,12 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
RageSurface *pRet = CreateSurface( pImg->w, pImg->h, 8, 0, 0, 0, 0 ); RageSurface *pRet = CreateSurface( pImg->w, pImg->h, 8, 0, 0, 0, 0 );
pRet->format->palette->ncolors = newcolors; pRet->format->palette->ncolors = newcolors;
/* Rescale the palette colors to a maxval of 255. */ // Rescale the palette colors to a maxval of 255.
{ {
RageSurfacePalette *pal = pRet->format->palette; RageSurfacePalette *pal = pRet->format->palette;
for( int x = 0; x < pal->ncolors; ++x ) for( int x = 0; x < pal->ncolors; ++x )
{ {
/* This is really just PAM_DEPTH() broken out for the palette. */ // This is really just PAM_DEPTH() broken out for the palette.
pal->colors[x].r pal->colors[x].r
= (PAM_GETR(acolormap[x].acolor)*255 + (maxval >> 1)) / maxval; = (PAM_GETR(acolormap[x].acolor)*255 + (maxval >> 1)) / maxval;
pal->colors[x].g pal->colors[x].g
@@ -168,7 +166,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
} }
} }
/* Map the colors in the image to their closest match in the new colormap. */ // Map the colors in the image to their closest match in the new colormap.
acolorhash_hash acht; acolorhash_hash acht;
bool fs_direction = 0; bool fs_direction = 0;
@@ -176,7 +174,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
if( bDither ) if( bDither )
{ {
/* Initialize Floyd-Steinberg error vectors. */ // Initialize Floyd-Steinberg error vectors.
thiserr = new pixerror_t[pImg->w + 2]; thiserr = new pixerror_t[pImg->w + 2];
nexterr = new pixerror_t[pImg->w + 2]; nexterr = new pixerror_t[pImg->w + 2];
@@ -209,7 +207,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
uint8_t pixel[4] = { pIn[0], pIn[1], pIn[2], pIn[3] }; uint8_t pixel[4] = { pIn[0], pIn[1], pIn[2], pIn[3] };
if( bDither ) if( bDither )
{ {
/* Use Floyd-Steinberg errors to adjust actual color. */ // Use Floyd-Steinberg errors to adjust actual color.
for( int c = 0; c < 4; ++c ) for( int c = 0; c < 4; ++c )
{ {
sc[c] = pixel[c] + thiserr[col + 1].c[c] / FS_SCALE; sc[c] = pixel[c] + thiserr[col + 1].c[c] / FS_SCALE;
@@ -219,11 +217,11 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
PAM_ASSIGN( pixel, (uint8_t)sc[0], (uint8_t)sc[1], (uint8_t)sc[2], (uint8_t)sc[3] ); PAM_ASSIGN( pixel, (uint8_t)sc[0], (uint8_t)sc[1], (uint8_t)sc[2], (uint8_t)sc[3] );
} }
/* Check hash table to see if we have already matched this color. */ // Check hash table to see if we have already matched this color.
int ind = pam_lookupacolor( acht, pixel ); int ind = pam_lookupacolor( acht, pixel );
if( ind == -1 ) if( ind == -1 )
{ {
/* No; search acolormap for closest match. */ // No; search acolormap for closest match.
static int square_table[512], *pSquareTable = NULL; static int square_table[512], *pSquareTable = NULL;
if( pSquareTable == NULL ) if( pSquareTable == NULL )
{ {
@@ -255,7 +253,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
if( bDither ) if( bDither )
{ {
/* Propagate Floyd-Steinberg error terms. */ // Propagate Floyd-Steinberg error terms.
if( !fs_direction ) if( !fs_direction )
{ {
for( int c = 0; c < 4; ++c ) for( int c = 0; c < 4; ++c )
@@ -307,13 +305,9 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
pImg = pRet; pImg = pRet;
} }
/* Here is the fun part, the median-cut colormap generator. This is based
/*
* Here is the fun part, the median-cut colormap generator. This is based
* on Paul Heckbert's paper, "Color Image Quantization for Frame Buffer * on Paul Heckbert's paper, "Color Image Quantization for Frame Buffer
* Display," SIGGRAPH 1982 Proceedings, page 297. * Display," SIGGRAPH 1982 Proceedings, page 297. */
*/
typedef struct box *box_vector; typedef struct box *box_vector;
struct box struct box
@@ -343,34 +337,32 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
for ( int i = 0; i < newcolors; ++i ) for ( int i = 0; i < newcolors; ++i )
PAM_ASSIGN( acolormap[i].acolor, 0, 0, 0, 0 ); PAM_ASSIGN( acolormap[i].acolor, 0, 0, 0, 0 );
/* Set up the initial box. */ // Set up the initial box.
bv[0].ind = 0; bv[0].ind = 0;
bv[0].colors = colors; bv[0].colors = colors;
bv[0].sum = sum; bv[0].sum = sum;
boxes = 1; boxes = 1;
/* Main loop: split boxes until we have enough. */ // Main loop: split boxes until we have enough.
while( boxes < newcolors ) while( boxes < newcolors )
{ {
int indx, clrs; int indx, clrs;
int sm; int sm;
int halfsum, lowersum; int halfsum, lowersum;
/* Find the first splittable box. */ // Find the first splittable box.
int bi; int bi;
for( bi = 0; bi < boxes; ++bi ) for( bi = 0; bi < boxes; ++bi )
if ( bv[bi].colors >= 2 ) if ( bv[bi].colors >= 2 )
break; break;
if( bi == boxes ) if( bi == boxes )
break; /* ran out of colors! */ break; // ran out of colors!
indx = bv[bi].ind; indx = bv[bi].ind;
clrs = bv[bi].colors; clrs = bv[bi].colors;
sm = bv[bi].sum; sm = bv[bi].sum;
/* /* Go through the box finding the minimum and maximum of each
* Go through the box finding the minimum and maximum of each * component - the boundaries of the box. */
* component - the boundaries of the box.
*/
int mins[4], maxs[4]; int mins[4], maxs[4];
mins[0] = maxs[0] = achv[indx].acolor[0]; mins[0] = maxs[0] = achv[indx].acolor[0];
mins[1] = maxs[1] = achv[indx].acolor[1]; mins[1] = maxs[1] = achv[indx].acolor[1];
@@ -394,7 +386,7 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
maxs[3] = max( maxs[3], v ); maxs[3] = max( maxs[3], v );
} }
/* Find the largest dimension, and sort by that component. */ // Find the largest dimension, and sort by that component.
{ {
int iMax = 0; int iMax = 0;
for( int i = 1; i < 3; ++i ) for( int i = 1; i < 3; ++i )
@@ -409,10 +401,8 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
case 3: sort( &achv[indx], &achv[indx+clrs], compare_index_3 ); break; case 3: sort( &achv[indx], &achv[indx+clrs], compare_index_3 ); break;
} }
} }
/* /* Now find the median based on the counts, so that about half the
* Now find the median based on the counts, so that about half the * pixels (not colors, pixels) are in each subdivision. */
* pixels (not colors, pixels) are in each subdivision.
*/
lowersum = achv[indx].value; lowersum = achv[indx].value;
halfsum = sm / 2; halfsum = sm / 2;
int j; int j;
@@ -423,7 +413,7 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
lowersum += achv[indx + j].value; lowersum += achv[indx + j].value;
} }
/* Split the box, and sort to bring the biggest boxes to the top. */ // Split the box, and sort to bring the biggest boxes to the top.
bv[bi].colors = j; bv[bi].colors = j;
bv[bi].sum = lowersum; bv[bi].sum = lowersum;
bv[boxes].ind = indx + j; bv[boxes].ind = indx + j;
@@ -433,16 +423,14 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
sort( &bv[0], &bv[boxes], CompareBySumDescending ); sort( &bv[0], &bv[boxes], CompareBySumDescending );
} }
/* /* Ok, we've got enough boxes. Now choose a representative color for
* Ok, we've got enough boxes. Now choose a representative color for
* each box. There are a number of possible ways to make this choice. * each box. There are a number of possible ways to make this choice.
* One would be to choose the center of the box; this ignores any structure * One would be to choose the center of the box; this ignores any structure
* within the boxes. Another method would be to average all the colors in * within the boxes. Another method would be to average all the colors in
* the box - this is the method specified in Heckbert's paper. A third * the box - this is the method specified in Heckbert's paper. A third
* method is to average all the pixels in the box. You can switch which * method is to average all the pixels in the box. You can switch which
* method is used by switching the commenting on the REP_ defines at * method is used by switching the commenting on the REP_ defines at
* the beginning of this source file. * the beginning of this source file. */
*/
for( int bi = 0; bi < boxes; ++bi ) for( int bi = 0; bi < boxes; ++bi )
{ {
#ifdef REP_AVERAGE_COLORS #ifdef REP_AVERAGE_COLORS
@@ -462,7 +450,7 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
b = b / clrs; b = b / clrs;
a = a / clrs; a = a / clrs;
PAM_ASSIGN( acolormap[bi].acolor, r, g, b, a ); PAM_ASSIGN( acolormap[bi].acolor, r, g, b, a );
#endif /*REP_AVERAGE_COLORS*/ #endif // REP_AVERAGE_COLORS
#ifdef REP_AVERAGE_PIXELS #ifdef REP_AVERAGE_PIXELS
int indx = bv[bi].ind; int indx = bv[bi].ind;
int clrs = bv[bi].colors; int clrs = bv[bi].colors;
@@ -485,10 +473,10 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
a = a / sum; a = a / sum;
a = min( a, (long) maxval ); a = min( a, (long) maxval );
PAM_ASSIGN( acolormap[bi].acolor, (uint8_t)r, (uint8_t)g, (uint8_t)b, (uint8_t)a ); PAM_ASSIGN( acolormap[bi].acolor, (uint8_t)r, (uint8_t)g, (uint8_t)b, (uint8_t)a );
#endif /*REP_AVERAGE_PIXELS*/ #endif // REP_AVERAGE_PIXELS
} }
/* All done. */ // All done.
return acolormap; return acolormap;
} }
@@ -520,7 +508,7 @@ static bool pam_computeacolorhash( const RageSurface *src, int maxacolors, int*
*acolorsP = 0; *acolorsP = 0;
/* Go through the entire image, building a hash table of colors. */ // Go through the entire image, building a hash table of colors.
for( int row = 0; row < src->h; ++row ) for( int row = 0; row < src->h; ++row )
{ {
const apixel *pP = (const apixel *) (src->pixels + row*src->pitch); const apixel *pP = (const apixel *) (src->pixels + row*src->pitch);
@@ -553,23 +541,23 @@ static bool pam_computeacolorhash( const RageSurface *src, int maxacolors, int*
static acolorhist_item *pam_acolorhashtoacolorhist( const acolorhash_hash &acht, int maxacolors ) static acolorhist_item *pam_acolorhashtoacolorhist( const acolorhash_hash &acht, int maxacolors )
{ {
/* Collate the hash table into a simple acolorhist array. */ // Collate the hash table into a simple acolorhist array.
acolorhist_item *achv = (acolorhist_item*) malloc( maxacolors * sizeof(struct acolorhist_item) ); acolorhist_item *achv = (acolorhist_item*) malloc( maxacolors * sizeof(struct acolorhist_item) );
ASSERT( achv != NULL ); ASSERT( achv != NULL );
/* Loop through the hash table. */ // Loop through the hash table.
int j = 0; int j = 0;
for( unsigned i = 0; i < HASH_SIZE; ++i ) for( unsigned i = 0; i < HASH_SIZE; ++i )
{ {
for ( acolorhist_list achl = acht.hash[i]; achl != NULL; achl = achl->next ) for ( acolorhist_list achl = acht.hash[i]; achl != NULL; achl = achl->next )
{ {
/* Add the new entry. */ // Add the new entry.
achv[j] = achl->ch; achv[j] = achl->ch;
++j; ++j;
} }
} }
/* All done. */ // All done.
return achv; return achv;
} }
+11 -15
View File
@@ -7,14 +7,12 @@
#include <vector> #include <vector>
using namespace std; using namespace std;
/* /* Coordinate 0x0 represents the exact top-left corner of a bitmap. .5x.5
* Coordinate 0x0 represents the exact top-left corner of a bitmap. .5x.5
* represents the center of the top-left pixel; 1x1 is the center of the top * represents the center of the top-left pixel; 1x1 is the center of the top
* square of pixels. * square of pixels.
* *
* (Look at a grid: map coordinates to the lines, not the squares between the * (Look at a grid: map coordinates to the lines, not the squares between the
* lines.) * lines.) */
*/
static void InitVectors( vector<int> &s0, vector<int> &s1, vector<uint32_t> &percent, int src, int dst ) static void InitVectors( vector<int> &s0, vector<int> &s1, vector<uint32_t> &percent, int src, int dst )
{ {
@@ -35,7 +33,7 @@ static void InitVectors( vector<int> &s0, vector<int> &s1, vector<uint32_t> &per
* either pixel. */ * either pixel. */
const float xstep = sx/4.0f; const float xstep = sx/4.0f;
/* source x coordinates of left and right pixels to sample */ // source x coordinates of left and right pixels to sample
s0.push_back(int(sax-xstep)); s0.push_back(int(sax-xstep));
s1.push_back(int(sax+xstep)); s1.push_back(int(sax+xstep));
@@ -47,7 +45,7 @@ static void InitVectors( vector<int> &s0, vector<int> &s1, vector<uint32_t> &per
} else { } else {
const int xdist = s1[x] - s0[x]; const int xdist = s1[x] - s0[x];
/* fleft is the left pixel sampled; +.5 is the center: */ // fleft is the left pixel sampled; +.5 is the center:
const float fleft = s0[x] + .5f; const float fleft = s0[x] + .5f;
/* sax is somewhere between the centers of both sampled /* sax is somewhere between the centers of both sampled
@@ -59,21 +57,19 @@ static void InitVectors( vector<int> &s0, vector<int> &s1, vector<uint32_t> &per
} }
else else
{ {
/* /* Fencepost: If we have source:
* Fencepost: If we have source:
* abcd * abcd
* and dest: * and dest:
* xyz * xyz
* then we want x to be sampled entirely from a, and z entirely from d; * then we want x to be sampled entirely from a, and z entirely from d;
* the inner pixels are interpolated. (This behavior mimics Photoshop's * the inner pixels are interpolated. (This behavior mimics Photoshop's
* resize.) * resize.) */
*/
float sx = float(src-1) / (dst-1); float sx = float(src-1) / (dst-1);
for( int x = 0; x < dst; x++ ) for( int x = 0; x < dst; x++ )
{ {
const float sax = sx*x; const float sax = sx*x;
/* source x coordinates of left and right pixels to sample */ // source x coordinates of left and right pixels to sample
s0.push_back( clamp(int(sax), 0, src-1)); s0.push_back( clamp(int(sax), 0, src-1));
s1.push_back( clamp(int(sax+1), 0, src-1) ); s1.push_back( clamp(int(sax+1), 0, src-1) );
@@ -93,7 +89,7 @@ static void ZoomSurface( const RageSurface * src, RageSurface * dst )
InitVectors( esx0, esx1, ex0, src->w, dst->w ); InitVectors( esx0, esx1, ex0, src->w, dst->w );
InitVectors( esy0, esy1, ey0, src->h, dst->h ); InitVectors( esy0, esy1, ey0, src->h, dst->h );
/* This is where all of the real work is done. */ // This is where all of the real work is done.
const uint8_t *sp = (uint8_t *) src->pixels; const uint8_t *sp = (uint8_t *) src->pixels;
const int height = dst->h; const int height = dst->h;
const int width = dst->w; const int width = dst->w;
@@ -107,7 +103,7 @@ static void ZoomSurface( const RageSurface * src, RageSurface * dst )
for( int x = 0; x < width; x++ ) for( int x = 0; x < width; x++ )
{ {
/* Grab pointers to the sampled pixels: */ // Grab pointers to the sampled pixels:
const uint8_t *c00 = csp + esx0[x]*4; const uint8_t *c00 = csp + esx0[x]*4;
const uint8_t *c01 = csp + esx1[x]*4; const uint8_t *c01 = csp + esx1[x]*4;
const uint8_t *c10 = ncsp + esx0[x]*4; const uint8_t *c10 = ncsp + esx0[x]*4;
@@ -128,7 +124,7 @@ static void ZoomSurface( const RageSurface * src, RageSurface * dst )
} }
*dp = *(uint32_t *) color; *dp = *(uint32_t *) color;
/* Advance destination pointer. */ // Advance destination pointer.
++dp; ++dp;
} }
} }
@@ -145,7 +141,7 @@ void RageSurfaceUtils::Zoom( RageSurface *&src, int dstwidth, int dstheight )
if( src->w == dstwidth && src->h == dstheight ) if( src->w == dstwidth && src->h == dstheight )
return; return;
/* resize currently only does RGBA8888 */ // resize currently only does RGBA8888
if( src->fmt.BytesPerPixel != 4 ) if( src->fmt.BytesPerPixel != 4 )
{ {
RageSurfaceUtils::ConvertSurface( src, src->w, src->h, 32, RageSurfaceUtils::ConvertSurface( src, src->w, src->h, 32,
-2
View File
@@ -29,9 +29,7 @@ void RageTexture::CreateFrameRects()
{ {
GetFrameDimensionsFromFileName( GetID().filename, &m_iFramesWide, &m_iFramesHigh ); GetFrameDimensionsFromFileName( GetID().filename, &m_iFramesWide, &m_iFramesHigh );
//
// Fill in the m_FrameRects with the bounds of each frame in the animation. // Fill in the m_FrameRects with the bounds of each frame in the animation.
//
m_TextureCoordRects.clear(); m_TextureCoordRects.clear();
for( int j=0; j<m_iFramesHigh; j++ ) // traverse along Y for( int j=0; j<m_iFramesHigh; j++ ) // traverse along Y
+3 -5
View File
@@ -41,7 +41,7 @@ public:
int GetImageFrameWidth() const {return GetImageWidth() / GetFramesWide();} int GetImageFrameWidth() const {return GetImageWidth() / GetFramesWide();}
int GetImageFrameHeight() const {return GetImageHeight() / GetFramesHigh();} int GetImageFrameHeight() const {return GetImageHeight() / GetFramesHigh();}
/* Use these to convert between the different coordinate systems: */ // Use these to convert between the different coordinate systems:
float GetSourceToImageCoordsRatioX() const { return float(GetImageWidth()) / GetSourceWidth(); } float GetSourceToImageCoordsRatioX() const { return float(GetImageWidth()) / GetSourceWidth(); }
float GetImageToTexCoordsRatioX() const { return 1.0f / GetTextureWidth(); } float GetImageToTexCoordsRatioX() const { return 1.0f / GetTextureWidth(); }
float GetSourceToTexCoordsRatioX() const { return GetSourceToImageCoordsRatioX() * GetImageToTexCoordsRatioX(); } float GetSourceToTexCoordsRatioX() const { return GetSourceToImageCoordsRatioX() * GetImageToTexCoordsRatioX(); }
@@ -52,20 +52,18 @@ public:
const RectF *GetTextureCoordRect( int frameNo ) const; const RectF *GetTextureCoordRect( int frameNo ) const;
int GetNumFrames() const { return m_iFramesWide*m_iFramesHigh; } int GetNumFrames() const { return m_iFramesWide*m_iFramesHigh; }
/* Used by RageTextureManager. Order is important; see RageTextureManager.cpp. */ // Used by RageTextureManager. Order is important; see RageTextureManager.cpp.
const RageTextureID::TexPolicy &GetPolicy() const { return m_ID.Policy; } const RageTextureID::TexPolicy &GetPolicy() const { return m_ID.Policy; }
RageTextureID::TexPolicy &GetPolicy() { return m_ID.Policy; } RageTextureID::TexPolicy &GetPolicy() { return m_ID.Policy; }
int m_iRefCount; int m_iRefCount;
bool m_bWasUsed; bool m_bWasUsed;
/* The ID that we were asked to load: */ // The ID that we were asked to load:
const RageTextureID &GetID() const { return m_ID; } const RageTextureID &GetID() const { return m_ID; }
static void GetFrameDimensionsFromFileName( RString sPath, int* puFramesWide, int* puFramesHigh ); static void GetFrameDimensionsFromFileName( RString sPath, int* puFramesWide, int* puFramesHigh );
//
// Lua // Lua
//
virtual void PushSelf( lua_State *L ); virtual void PushSelf( lua_State *L );
private: private:
+1 -1
View File
@@ -11,7 +11,7 @@ void RageTextureID::Init()
iGrayscaleBits = -1; iGrayscaleBits = -1;
bDither = false; bDither = false;
bStretch = false; bStretch = false;
iColorDepth = -1; /* default */ iColorDepth = -1; // default
bHotPinkColorKey = false; bHotPinkColorKey = false;
AdditionalTextureHints = ""; AdditionalTextureHints = "";
Policy = TEXTUREMAN->GetDefaultTexturePolicy(); Policy = TEXTUREMAN->GetDefaultTexturePolicy();
+6 -6
View File
@@ -11,10 +11,10 @@ struct RageTextureID
{ {
RString filename; RString filename;
/* Maximum size of the texture, per dimension. */ // Maximum size of the texture, per dimension.
int iMaxSize; int iMaxSize;
/* Generate mipmaps for this texture */ // Generate mipmaps for this texture
bool bMipMaps; bool bMipMaps;
/* Maximum number of bits for alpha. In 16-bit modes, lowering /* Maximum number of bits for alpha. In 16-bit modes, lowering
@@ -35,17 +35,17 @@ struct RageTextureID
* paletted images and transparencies.) -1 for default. */ * paletted images and transparencies.) -1 for default. */
int iColorDepth; int iColorDepth;
/* If true and color precision is being lost, dither. (slow) */ // If true and color precision is being lost, dither. (slow)
bool bDither; bool bDither;
/* If true, resize the image to fill the internal texture. (slow) */ // If true, resize the image to fill the internal texture. (slow)
bool bStretch; bool bStretch;
/* If true, enable HOT PINK color keying. (deprecated but needed for /* If true, enable HOT PINK color keying. (deprecated but needed for
* banners) */ * banners) */
bool bHotPinkColorKey; /* #FF00FF */ bool bHotPinkColorKey; // #FF00FF
/* These hints will be used in addition to any in the filename. */ // These hints will be used in addition to any in the filename.
RString AdditionalTextureHints; RString AdditionalTextureHints;
bool operator< (const RageTextureID &rhs) const; bool operator< (const RageTextureID &rhs) const;
+9 -9
View File
@@ -20,15 +20,15 @@ void RageTextureRenderTarget::Reload()
Create(); Create();
} }
/* RageTextureID identifies a file and a mechanism for loading it. We don't use any /* RageTextureID identifies a file and a mechanism for loading it. We don't use
* of that, except as a unique identifier for this texture, so it can be loaded * any of that, except as a unique identifier for this texture, so it can be
* elsewhere. Render targets can't be loaded blindly like a regular texture, anyway, * loaded elsewhere. Render targets can't be loaded blindly like a regular
* since something has to render into it. */ * texture, anyway, since something has to render into it. */
void RageTextureRenderTarget::Create() void RageTextureRenderTarget::Create()
{ {
/* All render targets support non-power-of-two targets, but some require that the /* All render targets support non-power-of-two targets,
* resulting texture dimensions be powers of two. CreateRenderTarget returns * but some require that the resulting texture dimensions be powers of two.
* the actual resolution. */ * CreateRenderTarget returns the actual resolution. */
m_iTexHandle = DISPLAY->CreateRenderTarget( m_Param, m_iTextureWidth, m_iTextureHeight ); m_iTexHandle = DISPLAY->CreateRenderTarget( m_Param, m_iTextureWidth, m_iTextureHeight );
m_iSourceWidth = m_Param.iWidth; m_iSourceWidth = m_Param.iWidth;
@@ -49,8 +49,8 @@ void RageTextureRenderTarget::BeginRenderingTo( bool bPreserveTexture )
{ {
DISPLAY->SetRenderTarget( m_iTexHandle, bPreserveTexture ); DISPLAY->SetRenderTarget( m_iTexHandle, bPreserveTexture );
/* We're rendering to a texture, not the framebuffer. Stash away the /* We're rendering to a texture, not the framebuffer.
* centering matrix, and set it to identity. */ * Stash away the centering matrix, and set it to identity. */
DISPLAY->CenteringPushMatrix(); DISPLAY->CenteringPushMatrix();
DISPLAY->ChangeCentering( 0, 0, 0, 0 ); DISPLAY->ChangeCentering( 0, 0, 0, 0 );
-2
View File
@@ -21,9 +21,7 @@ public:
void UpdateText(); void UpdateText();
//
// Commands // Commands
//
virtual void PushSelf( lua_State *L ); virtual void PushSelf( lua_State *L );
private: private:
+6 -7
View File
@@ -178,12 +178,13 @@ void ScreenNetEvaluation::UpdateStats()
if( m_iCurrentPlayer >= (int) NSMAN->m_EvalPlayerData.size() ) if( m_iCurrentPlayer >= (int) NSMAN->m_EvalPlayerData.size() )
return; return;
// XXX: These commands assume that grades and score are shown in the theme
// on ScreenNetEvaluation, which is not always the case. If a theme doesn't
// have these elements for whatever reason, a crash will occur. -aj
m_Grades[m_pActivePlayer].SetGrade( (Grade)NSMAN->m_EvalPlayerData[m_iCurrentPlayer].grade ); m_Grades[m_pActivePlayer].SetGrade( (Grade)NSMAN->m_EvalPlayerData[m_iCurrentPlayer].grade );
//m_textScore[m_pActivePlayer].SetText( ssprintf("%*.0i", NUM_SCORE_DIGITS, NSMAN->m_EvalPlayerData[m_iCurrentPlayer].score) );
m_textScore[m_pActivePlayer].SetTargetNumber( NSMAN->m_EvalPlayerData[m_iCurrentPlayer].score ); m_textScore[m_pActivePlayer].SetTargetNumber( NSMAN->m_EvalPlayerData[m_iCurrentPlayer].score );
//Values greater than 6 will cause crash //Values greater than 6 will cause a crash
if ( NSMAN->m_EvalPlayerData[m_iCurrentPlayer].difficulty < 6 ) if ( NSMAN->m_EvalPlayerData[m_iCurrentPlayer].difficulty < 6 )
{ {
m_DifficultyIcon[m_pActivePlayer].SetPlayer( m_pActivePlayer ); m_DifficultyIcon[m_pActivePlayer].SetPlayer( m_pActivePlayer );
@@ -192,12 +193,10 @@ void ScreenNetEvaluation::UpdateStats()
for( int j=0; j<NETNUMTAPSCORES; ++j ) for( int j=0; j<NETNUMTAPSCORES; ++j )
{ {
// The name will be blank if ScreenEvaluation determined the // The name will be blank if ScreenEvaluation determined the line
// line should not be shown // should not be shown.
if( !m_textJudgmentLineNumber[j][m_pActivePlayer].GetName().empty() ) if( !m_textJudgmentLineNumber[j][m_pActivePlayer].GetName().empty() )
{ {
// do we need this iNumDigits thing anymore? -aj
//int iNumDigits = (j==JudgmentLine_MaxCombo)? MAX_COMBO_NUM_DIGITS:4;
m_textJudgmentLineNumber[j][m_pActivePlayer].SetTargetNumber( NSMAN->m_EvalPlayerData[m_iCurrentPlayer].tapScores[j] ); m_textJudgmentLineNumber[j][m_pActivePlayer].SetTargetNumber( NSMAN->m_EvalPlayerData[m_iCurrentPlayer].tapScores[j] );
} }
} }
+1
View File
@@ -104,6 +104,7 @@ static bool ExportPackage( RString sPackageName, RString sDirToExport, RString &
/* /*
RageFile f; RageFile f;
// TODO: Mount Desktop/ for each OS // TODO: Mount Desktop/ for each OS
// SpecialDirs::GetDesktopDir() [windows only right now -aj]
if( !f.Open("Desktop/"+sPackageName, RageFile::WRITE) ) if( !f.Open("Desktop/"+sPackageName, RageFile::WRITE) )
{ {
sErrorOut = ssprintf( "Couldn't open %s for writing: %s", fn.c_str(), f.GetError().c_str() ); sErrorOut = ssprintf( "Couldn't open %s for writing: %s", fn.c_str(), f.GetError().c_str() );
+6 -1
View File
@@ -187,7 +187,11 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM )
// create // create
RString sProfileID; RString sProfileID;
PROFILEMAN->CreateLocalProfile( ScreenTextEntry::s_sLastAnswer, sProfileID ); // TODO: Check return value
// is this the correct way to go about checking the return value? -aj
bool bCreateProfile = PROFILEMAN->CreateLocalProfile( ScreenTextEntry::s_sLastAnswer, sProfileID );
ASSERT(bCreateProfile);
GAMESTATE->m_sEditLocalProfileID.Set( sProfileID ); GAMESTATE->m_sEditLocalProfileID.Set( sProfileID );
if( iNumProfiles < NUM_PLAYERS ) if( iNumProfiles < NUM_PLAYERS )
@@ -294,6 +298,7 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM )
{ {
RString sTitle = pProfile->m_sDisplayName; RString sTitle = pProfile->m_sDisplayName;
RString sMessage = ssprintf( CONFIRM_DELETE_PROFILE.GetValue(), sTitle.c_str() ); RString sMessage = ssprintf( CONFIRM_DELETE_PROFILE.GetValue(), sTitle.c_str() );
LOG->Trace("[ScreenOptionsManageProfiles] ProfileAction_Delete");
ScreenPrompt::Prompt( SM_BackFromDeleteConfirm, sMessage, PROMPT_YES_NO ); ScreenPrompt::Prompt( SM_BackFromDeleteConfirm, sMessage, PROMPT_YES_NO );
} }
break; break;
+44 -41
View File
@@ -75,7 +75,7 @@ static void MoveMap( int &sel, T &opt, bool ToSel, const T *mapping, unsigned cn
{ {
sel = FindClosestEntry( opt, mapping, cnt ); sel = FindClosestEntry( opt, mapping, cnt );
} else { } else {
/* sel -> opt */ // sel -> opt
opt = mapping[sel]; opt = mapping[sel];
} }
} }
@@ -86,12 +86,12 @@ static void MoveMap( int &sel, IPreference &opt, bool ToSel, const T *mapping, u
if( ToSel ) if( ToSel )
{ {
RString sOpt = opt.ToString(); RString sOpt = opt.ToString();
/* This should really be T, but we can't FromString an enum. */ // This should really be T, but we can't FromString an enum.
float val; float val;
FromString( sOpt, val ); FromString( sOpt, val );
sel = FindClosestEntry( val, mapping, cnt ); sel = FindClosestEntry( val, mapping, cnt );
} else { } else {
/* sel -> opt */ // sel -> opt
RString sOpt = ToString( mapping[sel] ); RString sOpt = ToString( mapping[sel] );
opt.FromString( sOpt ); opt.FromString( sOpt );
} }
@@ -115,7 +115,8 @@ static void MovePref( int &iSel, bool bToSel, const ConfOption *pConfOption )
if( bToSel ) if( bToSel )
{ {
// TODO: why not get the int directly from pPref? Why are we writing it to a string and then back? // TODO: why not get the int directly from pPref?
// Why are we writing it to a string and then back?
T t; T t;
FromString( pPref->ToString(), t ); FromString( pPref->ToString(), t );
iSel = static_cast<int>( t ); iSel = static_cast<int>( t );
@@ -134,15 +135,17 @@ void MovePref<bool>( int &iSel, bool bToSel, const ConfOption *pConfOption )
if( bToSel ) if( bToSel )
{ {
// TODO: why not get the int directly from pPref? Why are we writing it to a string and then back? // TODO: why not get the int directly from pPref?
// Why are we writing it to a string and then back?
bool b; bool b;
FromString( pPref->ToString(), b ); FromString( pPref->ToString(), b );
iSel = b ? 1 : 0; iSel = b ? 1 : 0;
} }
else else
{ {
// If we don't make a specific instantiation of MovePref<bool>, there is a compile warning here because of // If we don't make a specific instantiation of MovePref<bool>, there is
// static_cast<bool>( iSel ) where iSel is an int. What is the best way to remove that compile warning? // a compile warning here because of static_cast<bool>( iSel ) where
// iSel is an int. What is the best way to remove that compile warning?
pPref->FromString( ToString<bool>( iSel ? true : false ) ); pPref->FromString( ToString<bool>( iSel ? true : false ) );
} }
} }
@@ -220,7 +223,7 @@ static void Language( int &sel, bool ToSel, const ConfOption *pConfOption )
if( !stricmp(vs[i], THEME->GetCurLanguage()) ) if( !stricmp(vs[i], THEME->GetCurLanguage()) )
sel = i; sel = i;
/* If the current language doesn't exist, we'll show BASE_LANGUAGE, so select that. */ // If the current language doesn't exist, we'll show BASE_LANGUAGE, so select that.
for( unsigned i=0; sel == -1 && i < vs.size(); ++i ) for( unsigned i=0; sel == -1 && i < vs.size(); ++i )
if( !stricmp(vs[i], SpecialFiles::BASE_LANGUAGE) ) if( !stricmp(vs[i], SpecialFiles::BASE_LANGUAGE) )
sel = i; sel = i;
@@ -337,12 +340,12 @@ static void DefaultNoteSkin( int &sel, bool ToSel, const ConfOption *pConfOption
} }
} }
/* Background options */ // Background options
static void BGBrightness( int &sel, bool ToSel, const ConfOption *pConfOption ) static void BGBrightness( int &sel, bool ToSel, const ConfOption *pConfOption )
{ {
// TODO: I hate the way the list of numbers is duplicated here and where the option is created. // TODO: I hate the way the list of numbers is duplicated here and where the
// Try to find a way to only use the same list once. Do that for all of these float and int lists. // option is created. Try to find a way to only use the same list once.
// Do that for all of these float and int lists.
const float mapping[] = { 0.0f,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f }; const float mapping[] = { 0.0f,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f };
MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) ); MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) );
} }
@@ -371,14 +374,14 @@ static void NumBackgrounds( int &sel, bool ToSel, const ConfOption *pConfOption
MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) ); MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) );
} }
/* Input options */ // Input options
static void MusicWheelSwitchSpeed( int &sel, bool ToSel, const ConfOption *pConfOption ) static void MusicWheelSwitchSpeed( int &sel, bool ToSel, const ConfOption *pConfOption )
{ {
const int mapping[] = { 5, 10, 15, 25 }; const int mapping[] = { 5, 10, 15, 25 };
MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) ); MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) );
} }
/* Gameplay options */ // Gameplay options
static void CoinModeNoHome( int &sel, bool ToSel, const ConfOption *pConfOption ) static void CoinModeNoHome( int &sel, bool ToSel, const ConfOption *pConfOption )
{ {
// The mapping without home is easy: subtract one to compensate for the missing CoinMode_Home // The mapping without home is easy: subtract one to compensate for the missing CoinMode_Home
@@ -425,8 +428,7 @@ static void SongsPerPlayOrEventMode( int &sel, bool ToSel, const ConfOption *pCo
PREFSMAN->m_bEventMode.Set( sel == 5 ); PREFSMAN->m_bEventMode.Set( sel == 5 );
} }
/* Machine options */ // Machine options
static void TimingWindowScale( int &sel, bool ToSel, const ConfOption *pConfOption ) static void TimingWindowScale( int &sel, bool ToSel, const ConfOption *pConfOption )
{ {
const float mapping[] = { 2.0f,1.66f,1.33f,1.00f,0.75f,0.50f,0.25f }; const float mapping[] = { 2.0f,1.66f,1.33f,1.00f,0.75f,0.50f,0.25f };
@@ -487,8 +489,7 @@ static void DefaultFailType( int &sel, bool ToSel, const ConfOption *pConfOption
} }
} }
/* Graphic options */ // Graphic options
struct res_t struct res_t
{ {
int w, h; int w, h;
@@ -506,7 +507,7 @@ struct res_t
return h < rhs.h; return h < rhs.h;
} }
/* Ugly: allow convert to a float for FindClosestEntry. */ // Ugly: allow convert to a float for FindClosestEntry.
operator float() const { return w * 5000.0f + h; } operator float() const { return w * 5000.0f + h; }
}; };
@@ -567,8 +568,8 @@ static void DisplayAspectRatio( int &sel, bool ToSel, const ConfOption *pConfOpt
MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) ); MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) );
} }
/* Simpler DisplayAspectRatio setting, which only offers "on" and "off". "On" can be 16:9 /* Simpler DisplayAspectRatio setting, which only offers "on" and "off".
* or 16:10. */ * "On" can be 16:9 or 16:10. */
static void WideScreen16_10( int &sel, bool ToSel, const ConfOption *pConfOption ) static void WideScreen16_10( int &sel, bool ToSel, const ConfOption *pConfOption )
{ {
const float mapping[] = { 4/3.0f, 16/10.0f }; const float mapping[] = { 4/3.0f, 16/10.0f };
@@ -581,17 +582,16 @@ static void WideScreen16_9( int &sel, bool ToSel, const ConfOption *pConfOption
MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) ); MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) );
} }
/* SSC */
/*
// BackgroundCache code isn't live yet -aj // BackgroundCache code isn't live yet -aj
/*
static void BackgroundCache( int &sel, bool ToSel, const ConfOption *pConfOption ) static void BackgroundCache( int &sel, bool ToSel, const ConfOption *pConfOption )
{ {
const BackgroundCache mapping[] = { BackgroundCacheMode_Off, BackgroundCacheMode_LowResPreload, BackgroundCacheMode_LowResLoadOnDemand, BackgroundCacheMode_Full }; const BackgroundCache mapping[] = { BackgroundCacheMode_Off, BackgroundCacheMode_LowResPreload, BackgroundCacheMode_LowResLoadOnDemand, BackgroundCacheMode_Full };
MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) ); MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) );
} }
*/ */
/* Sound options */
// Sound options
static void SoundVolume( int &sel, bool ToSel, const ConfOption *pConfOption ) static void SoundVolume( int &sel, bool ToSel, const ConfOption *pConfOption )
{ {
const float mapping[] = { 0.0f,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f }; const float mapping[] = { 0.0f,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f };
@@ -625,18 +625,21 @@ static void InitializeConfOptions()
if( !g_ConfOptions.empty() ) if( !g_ConfOptions.empty() )
return; return;
// There are a couple ways of getting the current preference column or turning a new choice in the interface // There are a couple ways of getting the current preference column or turning
// into a new preference. The easiest is when the interface choices are an exact mapping to the values the // a new choice in the interface into a new preference. The easiest is when
// preference can be. In that case, the easiest thing to do is use MovePref<bool or enum>. The next // the interface choices are an exact mapping to the values the preference
// easiest case is when there is a hardcoded mapping that is not 1-1, such as CoinModeNoHome. In that case, // can be. In that case, the easiest thing to do is use MovePref<bool or enum>.
// you need to remap the result of MovePref<enum> to the correct mapping. Harder yet is when there is a // The next easiest case is when there is a hardcoded mapping that is not 1-1,
// float or a dynamic set of options, such as Language or Theme. Those require individual attention. // such as CoinModeNoHome. In that case, you need to remap the result of
// MovePref<enum> to the correct mapping. Harder yet is when there is a
// float or a dynamic set of options, such as Language or Theme.
// Those require individual attention.
#define ADD(x) g_ConfOptions.push_back( x ) #define ADD(x) g_ConfOptions.push_back( x )
/* Select game */ // Select game
ADD( ConfOption( "Game", GameSel, GameChoices ) ); ADD( ConfOption( "Game", GameSel, GameChoices ) );
g_ConfOptions.back().m_iEffects = OPT_RESET_GAME; g_ConfOptions.back().m_iEffects = OPT_RESET_GAME;
/* Appearance options */ // Appearance options
ADD( ConfOption( "Language", Language, LanguageChoices ) ); ADD( ConfOption( "Language", Language, LanguageChoices ) );
ADD( ConfOption( "Theme", Theme, ThemeChoices ) ); ADD( ConfOption( "Theme", Theme, ThemeChoices ) );
g_ConfOptions.back().m_iEffects = OPT_APPLY_THEME; g_ConfOptions.back().m_iEffects = OPT_APPLY_THEME;
@@ -653,7 +656,7 @@ static void InitializeConfOptions()
ADD( ConfOption( "ShowNativeLanguage", MovePref<bool>, "Romanization","Native Language") ); ADD( ConfOption( "ShowNativeLanguage", MovePref<bool>, "Romanization","Native Language") );
ADD( ConfOption( "ShowLyrics", MovePref<bool>, "Hide","Show") ); ADD( ConfOption( "ShowLyrics", MovePref<bool>, "Hide","Show") );
/* Misc options */ // Misc options
ADD( ConfOption( "AutogenSteps", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "AutogenSteps", MovePref<bool>, "Off","On" ) );
ADD( ConfOption( "OnlyPreferredDifficulties", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "OnlyPreferredDifficulties", MovePref<bool>, "Off","On" ) );
g_ConfOptions.back().m_iEffects = OPT_APPLY_SONG; g_ConfOptions.back().m_iEffects = OPT_APPLY_SONG;
@@ -661,7 +664,7 @@ static void InitializeConfOptions()
ADD( ConfOption( "AutogenGroupCourses", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "AutogenGroupCourses", MovePref<bool>, "Off","On" ) );
ADD( ConfOption( "FastLoad", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "FastLoad", MovePref<bool>, "Off","On" ) );
/* Background options */ // Background options
ADD( ConfOption( "RandomBackgroundMode", MovePref<RandomBackgroundMode>, "Off","Animations","Random Movies" ) ); ADD( ConfOption( "RandomBackgroundMode", MovePref<RandomBackgroundMode>, "Off","Animations","Random Movies" ) );
ADD( ConfOption( "BGBrightness", BGBrightness, "|0%","|10%","|20%","|30%","|40%","|50%","|60%","|70%","|80%","|90%","|100%" ) ); ADD( ConfOption( "BGBrightness", BGBrightness, "|0%","|10%","|20%","|30%","|40%","|50%","|60%","|70%","|80%","|90%","|100%" ) );
ADD( ConfOption( "BGBrightnessNoZero", BGBrightnessNoZero, "|10%","|20%","|30%","|40%","|50%","|60%","|70%","|80%","|90%","|100%" ) ); ADD( ConfOption( "BGBrightnessNoZero", BGBrightnessNoZero, "|10%","|20%","|30%","|40%","|50%","|60%","|70%","|80%","|90%","|100%" ) );
@@ -674,7 +677,7 @@ static void InitializeConfOptions()
ADD( ConfOption( "ShowBeginnerHelper", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "ShowBeginnerHelper", MovePref<bool>, "Off","On" ) );
ADD( ConfOption( "NumBackgrounds", NumBackgrounds, "|5","|10","|15","|20" ) ); ADD( ConfOption( "NumBackgrounds", NumBackgrounds, "|5","|10","|15","|20" ) );
/* Input options */ // Input options
ADD( ConfOption( "AutoMapOnJoyChange", MovePref<bool>, "Off","On (recommended)" ) ); ADD( ConfOption( "AutoMapOnJoyChange", MovePref<bool>, "Off","On (recommended)" ) );
ADD( ConfOption( "OnlyDedicatedMenuButtons", MovePref<bool>, "Use Gameplay Buttons","Only Dedicated Buttons" ) ); ADD( ConfOption( "OnlyDedicatedMenuButtons", MovePref<bool>, "Use Gameplay Buttons","Only Dedicated Buttons" ) );
ADD( ConfOption( "AutoPlay", MovePref<PlayerController>, "Off","On","CPU-Controlled" ) ); ADD( ConfOption( "AutoPlay", MovePref<PlayerController>, "Off","On","CPU-Controlled" ) );
@@ -682,7 +685,7 @@ static void InitializeConfOptions()
ADD( ConfOption( "ArcadeOptionsNavigation", MovePref<bool>, "StepMania Style","Arcade Style" ) ); ADD( ConfOption( "ArcadeOptionsNavigation", MovePref<bool>, "StepMania Style","Arcade Style" ) );
ADD( ConfOption( "MusicWheelSwitchSpeed", MusicWheelSwitchSpeed, "Slow","Normal","Fast","Really Fast" ) ); ADD( ConfOption( "MusicWheelSwitchSpeed", MusicWheelSwitchSpeed, "Slow","Normal","Fast","Really Fast" ) );
/* Gameplay options */ // Gameplay options
ADD( ConfOption( "Center1Player", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "Center1Player", MovePref<bool>, "Off","On" ) );
ADD( ConfOption( "HiddenSongs", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "HiddenSongs", MovePref<bool>, "Off","On" ) );
ADD( ConfOption( "EasterEggs", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "EasterEggs", MovePref<bool>, "Off","On" ) );
@@ -692,7 +695,7 @@ static void InitializeConfOptions()
ADD( ConfOption( "PickExtraStage", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "PickExtraStage", MovePref<bool>, "Off","On" ) );
ADD( ConfOption( "UseUnlockSystem", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "UseUnlockSystem", MovePref<bool>, "Off","On" ) );
/* Machine options */ // Machine options
ADD( ConfOption( "MenuTimer", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "MenuTimer", MovePref<bool>, "Off","On" ) );
ADD( ConfOption( "CoinMode", MovePref<CoinMode>, "Home","Pay","Free Play" ) ); ADD( ConfOption( "CoinMode", MovePref<CoinMode>, "Home","Pay","Free Play" ) );
ADD( ConfOption( "CoinModeNoHome", CoinModeNoHome, "Pay","Free Play" ) ); ADD( ConfOption( "CoinModeNoHome", CoinModeNoHome, "Pay","Free Play" ) );
@@ -719,7 +722,7 @@ static void InitializeConfOptions()
ADD( ConfOption( "PercentageScoring", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "PercentageScoring", MovePref<bool>, "Off","On" ) );
ADD( ConfOption( "GetRankingName", MovePref<GetRankingName>, "Off", "On", "Ranking Songs" ) ); ADD( ConfOption( "GetRankingName", MovePref<GetRankingName>, "Off", "On", "Ranking Songs" ) );
/* Graphic options */ // Graphic options
ADD( ConfOption( "Windowed", MovePref<bool>, "Full Screen", "Windowed" ) ); ADD( ConfOption( "Windowed", MovePref<bool>, "Full Screen", "Windowed" ) );
g_ConfOptions.back().m_iEffects = OPT_APPLY_GRAPHICS; g_ConfOptions.back().m_iEffects = OPT_APPLY_GRAPHICS;
ADD( ConfOption( "DisplayResolution", DisplayResolutionM, DisplayResolutionChoices ) ); ADD( ConfOption( "DisplayResolution", DisplayResolutionM, DisplayResolutionChoices ) );
@@ -753,7 +756,7 @@ static void InitializeConfOptions()
ADD( ConfOption( "ShowStats", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "ShowStats", MovePref<bool>, "Off","On" ) );
ADD( ConfOption( "ShowBanners", MovePref<bool>, "Off","On" ) ); ADD( ConfOption( "ShowBanners", MovePref<bool>, "Off","On" ) );
/* Sound options */ // Sound options
ADD( ConfOption( "AttractSoundFrequency", MovePref<AttractSoundFrequency>, "Never","Always","2 Times","3 Times","4 Times","5 Times" ) ); ADD( ConfOption( "AttractSoundFrequency", MovePref<AttractSoundFrequency>, "Never","Always","2 Times","3 Times","4 Times","5 Times" ) );
ADD( ConfOption( "SoundVolume", SoundVolume, "Silent","|10%","|20%","|30%","|40%","|50%","|60%","|70%","|80%","|90%","|100%" ) ); ADD( ConfOption( "SoundVolume", SoundVolume, "Silent","|10%","|20%","|30%","|40%","|50%","|60%","|70%","|80%","|90%","|100%" ) );
g_ConfOptions.back().m_iEffects = OPT_APPLY_SOUND; g_ConfOptions.back().m_iEffects = OPT_APPLY_SOUND;
@@ -768,13 +771,13 @@ static void InitializeConfOptions()
ADD( ConfOption( "EnableAttackSounds", MovePref<bool>, "No","Yes" ) ); ADD( ConfOption( "EnableAttackSounds", MovePref<bool>, "No","Yes" ) );
ADD( ConfOption( "EnableMineHitSound", MovePref<bool>, "No","Yes" ) ); ADD( ConfOption( "EnableMineHitSound", MovePref<bool>, "No","Yes" ) );
/* Editor options */ // Editor options
ADD( ConfOption( "EditorShowBGChangesPlay", MovePref<bool>, "Hide","Show") ); ADD( ConfOption( "EditorShowBGChangesPlay", MovePref<bool>, "Hide","Show") );
ADD( ConfOption( "Invalid", MoveNop, "|Invalid option") ); ADD( ConfOption( "Invalid", MoveNop, "|Invalid option") );
} }
/* Get a mask of effects to apply if the given option changes. */ // Get a mask of effects to apply if the given option changes.
int ConfOption::GetEffects() const int ConfOption::GetEffects() const
{ {
return m_iEffects | OPT_SAVE_PREFERENCES; return m_iEffects | OPT_SAVE_PREFERENCES;
+4 -4
View File
@@ -14,10 +14,10 @@ struct ConfOption
{ {
static ConfOption *Find( RString name ); static ConfOption *Find( RString name );
/* Name of this option. */ // Name of this option.
RString name; RString name;
/* Name of the preference this option affects. */ // Name of the preference this option affects.
RString m_sPrefName; RString m_sPrefName;
typedef void (*MoveData_t)( int &sel, bool ToSel, const ConfOption *pConfOption ); typedef void (*MoveData_t)( int &sel, bool ToSel, const ConfOption *pConfOption );
@@ -29,8 +29,8 @@ struct ConfOption
* options, this may invalidate the offsets returned by Get() and Put(). */ * options, this may invalidate the offsets returned by Get() and Put(). */
void UpdateAvailableOptions(); void UpdateAvailableOptions();
/* Return the list of available selections; Get() and Put() use indexes into this /* Return the list of available selections; Get() and Put() use indexes into
* array. UpdateAvailableOptions() should be called before using this. */ * this array. UpdateAvailableOptions() should be called before using this. */
void MakeOptionsList( vector<RString> &out ) const; void MakeOptionsList( vector<RString> &out ) const;
inline int Get() const { int sel; MoveData( sel, true, this ); return sel; } inline int Get() const { int sel; MoveData( sel, true, this ); return sel; }
+19 -19
View File
@@ -15,19 +15,18 @@
#define UPDATE_ON_MESSAGE THEME->GetMetric (m_sName,"UpdateOnMessage") #define UPDATE_ON_MESSAGE THEME->GetMetric (m_sName,"UpdateOnMessage")
#if defined(SSC_FUTURES) #if defined(SSC_FUTURES)
// ???: Instead of using NumLists, use a comma-separated list of list names? #define LIST_NAMES THEME->GetMetric (m_sName,"ListNames")
#define NUM_LISTS THEME->GetMetricI (m_sName,"NumLists")
#else #else
// xxx: USE_TWO_LISTS is just a hack for two players. // xxx: USE_TWO_LISTS is just a hack for two players. -aj
#define USE_TWO_LISTS THEME->GetMetricB (m_sName,"UseTwoLists") #define USE_TWO_LISTS THEME->GetMetricB (m_sName,"UseTwoLists")
#endif #endif
#if defined(SSC_FUTURES) #if defined(SSC_FUTURES)
#define LIST_CONDITION( i ) THEME->GetMetricR (m_sName,"List%iCondition",i) #define LIST_CONDITION( s ) THEME->GetMetricR (m_sName,"List%sCondition",s.c_str())
#define CHOICE_NAMES_MULTI( i ) THEME->GetMetric (m_sName,ssprintf("List%iChoiceNames",i)) #define CHOICE_NAMES_MULTI( s ) THEME->GetMetric (m_sName,ssprintf("List%sChoiceNames",s.c_str()))
#define CHOICEMULTI( i, s ) THEME->GetMetric (m_sName,ssprintf("List%iChoice%s",i,s.c_str())) #define CHOICEMULTI( s1, s2 ) THEME->GetMetric (m_sName,ssprintf("List%sChoice%s",s1.c_str(),s2.c_str()))
#else #else
// xxx: these are used by USE_TWO_LISTS. // xxx: these are used by USE_TWO_LISTS. -aj
#define CHOICE_NAMESB THEME->GetMetric (m_sName,"ChoiceNamesB") #define CHOICE_NAMESB THEME->GetMetric (m_sName,"ChoiceNamesB")
#define CHOICEB( s ) THEME->GetMetric (m_sName,ssprintf("ChoiceB%s",s.c_str())) #define CHOICEB( s ) THEME->GetMetric (m_sName,ssprintf("ChoiceB%s",s.c_str()))
#endif #endif
@@ -50,10 +49,10 @@ void ScreenSelect::Init()
// Load choices // Load choices
{ {
// Instead of using NUM_CHOICES, use a comma-separated list of choices. Each // Instead of using NUM_CHOICES, use a comma-separated list of choices.
// element in the list is a choice name. This level of indirection // Each element in the list is a choice name. This level of indirection
// makes it easier to add or remove items without having to change a bunch // makes it easier to add or remove items without having to change a
// of indices. // bunch of indices.
vector<RString> asChoiceNames; vector<RString> asChoiceNames;
split( CHOICE_NAMES, ",", asChoiceNames, true ); split( CHOICE_NAMES, ",", asChoiceNames, true );
@@ -172,7 +171,6 @@ void ScreenSelect::Input( const InputEventPlus &input )
this->UpdateSelectableChoices(); this->UpdateSelectableChoices();
} }
// HACK: Only play start sound for the 2nd player who joins. The // HACK: Only play start sound for the 2nd player who joins. The
// start sound for the 1st player will be played by ScreenTitleMenu // start sound for the 1st player will be played by ScreenTitleMenu
// when the player makes a selection on the screen. // when the player makes a selection on the screen.
@@ -189,9 +187,11 @@ void ScreenSelect::Input( const InputEventPlus &input )
if( !ALLOW_DISABLED_PLAYER_INPUT ) if( !ALLOW_DISABLED_PLAYER_INPUT )
return; return;
/* Never allow a START press by a player that's still not joined, even if ALLOW_DISABLED_PLAYER_INPUT /* Never allow a START press by a player that's still not joined, even if
* would allow other types of input. If we let a non-joined player start, we might start the * ALLOW_DISABLED_PLAYER_INPUT would allow other types of input. If we
* game with no players joined (eg. if ScreenTitleJoin is started in pay with no credits). */ * let a non-joined player start, we might start the game with no
* players joined (eg. if ScreenTitleJoin is started in pay with no
* credits). */
if( input.MenuI == GAME_BUTTON_START ) if( input.MenuI == GAME_BUTTON_START )
return; return;
} }
@@ -201,12 +201,12 @@ void ScreenSelect::Input( const InputEventPlus &input )
void ScreenSelect::HandleScreenMessage( const ScreenMessage SM ) void ScreenSelect::HandleScreenMessage( const ScreenMessage SM )
{ {
if( SM == SM_BeginFadingOut ) /* Screen is starting to tween out. */ if( SM == SM_BeginFadingOut ) // Screen is starting to tween out.
{ {
/* Don't call GameCommand::Apply once per player on screens that /* Don't call GameCommand::Apply once per player on screens that
* have a shared selection. This can cause change messages to be broadcast * have a shared selection. This can cause change messages to be
* multiple times. Detect whether all players have the same choice, and * broadcast multiple times. Detect whether all players have the
* if so, call ApplyToAll instead. * same choice, and if so, call ApplyToAll instead.
* TODO: Think of a better way to handle this. * TODO: Think of a better way to handle this.
*/ */
ASSERT( GAMESTATE->m_MasterPlayerNumber != PlayerNumber_Invalid ); ASSERT( GAMESTATE->m_MasterPlayerNumber != PlayerNumber_Invalid );
+1 -1
View File
@@ -34,7 +34,7 @@ protected:
vector<GameCommand> m_aGameCommands; // derived classes should look here for what choices are available vector<GameCommand> m_aGameCommands; // derived classes should look here for what choices are available
#if defined(SSC_FUTURES) #if defined(SSC_FUTURES)
// this is gonna become awkward.. -aj // this is gonna become awkward... -aj
#else #else
vector<GameCommand> m_aGameCommandsB; // only used if the theme requires a second list vector<GameCommand> m_aGameCommandsB; // only used if the theme requires a second list
#endif #endif
+46 -3
View File
@@ -25,6 +25,7 @@
#include "PlayerState.h" #include "PlayerState.h"
#include "CommonMetrics.h" #include "CommonMetrics.h"
#include "BannerCache.h" #include "BannerCache.h"
//#include "BackgroundCache.h"
#include "Song.h" #include "Song.h"
#include "InputEventPlus.h" #include "InputEventPlus.h"
#include "RageInput.h" #include "RageInput.h"
@@ -119,6 +120,7 @@ void ScreenSelectMusic::Init()
m_TexturePreload.Load( m_sFallbackCDTitlePath ); m_TexturePreload.Load( m_sFallbackCDTitlePath );
// load banners
if( PREFSMAN->m_BannerCache != BNCACHE_OFF ) if( PREFSMAN->m_BannerCache != BNCACHE_OFF )
{ {
m_TexturePreload.Load( Banner::SongBannerTexture(THEME->GetPathG("Banner","all music")) ); m_TexturePreload.Load( Banner::SongBannerTexture(THEME->GetPathG("Banner","all music")) );
@@ -127,9 +129,23 @@ void ScreenSelectMusic::Init()
m_TexturePreload.Load( Banner::SongBannerTexture(THEME->GetPathG("Banner","random")) ); m_TexturePreload.Load( Banner::SongBannerTexture(THEME->GetPathG("Banner","random")) );
m_TexturePreload.Load( Banner::SongBannerTexture(THEME->GetPathG("Banner","mode")) ); m_TexturePreload.Load( Banner::SongBannerTexture(THEME->GetPathG("Banner","mode")) );
} }
// load backgrounds
/*
if( PREFSMAN->m_BackgroundCache != BGCACHE_OFF )
{
m_TexturePreload.Load( Sprite::SongBGTexture(THEME->GetPathG("SongBackgroundItem","AllMusic")) );
m_TexturePreload.Load( Sprite::SongBGTexture(THEME->GetPathG("Common","fallback banner")) );
m_TexturePreload.Load( Sprite::SongBGTexture(THEME->GetPathG("SongBackgroundItem","roulette")) );
m_TexturePreload.Load( Sprite::SongBGTexture(THEME->GetPathG("SongBackgroundItem","random")) );
m_TexturePreload.Load( Sprite::SongBGTexture(THEME->GetPathG("SongBackgroundItem","Mode")) );
m_TexturePreload.Load( Sprite::SongBGTexture(THEME->GetPathG("SongBackgroundItem","group fallback")) );
m_TexturePreload.Load( Sprite::SongBGTexture(THEME->GetPathG("SongBackgroundItem","course fallback")) );
}
*/
/* Load low-res banners, if needed. */ // Load low-res banners and backgrounds if needed.
BANNERCACHE->Demand(); BANNERCACHE->Demand();
//BACKGROUNDCACHE->Demand();
m_MusicWheel.SetName( "MusicWheel" ); m_MusicWheel.SetName( "MusicWheel" );
m_MusicWheel.Load( MUSIC_WHEEL_TYPE ); m_MusicWheel.Load( MUSIC_WHEEL_TYPE );
@@ -248,7 +264,7 @@ ScreenSelectMusic::~ScreenSelectMusic()
{ {
LOG->Trace( "ScreenSelectMusic::~ScreenSelectMusic()" ); LOG->Trace( "ScreenSelectMusic::~ScreenSelectMusic()" );
BANNERCACHE->Undemand(); BANNERCACHE->Undemand();
//BACKGROUNDCACHE->Undemand();
} }
// If bForce is true, the next request will be started even if it might cause a skip. // If bForce is true, the next request will be started even if it might cause a skip.
@@ -441,7 +457,9 @@ void ScreenSelectMusic::Input( const InputEventPlus &input )
return; // ignore return; // ignore
// Handle unselect steps // Handle unselect steps
if( m_SelectionState == SelectionState_SelectingSteps && m_bStepsChosen[input.pn] && input.MenuI == GAME_BUTTON_SELECT && input.type == IET_FIRST_PRESS ) // xxx: select button could conflict with OptionsList here -aj
if( m_SelectionState == SelectionState_SelectingSteps && m_bStepsChosen[input.pn]
&& input.MenuI == GAME_BUTTON_SELECT && input.type == IET_FIRST_PRESS )
{ {
Message msg("StepsUnchosen"); Message msg("StepsUnchosen");
msg.SetParam( "Player", input.pn ); msg.SetParam( "Player", input.pn );
@@ -1002,6 +1020,14 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
// I believe this is for those who like pump pro. -aj // I believe this is for those who like pump pro. -aj
MESSAGEMAN->Broadcast("SongChosen"); MESSAGEMAN->Broadcast("SongChosen");
/*
if(TWO_PART_CONFIRMS_ONLY && SAMPLE_MUSIC_PREVIEW_MODE == SampleMusicPreviewMode_StartToPreview)
{
// start playing the preview music.
g_bSampleMusicWaiting = true;
}
*/
break; break;
case SelectionState_SelectingSteps: case SelectionState_SelectingSteps:
@@ -1426,33 +1452,50 @@ void ScreenSelectMusic::AfterMusicChange()
g_sCDTitlePath = ""; // none g_sCDTitlePath = ""; // none
//if( SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong )
//{
m_fSampleStartSeconds = 0; m_fSampleStartSeconds = 0;
m_fSampleLengthSeconds = -1; m_fSampleLengthSeconds = -1;
//}
switch( m_MusicWheel.GetSelectedType() ) switch( m_MusicWheel.GetSelectedType() )
{ {
case TYPE_SECTION: case TYPE_SECTION:
g_sBannerPath = SONGMAN->GetSongGroupBannerPath( m_MusicWheel.GetSelectedSection() ); g_sBannerPath = SONGMAN->GetSongGroupBannerPath( m_MusicWheel.GetSelectedSection() );
//if( SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong )
m_sSampleMusicToPlay = m_sSectionMusicPath; m_sSampleMusicToPlay = m_sSectionMusicPath;
break; break;
case TYPE_SORT: case TYPE_SORT:
bWantBanner = false; // we load it ourself bWantBanner = false; // we load it ourself
m_Banner.LoadMode(); m_Banner.LoadMode();
//if( SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong )
m_sSampleMusicToPlay = m_sSortMusicPath; m_sSampleMusicToPlay = m_sSortMusicPath;
break; break;
case TYPE_ROULETTE: case TYPE_ROULETTE:
bWantBanner = false; // we load it ourself bWantBanner = false; // we load it ourself
m_Banner.LoadRoulette(); m_Banner.LoadRoulette();
//if( SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong )
m_sSampleMusicToPlay = m_sRouletteMusicPath; m_sSampleMusicToPlay = m_sRouletteMusicPath;
break; break;
case TYPE_RANDOM: case TYPE_RANDOM:
bWantBanner = false; // we load it ourself bWantBanner = false; // we load it ourself
m_Banner.LoadRandom(); m_Banner.LoadRandom();
//if( SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong )
m_sSampleMusicToPlay = m_sRandomMusicPath; m_sSampleMusicToPlay = m_sRandomMusicPath;
break; break;
default: default:
ASSERT(0); ASSERT(0);
} }
// override this if the sample music mode wants to.
/*
if(SAMPLE_MUSIC_PREVIEW_MODE == SampleMusicPreviewMode_LastSong)
{
m_sSampleMusicToPlay = pSong->GetMusicPath();
m_pSampleMusicTimingData = &pSong->m_Timing;
m_fSampleStartSeconds = pSong->m_fMusicSampleStartSeconds;
m_fSampleLengthSeconds = pSong->m_fMusicSampleLengthSeconds;
}
*/
break; break;
case TYPE_SONG: case TYPE_SONG:
case TYPE_PORTAL: case TYPE_PORTAL:
+1 -1
View File
@@ -41,7 +41,7 @@ public:
virtual void MenuStart( const InputEventPlus &input ); virtual void MenuStart( const InputEventPlus &input );
virtual void MenuBack( const InputEventPlus &input ); virtual void MenuBack( const InputEventPlus &input );
/* ScreenWithMenuElements override: never play music here; we do it ourself. */ // ScreenWithMenuElements override: never play music here; we do it ourself.
virtual void StartPlayingMusic() { } virtual void StartPlayingMusic() { }
bool GetGoToOptions() const { return m_bGoToOptions; } bool GetGoToOptions() const { return m_bGoToOptions; }
+12 -2
View File
@@ -13,6 +13,7 @@
#include "FontCharAliases.h" #include "FontCharAliases.h"
#include "TitleSubstitution.h" #include "TitleSubstitution.h"
#include "BannerCache.h" #include "BannerCache.h"
//#include "BackgroundCache.h"
#include "Sprite.h" #include "Sprite.h"
#include "RageFileManager.h" #include "RageFileManager.h"
#include "RageSurface.h" #include "RageSurface.h"
@@ -70,6 +71,7 @@ Song::Song()
m_bIsSymLink = false; m_bIsSymLink = false;
m_bHasMusic = false; m_bHasMusic = false;
m_bHasBanner = false; m_bHasBanner = false;
m_bHasBackground = false;
} }
Song::~Song() Song::~Song()
@@ -266,6 +268,11 @@ bool Song::LoadFromSongDir( RString sDir )
/* Load the cached banners, if it's not loaded already. */ /* Load the cached banners, if it's not loaded already. */
if( PREFSMAN->m_BannerCache == BNCACHE_LOW_RES_PRELOAD && m_bHasBanner ) if( PREFSMAN->m_BannerCache == BNCACHE_LOW_RES_PRELOAD && m_bHasBanner )
BANNERCACHE->LoadBanner( GetBannerPath() ); BANNERCACHE->LoadBanner( GetBannerPath() );
/* Load the cached background, if it's not loaded already. */
/*
if( PREFSMAN->m_BackgroundCache == BGCACHE_LOW_RES_PRELOAD && m_bHasBackground )
BACKGROUNDCACHE->LoadBackground( GetBackgroundPath() );
*/
/* Add AutoGen pointers. (These aren't cached.) */ /* Add AutoGen pointers. (These aren't cached.) */
AddAutoGenNotes(); AddAutoGenNotes();
@@ -640,11 +647,14 @@ void Song::TidyUpData()
/* These will be written to cache, for Song::LoadFromSongDir to use later. */ /* These will be written to cache, for Song::LoadFromSongDir to use later. */
m_bHasMusic = HasMusic(); m_bHasMusic = HasMusic();
m_bHasBanner = HasBanner(); m_bHasBanner = HasBanner();
m_bHasBackground = HasBackground();
if( HasBanner() ) if( HasBanner() )
BANNERCACHE->CacheBanner( GetBannerPath() ); BANNERCACHE->CacheBanner( GetBannerPath() );
// todo: backgroundcache -aj /*
if( HasBackground() )
BANNERCACHE->CacheBackground( GetBackgroundPath() );
*/
// If no BGChanges are specified and there are movies in the song directory, then assume // If no BGChanges are specified and there are movies in the song directory, then assume
// they are DWI style where the movie begins at beat 0. // they are DWI style where the movie begins at beat 0.
+1 -1
View File
@@ -158,7 +158,7 @@ public:
/* For loading only: */ /* For loading only: */
bool m_bHasMusic, m_bHasBanner; bool m_bHasMusic, m_bHasBanner, m_bHasBackground;
bool HasMusic() const; bool HasMusic() const;
bool HasInstrumentTrack( InstrumentTrack it ) const; bool HasInstrumentTrack( InstrumentTrack it ) const;
+2 -1
View File
@@ -93,11 +93,12 @@ void SongCacheIndex::ReadCacheIndex()
int iCacheVersion = -1; int iCacheVersion = -1;
CacheIndex.GetValue( "Cache", "CacheVersion", iCacheVersion ); CacheIndex.GetValue( "Cache", "CacheVersion", iCacheVersion );
if( iCacheVersion == FILE_CACHE_VERSION ) if( iCacheVersion == FILE_CACHE_VERSION )
return; /* OK */ return; // OK
LOG->Trace( "Cache format is out of date. Deleting all cache files." ); LOG->Trace( "Cache format is out of date. Deleting all cache files." );
EmptyDir( SpecialFiles::CACHE_DIR ); EmptyDir( SpecialFiles::CACHE_DIR );
EmptyDir( SpecialFiles::CACHE_DIR+"Banners/" ); EmptyDir( SpecialFiles::CACHE_DIR+"Banners/" );
//EmptyDir( SpecialFiles::CACHE_DIR+"Backgrounds/" );
EmptyDir( SpecialFiles::CACHE_DIR+"Songs/" ); EmptyDir( SpecialFiles::CACHE_DIR+"Songs/" );
EmptyDir( SpecialFiles::CACHE_DIR+"Courses/" ); EmptyDir( SpecialFiles::CACHE_DIR+"Courses/" );
+87 -17
View File
@@ -193,10 +193,36 @@ void SongManager::AddGroup( RString sDir, RString sGroupDirName )
sBannerPath = sDir+arrayGroupBanners[0]; sBannerPath = sDir+arrayGroupBanners[0];
} }
// Group backgrounds are a bit trickier, and usually don't exist.
// However, for Background wheels, we support them. -aj
// background files MUST end in "-bg".ext in order to distinguish them.
// Yes hardcoding it sucks sometimes, but this is to keep my sanity. -aj
/*
vector<RString> arrayGroupBackgrounds;
GetDirListing( sDir+sGroupDirName+"/*-bg.png", arrayGroupBanners );
GetDirListing( sDir+sGroupDirName+"/*-bg.jpg", arrayGroupBanners );
GetDirListing( sDir+sGroupDirName+"/*-bg.gif", arrayGroupBanners );
GetDirListing( sDir+sGroupDirName+"/*-bg.bmp", arrayGroupBanners );
RString sBackgroundPath;
if( !arrayGroupBackgrounds.empty() )
sBackgroundPath = sDir+sGroupDirName+"/"+arrayGroupBackgrounds[0];
else
{
// Look for a group background in the parent folder
GetDirListing( sDir+sGroupDirName+"-bg.png", arrayGroupBackgrounds );
GetDirListing( sDir+sGroupDirName+"-bg.jpg", arrayGroupBackgrounds );
GetDirListing( sDir+sGroupDirName+"-bg.gif", arrayGroupBackgrounds );
GetDirListing( sDir+sGroupDirName+"-bg.bmp", arrayGroupBackgrounds );
if( !arrayGroupBackgrounds.empty() )
sBackgroundPath = sDir+arrayGroupBackgrounds[0];
}
*/
LOG->Trace( "Group banner for '%s' is '%s'.", sGroupDirName.c_str(), LOG->Trace( "Group banner for '%s' is '%s'.", sGroupDirName.c_str(),
sBannerPath != ""? sBannerPath.c_str():"(none)" ); sBannerPath != ""? sBannerPath.c_str():"(none)" );
m_sSongGroupNames.push_back( sGroupDirName ); m_sSongGroupNames.push_back( sGroupDirName );
m_sSongGroupBannerPaths.push_back( sBannerPath ); m_sSongGroupBannerPaths.push_back( sBannerPath );
//m_sSongGroupBackgroundPaths.push_back( sBackgroundPath );
} }
static LocalizedString LOADING_SONGS ( "SongManager", "Loading songs..." ); static LocalizedString LOADING_SONGS ( "SongManager", "Loading songs..." );
@@ -263,7 +289,7 @@ void SongManager::LoadStepManiaSongDir( RString sDir, LoadingWindow *ld )
/* Add this group to the group array. */ /* Add this group to the group array. */
AddGroup(sDir, sGroupDirName); AddGroup(sDir, sGroupDirName);
/* Cache and load the group banner. */ // Cache and load the group banner. (and background if it has one)
BANNERCACHE->CacheBanner( GetSongGroupBannerPath(sGroupDirName) ); BANNERCACHE->CacheBanner( GetSongGroupBannerPath(sGroupDirName) );
/* Load the group sym links (if any)*/ /* Load the group sym links (if any)*/
@@ -312,23 +338,49 @@ void SongManager::LoadGroupSymLinks(RString sDir, RString sGroupFolder)
void SongManager::PreloadSongImages() void SongManager::PreloadSongImages()
{ {
bool bSkipBanners = false;
//bool bSkipBackgrounds = false;
if( PREFSMAN->m_BannerCache != BNCACHE_FULL ) if( PREFSMAN->m_BannerCache != BNCACHE_FULL )
return; bSkipBanners = true;
/*
if( PREFSMAN->m_BackgroundCache != BNCACHE_FULL )
bSkipBackgrounds = true;
*/
/* Load textures before unloading old ones, so we don't reload textures /* Load textures before unloading old ones, so we don't reload textures
* that we don't need to. */ * that we don't need to. */
RageTexturePreloader preload; RageTexturePreloader preload;
//if( !bSkipBanners && !bSkipBackgrounds )
if( !bSkipBanners )
{
const vector<Song*> &songs = GetAllSongs(); const vector<Song*> &songs = GetAllSongs();
for( unsigned i = 0; i < songs.size(); ++i ) for( unsigned i = 0; i < songs.size(); ++i )
{ {
if( !songs[i]->HasBanner() ) // preload banners
if( !songs[i]->HasBanner() && !songs[i]->HasBackground() )
continue; continue;
if( !bSkipBanners && songs[i]->HasBanner() )
{
const RageTextureID ID = Sprite::SongBannerTexture( songs[i]->GetBannerPath() ); const RageTextureID ID = Sprite::SongBannerTexture( songs[i]->GetBannerPath() );
preload.Load( ID ); preload.Load( ID );
} }
// preload backgrounds
/*
if( !bSkipBackgrounds && songs[i]->HasBackground() )
{
if ( !songs[i]->HasBackground() )
continue;
const RageTextureID IDbg = Sprite::SongBGTexture( songs[i]->GetBackgroundPath() );
preload.Load( IDbg );
}
*/
}
}
vector<Course*> courses; vector<Course*> courses;
GetAllCourses( courses, false ); GetAllCourses( courses, false );
for( unsigned i = 0; i < courses.size(); ++i ) for( unsigned i = 0; i < courses.size(); ++i )
@@ -347,13 +399,16 @@ void SongManager::FreeSongs()
{ {
m_sSongGroupNames.clear(); m_sSongGroupNames.clear();
m_sSongGroupBannerPaths.clear(); m_sSongGroupBannerPaths.clear();
//m_sSongGroupBackgroundPaths.clear();
for( unsigned i=0; i<m_pSongs.size(); i++ ) for( unsigned i=0; i<m_pSongs.size(); i++ )
SAFE_DELETE( m_pSongs[i] ); SAFE_DELETE( m_pSongs[i] );
m_pSongs.clear(); m_pSongs.clear();
m_mapSongGroupIndex.clear(); m_mapSongGroupIndex.clear();
// wait why is it cleared twice? -aj
m_sSongGroupBannerPaths.clear(); m_sSongGroupBannerPaths.clear();
//m_sSongGroupBackgroundPaths.clear(); // when in Rome... -aj
m_pPopularSongs.clear(); m_pPopularSongs.clear();
m_pShuffledSongs.clear(); m_pShuffledSongs.clear();
@@ -369,7 +424,18 @@ RString SongManager::GetSongGroupBannerPath( RString sSongGroup ) const
return RString(); return RString();
} }
/*
RString SongManager::GetSongGroupBackgroundPath( RString sSongGroup ) const
{
for( unsigned i = 0; i < m_sSongGroupNames.size(); ++i )
{
if( sSongGroup == m_sSongGroupNames[i] )
return m_sSongGroupBackgroundPaths[i];
}
return RString();
}
*/
void SongManager::GetSongGroupNames( vector<RString> &AddTo ) const void SongManager::GetSongGroupNames( vector<RString> &AddTo ) const
{ {
AddTo.insert(AddTo.end(), m_sSongGroupNames.begin(), m_sSongGroupNames.end() ); AddTo.insert(AddTo.end(), m_sSongGroupNames.begin(), m_sSongGroupNames.end() );
@@ -385,8 +451,10 @@ RageColor SongManager::GetSongGroupColor( const RString &sSongGroup ) const
for( unsigned i=0; i<m_sSongGroupNames.size(); i++ ) for( unsigned i=0; i<m_sSongGroupNames.size(); i++ )
{ {
if( m_sSongGroupNames[i] == sSongGroup ) if( m_sSongGroupNames[i] == sSongGroup )
{
return SONG_GROUP_COLOR.GetValue( i%NUM_SONG_GROUP_COLORS ); return SONG_GROUP_COLOR.GetValue( i%NUM_SONG_GROUP_COLORS );
} }
}
ASSERT_M( 0, ssprintf("requested color for song group '%s' that doesn't exist",sSongGroup.c_str()) ); ASSERT_M( 0, ssprintf("requested color for song group '%s' that doesn't exist",sSongGroup.c_str()) );
return RageColor(1,1,1,1); return RageColor(1,1,1,1);
@@ -401,7 +469,6 @@ RageColor SongManager::GetSongColor( const Song* pSong ) const
if( pUE && USE_UNLOCK_COLOR.GetValue() ) if( pUE && USE_UNLOCK_COLOR.GetValue() )
return UNLOCK_COLOR.GetValue(); return UNLOCK_COLOR.GetValue();
if( USE_PREFERRED_SORT_COLOR ) if( USE_PREFERRED_SORT_COLOR )
{ {
FOREACH_CONST( PreferredSortSection, m_vPreferredSongSort, v ) FOREACH_CONST( PreferredSortSection, m_vPreferredSongSort, v )
@@ -423,18 +490,18 @@ RageColor SongManager::GetSongColor( const Song* pSong ) const
{ {
/* XXX: /* XXX:
* Previously, this matched all notes, which set a song to "extra" if it * Previously, this matched all notes, which set a song to "extra" if
* had any 10-foot steps at all, even edits or doubles. * it had any 10-foot steps at all, even edits or doubles.
* *
* For now, only look at notes for the current note type. This means that * For now, only look at notes for the current note type. This means
* if a song has 10-foot steps on Doubles, it'll only show up red in Doubles. * that if a song has 10-foot steps on Doubles, it'll only show up red
* That's not too bad, I think. This will also change it in the song scroll, * in Doubles. That's not too bad, I think. This will also change it
* which is a little odd but harmless. * in the song scroll, which is a little odd but harmless.
* *
* XXX: Ack. This means this function can only be called when we have a style * XXX: Ack. This means this function can only be called when we have
* set up, which is too restrictive. How to handle this? * a style set up, which is too restrictive. How to handle this?
*/ */
// const StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; //const StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
const vector<Steps*>& vpSteps = pSong->GetAllSteps(); const vector<Steps*>& vpSteps = pSong->GetAllSteps();
for( unsigned i=0; i<vpSteps.size(); i++ ) for( unsigned i=0; i<vpSteps.size(); i++ )
{ {
@@ -446,7 +513,7 @@ RageColor SongManager::GetSongColor( const Song* pSong ) const
continue; continue;
} }
// if(pSteps->m_StepsType != st) //if(pSteps->m_StepsType != st)
// continue; // continue;
if( pSteps->GetMeter() >= EXTRA_COLOR_METER ) if( pSteps->GetMeter() >= EXTRA_COLOR_METER )
@@ -1335,13 +1402,13 @@ void SongManager::UpdatePopular()
for ( unsigned j=0; j < apBestSongs.size() ; ++j ) for ( unsigned j=0; j < apBestSongs.size() ; ++j )
{ {
bool bFiltered = false; bool bFiltered = false;
/* Filter out locked songs. */ // Filter out locked songs.
if( !apBestSongs[j]->NormallyDisplayed() ) if( !apBestSongs[j]->NormallyDisplayed() )
bFiltered = true; bFiltered = true;
if( !bFiltered ) if( !bFiltered )
continue; continue;
/* Remove it. */ // Remove it.
swap( apBestSongs[j], apBestSongs.back() ); swap( apBestSongs[j], apBestSongs.back() );
apBestSongs.erase( apBestSongs.end()-1 ); apBestSongs.erase( apBestSongs.end()-1 );
--j; --j;
@@ -1780,7 +1847,7 @@ public:
// this binding has ABYSMAL performance, most likely due to the whole "hey // this binding has ABYSMAL performance, most likely due to the whole "hey
// let's keep repopulating the vector every time this is called" thing. // let's keep repopulating the vector every time this is called" thing.
// gg whitehouse maybe if you included global variables in your terror // gg whitehouse maybe if you included global variables in your terror
// alerts this wouldn't have happened ffffffffffffff // alerts this wouldn't have happened ffffffffffffff -aj
/* /*
static int GetSongRank( T* p, lua_State *L ) static int GetSongRank( T* p, lua_State *L )
{ {
@@ -1799,6 +1866,8 @@ public:
} }
*/ */
DEFINE_METHOD( ShortenGroupName, ShortenGroupName( SArg(1) ) )
LunaSongManager() LunaSongManager()
{ {
ADD_METHOD( GetAllSongs ); ADD_METHOD( GetAllSongs );
@@ -1821,6 +1890,7 @@ public:
ADD_METHOD( GetSongGroupColor ); ADD_METHOD( GetSongGroupColor );
ADD_METHOD( GetCourseColor ); ADD_METHOD( GetCourseColor );
//ADD_METHOD( GetSongRank ); //ADD_METHOD( GetSongRank );
ADD_METHOD( ShortenGroupName );
} }
}; };
+11 -12
View File
@@ -97,12 +97,11 @@ RageTextureID Sprite::SongBGTexture( RageTextureID ID )
RageTextureID Sprite::SongBannerTexture( RageTextureID ID ) RageTextureID Sprite::SongBannerTexture( RageTextureID ID )
{ {
/* Song banners often have HOT PINK color keys. */ // Older song banners often have HOT PINK color keys.
/* Use color keying only if the graphic is a diagonal banner.
/* TODO: Change to use color keying only if the graphic is a diagonal banner. The color key convention is * The color key convention is causing small holes in moderm banners that
* causing small holes in moderm banners that use magenta, and it's not good to require graphic * use magenta, and it's not good to require graphic makers to know about
* makers to know about archaic color key conventions. -Chris */ * archaic color key conventions. -Chris */
// I disabled this anyways, it's extremely annoying -Colby // I disabled this anyways, it's extremely annoying -Colby
ID.bHotPinkColorKey = false; ID.bHotPinkColorKey = false;
@@ -111,9 +110,9 @@ RageTextureID Sprite::SongBannerTexture( RageTextureID ID )
* be as fast as possible. */ * be as fast as possible. */
ID.iColorDepth = 32; ID.iColorDepth = 32;
/* If we don't support RGBA8 (and will probably fall back on RGBA4), we're probably /* If we don't support RGBA8 (and will probably fall back on RGBA4), we're
* on something very old and slow, so let's opt for banding instead of slowing things * probably on something very old and slow, so let's opt for banding
* down further by dithering. */ * instead of slowing things down further by dithering. */
// ID.bDither = true; // ID.bDither = true;
ID.Policy = RageTextureID::TEX_VOLATILE; ID.Policy = RageTextureID::TEX_VOLATILE;
@@ -438,9 +437,10 @@ void Sprite::DrawTexture( const TweenState *state )
{ {
Actor::SetGlobalRenderStates(); // set Actor-specified render states Actor::SetGlobalRenderStates(); // set Actor-specified render states
RectF crop = state->crop;
// bail if cropped all the way // bail if cropped all the way
if( state->crop.left + state->crop.right >= 1 || if( crop.left + crop.right >= 1 ||
state->crop.top + state->crop.bottom >= 1 ) crop.top + crop.bottom >= 1 )
return; return;
// use m_temp_* variables to draw the object // use m_temp_* variables to draw the object
@@ -454,7 +454,6 @@ void Sprite::DrawTexture( const TweenState *state )
* of the image area aren't guaranteed to be initialized. */ * of the image area aren't guaranteed to be initialized. */
/* HACK: Clamp the crop values. It would be more accurate to clip the /* HACK: Clamp the crop values. It would be more accurate to clip the
* vertices so that the diffuse value is adjusted. */ * vertices so that the diffuse value is adjusted. */
RectF crop = state->crop;
CLAMP( crop.left, 0, 1 ); CLAMP( crop.left, 0, 1 );
CLAMP( crop.right, 0, 1 ); CLAMP( crop.right, 0, 1 );
CLAMP( crop.top, 0, 1 ); CLAMP( crop.top, 0, 1 );
+1 -1
View File
@@ -839,7 +839,7 @@ void StepMania::ChangeCurrentGame( const Game* g )
// process theme and language command line arguments; // process theme and language command line arguments;
// these change the preferences in order for transparent loading -aj // these change the preferences in order for transparent loading -aj
RString argTheme; RString argTheme;
if( GetCommandlineArgument( "theme",&argTheme) ) if( GetCommandlineArgument( "theme",&argTheme) && argTheme != sTheme )
{ {
sTheme = argTheme; sTheme = argTheme;
// set theme in preferences too for correct behavior -aj // set theme in preferences too for correct behavior -aj
+38 -18
View File
@@ -44,7 +44,7 @@ void TimingData::AddTimeSignatureSegment( const TimeSignatureSegment &seg )
/* /*
void TimingData::AddWarpSegment( const WarpSegment &seg ) void TimingData::AddWarpSegment( const WarpSegment &seg )
{ {
m_vWarpSegments.insert( upper_bound(m_vWarpSegments.begin(), m_vWarpSegments.end(), seg), seg ); m_WarpSegments.insert( upper_bound(m_WarpSegments.begin(), m_WarpSegments.end(), seg), seg );
} }
*/ */
@@ -127,10 +127,10 @@ float TimingData::GetStopAtRow( int iNoteRow, bool &bDelayOut ) const
return 0; return 0;
} }
/* Multiply the BPM in the range [fStartBeat,fEndBeat) by fFactor. */ // Multiply the BPM in the range [fStartBeat,fEndBeat) by fFactor.
void TimingData::MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor ) void TimingData::MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor )
{ {
/* Change all other BPM segments in this range. */ // Change all other BPM segments in this range.
for( unsigned i=0; i<m_BPMSegments.size(); i++ ) for( unsigned i=0; i<m_BPMSegments.size(); i++ )
{ {
const int iStartIndexThisSegment = m_BPMSegments[i].m_iStartRow; const int iStartIndexThisSegment = m_BPMSegments[i].m_iStartRow;
@@ -140,19 +140,20 @@ void TimingData::MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float f
if( iStartIndexThisSegment <= iStartIndex && iStartIndexNextSegment <= iStartIndex ) if( iStartIndexThisSegment <= iStartIndex && iStartIndexNextSegment <= iStartIndex )
continue; continue;
/* If this BPM segment crosses the beginning of the range, split it into two. */ /* If this BPM segment crosses the beginning of the range,
* split it into two. */
if( iStartIndexThisSegment < iStartIndex && iStartIndexNextSegment > iStartIndex ) if( iStartIndexThisSegment < iStartIndex && iStartIndexNextSegment > iStartIndex )
{ {
BPMSegment b = m_BPMSegments[i]; BPMSegment b = m_BPMSegments[i];
b.m_iStartRow = iStartIndexNextSegment; b.m_iStartRow = iStartIndexNextSegment;
m_BPMSegments.insert( m_BPMSegments.begin()+i+1, b ); m_BPMSegments.insert( m_BPMSegments.begin()+i+1, b );
/* Don't apply the BPM change to the first half of the segment we just split, /* Don't apply the BPM change to the first half of the segment we
* since it lies outside the range. */ * just split, since it lies outside the range. */
continue; continue;
} }
/* If this BPM segment crosses the end of the range, split it into two. */ // If this BPM segment crosses the end of the range, split it into two.
if( iStartIndexThisSegment < iEndIndex && iStartIndexNextSegment > iEndIndex ) if( iStartIndexThisSegment < iEndIndex && iStartIndexNextSegment > iEndIndex )
{ {
BPMSegment b = m_BPMSegments[i]; BPMSegment b = m_BPMSegments[i];
@@ -265,6 +266,7 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
} }
} }
// by this point we should have the warps in their own place.
/* /*
for( unsigned j=0; j<m_WarpSegments.size(); j++ ) // foreach warp for( unsigned j=0; j<m_WarpSegments.size(); j++ ) // foreach warp
{ {
@@ -282,6 +284,13 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
const float fBeatsInThisSegment = fStartBeatNextSegment - fStartBeatThisSegment; const float fBeatsInThisSegment = fStartBeatNextSegment - fStartBeatThisSegment;
const float fSecondsInThisSegment = fBeatsInThisSegment / fBPS; const float fSecondsInThisSegment = fBeatsInThisSegment / fBPS;
//if(fBPS < 0.0f)
/*
if(fStartBeatThisSegment == 445.500f || fStartBeatThisSegment == 449.500)
{
LOG->Trace( ssprintf("segment (beat %f) beats: %f / seconds: %f / BPS: %f",fStartBeatThisSegment,fBeatsInThisSegment,fSecondsInThisSegment,fBPS) );
}
*/
if( bIsLastBPMSegment || fElapsedTime <= fSecondsInThisSegment ) if( bIsLastBPMSegment || fElapsedTime <= fSecondsInThisSegment )
{ {
// this BPMSegment IS the current segment // this BPMSegment IS the current segment
@@ -290,11 +299,22 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
bFreezeOut = false; bFreezeOut = false;
bDelayOut = false; bDelayOut = false;
//bWarpOut = false; //bWarpOut = false;
return; return;
} }
// this BPMSegment is NOT the current segment // this BPMSegment is NOT the current segment
fElapsedTime -= fSecondsInThisSegment; fElapsedTime -= fSecondsInThisSegment;
// xxx: negative testing
/*
//if(fBPS < 0.0f)
if( (fStartBeatNextSegment >= 445.490f && fStartBeatNextSegment <= 453.72f) || fBPS < 0.0f )
{
//LOG->Trace( ssprintf("beat %f is %f BPS (%f BPM)",fBeatOut,fBPSOut,fBPSOut*60.0f) );
//LOG->Trace( ssprintf("start beat %f + elapsed time %f",fStartBeatThisSegment,fElapsedTime) );
//LOG->Trace( ssprintf("elapsed time is now %f",fElapsedTime) );
}
*/
} }
// If we get here, something has gone wrong. Is everything sorted? // If we get here, something has gone wrong. Is everything sorted?
vector<BPMSegment> vBPMS = m_BPMSegments; vector<BPMSegment> vBPMS = m_BPMSegments;
@@ -413,30 +433,30 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd )
if( iStartRow == 0 ) if( iStartRow == 0 )
{ {
/* If we're shifting up at the beginning, we just shifted up the first BPMSegment. That /* If we're shifting up at the beginning, we just shifted up the first
* segment must always begin at 0. */ * BPMSegment. That segment must always begin at 0. */
ASSERT( m_BPMSegments.size() > 0 ); ASSERT( m_BPMSegments.size() > 0 );
m_BPMSegments[0].m_iStartRow = 0; m_BPMSegments[0].m_iStartRow = 0;
} }
} }
/* Delete BPMChanges and StopSegments in [iStartRow,iRowsToDelete), and shift down. */ // Delete BPMChanges and StopSegments in [iStartRow,iRowsToDelete), and shift down.
void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) void TimingData::DeleteRows( int iStartRow, int iRowsToDelete )
{ {
/* Remember the BPM at the end of the region being deleted. */ /* Remember the BPM at the end of the region being deleted. */
float fNewBPM = this->GetBPMAtBeat( NoteRowToBeat(iStartRow+iRowsToDelete) ); float fNewBPM = this->GetBPMAtBeat( NoteRowToBeat(iStartRow+iRowsToDelete) );
/* We're moving rows up. Delete any BPM changes and stops in the region being /* We're moving rows up. Delete any BPM changes and stops in the region
* deleted. */ * being deleted. */
for( unsigned i = 0; i < m_BPMSegments.size(); i++ ) for( unsigned i = 0; i < m_BPMSegments.size(); i++ )
{ {
BPMSegment &bpm = m_BPMSegments[i]; BPMSegment &bpm = m_BPMSegments[i];
/* Before deleted region: */ // Before deleted region:
if( bpm.m_iStartRow < iStartRow ) if( bpm.m_iStartRow < iStartRow )
continue; continue;
/* Inside deleted region: */ // Inside deleted region:
if( bpm.m_iStartRow < iStartRow+iRowsToDelete ) if( bpm.m_iStartRow < iStartRow+iRowsToDelete )
{ {
m_BPMSegments.erase( m_BPMSegments.begin()+i, m_BPMSegments.begin()+i+1 ); m_BPMSegments.erase( m_BPMSegments.begin()+i, m_BPMSegments.begin()+i+1 );
@@ -444,7 +464,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete )
continue; continue;
} }
/* After deleted region: */ // After deleted region:
bpm.m_iStartRow -= iRowsToDelete; bpm.m_iStartRow -= iRowsToDelete;
} }
@@ -452,11 +472,11 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete )
{ {
StopSegment &stop = m_StopSegments[i]; StopSegment &stop = m_StopSegments[i];
/* Before deleted region: */ // Before deleted region:
if( stop.m_iStartRow < iStartRow ) if( stop.m_iStartRow < iStartRow )
continue; continue;
/* Inside deleted region: */ // Inside deleted region:
if( stop.m_iStartRow < iStartRow+iRowsToDelete ) if( stop.m_iStartRow < iStartRow+iRowsToDelete )
{ {
m_StopSegments.erase( m_StopSegments.begin()+i, m_StopSegments.begin()+i+1 ); m_StopSegments.erase( m_StopSegments.begin()+i, m_StopSegments.begin()+i+1 );
@@ -464,7 +484,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete )
continue; continue;
} }
/* After deleted region: */ // After deleted region:
stop.m_iStartRow -= iRowsToDelete; stop.m_iStartRow -= iRowsToDelete;
} }
+4 -3
View File
@@ -82,8 +82,8 @@ struct TimeSignatureSegment
/* /*
struct WarpSegment struct WarpSegment
{ {
WarpSegment() : m_iStartRow(-1), int m_iEndRow(-1) { } WarpSegment() : m_iStartRow(-1), m_iEndRow(-1) { }
WarpSegment( int s, int e ){ m_iStartRow = max( 0, s ); m_iEndRow = max( 0, e ) } WarpSegment( int s, int e ){ m_iStartRow = max( 0, s ); m_iEndRow = max( 0, e ); }
int m_iStartRow; int m_iStartRow;
int m_iEndRow; int m_iEndRow;
@@ -95,7 +95,7 @@ struct WarpSegment
} }
bool operator!=( const WarpSegment &other ) const { return !operator==(other); } bool operator!=( const WarpSegment &other ) const { return !operator==(other); }
bool operator<( const WarpSegment &other ) const { return m_iStartRow < other.m_iStartRow; } bool operator<( const WarpSegment &other ) const { return m_iStartRow < other.m_iStartRow; }
} };
*/ */
class TimingData class TimingData
@@ -112,6 +112,7 @@ public:
void SetStopAtBeat( float fBeat, float fSeconds ) { SetStopAtRow( BeatToNoteRow(fBeat), fSeconds ); } void SetStopAtBeat( float fBeat, float fSeconds ) { SetStopAtRow( BeatToNoteRow(fBeat), fSeconds ); }
void SetStopAtBeat( float fBeat, float fSeconds, bool bDelay ) { SetStopAtRow( BeatToNoteRow(fBeat), fSeconds, bDelay ); } // (sm-ssc) void SetStopAtBeat( float fBeat, float fSeconds, bool bDelay ) { SetStopAtRow( BeatToNoteRow(fBeat), fSeconds, bDelay ); } // (sm-ssc)
float GetStopAtRow( int iNoteRow, bool &bDelayOut ) const; float GetStopAtRow( int iNoteRow, bool &bDelayOut ) const;
void SetDelayAtRow( int iNoteRow, float fSeconds ); // sm-ssc
void MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor ); void MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor );
void AddBPMSegment( const BPMSegment &seg ); void AddBPMSegment( const BPMSegment &seg );
void AddStopSegment( const StopSegment &seg ); void AddStopSegment( const StopSegment &seg );
+11 -5
View File
@@ -95,7 +95,7 @@ void WheelBase::SetItemPosition( Actor &item, float fPosOffsetsFromMiddle )
Actor::TweenState ts = m_exprItemTransformFunction.GetTransformCached( fPosOffsetsFromMiddle, iItemIndex, iNumItems ); Actor::TweenState ts = m_exprItemTransformFunction.GetTransformCached( fPosOffsetsFromMiddle, iItemIndex, iNumItems );
/* Round to achieve pixel alignment. Any benefit to moving this to Lua? -Chris */ // Round to achieve pixel alignment. Any benefit to moving this to Lua? -Chris
ts.pos.x = roundf( ts.pos.x ); ts.pos.x = roundf( ts.pos.x );
ts.pos.y = roundf( ts.pos.y ); ts.pos.y = roundf( ts.pos.y );
ts.pos.z = roundf( ts.pos.z ); ts.pos.z = roundf( ts.pos.z );
@@ -148,7 +148,7 @@ void WheelBase::Update( float fDeltaTime )
{ {
ActorFrame::Update( fDeltaTime ); ActorFrame::Update( fDeltaTime );
/* If tweens aren't controlling the position of the wheel, set positions. */ // If tweens aren't controlling the position of the wheel, set positions.
if( !GetTweenTimeLeft() ) if( !GetTweenTimeLeft() )
SetPositions(); SetPositions();
@@ -216,7 +216,7 @@ void WheelBase::Update( float fDeltaTime )
* speed is very high or we miss a lot of frames. */ * speed is very high or we miss a lot of frames. */
m_fPositionOffsetFromSelection = clamp(m_fPositionOffsetFromSelection, -1.0f, 1.0f); m_fPositionOffsetFromSelection = clamp(m_fPositionOffsetFromSelection, -1.0f, 1.0f);
/* If it passed the selection, move again. */ // If it passed the selection, move again.
if((m_Moving == -1 && m_fPositionOffsetFromSelection >= 0) || if((m_Moving == -1 && m_fPositionOffsetFromSelection >= 0) ||
(m_Moving == 1 && m_fPositionOffsetFromSelection <= 0)) (m_Moving == 1 && m_fPositionOffsetFromSelection <= 0))
{ {
@@ -526,7 +526,10 @@ public:
static int IsSettled( T* p, lua_State *L ){ lua_pushboolean( L, p->IsSettled() ); return 1; } static int IsSettled( T* p, lua_State *L ){ lua_pushboolean( L, p->IsSettled() ); return 1; }
static int IsLocked( T* p, lua_State *L ){ lua_pushboolean( L, p->WheelIsLocked() ); return 1; } static int IsLocked( T* p, lua_State *L ){ lua_pushboolean( L, p->WheelIsLocked() ); return 1; }
// evil shit // evil shit
static int Move( T* p, lua_State *L ){ p->Move( IArg(1) ); return 1; } //static int Move( T* p, lua_State *L ){ p->Move( IArg(1) ); return 0; }
//static int ChangeMusic( T* p, lua_State *L ){ p->ChangeMusic( IArg(1) ); return 0; }
//static int ChangeMusicUnlessLocked( T* p, lua_State *L ){ p->ChangeMusicUnlessLocked( IArg(1) ); return 0; }
//static int SetOpenSection( T* p, lua_State *L ){ p->SetOpenSection( SArg(1) ); return 0; }
LunaWheelBase() LunaWheelBase()
{ {
@@ -534,7 +537,10 @@ public:
ADD_METHOD( IsSettled ); ADD_METHOD( IsSettled );
ADD_METHOD( IsLocked ); ADD_METHOD( IsLocked );
// evil shit // evil shit
ADD_METHOD( Move ); //ADD_METHOD( Move );
//ADD_METHOD( ChangeMusic );
//ADD_METHOD( ChangeMusicUnlessLocked );
//ADD_METHOD( SetOpenSection );
} }
}; };
-1
View File
@@ -74,7 +74,6 @@ protected:
int m_iSelection; // index into m_CurWheelItemBaseData int m_iSelection; // index into m_CurWheelItemBaseData
RString m_sExpandedSectionName; RString m_sExpandedSectionName;
int m_iSwitchesLeftInSpinDown; int m_iSwitchesLeftInSpinDown;
float m_fLockedWheelVelocity; float m_fLockedWheelVelocity;
// 0 = none; -1 or 1 = up/down // 0 = none; -1 or 1 = up/down
+8 -8
View File
@@ -39,14 +39,14 @@ static bool DoCleanShutdown( int signal, siginfo_t *si, const ucontext_t *uc )
if( IsFatalSignal(signal) ) if( IsFatalSignal(signal) )
return false; return false;
/* ^C. */ // ^C.
ArchHooks::SetUserQuit(); ArchHooks::SetUserQuit();
return true; return true;
} }
static bool DoCrashSignalHandler( int signal, siginfo_t *si, const ucontext_t *uc ) static bool DoCrashSignalHandler( int signal, siginfo_t *si, const ucontext_t *uc )
{ {
/* Don't dump a debug file if the user just hit ^C. */ // Don't dump a debug file if the user just hit ^C.
if( !IsFatalSignal(signal) ) if( !IsFatalSignal(signal) )
return true; return true;
@@ -63,14 +63,14 @@ static bool DoEmergencyShutdown( int signal, siginfo_t *si, const ucontext_t *us
void ArchHooks_MacOSX::Init() void ArchHooks_MacOSX::Init()
{ {
/* First, handle non-fatal termination signals. */ // First, handle non-fatal termination signals.
SignalHandler::OnClose( DoCleanShutdown ); SignalHandler::OnClose( DoCleanShutdown );
CrashHandler::CrashHandlerHandleArgs( g_argc, g_argv ); CrashHandler::CrashHandlerHandleArgs( g_argc, g_argv );
CrashHandler::InitializeCrashHandler(); CrashHandler::InitializeCrashHandler();
SignalHandler::OnClose( DoCrashSignalHandler ); SignalHandler::OnClose( DoCrashSignalHandler );
SignalHandler::OnClose( DoEmergencyShutdown ); SignalHandler::OnClose( DoEmergencyShutdown );
/* Now that the crash handler is set up, disable crash reporter. */ // Now that the crash handler is set up, disable crash reporter.
// Breaks gdb // Breaks gdb
// task_set_exception_ports( mach_task_self(), EXC_MASK_ALL, MACH_PORT_NULL, EXCEPTION_DEFAULT, 0 ); // task_set_exception_ports( mach_task_self(), EXC_MASK_ALL, MACH_PORT_NULL, EXCEPTION_DEFAULT, 0 );
@@ -220,7 +220,7 @@ RString ArchHooks_MacOSX::GetMachineId() const
void ArchHooks_MacOSX::DumpDebugInfo() void ArchHooks_MacOSX::DumpDebugInfo()
{ {
/* Get system version */ // Get system version
RString sSystemVersion; RString sSystemVersion;
{ {
long major = 0, minor = 0, bugFix = 0; long major = 0, minor = 0, bugFix = 0;
@@ -236,7 +236,7 @@ void ArchHooks_MacOSX::DumpDebugInfo()
size_t size; size_t size;
#define GET_PARAM( name, var ) (size = sizeof(var), sysctlbyname(name, &var, &size, NULL, 0) ) #define GET_PARAM( name, var ) (size = sizeof(var), sysctlbyname(name, &var, &size, NULL, 0) )
/* Get memory */ // Get memory
float fRam; float fRam;
char ramPower; char ramPower;
{ {
@@ -254,7 +254,7 @@ void ArchHooks_MacOSX::DumpDebugInfo()
} }
} }
/* Get processor information */ // Get processor information
int iMaxCPUs = 0; int iMaxCPUs = 0;
int iCPUs = 0; int iCPUs = 0;
float fFreq; float fFreq;
@@ -314,7 +314,7 @@ void ArchHooks_MacOSX::DumpDebugInfo()
} while( false ); } while( false );
#undef GET_PARAM #undef GET_PARAM
/* Send all of the information to the log */ // Send all of the information to the log
LOG->Info( "Model: %s (%d/%d)", sModel.c_str(), iCPUs, iMaxCPUs ); LOG->Info( "Model: %s (%d/%d)", sModel.c_str(), iCPUs, iMaxCPUs );
LOG->Info( "Clock speed %.2f %cHz", fFreq, freqPower ); LOG->Info( "Clock speed %.2f %cHz", fFreq, freqPower );
LOG->Info( "%s", sSystemVersion.c_str()); LOG->Info( "%s", sSystemVersion.c_str());
+14 -16
View File
@@ -94,8 +94,7 @@ void *LowLevelWindow_X11::GetProcAddress( RString s )
RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDeviceOut ) RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDeviceOut )
{ {
#if defined(UNIX) #if defined(UNIX)
/* /* nVidia cards:
* nVidia cards:
* *
* This only works the first time we set up a window; after that, the * This only works the first time we set up a window; after that, the
* drivers appear to cache the value, so you have to actually restart * drivers appear to cache the value, so you have to actually restart
@@ -178,8 +177,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
} }
else else
{ {
// We're remodeling the existing window, and not touching the // We're remodeling the existing window, and not touching the context.
// context.
bNewDeviceOut = false; bNewDeviceOut = false;
} }
@@ -275,21 +273,21 @@ void LowLevelWindow_X11::SwapBuffers()
if( PREFSMAN->m_bDisableScreenSaver ) if( PREFSMAN->m_bDisableScreenSaver )
{ {
/* Disable the screensaver. */ // Disable the screensaver.
#if defined(HAVE_LIBXTST) #if defined(HAVE_LIBXTST)
/* This causes flicker. */ // This causes flicker.
// XForceScreenSaver( Dpy, ScreenSaverReset ); // XForceScreenSaver( Dpy, ScreenSaverReset );
/* /* Instead, send a null relative mouse motion, to trick X into thinking
* Instead, send a null relative mouse motion, to trick X into thinking there has been * there has been user activity.
* user activity.
* *
* This also handles XScreenSaver; XForceScreenSaver only handles the internal X11 * This also handles XScreenSaver; XForceScreenSaver only handles the
* screen blanker. * internal X11 screen blanker.
* *
* This will delay the X blanker, DPMS and XScreenSaver from activating, and will * This will delay the X blanker, DPMS and XScreenSaver from activating,
* disable the blanker and XScreenSaver if they're already active (unless XSS is * and will disable the blanker and XScreenSaver if they're already active
* locked). For some reason, it doesn't un-blank DPMS if it's already active. * (unless XSS is locked). For some reason, it doesn't un-blank DPMS if
* it's already active.
*/ */
XLockDisplay( Dpy ); XLockDisplay( Dpy );
@@ -335,7 +333,7 @@ public:
void StartRenderingTo(); void StartRenderingTo();
void FinishRenderingTo(); void FinishRenderingTo();
/* Copying from the Pbuffer to the texture flips Y. */ // Copying from the Pbuffer to the texture flips Y.
virtual bool InvertY() const { return true; } virtual bool InvertY() const { return true; }
private: private:
@@ -476,7 +474,7 @@ void RenderTarget_X11::FinishRenderingTo()
bool LowLevelWindow_X11::SupportsRenderToTexture() const bool LowLevelWindow_X11::SupportsRenderToTexture() const
{ {
/* Server must support pbuffers: */ // Server must support pbuffers:
const int iScreen = DefaultScreen( Dpy ); const int iScreen = DefaultScreen( Dpy );
float fVersion = strtof( glXQueryServerString(Dpy, iScreen, GLX_VERSION), NULL ); float fVersion = strtof( glXQueryServerString(Dpy, iScreen, GLX_VERSION), NULL );
if( fVersion < 1.3f ) if( fVersion < 1.3f )
+4 -4
View File
@@ -206,8 +206,8 @@ static void AdjustVideoModeParams( VideoModeParams &p )
} }
} }
/* Set the display mode to the given size, bit depth and refresh. The refresh /* Set the display mode to the given size, bit depth and refresh.
* setting may be ignored. */ * The refresh setting may be ignored. */
RString GraphicsWindow::SetScreenMode( const VideoModeParams &p ) RString GraphicsWindow::SetScreenMode( const VideoModeParams &p )
{ {
if( p.windowed ) if( p.windowed )
@@ -293,7 +293,7 @@ void GraphicsWindow::CreateGraphicsWindow( const VideoModeParams &p, bool bForce
g_HDC = GetDC( g_hWndMain ); g_HDC = GetDC( g_hWndMain );
} }
/* Update the window title. */ // Update the window title.
do do
{ {
if( m_bWideWindowClass ) if( m_bWideWindowClass )
@@ -305,7 +305,7 @@ void GraphicsWindow::CreateGraphicsWindow( const VideoModeParams &p, bool bForce
SetWindowTextA( g_hWndMain, ConvertUTF8ToACP(p.sWindowTitle) ); SetWindowTextA( g_hWndMain, ConvertUTF8ToACP(p.sWindowTitle) );
} while(0); } while(0);
/* Update the window icon. */ // Update the window icon.
if( g_hIcon != NULL ) if( g_hIcon != NULL )
{ {
SetClassLong( g_hWndMain, GCL_HICON, (LONG) LoadIcon(NULL,IDI_APPLICATION) ); SetClassLong( g_hWndMain, GCL_HICON, (LONG) LoadIcon(NULL,IDI_APPLICATION) );