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:
+47
-32
@@ -2,7 +2,6 @@
|
||||
; created by
|
||||
; BBF, GlennMaynard, ChrisDanford
|
||||
; 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+
|
||||
|
||||
;--------------------------------
|
||||
@@ -25,8 +24,8 @@
|
||||
Name "${PRODUCT_DISPLAY}"
|
||||
OutFile "${PRODUCT_DISPLAY}.exe"
|
||||
|
||||
Caption "${PRODUCT_DISPLAY}"
|
||||
UninstallCaption "${PRODUCT_DISPLAY}"
|
||||
Caption "${PRODUCT_DISPLAY} | install"
|
||||
UninstallCaption "${PRODUCT_DISPLAY} | uninstall"
|
||||
|
||||
; Some default compiler settings (uncomment and change at will):
|
||||
!ifdef COMPRESS
|
||||
@@ -44,6 +43,7 @@
|
||||
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)
|
||||
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}"
|
||||
InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\${PRODUCT_ID}" ""
|
||||
; DirShow show ; (make this hide to not let the user change it)
|
||||
@@ -148,7 +148,8 @@
|
||||
|
||||
; generate, then include installer strings
|
||||
;!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"
|
||||
|
||||
;--------------------------------
|
||||
@@ -194,6 +195,11 @@ Section "Main Section" SecMain
|
||||
; add registry entries
|
||||
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}" "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"'
|
||||
!endif
|
||||
|
||||
@@ -211,8 +217,8 @@ Section "Main Section" SecMain
|
||||
|
||||
!ifdef ASSOCIATE_SMZIP
|
||||
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\shell\open\command" "" '"$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\StepMania.exe" "%1"'
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Classes\.smzip" "" "smzipfile"
|
||||
!endif
|
||||
|
||||
@@ -232,9 +238,9 @@ Section "Main Section" SecMain
|
||||
CreateDirectory "$INSTDIR\BackgroundTransitions"
|
||||
File /r /x CVS /x .svn "BackgroundTransitions"
|
||||
|
||||
CreateDirectory "$INSTDIR\RandomMovies"
|
||||
SetOutPath "$INSTDIR\RandomMovies"
|
||||
File "RandomMovies\instructions.txt"
|
||||
;CreateDirectory "$INSTDIR\RandomMovies"
|
||||
;SetOutPath "$INSTDIR\RandomMovies"
|
||||
;File "RandomMovies\instructions.txt"
|
||||
; end background/movie related
|
||||
|
||||
; Nobody should be using this directory anymore. -aj
|
||||
@@ -251,10 +257,10 @@ Section "Main Section" SecMain
|
||||
CreateDirectory "$INSTDIR\Courses"
|
||||
SetOutPath "$INSTDIR\Courses"
|
||||
File "Courses\instructions.txt"
|
||||
File /r /x CVS /x .svn "Courses\Samples"
|
||||
File /r /x CVS /x .svn "Courses\Default"
|
||||
|
||||
CreateDirectory "$INSTDIR\Packages"
|
||||
File "Packages\Instructions.txt"
|
||||
;File "Packages\Instructions.txt"
|
||||
|
||||
; remove old noteskins
|
||||
RMDir /r "$INSTDIR\NoteSkins\common\default"
|
||||
@@ -296,7 +302,7 @@ Section "Main Section" SecMain
|
||||
; make songs dir
|
||||
CreateDirectory "$INSTDIR\Songs"
|
||||
SetOutPath "$INSTDIR\Songs"
|
||||
File "Songs\Instructions.txt"
|
||||
;File "Songs\Instructions.txt"
|
||||
|
||||
; remove and install themes
|
||||
RMDir /r "$INSTDIR\Themes\_fallback"
|
||||
@@ -304,7 +310,7 @@ Section "Main Section" SecMain
|
||||
RMDir /r "$INSTDIR\Themes\default"
|
||||
CreateDirectory "$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\_portKit-sm4"
|
||||
File /r /x CVS /x .svn "Themes\default"
|
||||
@@ -322,15 +328,15 @@ Section "Main Section" SecMain
|
||||
|
||||
SetOutPath "$INSTDIR\Program"
|
||||
!ifdef INSTALL_EXECUTABLES
|
||||
; normal exec
|
||||
File "Program\${PRODUCT_FAMILY}.exe"
|
||||
File "Program\${PRODUCT_FAMILY}.vdi"
|
||||
; normal exec (xxx: hardcoded to StepMania instead of ${PRODUCT_FAMILY})
|
||||
File "Program\StepMania.exe"
|
||||
File "Program\StepMania.vdi"
|
||||
; sse2 exec
|
||||
File "Program\${PRODUCT_FAMILY}-SSE2.exe"
|
||||
File "Program\${PRODUCT_FAMILY}-SSE2.vdi"
|
||||
File "Program\StepMania-SSE2.exe"
|
||||
File "Program\StepMania-SSE2.vdi"
|
||||
; other programs
|
||||
File "Program\tools.exe"
|
||||
File "Program\Texture Font Generator.exe"
|
||||
;File "Program\tools.exe" ; to be replaced
|
||||
!endif
|
||||
!ifdef ASSOCIATE_SMZIP
|
||||
Call RefreshShellIcons
|
||||
@@ -358,10 +364,10 @@ Section "Main Section" SecMain
|
||||
; documentation
|
||||
CreateDirectory "$INSTDIR\Docs"
|
||||
SetOutPath "$INSTDIR\Docs"
|
||||
File "Licenses.txt"
|
||||
File "credits.txt"
|
||||
File "Changelog_sm-ssc.txt"
|
||||
File "CommandLineArgs.txt"
|
||||
File "Docs\Licenses.txt"
|
||||
File "Docs\credits.txt"
|
||||
File "Docs\Changelog_sm-ssc.txt"
|
||||
File "Docs\CommandLineArgs.txt"
|
||||
|
||||
CreateDirectory "$INSTDIR\Manual"
|
||||
SetOutPath "$INSTDIR\Manual"
|
||||
@@ -370,8 +376,10 @@ Section "Main Section" SecMain
|
||||
; Create Start Menu icons
|
||||
SetShellVarContext current # 'all' doesn't work on Win9x
|
||||
CreateDirectory "$SMPROGRAMS\${PRODUCT_ID}\"
|
||||
CreateShortCut "$DESKTOP\$(TEXT_IO_RUN).lnk" "$INSTDIR\Program\${PRODUCT_FAMILY}.exe"
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_RUN).lnk" "$INSTDIR\Program\${PRODUCT_FAMILY}.exe"
|
||||
; xxx: StepMania.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
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_OPEN_PROGRAM_FOLDER).lnk" "$WINDIR\explorer.exe" "$INSTDIR\"
|
||||
!endif
|
||||
@@ -384,7 +392,8 @@ Section "Main Section" SecMain
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_CHECK_FOR_UPDATES).lnk" "${UPDATES_URL}"
|
||||
!endif
|
||||
|
||||
CreateShortCut "$INSTDIR\${PRODUCT_ID}.lnk" "$INSTDIR\Program\${PRODUCT_FAMILY}.exe"
|
||||
; xxx: StepMania.exe
|
||||
CreateShortCut "$INSTDIR\${PRODUCT_ID}.lnk" "$INSTDIR\Program\StepMania.exe"
|
||||
!endif
|
||||
|
||||
IfErrors do_error do_no_error
|
||||
@@ -457,9 +466,10 @@ Function LeaveAutorun
|
||||
install:
|
||||
Call PreInstall
|
||||
GoTo proceed
|
||||
|
||||
|
||||
play:
|
||||
Exec "$INSTDIR\Program\${PRODUCT_FAMILY}.exe"
|
||||
; xxx: StepMania.exe
|
||||
Exec "$INSTDIR\Program\StepMania.exe"
|
||||
IfErrors play_error
|
||||
quit
|
||||
|
||||
@@ -543,7 +553,8 @@ Function PreInstall
|
||||
!endif
|
||||
!else
|
||||
; 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
|
||||
Abort
|
||||
proceed_with_patch:
|
||||
@@ -582,6 +593,7 @@ FunctionEnd
|
||||
|
||||
;--------------------------------
|
||||
;Uninstaller Section
|
||||
; todo: update big time
|
||||
|
||||
Section "Uninstall"
|
||||
|
||||
@@ -619,7 +631,7 @@ Section "Uninstall"
|
||||
RMDir "$INSTDIR\Packages"
|
||||
|
||||
Delete "$INSTDIR\Courses\instructions.txt"
|
||||
RMDir /r "$INSTDIR\Courses\Samples"
|
||||
RMDir /r "$INSTDIR\Courses\Default"
|
||||
RMDir "$INSTDIR\Courses"
|
||||
|
||||
Delete "$INSTDIR\NoteSkins\instructions.txt"
|
||||
@@ -657,8 +669,11 @@ Section "Uninstall"
|
||||
!endif
|
||||
|
||||
!ifdef INSTALL_EXECUTABLES
|
||||
Delete "$INSTDIR\Program\${PRODUCT_FAMILY}.exe"
|
||||
Delete "$INSTDIR\Program\${PRODUCT_FAMILY}.vdi"
|
||||
; xxx: StepMania.exe
|
||||
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\Texture Font Generator.exe"
|
||||
!endif
|
||||
|
||||
@@ -21,9 +21,7 @@ public:
|
||||
Actor *GetTarget() { return m_pActorTarget; }
|
||||
void SetTarget( Actor *pTarget ) { m_pActorTarget = pTarget; }
|
||||
|
||||
//
|
||||
// Lua
|
||||
//
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
|
||||
+34
-35
@@ -54,23 +54,19 @@ void ArrowEffects::Update()
|
||||
const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pn];
|
||||
|
||||
PerPlayerData &data = g_EffectData[pn];
|
||||
//
|
||||
// Update Tornado
|
||||
//
|
||||
for( int iColNum = 0; iColNum < MAX_COLS_PER_PLAYER; ++iColNum )
|
||||
{
|
||||
// TRICKY: Tornado is very unplayable in doubles, so use a smaller
|
||||
// tornado width if there are many columns
|
||||
|
||||
/*
|
||||
* the above makes an assumption for dance mode.
|
||||
* perhaps check if we are actually playing on singles without, say
|
||||
* more than 6 columns. That would exclude IIDX, pop'n, and
|
||||
* techno-8, all of which would be clusterfucks.
|
||||
* certain non-singles modes like halfdoubles (6cols),
|
||||
/* the below makes an assumption for dance mode.
|
||||
* perhaps check if we are actually playing on singles without,
|
||||
* say more than 6 columns. That would exclude IIDX, pop'n, and
|
||||
* techno-8, all of which would be very hectic.
|
||||
* certain non-singles modes (like halfdoubles 6cols)
|
||||
* 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;
|
||||
int iTornadoWidth = bWideField ? 2 : 3;
|
||||
|
||||
@@ -89,9 +85,7 @@ void ArrowEffects::Update()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update Invert
|
||||
//
|
||||
for( int iColNum = 0; iColNum < MAX_COLS_PER_PLAYER; ++iColNum )
|
||||
{
|
||||
const int iNumCols = pStyle->m_iColsPerPlayer;
|
||||
@@ -135,9 +129,7 @@ void ArrowEffects::Update()
|
||||
data.m_fInvertDistance[iColNum] = fNewPixelOffset - fOldPixelOffset;
|
||||
}
|
||||
|
||||
//
|
||||
// Update Beat
|
||||
//
|
||||
do {
|
||||
float fAccelTime = 0.2f, fTotalTime = 0.5f;
|
||||
float fBeat = GAMESTATE->m_fSongBeatVisible + fAccelTime;
|
||||
@@ -148,7 +140,7 @@ void ArrowEffects::Update()
|
||||
if( fBeat < 0 )
|
||||
break;
|
||||
|
||||
/* -100.2 -> -0.2 -> 0.2 */
|
||||
// -100.2 -> -0.2 -> 0.2
|
||||
fBeat -= truncf( fBeat );
|
||||
fBeat += 1;
|
||||
fBeat -= truncf( fBeat );
|
||||
@@ -172,19 +164,18 @@ void ArrowEffects::Update()
|
||||
}
|
||||
}
|
||||
|
||||
/* For visibility testing: if bAbsolute is false, random modifiers must return the
|
||||
* minimum possible scroll speed. */
|
||||
/* For visibility testing: if bAbsolute is false, random modifiers must return
|
||||
* the minimum possible scroll speed. */
|
||||
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.
|
||||
fPeakYOffsetOut = FLT_MAX;
|
||||
bIsPastPeakOut = true;
|
||||
|
||||
|
||||
float fYOffset = 0;
|
||||
|
||||
/* Usually, fTimeSpacing is 0 or 1, in which case we use entirely beat spacing or
|
||||
* entirely time spacing (respectively). Occasionally, we tween between them. */
|
||||
* entirely time spacing (respectively). Occasionally, we tween between them. */
|
||||
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 1.0f )
|
||||
{
|
||||
float fSongBeat = GAMESTATE->m_fSongBeatVisible;
|
||||
@@ -213,7 +204,6 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
|
||||
const float* fAccels = pPlayerState->m_PlayerOptions.GetCurrent().m_fAccels;
|
||||
//const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
|
||||
|
||||
|
||||
float fYAdjust = 0; // fill this in depending on PlayerOptions
|
||||
|
||||
if( fAccels[PlayerOptions::ACCEL_BOOST] != 0 )
|
||||
@@ -221,7 +211,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
|
||||
float fEffectHeight = GetNoteFieldHeight(pPlayerState);
|
||||
float fNewYOffset = fYOffset * 1.5f / ((fYOffset+fEffectHeight/1.2f)/fEffectHeight);
|
||||
float fAccelYAdjust = fAccels[PlayerOptions::ACCEL_BOOST] * (fNewYOffset - fYOffset);
|
||||
// TRICKY: Clamp this value, or else BOOST+BOOMERANG will draw a ton of arrows on the screen.
|
||||
// TRICKY: Clamp this value, or else BOOST+BOOMERANG will draw a ton of arrows on the screen.
|
||||
CLAMP( fAccelYAdjust, -400.f, 400.f );
|
||||
fYAdjust += fAccelYAdjust;
|
||||
}
|
||||
@@ -231,7 +221,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
|
||||
float fScale = SCALE( fYOffset, 0.f, fEffectHeight, 0, 1.f );
|
||||
float fNewYOffset = fYOffset * fScale;
|
||||
float fBrakeYAdjust = fAccels[PlayerOptions::ACCEL_BRAKE] * (fNewYOffset - fYOffset);
|
||||
// TRICKY: Clamp this value the same way as BOOST so that in BOOST+BRAKE, BRAKE doesn't overpower BOOST
|
||||
// TRICKY: Clamp this value the same way as BOOST so that in BOOST+BRAKE, BRAKE doesn't overpower BOOST
|
||||
CLAMP( fBrakeYAdjust, -400.f, 400.f );
|
||||
fYAdjust += fBrakeYAdjust;
|
||||
}
|
||||
@@ -240,9 +230,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
|
||||
|
||||
fYOffset += fYAdjust;
|
||||
|
||||
//
|
||||
// Factor in boomerang
|
||||
//
|
||||
if( fAccels[PlayerOptions::ACCEL_BOOMERANG] != 0 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
// Factor in scroll speed
|
||||
//
|
||||
float fScrollSpeed = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollSpeed;
|
||||
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);
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
if( fAccels[PlayerOptions::ACCEL_EXPAND] != 0 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
/* 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 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 )
|
||||
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 floor(f);
|
||||
}
|
||||
|
||||
float ArrowEffects::GetYOffsetFromYPos( const PlayerState* pPlayerState, int iCol, float YPos, float fYReverseOffsetPixels )
|
||||
@@ -344,8 +335,8 @@ float ArrowEffects::GetYOffsetFromYPos( const PlayerState* pPlayerState, int iCo
|
||||
|
||||
float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float fYOffset )
|
||||
{
|
||||
float fPixelOffsetFromCenter = 0; // fill this in below
|
||||
|
||||
float fPixelOffsetFromCenter = 0; // fill this in below
|
||||
|
||||
const Style* pStyle = GAMESTATE->GetCurrentStyle();
|
||||
const float* fEffects = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects;
|
||||
|
||||
@@ -386,11 +377,20 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float
|
||||
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;
|
||||
|
||||
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];
|
||||
fMiniPercent = min( powf(0.5f, fMiniPercent), 1.0f );
|
||||
fPixelOffsetFromCenter *= fMiniPercent;
|
||||
@@ -450,14 +450,13 @@ float ArrowEffects::ReceptorGetRotation( const PlayerState* pPlayerState )
|
||||
return fRotation;
|
||||
}
|
||||
|
||||
|
||||
#define CENTER_LINE_Y 160 // from fYOffset == 0
|
||||
#define FADE_DIST_Y 40
|
||||
|
||||
static float GetCenterLine( const PlayerState* pPlayerState )
|
||||
{
|
||||
/* Another mini hack: if EFFECT_MINI is on, then our center line is at eg. 320,
|
||||
* not 160. */
|
||||
/* Another mini hack: if EFFECT_MINI is on, then our center line is at
|
||||
* eg. 320, not 160. */
|
||||
const float fMiniPercent = pPlayerState->m_PlayerOptions.GetCurrent().m_fEffects[PlayerOptions::EFFECT_TINY];
|
||||
const float fZoom = 1 - fMiniPercent*0.5f;
|
||||
return CENTER_LINE_Y / fZoom;
|
||||
|
||||
@@ -28,7 +28,6 @@ public:
|
||||
// Inverse of ArrowGetYPos (YPos -> fYOffset).
|
||||
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
|
||||
// the arrow and possibly the Arrow effect and the fYOffset (in the case of
|
||||
// EFFECT_DIZZY).
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ void AutoActor::Load( const RString &sPath )
|
||||
Unload();
|
||||
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 )
|
||||
m_pActor = new Actor;
|
||||
}
|
||||
|
||||
+2
-4
@@ -38,9 +38,7 @@ public:
|
||||
void DemandGraphics();
|
||||
void UndemandGraphics();
|
||||
|
||||
//
|
||||
// Lua
|
||||
//
|
||||
void PushSelf( Lua *L );
|
||||
|
||||
// smart accessor
|
||||
@@ -48,17 +46,17 @@ public:
|
||||
|
||||
RString m_sCharDir;
|
||||
RString m_sCharacterID;
|
||||
|
||||
private:
|
||||
RString m_sDisplayName;
|
||||
RString m_sCardPath;
|
||||
RString m_sIconPath;
|
||||
|
||||
public:
|
||||
|
||||
apActorCommands m_cmdInit;
|
||||
|
||||
// All the stuff below will be filled in if this character is playable in Rave mode
|
||||
bool m_bUsableInRave;
|
||||
bool m_bUsableInRave;
|
||||
|
||||
RString m_sAttacks[NUM_ATTACK_LEVELS][NUM_ATTACKS_PER_LEVEL];
|
||||
RageTexturePreloader m_Preload;
|
||||
|
||||
@@ -32,9 +32,7 @@ public:
|
||||
|
||||
virtual ControllerStateDisplay *Copy() const;
|
||||
|
||||
//
|
||||
// Lua
|
||||
//
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
protected:
|
||||
|
||||
@@ -192,6 +192,7 @@ void Course::Init()
|
||||
m_sSubTitleTranslit = "";
|
||||
|
||||
m_sBannerPath = "";
|
||||
m_sBackgroundPath = "";
|
||||
m_sCDTitlePath = "";
|
||||
m_sGroupName = "";
|
||||
|
||||
@@ -883,11 +884,27 @@ RString Course::GetBannerPath() const
|
||||
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
|
||||
{
|
||||
return GetBannerPath() != "" && IsAFile(GetBannerPath());
|
||||
}
|
||||
|
||||
bool Course::HasBackground() const
|
||||
{
|
||||
return GetBackgroundPath() != "" && IsAFile(GetBackgroundPath());
|
||||
}
|
||||
|
||||
void Course::UpdateCourseStats( StepsType st )
|
||||
{
|
||||
m_SortOrder_TotalDifficulty = 0;
|
||||
@@ -1029,6 +1046,7 @@ public:
|
||||
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 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; }
|
||||
@@ -1059,6 +1077,7 @@ public:
|
||||
ADD_METHOD( GetCourseEntry );
|
||||
ADD_METHOD( GetAllTrails );
|
||||
ADD_METHOD( GetBannerPath );
|
||||
ADD_METHOD( GetBackgroundPath );
|
||||
ADD_METHOD( GetGroupName );
|
||||
ADD_METHOD( IsAutogen );
|
||||
ADD_METHOD( GetEstimatedNumStages );
|
||||
|
||||
+18
-15
@@ -85,7 +85,9 @@ public:
|
||||
Course();
|
||||
|
||||
RString GetBannerPath() const;
|
||||
RString GetBackgroundPath() const;
|
||||
bool HasBanner() const;
|
||||
bool HasBackground() const;
|
||||
|
||||
/* If PREFSMAN->m_bShowNative is off, these are the same as GetTranslit* below.
|
||||
* Otherwise, they return the main titles. */
|
||||
@@ -96,7 +98,7 @@ public:
|
||||
RString GetTranslitMainTitle() const { return m_sMainTitleTranslit.size()? m_sMainTitleTranslit: m_sMainTitle; }
|
||||
RString GetTranslitSubTitle() const { return m_sSubTitleTranslit.size()? m_sSubTitleTranslit: m_sSubTitle; }
|
||||
|
||||
/* "title subtitle" */
|
||||
// "title subtitle"
|
||||
RString GetDisplayFullTitle() const;
|
||||
RString GetTranslitFullTitle() const;
|
||||
|
||||
@@ -162,24 +164,25 @@ public:
|
||||
bool IsAnEdit() const { return m_LoadedFromProfile != ProfileSlot_Invalid; }
|
||||
|
||||
|
||||
bool m_bIsAutogen; // was this created by AutoGen?
|
||||
RString m_sPath;
|
||||
bool m_bIsAutogen; // was this created by AutoGen?
|
||||
RString m_sPath;
|
||||
|
||||
RString m_sMainTitle, m_sMainTitleTranslit;
|
||||
RString m_sSubTitle, m_sSubTitleTranslit;
|
||||
RString m_sMainTitle, m_sMainTitleTranslit;
|
||||
RString m_sSubTitle, m_sSubTitleTranslit;
|
||||
|
||||
RString m_sBannerPath;
|
||||
RString m_sCDTitlePath;
|
||||
RString m_sGroupName;
|
||||
RString m_sBannerPath;
|
||||
RString m_sBackgroundPath; // after 9 years yes finally -aj
|
||||
RString m_sCDTitlePath;
|
||||
RString m_sGroupName;
|
||||
|
||||
bool m_bRepeat; // repeat after last song? "Endless"
|
||||
float m_fGoalSeconds; // if not 0, stop play after this number of seconds
|
||||
bool m_bShuffle;
|
||||
int m_iLives; // -1 means use bar life meter
|
||||
int m_iCustomMeter[NUM_Difficulty]; // -1 = no meter specified
|
||||
bool m_bSortByMeter;
|
||||
bool m_bRepeat; // repeat after last song? "Endless"
|
||||
float m_fGoalSeconds; // if not 0, stop play after this number of seconds
|
||||
bool m_bShuffle;
|
||||
int m_iLives; // -1 means use bar life meter
|
||||
int m_iCustomMeter[NUM_Difficulty]; // -1 = no meter specified
|
||||
bool m_bSortByMeter;
|
||||
|
||||
bool m_bIncomplete;
|
||||
bool m_bIncomplete;
|
||||
|
||||
vector<CourseEntry> m_vEntries;
|
||||
|
||||
|
||||
+10
-10
@@ -99,7 +99,7 @@ int StepsDisplayList::GetCurrentRowIndex( PlayerNumber pn ) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Update m_fY and m_bHidden[]. */
|
||||
// Update m_fY and m_bHidden[].
|
||||
void StepsDisplayList::UpdatePositions()
|
||||
{
|
||||
int iCurrentRow[NUM_PLAYERS];
|
||||
@@ -111,7 +111,7 @@ void StepsDisplayList::UpdatePositions()
|
||||
|
||||
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 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);
|
||||
if( !BothPlayersActivated )
|
||||
{
|
||||
/* Simply center the cursor. */
|
||||
// Simply center the cursor.
|
||||
first_start = max( P1Choice - halfsize, 0 );
|
||||
first_end = first_start + total;
|
||||
second_start = second_end = first_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First half: */
|
||||
// First half:
|
||||
const int earliest = min( P1Choice, P2Choice );
|
||||
first_start = max( earliest - halfsize/2, 0 );
|
||||
first_end = first_start + halfsize;
|
||||
|
||||
/* Second half: */
|
||||
// Second half:
|
||||
const int latest = max( P1Choice, P2Choice );
|
||||
|
||||
second_start = max( latest - halfsize/2, 0 );
|
||||
@@ -152,23 +152,23 @@ void StepsDisplayList::UpdatePositions()
|
||||
{
|
||||
const int sum = (first_end - first_start) + (second_end - second_start);
|
||||
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
|
||||
* the first half. */
|
||||
if( second_start > first_end )
|
||||
second_start--;
|
||||
/* Otherwise, expand either end. */
|
||||
// Otherwise, expand either end.
|
||||
else if( first_start > 0 )
|
||||
first_start--;
|
||||
else if( second_end < (int) Rows.size() )
|
||||
second_end++;
|
||||
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;
|
||||
for( int i=0; i<(int) Rows.size(); i++ ) // foreach row
|
||||
for( int i=0; i<(int) Rows.size(); i++ ) // foreach row
|
||||
{
|
||||
float ItemPosition;
|
||||
if( i < first_start )
|
||||
@@ -181,7 +181,7 @@ void StepsDisplayList::UpdatePositions()
|
||||
ItemPosition = (float) pos++;
|
||||
else
|
||||
ItemPosition = (float) total - 0.5f;
|
||||
|
||||
|
||||
Row &row = Rows[i];
|
||||
|
||||
float fY = ITEMS_SPACING_Y*ItemPosition;
|
||||
|
||||
@@ -13,12 +13,10 @@ void DynamicActorScroller::LoadFromNode( const XNode *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.
|
||||
*
|
||||
* Make one extra copy if masking is enabled.
|
||||
*/
|
||||
* Make one extra copy if masking is enabled. */
|
||||
if( m_SubActors.size() != 1 )
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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();
|
||||
m_LoadFunction.PushSelf( L );
|
||||
@@ -55,20 +53,16 @@ void DynamicActorScroller::LoadFromNode( const XNode *pNode )
|
||||
LUA->Release(L);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reconfigure all items, so the loaded actors actually correspond with
|
||||
* m_iFirstSubActorIndex.
|
||||
*/
|
||||
/* Reconfigure all items, so the loaded actors actually correspond with
|
||||
* m_iFirstSubActorIndex. */
|
||||
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
|
||||
* 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 )
|
||||
{
|
||||
ActorScroller::ShiftSubActors( iDist );
|
||||
|
||||
+55
-58
@@ -29,7 +29,7 @@ void FontPage::Load( const FontPageSettings &cfg )
|
||||
ASSERT( m_FontPageTextures.m_pTextureMain != NULL );
|
||||
|
||||
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 )
|
||||
{
|
||||
ID2.filename.Replace( "]", "-stroke]" );
|
||||
@@ -97,7 +97,7 @@ void FontPage::Load( const FontPageSettings &cfg )
|
||||
m_iDrawExtraPixelsLeft = cfg.m_iDrawExtraPixelsLeft;
|
||||
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;
|
||||
|
||||
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). */
|
||||
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_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 )
|
||||
{
|
||||
/* 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++;
|
||||
iDrawExtraPixelsLeft++;
|
||||
|
||||
if( (iDrawExtraPixelsLeft % 2) == 1 )
|
||||
++iDrawExtraPixelsLeft;
|
||||
|
||||
/* Adjust for iDrawExtraPixelsLeft and iDrawExtraPixelsRight. */
|
||||
// Adjust for iDrawExtraPixelsLeft and iDrawExtraPixelsRight.
|
||||
for( unsigned i = 0; i < m_aGlyphs.size(); ++i )
|
||||
{
|
||||
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 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.right += fExtraRight * m_FontPageTextures.m_pTextureMain->GetSourceToTexCoordsRatioX();
|
||||
m_aGlyphs[i].m_fHshift -= fExtraLeft;
|
||||
@@ -213,7 +213,7 @@ int Font::GetLineHeightInSourcePixels( const wstring &szLine ) const
|
||||
{
|
||||
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++ )
|
||||
iLineHeight = max( iLineHeight, GetGlyph(szLine[i]).m_pPage->m_iHeight );
|
||||
|
||||
@@ -228,7 +228,7 @@ Font::Font()
|
||||
m_iRefCount = 1;
|
||||
m_pDefault = NULL;
|
||||
m_bRightToLeft = false;
|
||||
// don't show strokes by default
|
||||
// [sm-ssc] don't show strokes by default
|
||||
m_DefaultStrokeColor = RageColor(0,0,0,0);
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ void Font::Unload()
|
||||
m_iCharToGlyph.clear();
|
||||
m_pDefault = NULL;
|
||||
|
||||
/* Don't clear the refcount. We've unloaded, but that doesn't mean things
|
||||
/* Don't clear the refcount. We've unloaded, but that doesn't mean things
|
||||
* aren't still pointing to us. */
|
||||
}
|
||||
|
||||
@@ -293,20 +293,20 @@ const glyph &Font::GetGlyph( wchar_t c ) const
|
||||
{
|
||||
ASSERT(c >= 0 && c <= 0xFFFFFF);
|
||||
|
||||
/* Fast path: */
|
||||
// Fast path:
|
||||
if( c < (int) ARRAYLEN(m_iCharToGlyphCache) && 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);
|
||||
|
||||
/* If that's missing, use the default glyph. */
|
||||
// If that's missing, use the default glyph.
|
||||
if(it == m_iCharToGlyph.end())
|
||||
it = m_iCharToGlyph.find(FONT_DEFAULT_GLYPH);
|
||||
|
||||
if(it == m_iCharToGlyph.end())
|
||||
RageException::Throw( "The default glyph is missing from the font \"%s\".", path.c_str() );
|
||||
|
||||
|
||||
return *it->second;
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ bool Font::FontCompleteForString( const wstring &str ) const
|
||||
|
||||
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] );
|
||||
if( &g == m_pDefault->second )
|
||||
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 )
|
||||
{
|
||||
RString sPrefix = SetExtension( sFontIniPath, "" );
|
||||
@@ -384,7 +384,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
|
||||
{
|
||||
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++ )
|
||||
{
|
||||
char c = sChars[n];
|
||||
@@ -393,12 +393,13 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
|
||||
int iNumFramesWide, iNumFramesHigh;
|
||||
RageTexture::GetFrameDimensionsFromFileName( sTexturePath, &iNumFramesWide, &iNumFramesHigh );
|
||||
int iNumFrames = iNumFramesWide * iNumFramesHigh;
|
||||
|
||||
|
||||
// Deal with fonts generated by Bitmap Font Builder.
|
||||
ini.RenameKey("Char Widths", "main");
|
||||
|
||||
// LOG->Trace("Loading font page '%s' settings from page name '%s'",
|
||||
// TexturePath.c_str(), sPageName.c_str());
|
||||
|
||||
|
||||
ini.GetValue( sPageName, "DrawExtraPixelsLeft", cfg.m_iDrawExtraPixelsLeft );
|
||||
ini.GetValue( sPageName, "DrawExtraPixelsRight", cfg.m_iDrawExtraPixelsRight );
|
||||
ini.GetValue( sPageName, "AddToAllWidths", cfg.m_iAddToAllWidths );
|
||||
@@ -410,7 +411,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
|
||||
ini.GetValue( sPageName, "AdvanceExtraPixels", cfg.m_iAdvanceExtraPixels );
|
||||
ini.GetValue( sPageName, "TextureHints", cfg.m_sTextureHints );
|
||||
|
||||
/* Iterate over all keys. */
|
||||
// Iterate over all keys.
|
||||
const XNode* pNode = ini.GetChild( sPageName );
|
||||
if( pNode )
|
||||
{
|
||||
@@ -421,18 +422,17 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
|
||||
|
||||
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) )
|
||||
{
|
||||
cfg.m_mapGlyphWidths[atoi(sName)] = pValue->GetValue<int>();
|
||||
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 " )
|
||||
{
|
||||
/*
|
||||
* map CODEPOINT=frame. CODEPOINT can be
|
||||
/* map CODEPOINT=frame. CODEPOINT can be
|
||||
* 1. U+hexval
|
||||
* 2. an alias ("oq")
|
||||
* 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
|
||||
* range unicode #1-1=2
|
||||
*/
|
||||
RString sCodepoint = sName.substr(4); /* "CODEPOINT" */
|
||||
RString sCodepoint = sName.substr(4); // "CODEPOINT"
|
||||
|
||||
wchar_t c;
|
||||
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 " )
|
||||
{
|
||||
/*
|
||||
* range CODESET=first_frame or
|
||||
/* range CODESET=first_frame or
|
||||
* range CODESET #start-end=first_frame
|
||||
* eg
|
||||
* range CP1252=0 (default for 256-frame fonts)
|
||||
@@ -486,15 +485,14 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr
|
||||
vector<RString> asMatches;
|
||||
static Regex parse("^RANGE ([A-Z0-9\\-]+)( ?#([0-9A-F]+)-([0-9A-F]+))?$");
|
||||
bool bMatch = parse.Compare( sName, asMatches );
|
||||
|
||||
ASSERT( asMatches.size() == 4 ); /* 4 parens */
|
||||
|
||||
ASSERT( asMatches.size() == 4 ); // 4 parens
|
||||
|
||||
if( !bMatch || asMatches[0].empty() )
|
||||
RageException::Throw( "Font definition \"%s\" has an invalid range \"%s\": parse error.",
|
||||
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 iFirst = 0;
|
||||
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.",
|
||||
ini.GetPath().c_str(), iFirstFrame, iNumFramesHigh );
|
||||
|
||||
/* Decode the string. */
|
||||
// Decode the string.
|
||||
const wstring wdata( RStringToWstring(pValue->GetValue<RString>()) );
|
||||
|
||||
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,
|
||||
* respectively. If it's anything else, we don't know what it
|
||||
* is, so don't make any default mappings (the INI needs to do
|
||||
* it itself). */
|
||||
* respectively. 5x3 and 4x4 numbers fonts are supported as well.
|
||||
* If it's anything else, we don't know what it is, so don't make
|
||||
* any default mappings (the INI needs to do that itself). */
|
||||
if( sPageName != "common" && cfg.CharToGlyphNo.empty() )
|
||||
{
|
||||
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() )
|
||||
cfg.CharToGlyphNo[0x00A0] = cfg.CharToGlyphNo[' '];
|
||||
}
|
||||
@@ -581,14 +579,14 @@ RString FontPageSettings::MapRange( RString sMapping, int iMapOffset, int iGlyph
|
||||
{
|
||||
if( !sMapping.CompareNoCase("Unicode") )
|
||||
{
|
||||
/* Special case. */
|
||||
// Special case.
|
||||
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,
|
||||
* which is 16384 glyphs. (Use a grayscale map and that's only 4 megs.) Let's use
|
||||
* that as a cap. (We don't want to go crazy if someone says "range Unicode
|
||||
* #0-FFFFFFFF".) */
|
||||
/* What's a practical limit? A 2048x2048 texture could contain 16x16
|
||||
* characters, which is 16384 glyphs. (Use a grayscale map and that's
|
||||
* only 4 megs.) Let's use that as a cap. (We don't want to go crazy
|
||||
* if someone says "range Unicode #0-FFFFFFFF".) */
|
||||
if( iCount > 16384 )
|
||||
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;
|
||||
}
|
||||
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 )
|
||||
for( iCount = 0; pMapping[iCount] != 0; ++iCount ) ;
|
||||
|
||||
@@ -629,15 +627,14 @@ RString FontPageSettings::MapRange( RString sMapping, int iMapOffset, int iGlyph
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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 [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
|
||||
* 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
|
||||
* 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 );
|
||||
|
||||
/* Check for recursion (recursive imports). */
|
||||
// Check for recursion (recursive imports).
|
||||
for( unsigned i = 0; i < LoadStack.size(); ++i )
|
||||
{
|
||||
if( LoadStack[i] == sIniPath )
|
||||
@@ -670,20 +668,19 @@ void Font::Load( const RString &sIniPath, RString sChars )
|
||||
}
|
||||
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()) );
|
||||
|
||||
path = sIniPath;
|
||||
m_sChars = sChars;
|
||||
|
||||
/* Get the filenames associated with this font. */
|
||||
// Get the filenames associated with this font.
|
||||
vector<RString> asTexturePaths;
|
||||
GetFontPaths( sIniPath, asTexturePaths );
|
||||
|
||||
|
||||
bool bCapitalsOnly = false;
|
||||
|
||||
/* If we have an INI, load it. */
|
||||
// If we have an INI, load it.
|
||||
IniFile ini;
|
||||
if( !sIniPath.empty() )
|
||||
{
|
||||
@@ -701,7 +698,7 @@ void Font::Load( const RString &sIniPath, RString sChars )
|
||||
|
||||
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 )
|
||||
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 )
|
||||
{
|
||||
const RString &sTexturePath = asTexturePaths[i];
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
// Ignore stroke textures
|
||||
if( sTexturePath.find("-stroke") != string::npos )
|
||||
continue;
|
||||
|
||||
/* Load settings for this page from the INI. */
|
||||
// Load settings for this page from the INI.
|
||||
FontPageSettings cfg;
|
||||
LoadFontPageSettings( cfg, ini, sTexturePath, "common", sChars );
|
||||
LoadFontPageSettings( cfg, ini, sTexturePath, sPagename, sChars );
|
||||
|
||||
/* Go. */
|
||||
// Load.
|
||||
pPage->Load( cfg );
|
||||
|
||||
/* 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() )
|
||||
{
|
||||
/* Cache ASCII glyphs. */
|
||||
// Cache ASCII glyphs.
|
||||
ZERO( m_iCharToGlyphCache );
|
||||
map<wchar_t,glyph*>::iterator it;
|
||||
for( it = m_iCharToGlyph.begin(); it != m_iCharToGlyph.end(); ++it )
|
||||
|
||||
+21
-19
@@ -15,7 +15,9 @@ class IniFile;
|
||||
struct FontPageTextures
|
||||
{
|
||||
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()
|
||||
{
|
||||
@@ -30,16 +32,16 @@ struct glyph
|
||||
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;
|
||||
|
||||
/* Size of the actual rendered character. */
|
||||
// Size of the actual rendered character.
|
||||
float m_fWidth, m_fHeight;
|
||||
|
||||
/* Number of pixels to offset this character when rendering. */
|
||||
float m_fHshift; // , vshift;
|
||||
// Number of pixels to offset this character when rendering.
|
||||
float m_fHshift; // , m_fVshift;
|
||||
|
||||
/* Texture coordinate rect. */
|
||||
// Texture coordinate rect.
|
||||
RectF m_TexRect;
|
||||
};
|
||||
|
||||
@@ -59,7 +61,7 @@ struct FontPageSettings
|
||||
RString m_sTextureHints;
|
||||
|
||||
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;
|
||||
|
||||
FontPageSettings():
|
||||
@@ -74,7 +76,7 @@ struct FontPageSettings
|
||||
m_sTextureHints("default")
|
||||
{ }
|
||||
|
||||
/* Map a range from a character map to glyphs. If cnt is -1, map the
|
||||
/* Map a range from a character map to glyphs. If cnt is -1, map the
|
||||
* whole map. Returns "" or an error message. */
|
||||
RString MapRange( RString sMapping, int iMapOffset, int iGlyphOffset, int iCount );
|
||||
};
|
||||
@@ -87,21 +89,21 @@ public:
|
||||
|
||||
void Load( const FontPageSettings &cfg );
|
||||
|
||||
/* Page-global properties. */
|
||||
// Page-global properties.
|
||||
int m_iHeight;
|
||||
int m_iLineSpacing;
|
||||
float m_fVshift;
|
||||
int GetCenter() const { return m_iHeight/2; }
|
||||
|
||||
/* Remember these only for GetLineWidthInSourcePixels. */
|
||||
// Remember these only for GetLineWidthInSourcePixels.
|
||||
int m_iDrawExtraPixelsLeft, m_iDrawExtraPixelsRight;
|
||||
|
||||
FontPageTextures m_FontPageTextures;
|
||||
|
||||
// XXX remove?
|
||||
// XXX: remove?
|
||||
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;
|
||||
|
||||
map<wchar_t,int> m_iCharToGlyphNo;
|
||||
@@ -127,17 +129,17 @@ public:
|
||||
|
||||
bool FontCompleteForString( const wstring &str ) const;
|
||||
|
||||
/* Add a FontPage to this font. */
|
||||
// Add a FontPage to this font.
|
||||
void AddPage(FontPage *fp);
|
||||
|
||||
/* Steal all of a font's pages. */
|
||||
// Steal all of a font's pages.
|
||||
void MergeFont(Font &f);
|
||||
|
||||
void Load(const RString &sFontOrTextureFilePath, RString sChars);
|
||||
void Unload();
|
||||
void Reload();
|
||||
|
||||
/* Load font-wide settings. */
|
||||
// Load font-wide settings.
|
||||
void CapsOnly();
|
||||
|
||||
int GetHeight() const { return m_pDefault->m_iHeight; }
|
||||
@@ -150,14 +152,14 @@ public:
|
||||
const RageColor &GetDefaultStrokeColor() const { return m_DefaultStrokeColor; };
|
||||
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
glyph *m_iCharToGlyphCache[128];
|
||||
|
||||
@@ -168,7 +170,7 @@ private:
|
||||
|
||||
RageColor m_DefaultStrokeColor;
|
||||
|
||||
/* We keep this around only for reloading. */
|
||||
// We keep this around only for reloading.
|
||||
RString m_sChars;
|
||||
|
||||
void LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RString &sTexturePath, const RString &PageName, RString sChars );
|
||||
|
||||
+23
-17
@@ -6,7 +6,7 @@
|
||||
|
||||
#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;
|
||||
static aliasmap CharAliases;
|
||||
static map<RString,RString> CharAliasRepl;
|
||||
@@ -25,12 +25,18 @@ static map<RString,RString> CharAliasRepl;
|
||||
* [Katakana]
|
||||
* [Punctuation]
|
||||
*
|
||||
* I'm not sure how to handle internal-use character, like Zz. Whenever we write
|
||||
* I'm not sure how to handle internal-use character, like Zz. Whenever we write
|
||||
* text to disk, we need to write placeholders (&doublezeta;) for them, and never
|
||||
* Unicode characters, since the codepoint is prone to change. We can't currently
|
||||
* Unicode characters, since the codepoint is prone to change. We can't currently
|
||||
* 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:
|
||||
|
||||
、。〃〄々〆〇〈〉《》「」『』
|
||||
@@ -67,17 +73,17 @@ static void InitCharAliases()
|
||||
if(!CharAliases.empty())
|
||||
return;
|
||||
|
||||
CharAliases["default"] = FONT_DEFAULT_GLYPH; /* ? */
|
||||
CharAliases["invalid"] = INVALID_CHAR; /* 0xFFFD */
|
||||
CharAliases["default"] = FONT_DEFAULT_GLYPH; // ?
|
||||
CharAliases["invalid"] = INVALID_CHAR; // 0xFFFD
|
||||
|
||||
/* The comments here are UTF-8; they won't show up in VC6 (use a later
|
||||
* version of visual studio then, you old fart). -aj edited this */
|
||||
// The comments here are UTF-8; they won't show up in VC6
|
||||
// (use a better editor then -aj)
|
||||
|
||||
#define INTERNAL 0xE000
|
||||
|
||||
// todo: convert this into a vector? that way we can dynamically add
|
||||
// to the list easier.
|
||||
/* Hiragana: */
|
||||
// to the list easier. -aj(?)
|
||||
// Hiragana:
|
||||
struct alias {
|
||||
const char *str;
|
||||
wchar_t chr;
|
||||
@@ -168,7 +174,7 @@ static void InitCharAliases()
|
||||
{ "hyos", 0x3087 }, /* ょ */
|
||||
{ "hwas", 0x308e }, /* ゎ */
|
||||
|
||||
/* Katakana: */
|
||||
// Katakana:
|
||||
{ "hq", 0x3063 }, /* っ */
|
||||
{ "ka", 0x30a2 }, /* ア */
|
||||
{ "ki", 0x30a4 }, /* イ */
|
||||
@@ -263,7 +269,7 @@ static void InitCharAliases()
|
||||
|
||||
{ "nbsp", 0x00a0 }, /* Non-breaking space */
|
||||
|
||||
/* Symbols: */
|
||||
// Symbols:
|
||||
{ "delta", 0x0394 }, /* Δ */
|
||||
{ "sigma", 0x03a3 }, /* Σ */
|
||||
{ "omega", 0x03a9 }, /* Ω */
|
||||
@@ -309,7 +315,7 @@ static void InitCharAliases()
|
||||
{ "ok", INTERNAL },
|
||||
{ "nextrow", INTERNAL },
|
||||
{ "select", INTERNAL },
|
||||
/* PlayStation-style controller */
|
||||
// PlayStation-style controller
|
||||
{ "auxx", INTERNAL },
|
||||
{ "auxtriangle",INTERNAL },
|
||||
{ "auxsquare", INTERNAL },
|
||||
@@ -322,17 +328,17 @@ static void InitCharAliases()
|
||||
{ "auxr3", INTERNAL },
|
||||
{ "auxselect", INTERNAL },
|
||||
{ "auxstart", INTERNAL },
|
||||
/* various other controllers (SNES, Saturn, Dreamcast stick styles) */
|
||||
// various other controllers (SNES, Saturn, Dreamcast stick styles)
|
||||
{ "auxa", INTERNAL },
|
||||
{ "auxb", INTERNAL },
|
||||
{ "auxc", INTERNAL },
|
||||
{ "auxd", INTERNAL },
|
||||
/* auxx is handled above */
|
||||
// auxx is handled above
|
||||
{ "auxy", INTERNAL },
|
||||
{ "auxz", INTERNAL },
|
||||
{ "auxl", INTERNAL },
|
||||
{ "auxr", INTERNAL },
|
||||
/* Xbox (original, 360)-style controllers */
|
||||
// Xbox (original, 360)-style controllers
|
||||
{ "auxwhite", INTERNAL },
|
||||
{ "auxblack", 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 )
|
||||
{
|
||||
InitCharAliases();
|
||||
@@ -370,7 +376,7 @@ void FontCharAliases::ReplaceMarkers( RString &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 )
|
||||
{
|
||||
InitCharAliases();
|
||||
|
||||
@@ -195,7 +195,7 @@ static const wchar_t map_korean_jamo[] =
|
||||
0
|
||||
};
|
||||
|
||||
/* Numbers. "0123456789%. :x" */
|
||||
/* 5x3 Numbers. "0123456789%. :x" */
|
||||
static const wchar_t map_numbers[] = {
|
||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038, 0x0039,
|
||||
|
||||
@@ -88,7 +88,7 @@ RankingCategory AverageMeterToRankingCategory( int iAverageMeter )
|
||||
if( iAverageMeter <= 3 ) return RANKING_A;
|
||||
else if( iAverageMeter <= 6 ) return RANKING_B;
|
||||
else if( iAverageMeter <= 9 ) return RANKING_C;
|
||||
else return RANKING_D;
|
||||
else return RANKING_D;
|
||||
}
|
||||
|
||||
|
||||
@@ -316,9 +316,9 @@ StringToX( StageAward );
|
||||
LuaFunction( StageAwardToLocalizedString, StageAwardToLocalizedString(Enum::Check<StageAward>(L, 1)) );
|
||||
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.
|
||||
// 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.
|
||||
static const char *PeakComboAwardNames[] = {
|
||||
"1000",
|
||||
@@ -415,7 +415,9 @@ LuaXType( EditMode );
|
||||
|
||||
static const char *SampleMusicPreviewModeNames[] = {
|
||||
"Normal",
|
||||
//"StartToPreview",
|
||||
"ScreenMusic",
|
||||
//"LastSong"
|
||||
};
|
||||
XToString( SampleMusicPreviewMode );
|
||||
StringToX( SampleMusicPreviewMode );
|
||||
|
||||
@@ -282,8 +282,6 @@ RankingCategory AverageMeterToRankingCategory( int iAverageMeter );
|
||||
extern const RString GROUP_ALL;
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
enum PlayerController
|
||||
{
|
||||
@@ -316,9 +314,7 @@ enum StageResult
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Battle stuff
|
||||
//
|
||||
const int NUM_INVENTORY_SLOTS = 3;
|
||||
enum AttackLevel
|
||||
{
|
||||
@@ -331,11 +327,7 @@ const int NUM_ATTACKS_PER_LEVEL = 3;
|
||||
const int ITEM_NONE = -1;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Coin stuff
|
||||
//
|
||||
|
||||
enum CoinMode
|
||||
{
|
||||
CoinMode_Home,
|
||||
@@ -348,9 +340,7 @@ const RString& CoinModeToString( CoinMode cm );
|
||||
LuaDeclareType( CoinMode );
|
||||
|
||||
|
||||
//
|
||||
// Premium
|
||||
//
|
||||
enum Premium
|
||||
{
|
||||
Premium_Off,
|
||||
@@ -364,10 +354,7 @@ const RString& PremiumToLocalizedString( Premium p );
|
||||
LuaDeclareType( Premium );
|
||||
|
||||
|
||||
//
|
||||
// Award stuff
|
||||
//
|
||||
|
||||
enum StageAward
|
||||
{
|
||||
StageAward_FullComboW3,
|
||||
@@ -422,7 +409,7 @@ struct DisplayBpms
|
||||
|
||||
enum StyleType
|
||||
{
|
||||
StyleType_OnePlayerOneSide, // e.g. single
|
||||
StyleType_OnePlayerOneSide, // e.g. single
|
||||
StyleType_TwoPlayersTwoSides, // e.g. versus
|
||||
StyleType_OnePlayerTwoSides, // e.g. double
|
||||
StyleType_TwoPlayersSharedSides, // e.g. routine
|
||||
@@ -460,7 +447,6 @@ const RString& EditModeToString( EditMode em );
|
||||
EditMode StringToEditMode( const RString& s );
|
||||
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:
|
||||
(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
|
||||
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)
|
||||
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
|
||||
|
||||
Options 1 and 3 need to behave well with TWO_PART_SELECTION, and are not
|
||||
currently represented because of this.
|
||||
*/
|
||||
enum SampleMusicPreviewMode
|
||||
{
|
||||
SampleMusicPreviewMode_Normal,
|
||||
//SampleMusicPreviewMode_StartToPreview,
|
||||
SampleMusicPreviewMode_ScreenMusic,
|
||||
//SampleMusicPreviewMode_LastSong, // continue playing the last song
|
||||
NUM_SampleMusicPreviewMode,
|
||||
SampleMusicPreviewMode_Invalid,
|
||||
};
|
||||
@@ -485,7 +470,7 @@ const RString& SampleMusicPreviewModeToString( SampleMusicPreviewMode );
|
||||
SampleMusicPreviewMode StringToSampleMusicPreviewMode( const RString& s );
|
||||
LuaDeclareType( SampleMusicPreviewMode );
|
||||
|
||||
enum Stage // Shared stage values (not per-player) that are shown in StageDisplay
|
||||
enum Stage // Shared stage values (not per-player) that are shown in StageDisplay
|
||||
{
|
||||
Stage_1st,
|
||||
Stage_2nd,
|
||||
@@ -493,7 +478,7 @@ enum Stage // Shared stage values (not per-player) that are shown in StageDispla
|
||||
Stage_4th,
|
||||
Stage_5th,
|
||||
Stage_6th,
|
||||
Stage_Next, // after Stage_6th but not Final. This won't normally happen because 7 stages is the max in the UI.
|
||||
Stage_Next, // after Stage_6th but not Final. This won't normally happen because 7 stages is the max in the UI.
|
||||
Stage_Final,
|
||||
Stage_Extra1,
|
||||
Stage_Extra2,
|
||||
@@ -545,7 +530,7 @@ const RString& MultiPlayerStatusToString( MultiPlayerStatus i );
|
||||
enum CourseType
|
||||
{
|
||||
COURSE_TYPE_NONSTOP, // if life meter type is BAR
|
||||
COURSE_TYPE_ONI, // if life meter type is BATTERY
|
||||
COURSE_TYPE_ONI, // if life meter type is BATTERY
|
||||
COURSE_TYPE_ENDLESS, // if set to REPEAT
|
||||
COURSE_TYPE_SURVIVAL, // if life meter type is TIME
|
||||
NUM_CourseType,
|
||||
|
||||
+37
-27
@@ -62,21 +62,22 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
|
||||
|
||||
#define GAME_BUTTON_NEXT GAME_BUTTON_CUSTOM_01
|
||||
|
||||
// dance
|
||||
#define DANCE_BUTTON_LEFT GAME_BUTTON_CUSTOM_01
|
||||
#define DANCE_BUTTON_RIGHT GAME_BUTTON_CUSTOM_02
|
||||
#define DANCE_BUTTON_UP GAME_BUTTON_CUSTOM_03
|
||||
#define DANCE_BUTTON_DOWN GAME_BUTTON_CUSTOM_04
|
||||
#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
|
||||
|
||||
// pump
|
||||
#define PUMP_BUTTON_UPLEFT GAME_BUTTON_CUSTOM_01
|
||||
#define PUMP_BUTTON_UPRIGHT GAME_BUTTON_CUSTOM_02
|
||||
#define PUMP_BUTTON_CENTER GAME_BUTTON_CUSTOM_03
|
||||
#define PUMP_BUTTON_DOWNLEFT GAME_BUTTON_CUSTOM_04
|
||||
#define PUMP_BUTTON_DOWNRIGHT GAME_BUTTON_CUSTOM_05
|
||||
#define PUMP_BUTTON_DOWNLEFT GAME_BUTTON_CUSTOM_04
|
||||
#define PUMP_BUTTON_DOWNRIGHT GAME_BUTTON_CUSTOM_05
|
||||
#define NUM_PUMP_BUTTONS GAME_BUTTON_CUSTOM_06
|
||||
|
||||
// kb7
|
||||
#define KB7_BUTTON_KEY1 GAME_BUTTON_CUSTOM_01
|
||||
#define KB7_BUTTON_KEY2 GAME_BUTTON_CUSTOM_02
|
||||
#define KB7_BUTTON_KEY3 GAME_BUTTON_CUSTOM_03
|
||||
@@ -84,23 +85,23 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
|
||||
#define KB7_BUTTON_KEY5 GAME_BUTTON_CUSTOM_05
|
||||
#define KB7_BUTTON_KEY6 GAME_BUTTON_CUSTOM_06
|
||||
#define NUM_KB7_BUTTONS GAME_BUTTON_CUSTOM_07
|
||||
|
||||
#define EZ2_BUTTON_FOOTUPLEFT GAME_BUTTON_CUSTOM_01
|
||||
#define EZ2_BUTTON_FOOTUPRIGHT GAME_BUTTON_CUSTOM_02
|
||||
// ez2(dancer)
|
||||
#define EZ2_BUTTON_FOOTUPLEFT GAME_BUTTON_CUSTOM_01
|
||||
#define EZ2_BUTTON_FOOTUPRIGHT GAME_BUTTON_CUSTOM_02
|
||||
#define EZ2_BUTTON_FOOTDOWN GAME_BUTTON_CUSTOM_03
|
||||
#define EZ2_BUTTON_HANDUPLEFT GAME_BUTTON_CUSTOM_04
|
||||
#define EZ2_BUTTON_HANDUPRIGHT GAME_BUTTON_CUSTOM_05
|
||||
#define EZ2_BUTTON_HANDLRLEFT GAME_BUTTON_CUSTOM_06
|
||||
#define EZ2_BUTTON_HANDLRRIGHT GAME_BUTTON_CUSTOM_07
|
||||
#define EZ2_BUTTON_HANDUPLEFT GAME_BUTTON_CUSTOM_04
|
||||
#define EZ2_BUTTON_HANDUPRIGHT GAME_BUTTON_CUSTOM_05
|
||||
#define EZ2_BUTTON_HANDLRLEFT GAME_BUTTON_CUSTOM_06
|
||||
#define EZ2_BUTTON_HANDLRRIGHT GAME_BUTTON_CUSTOM_07
|
||||
#define NUM_EZ2_BUTTONS GAME_BUTTON_CUSTOM_08
|
||||
|
||||
// para
|
||||
#define PARA_BUTTON_LEFT GAME_BUTTON_CUSTOM_01
|
||||
#define PARA_BUTTON_UPLEFT GAME_BUTTON_CUSTOM_02
|
||||
#define PARA_BUTTON_UP GAME_BUTTON_CUSTOM_03
|
||||
#define PARA_BUTTON_UPRIGHT GAME_BUTTON_CUSTOM_04
|
||||
#define PARA_BUTTON_RIGHT GAME_BUTTON_CUSTOM_05
|
||||
#define NUM_PARA_BUTTONS GAME_BUTTON_CUSTOM_06
|
||||
|
||||
// ds3ddx
|
||||
#define DS3DDX_BUTTON_HANDLEFT GAME_BUTTON_CUSTOM_01
|
||||
#define DS3DDX_BUTTON_FOOTDOWNLEFT GAME_BUTTON_CUSTOM_02
|
||||
#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_HANDRIGHT GAME_BUTTON_CUSTOM_08
|
||||
#define NUM_DS3DDX_BUTTONS GAME_BUTTON_CUSTOM_09
|
||||
|
||||
// beat
|
||||
#define BEAT_BUTTON_KEY1 GAME_BUTTON_CUSTOM_01
|
||||
#define BEAT_BUTTON_KEY2 GAME_BUTTON_CUSTOM_02
|
||||
#define BEAT_BUTTON_KEY3 GAME_BUTTON_CUSTOM_03
|
||||
@@ -118,37 +119,46 @@ GameButton StringToGameButton( const InputScheme* pInputs, const RString& s );
|
||||
#define BEAT_BUTTON_KEY5 GAME_BUTTON_CUSTOM_05
|
||||
#define BEAT_BUTTON_KEY6 GAME_BUTTON_CUSTOM_06
|
||||
#define BEAT_BUTTON_KEY7 GAME_BUTTON_CUSTOM_07
|
||||
#define BEAT_BUTTON_SCRATCHUP GAME_BUTTON_CUSTOM_08
|
||||
#define BEAT_BUTTON_SCRATCHDOWN GAME_BUTTON_CUSTOM_09
|
||||
#define BEAT_BUTTON_SCRATCHUP GAME_BUTTON_CUSTOM_08
|
||||
#define BEAT_BUTTON_SCRATCHDOWN GAME_BUTTON_CUSTOM_09
|
||||
#define NUM_BEAT_BUTTONS GAME_BUTTON_CUSTOM_10
|
||||
|
||||
// maniax
|
||||
#define MANIAX_BUTTON_HANDUPLEFT GAME_BUTTON_CUSTOM_01
|
||||
#define MANIAX_BUTTON_HANDUPRIGHT GAME_BUTTON_CUSTOM_02
|
||||
#define MANIAX_BUTTON_HANDLRLEFT GAME_BUTTON_CUSTOM_03
|
||||
#define MANIAX_BUTTON_HANDLRRIGHT GAME_BUTTON_CUSTOM_04
|
||||
#define NUM_MANIAX_BUTTONS GAME_BUTTON_CUSTOM_05
|
||||
|
||||
// techno
|
||||
#define TECHNO_BUTTON_LEFT GAME_BUTTON_CUSTOM_01
|
||||
#define TECHNO_BUTTON_RIGHT GAME_BUTTON_CUSTOM_02
|
||||
#define TECHNO_BUTTON_UP GAME_BUTTON_CUSTOM_03
|
||||
#define TECHNO_BUTTON_DOWN GAME_BUTTON_CUSTOM_04
|
||||
#define TECHNO_BUTTON_UPLEFT GAME_BUTTON_CUSTOM_05
|
||||
#define TECHNO_BUTTON_UPRIGHT GAME_BUTTON_CUSTOM_06
|
||||
#define TECHNO_BUTTON_CENTER GAME_BUTTON_CUSTOM_07
|
||||
#define TECHNO_BUTTON_DOWNLEFT GAME_BUTTON_CUSTOM_08
|
||||
#define TECHNO_BUTTON_DOWNRIGHT GAME_BUTTON_CUSTOM_09
|
||||
#define TECHNO_BUTTON_UPLEFT GAME_BUTTON_CUSTOM_05
|
||||
#define TECHNO_BUTTON_UPRIGHT GAME_BUTTON_CUSTOM_06
|
||||
#define TECHNO_BUTTON_CENTER GAME_BUTTON_CUSTOM_07
|
||||
#define TECHNO_BUTTON_DOWNLEFT GAME_BUTTON_CUSTOM_08
|
||||
#define TECHNO_BUTTON_DOWNRIGHT GAME_BUTTON_CUSTOM_09
|
||||
#define NUM_TECHNO_BUTTONS GAME_BUTTON_CUSTOM_10
|
||||
|
||||
// popn
|
||||
#define POPN_BUTTON_LEFT_WHITE GAME_BUTTON_CUSTOM_01
|
||||
#define POPN_BUTTON_LEFT_YELLOW GAME_BUTTON_CUSTOM_02
|
||||
#define POPN_BUTTON_LEFT_GREEN GAME_BUTTON_CUSTOM_03
|
||||
#define POPN_BUTTON_LEFT_BLUE GAME_BUTTON_CUSTOM_04
|
||||
#define POPN_BUTTON_RED GAME_BUTTON_CUSTOM_05
|
||||
#define POPN_BUTTON_RED GAME_BUTTON_CUSTOM_05
|
||||
#define POPN_BUTTON_RIGHT_BLUE GAME_BUTTON_CUSTOM_06
|
||||
#define POPN_BUTTON_RIGHT_GREEN GAME_BUTTON_CUSTOM_07
|
||||
#define POPN_BUTTON_RIGHT_YELLOW GAME_BUTTON_CUSTOM_08
|
||||
#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 NUM_KARAOKE_BUTTONS GAME_BUTTON_CUSTOM_02
|
||||
|
||||
+46
-20
@@ -2548,8 +2548,8 @@ static const Game g_Game_Popn =
|
||||
|
||||
/** 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 =
|
||||
{ // STYLE_GUITAR_FIVE
|
||||
true, // m_bUsedForGameplay
|
||||
@@ -2577,8 +2577,8 @@ static const Style g_Style_Guitar_Five =
|
||||
},
|
||||
},
|
||||
{ // m_iInputColumn[NUM_GameController][NUM_GameButton]
|
||||
{ 0, 4, 3, 2, 1, Style::END_MAPPING },
|
||||
{ 0, 4, 3, 2, 1, Style::END_MAPPING },
|
||||
{ 0, 1, 2, 3, 4, Style::END_MAPPING },
|
||||
{ 0, 1, 2, 3, 4, Style::END_MAPPING },
|
||||
},
|
||||
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
|
||||
0,1,2,3,4
|
||||
@@ -2595,39 +2595,64 @@ static const Style *g_apGame_Guitar_Styles[] =
|
||||
};
|
||||
|
||||
// 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 =
|
||||
{
|
||||
"guitar", // m_szName
|
||||
g_apGame_Guitar_Styles, // m_apStyles
|
||||
true, // m_bCountNotesSeparately
|
||||
false, // m_bCountNotesSeparately (false stops crashes and failing)
|
||||
true, // m_bAllowHopos
|
||||
{ // m_InputScheme
|
||||
"guitar", // m_szName
|
||||
NUM_GUITAR_BUTTONS, // m_iButtonsPerController
|
||||
{ // 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
|
||||
},
|
||||
{
|
||||
{ GameButtonType_Step },
|
||||
{ GameButtonType_Step },
|
||||
{ GameButtonType_Step },
|
||||
{ GameButtonType_Step },
|
||||
{ GameButtonType_Step },
|
||||
{ GameButtonType_Step },
|
||||
{ GameButtonType_Step },
|
||||
{ GameButtonType_Step },
|
||||
{ GameButtonType_Step },
|
||||
{ GameButtonType_Fret }, // Green
|
||||
{ GameButtonType_Fret }, // Red
|
||||
{ GameButtonType_Fret }, // Yellow
|
||||
{ GameButtonType_Fret }, // Blue
|
||||
{ GameButtonType_Fret }, // Orange
|
||||
{ GameButtonType_Strum },
|
||||
{ GameButtonType_Strum },
|
||||
},
|
||||
TNS_W1, // m_mapW1To
|
||||
TNS_W1, // m_mapW2To
|
||||
TNS_W1, // m_mapW3To
|
||||
TNS_W1, // m_mapW4To
|
||||
TNS_Miss, // m_mapW5To
|
||||
TNS_W2, // m_mapW2To
|
||||
TNS_W3, // m_mapW3To
|
||||
TNS_W4, // m_mapW4To
|
||||
TNS_W5, // m_mapW5To
|
||||
};
|
||||
*/
|
||||
|
||||
/** Karaoke ******************************************************************/
|
||||
|
||||
static const Style g_Style_Karaoke_Single =
|
||||
@@ -2813,6 +2838,7 @@ static const Game *g_Games[] =
|
||||
&g_Game_Maniax,
|
||||
&g_Game_Techno,
|
||||
&g_Game_Popn,
|
||||
//&g_Game_Guitar, // nope, still broken. -aj
|
||||
&g_Game_Karaoke,
|
||||
&g_Game_Lights,
|
||||
};
|
||||
|
||||
@@ -49,12 +49,12 @@ struct MusicPlaying
|
||||
bool m_bTimingDelayed;
|
||||
bool m_bHasTiming;
|
||||
bool m_bApplyMusicRate;
|
||||
/* The timing data that we're currently using. */
|
||||
// The timing data that we're currently using.
|
||||
TimingData m_Timing;
|
||||
NoteData m_Lights;
|
||||
|
||||
/* If m_bTimingDelayed is true, this will be the timing data for the song that's starting.
|
||||
* We'll copy it to m_Timing once sound is heard. */
|
||||
/* If m_bTimingDelayed is true, this will be the timing data for the
|
||||
* song that's starting. We'll copy it to m_Timing once sound is heard. */
|
||||
TimingData m_NewTiming;
|
||||
RageSound *m_Music;
|
||||
MusicPlaying( RageSound *Music )
|
||||
|
||||
+48
-9
@@ -205,7 +205,7 @@ void GameState::ApplyGameCommand( const RString &sCommand, PlayerNumber pn )
|
||||
|
||||
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;
|
||||
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 );
|
||||
}
|
||||
|
||||
//static Preference<bool> g_bMultiplayer( "Multiplayer", false );
|
||||
void GameState::Reset()
|
||||
{
|
||||
m_MasterPlayerNumber = PLAYER_INVALID; // must initialize for UnjoinPlayer
|
||||
@@ -346,7 +347,7 @@ void GameState::JoinPlayer( PlayerNumber pn )
|
||||
if( GetNumSidesJoined() == 1 )
|
||||
BeginGame();
|
||||
|
||||
/* Count each player join as a play. */
|
||||
// Count each player join as a play.
|
||||
{
|
||||
Profile* pMachineProfile = PROFILEMAN->GetMachineProfile();
|
||||
pMachineProfile->m_iTotalSessions++;
|
||||
@@ -889,11 +890,14 @@ void GameState::ResetMusicStatistics()
|
||||
//m_bStop = false;
|
||||
m_bFreeze = 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_fSongBeatVisible = 0;
|
||||
Actor::SetBGMTime( 0, 0, 0, 0 );
|
||||
|
||||
|
||||
FOREACH_PlayerNumber( p )
|
||||
m_pPlayerState[p]->ClearHopoState();
|
||||
}
|
||||
@@ -935,17 +939,35 @@ void GameState::ResetStageStatistics()
|
||||
}
|
||||
|
||||
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 ×tamp )
|
||||
{
|
||||
if( !timestamp.IsZero() )
|
||||
m_LastBeatUpdate = timestamp;
|
||||
else
|
||||
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 );
|
||||
// "Crash reason : -243478.890625 -48695.773438"
|
||||
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;
|
||||
/*
|
||||
// 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_fSongBeatNoOffset = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds );
|
||||
@@ -955,6 +977,25 @@ void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &ti
|
||||
bool 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 );
|
||||
// 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
|
||||
{
|
||||
/* 0 = first step; 1 = last step */
|
||||
// 0 = first step; 1 = last step
|
||||
return (beat - m_pCurSong->m_fFirstBeat) / m_pCurSong->m_fLastBeat;
|
||||
}
|
||||
|
||||
@@ -1482,7 +1523,7 @@ PlayerOptions::FailType GameState::GetPlayerFailType( const PlayerState *pPlayer
|
||||
if( !IsEventMode() )
|
||||
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 )
|
||||
setmax( ft, PlayerOptions::FAIL_IMMEDIATE_CONTINUE );
|
||||
|
||||
@@ -1535,11 +1576,9 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector<RankingFeat> &asFeatsOu
|
||||
|
||||
StepsType st = GetCurrentStyle()->m_StepsType;
|
||||
|
||||
//
|
||||
// Find unique Song and Steps combinations that were played.
|
||||
// We must keep only the unique combination or else we'll double-count
|
||||
// high score markers.
|
||||
//
|
||||
vector<SongAndSteps> vSongAndSteps;
|
||||
|
||||
for( unsigned i=0; i<STATSMAN->m_vPlayedStageStats.size(); i++ )
|
||||
@@ -2289,7 +2328,7 @@ public:
|
||||
ModsLevel m = Enum::Check<ModsLevel>( L, 1 );
|
||||
|
||||
SongOptions so;
|
||||
|
||||
|
||||
so.FromString( SArg(2) );
|
||||
p->m_SongOptions.Assign( m, so );
|
||||
return 0;
|
||||
@@ -2339,7 +2378,7 @@ public:
|
||||
{
|
||||
const Steps* pSteps = vpStepsToShow[i];
|
||||
RString sDifficulty = CustomDifficultyToLocalizedString( GetCustomDifficulty( pSteps->m_StepsType, pSteps->GetDifficulty(), CourseType_Invalid ) );
|
||||
|
||||
|
||||
lua_pushstring( L, sDifficulty );
|
||||
lua_pushstring( L, pSteps->GetDescription() );
|
||||
}
|
||||
|
||||
@@ -184,6 +184,7 @@ public:
|
||||
//bool m_bStop; // in the middle of a stop (freeze or delay)
|
||||
bool m_bFreeze; // in the middle of a freeze
|
||||
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
|
||||
BroadcastOnChange<bool> m_bGameplayLeadIn;
|
||||
|
||||
|
||||
@@ -174,9 +174,7 @@ void GraphDisplay::Set( const StageStats &ss, const PlayerStageStats &pss )
|
||||
|
||||
UpdateVerts();
|
||||
|
||||
//
|
||||
// Show song boundaries
|
||||
//
|
||||
float fSec = 0;
|
||||
FOREACH_CONST( Song*, ss.m_vpPossibleSongs, song )
|
||||
{
|
||||
@@ -193,9 +191,7 @@ void GraphDisplay::Set( const StageStats &ss, const PlayerStageStats &pss )
|
||||
|
||||
if( !pss.m_bFailed )
|
||||
{
|
||||
//
|
||||
// Search for the min life record to show "Just Barely!"
|
||||
//
|
||||
float fMinLifeSoFar = 1.0f;
|
||||
int iMinLifeSoFarAt = 0;
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@ public:
|
||||
void Load( RString sMetricsGroup );
|
||||
void Set( const StageStats &ss, const PlayerStageStats &s );
|
||||
|
||||
//
|
||||
// Lua
|
||||
//
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
|
||||
+2
-1
@@ -44,7 +44,7 @@ static SortOrder ForceAppropriateSort( PlayMode pm, SortOrder so )
|
||||
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 )
|
||||
{
|
||||
case SORT_ONI_COURSES:
|
||||
@@ -576,6 +576,7 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
|
||||
{
|
||||
if( SHOW_ROULETTE )
|
||||
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.
|
||||
bool bFoundAnySong = false;
|
||||
for( unsigned i=0; !bFoundAnySong && i < arrayWheelItemDatas.size(); i++ )
|
||||
|
||||
+11
-33
@@ -379,7 +379,7 @@ void NoteField::DrawAreaHighlight( int iStartBeat, int iEndBeat )
|
||||
m_rectAreaHighlight.Draw();
|
||||
}
|
||||
|
||||
|
||||
// todo: add DrawWarpAreaBG? -aj
|
||||
|
||||
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 )
|
||||
{
|
||||
//
|
||||
// Probe for last note to draw.
|
||||
// worst case is 0.25x + boost. Adjust search distance to
|
||||
// so that notes don't pop onto the screen.
|
||||
//
|
||||
float fSearchDistance = 10;
|
||||
float fLastBeatToDraw = GAMESTATE->m_fSongBeat+fSearchDistance;
|
||||
|
||||
@@ -518,9 +516,9 @@ float FindLastDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceB
|
||||
|
||||
if( bBoomerang && !bIsPastPeakYOffset )
|
||||
fLastBeatToDraw += fSearchDistance;
|
||||
else if( fYOffset > iDrawDistanceBeforeTargetsPixels ) // off screen
|
||||
else if( fYOffset > iDrawDistanceBeforeTargetsPixels ) // off screen
|
||||
fLastBeatToDraw -= fSearchDistance;
|
||||
else // on screen
|
||||
else // on screen
|
||||
fLastBeatToDraw += fSearchDistance;
|
||||
|
||||
fSearchDistance /= 2;
|
||||
@@ -547,7 +545,7 @@ void 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 );
|
||||
|
||||
ArrowEffects::Update();
|
||||
@@ -556,9 +554,7 @@ void NoteField::DrawPrimitives()
|
||||
|
||||
const PlayerOptions ¤t_po = m_pPlayerState->m_PlayerOptions.GetCurrent();
|
||||
|
||||
//
|
||||
// Adjust draw range depending on some effects
|
||||
//
|
||||
int iDrawDistanceAfterTargetsPixels = m_iDrawDistanceAfterTargetsPixels;
|
||||
// HACK: if boomerang and centered are on, then we want to draw much
|
||||
// earlier to that the notes don't pop on screen.
|
||||
@@ -567,11 +563,11 @@ void NoteField::DrawPrimitives()
|
||||
current_po.m_fAccels[PlayerOptions::ACCEL_BOOMERANG];
|
||||
iDrawDistanceAfterTargetsPixels += int(SCALE( fCenteredTimesBoomerang, 0.f, 1.f, 0.f, -SCREEN_HEIGHT/2 ));
|
||||
int iDrawDistanceBeforeTargetsPixels = m_iDrawDistanceBeforeTargetsPixels;
|
||||
|
||||
|
||||
float fDrawScale = 1;
|
||||
fDrawScale *= 1 + 0.5f * fabsf( current_po.m_fPerspectiveTilt );
|
||||
fDrawScale *= 1 + fabsf( current_po.m_fEffects[PlayerOptions::EFFECT_TINY] );
|
||||
|
||||
|
||||
iDrawDistanceAfterTargetsPixels = (int)(iDrawDistanceAfterTargetsPixels * fDrawScale);
|
||||
iDrawDistanceBeforeTargetsPixels = (int)(iDrawDistanceBeforeTargetsPixels * fDrawScale);
|
||||
|
||||
@@ -590,24 +586,18 @@ void NoteField::DrawPrimitives()
|
||||
|
||||
#define IS_ON_SCREEN( fBeat ) IsOnScreen( fBeat, 0, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels )
|
||||
|
||||
//
|
||||
// Draw board
|
||||
//
|
||||
if( SHOW_BOARD )
|
||||
{
|
||||
DrawBoard( iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels );
|
||||
}
|
||||
|
||||
//
|
||||
// Draw Receptors
|
||||
//
|
||||
{
|
||||
cur->m_ReceptorArrowRow.Draw();
|
||||
}
|
||||
|
||||
//
|
||||
// Draw beat bars
|
||||
//
|
||||
if( GAMESTATE->IsEditing() || SHOW_BEAT_BARS )
|
||||
{
|
||||
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
|
||||
const Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||
@@ -715,9 +705,7 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// BGChange text
|
||||
//
|
||||
switch( GAMESTATE->m_EditMode )
|
||||
{
|
||||
case EditMode_Home:
|
||||
@@ -783,9 +771,7 @@ void NoteField::DrawPrimitives()
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw marker bars
|
||||
//
|
||||
if( m_iBeginMarker != -1 && m_iEndMarker != -1 )
|
||||
{
|
||||
int iBegin = m_iBeginMarker;
|
||||
@@ -809,12 +795,9 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
float fSelectedRangeGlow = SCALE( RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f );
|
||||
|
||||
@@ -827,9 +810,7 @@ void NoteField::DrawPrimitives()
|
||||
|
||||
bool bAnyUpcomingInThisCol = false;
|
||||
|
||||
//
|
||||
// Draw all HoldNotes in this column (so that they appear under the tap notes)
|
||||
//
|
||||
{
|
||||
NoteData::TrackMap::const_iterator 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 notes from furthest to closest
|
||||
|
||||
@@ -909,7 +887,7 @@ void NoteField::DrawPrimitives()
|
||||
continue; // skip
|
||||
}
|
||||
|
||||
/* Don't draw hidden (fully judged) steps. */
|
||||
// Don't draw hidden (fully judged) steps.
|
||||
if( tn.result.bHidden )
|
||||
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) );
|
||||
|
||||
// See if there is a hold step that begins on this index. Only do this
|
||||
// if the note skin cares.
|
||||
// See if there is a hold step that begins on this index.
|
||||
// Only do this if the noteskin cares.
|
||||
bool bHoldNoteBeginsOnThisBeat = false;
|
||||
if( m_pCurDisplay->display[c].DrawHoldHeadForTapsOnSameRow() )
|
||||
{
|
||||
|
||||
+102
-23
@@ -38,11 +38,11 @@ static void LoadFromSMTokens(
|
||||
out.SetDescription( sDescription );
|
||||
out.SetDifficulty( DwiCompatibleStringToDifficulty(sDifficulty) );
|
||||
|
||||
// HACK: We used to store SMANIAC as Difficulty_Hard with special description.
|
||||
// HACK: We used to store SMANIAC as Difficulty_Hard with special description.
|
||||
// Now, it has its own Difficulty_Challenge
|
||||
if( sDescription.CompareNoCase("smaniac") == 0 )
|
||||
out.SetDifficulty( Difficulty_Challenge );
|
||||
// HACK: We used to store CHALLENGE as Difficulty_Hard with special description.
|
||||
// HACK: We used to store CHALLENGE as Difficulty_Hard with special description.
|
||||
// Now, it has its own Difficulty_Challenge
|
||||
if( sDescription.CompareNoCase("challenge") == 0 )
|
||||
out.SetDifficulty( Difficulty_Challenge );
|
||||
@@ -88,6 +88,9 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
out.m_fBeat0OffsetInSeconds = 0;
|
||||
out.m_BPMSegments.clear();
|
||||
out.m_StopSegments.clear();
|
||||
//out.m_WarpSegments.clear();
|
||||
|
||||
//vector<WarpSegment> arrayWarpsFromNegativeBPMs;
|
||||
|
||||
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 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 )
|
||||
{
|
||||
// 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) );
|
||||
}
|
||||
else
|
||||
@@ -257,11 +308,35 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
const float fWarpAt = StringToFloat( arrayWarpValues[0] );
|
||||
const float fWarpTo = StringToFloat( arrayWarpValues[1] );
|
||||
|
||||
WarpSegment new_seg( BeatToNoteRow(fWarpAt), BeatToNoteRow(fWarpTo) );
|
||||
if( fWarpAt > 0.0f && fWarpTo > 0.0f )
|
||||
{
|
||||
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 );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LOG->Trace( "Adding a warp segment: starts at %f, jumps to %f", new_seg.m_iStartRow, new_seg.m_iEndRow );
|
||||
|
||||
out.AddWarpSegment( new_seg );
|
||||
// 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" )
|
||||
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" )
|
||||
out.m_sLyricsFile = sParams[1];
|
||||
|
||||
@@ -463,6 +538,10 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache
|
||||
else if( sValueName=="SAMPLELENGTH" )
|
||||
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" )
|
||||
{
|
||||
// #DISPLAYBPM:[xxx][xxx:xxx]|[*];
|
||||
@@ -489,8 +568,8 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache
|
||||
// (Why was it removed?)
|
||||
else if(!stricmp(sParams[1],"ROULETTE"))
|
||||
out.m_SelectionDisplay = out.SHOW_ALWAYS;
|
||||
/* The following two cases are just fixes to make sure simfiles that used 3.9+ features
|
||||
* are not excluded here */
|
||||
/* The following two cases are just fixes to make sure simfiles that
|
||||
* used 3.9+ features are not excluded here */
|
||||
else if(!stricmp(sParams[1],"ES") || !stricmp(sParams[1],"OMES"))
|
||||
out.m_SelectionDisplay = out.SHOW_ALWAYS;
|
||||
else if( atoi(sParams[1]) > 0 )
|
||||
@@ -752,7 +831,7 @@ bool SMLoader::LoadFromDir( const RString &sPath, Song &out )
|
||||
|
||||
ASSERT( aFileNames.size() == 1 );
|
||||
/* We should have at least one; if we had none, we shouldn't have been
|
||||
* called to begin with. */
|
||||
* called to begin with. */
|
||||
//ASSERT( aFileNames.size() >= 1 );
|
||||
|
||||
return LoadFromSMFile( sPath + aFileNames[0], out );
|
||||
@@ -770,7 +849,7 @@ bool SMLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool b
|
||||
}
|
||||
|
||||
MsdFile msd;
|
||||
if( !msd.ReadFile( sEditFilePath, true ) ) // unescape
|
||||
if( !msd.ReadFile( sEditFilePath, true ) ) // unescape
|
||||
{
|
||||
LOG->UserLog( "Edit file", sEditFilePath, "couldn't be opened: %s", msd.GetError().c_str() );
|
||||
return false;
|
||||
@@ -782,7 +861,7 @@ bool SMLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool b
|
||||
bool SMLoader::LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot )
|
||||
{
|
||||
MsdFile msd;
|
||||
msd.ReadFromString( sBuffer, true ); // unescape
|
||||
msd.ReadFromString( sBuffer, true ); // unescape
|
||||
return LoadEditFromMsd( msd, sEditFilePath, slot, true );
|
||||
}
|
||||
|
||||
@@ -857,7 +936,7 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath
|
||||
}
|
||||
|
||||
pSong->AddSteps( pNewNotes );
|
||||
return true; // Only allow one Steps per edit file!
|
||||
return true; // Only allow one Steps per edit file!
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -884,8 +963,8 @@ void SMLoader::TidyUpData( Song &song, bool bFromCache )
|
||||
vector<BackgroundChange> &bg = song.GetBackgroundChanges(BACKGROUND_LAYER_1);
|
||||
if( !bg.empty() )
|
||||
{
|
||||
/* BGChanges have been sorted. On the odd chance that a BGChange exists
|
||||
* with a very high beat, search the whole list. */
|
||||
/* BGChanges have been sorted. On the odd chance that a BGChange exists
|
||||
* with a very high beat, search the whole list. */
|
||||
bool bHasNoSongBgTag = false;
|
||||
|
||||
for( unsigned i = 0; !bHasNoSongBgTag && i < bg.size(); ++i )
|
||||
@@ -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 we're loading cache, -nosongbg- should always be in there. We must
|
||||
* not call IsAFile(song.GetBackgroundPath()) when loading cache. */
|
||||
/* If we're loading cache, -nosongbg- should always be in there. We
|
||||
* must not call IsAFile(song.GetBackgroundPath()) when loading cache. */
|
||||
if( bFromCache )
|
||||
break;
|
||||
|
||||
/* If BGChanges already exist after the last beat, don't add the background
|
||||
* in the middle. */
|
||||
/* If BGChanges already exist after the last beat, don't add the
|
||||
* background in the middle. */
|
||||
if( !bg.empty() && bg.back().m_fStartBeat-0.0001f >= song.m_fLastBeat )
|
||||
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) )
|
||||
break;
|
||||
|
||||
|
||||
+21
-4
@@ -71,10 +71,11 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
f.PutLine( ssprintf("#LASTBEATHINT:%.3f;", out.m_fSpecifiedLastBeat) );
|
||||
|
||||
f.Write( "#SELECTABLE:" );
|
||||
switch(out.m_SelectionDisplay) {
|
||||
default: ASSERT(0); /* fallthrough */
|
||||
case Song::SHOW_ALWAYS: f.Write( "YES" ); break;
|
||||
case Song::SHOW_NEVER: f.Write( "NO" ); break;
|
||||
switch(out.m_SelectionDisplay)
|
||||
{
|
||||
default: ASSERT(0); // fall through
|
||||
case Song::SHOW_ALWAYS: f.Write( "YES" ); break;
|
||||
case Song::SHOW_NEVER: f.Write( "NO" ); break;
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
@@ -134,6 +135,22 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
}
|
||||
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() );
|
||||
f.Write( "#TIMESIGNATURES:" );
|
||||
FOREACH_CONST( TimeSignatureSegment, out.m_Timing.m_vTimeSignatureSegments, iter )
|
||||
|
||||
+6
-6
@@ -32,17 +32,17 @@ private:
|
||||
ThemeMetric<float> ITEMS_END_X;
|
||||
ThemeMetric<float> ITEMS_GAP_X;
|
||||
ThemeMetric<float> ITEMS_MIN_BASE_ZOOM;
|
||||
ThemeMetric1D<float> ITEMS_LONG_ROW_X;
|
||||
ThemeMetric1D<float> ITEMS_LONG_ROW_X;
|
||||
ThemeMetric<float> ITEMS_LONG_ROW_SHARED_X;
|
||||
ThemeMetric1D<float> MOD_ICON_X;
|
||||
ThemeMetric<RageColor> COLOR_SELECTED;
|
||||
ThemeMetric<RageColor> COLOR_NOT_SELECTED;
|
||||
ThemeMetric<RageColor> COLOR_DISABLED;
|
||||
ThemeMetric1D<float> MOD_ICON_X;
|
||||
ThemeMetric<RageColor> COLOR_SELECTED;
|
||||
ThemeMetric<RageColor> COLOR_NOT_SELECTED;
|
||||
ThemeMetric<RageColor> COLOR_DISABLED;
|
||||
ThemeMetric<float> TWEEN_SECONDS;
|
||||
ThemeMetric<bool> SHOW_BPM_IN_SPEED_TITLE;
|
||||
ThemeMetric<bool> SHOW_MOD_ICONS;
|
||||
ThemeMetric<bool> SHOW_UNDERLINES;
|
||||
ThemeMetric<RString> MOD_ICON_METRICS_GROUP;
|
||||
ThemeMetric<RString> MOD_ICON_METRICS_GROUP;
|
||||
|
||||
friend class OptionRow;
|
||||
};
|
||||
|
||||
+10
-6
@@ -25,6 +25,7 @@ static const char *PaneCategoryNames[] = {
|
||||
"Rolls",
|
||||
"Mines",
|
||||
"Hands",
|
||||
//"Lifts",
|
||||
"MachineHighScore",
|
||||
"MachineHighName",
|
||||
"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, "score" },
|
||||
{ NEED_NOTES, "name" },
|
||||
{ NEED_NOTES|NEED_PROFILE, "score" },
|
||||
@@ -112,7 +114,7 @@ void PaneDisplay::LoadFromNode( const XNode *pNode )
|
||||
void PaneDisplay::SetContent( PaneCategory c )
|
||||
{
|
||||
RString str = ""; // fill this in
|
||||
float val = 0; // fill this in
|
||||
float val = 0; // fill this in
|
||||
|
||||
const Song *pSong = GAMESTATE->m_pCurSong;
|
||||
const Steps *pSteps = GAMESTATE->m_pCurSteps[m_PlayerNumber];
|
||||
@@ -153,11 +155,12 @@ void PaneDisplay::SetContent( PaneCategory c )
|
||||
switch( c )
|
||||
{
|
||||
case PaneCategory_NumSteps: val = rv[RadarCategory_TapsAndHolds]; break;
|
||||
case PaneCategory_Jumps: val = rv[RadarCategory_Jumps]; break;
|
||||
case PaneCategory_Holds: val = rv[RadarCategory_Holds]; break;
|
||||
case PaneCategory_Rolls: val = rv[RadarCategory_Rolls]; break;
|
||||
case PaneCategory_Mines: val = rv[RadarCategory_Mines]; break;
|
||||
case PaneCategory_Hands: val = rv[RadarCategory_Hands]; break;
|
||||
case PaneCategory_Jumps: val = rv[RadarCategory_Jumps]; break;
|
||||
case PaneCategory_Holds: val = rv[RadarCategory_Holds]; break;
|
||||
case PaneCategory_Rolls: val = rv[RadarCategory_Rolls]; break;
|
||||
case PaneCategory_Mines: val = rv[RadarCategory_Mines]; break;
|
||||
case PaneCategory_Hands: val = rv[RadarCategory_Hands]; break;
|
||||
//case PaneCategory_Lifts: val = rv[RadarCategory_Lifts]; break;
|
||||
case PaneCategory_ProfileHighScore:
|
||||
case PaneCategory_MachineHighName: /* set val for color */
|
||||
case PaneCategory_MachineHighScore:
|
||||
@@ -196,6 +199,7 @@ void PaneDisplay::SetContent( PaneCategory c )
|
||||
case PaneCategory_Rolls:
|
||||
case PaneCategory_Mines:
|
||||
case PaneCategory_Hands:
|
||||
//case PaneCategory_Lifts:
|
||||
str = ssprintf( COUNT_FORMAT.GetValue(), val );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ enum PaneCategory
|
||||
PaneCategory_Rolls,
|
||||
PaneCategory_Mines,
|
||||
PaneCategory_Hands,
|
||||
//PaneCategory_Lifts,
|
||||
PaneCategory_MachineHighScore,
|
||||
PaneCategory_MachineHighName,
|
||||
PaneCategory_ProfileHighScore,
|
||||
|
||||
+1
-1
@@ -3019,7 +3019,7 @@ void Player::SetCombo( int iCombo, int iMisses )
|
||||
if( b1000Milestone )
|
||||
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) &&
|
||||
GAMESTATE->m_fMusicSeconds > GAMESTATE->m_pCurSong->m_fMusicLengthSeconds * PERCENT_UNTIL_COLOR_COMBO;
|
||||
|
||||
|
||||
@@ -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_CROSS], "Cross" );
|
||||
AddPart( AddTo, m_fScrolls[SCROLL_CENTERED], "Centered" );
|
||||
//AddPart( AddTo, m_fScrolls[SCROLL_X], "XMode" );
|
||||
|
||||
AddPart( AddTo, m_fDark, "Dark" );
|
||||
|
||||
@@ -327,6 +328,16 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
|
||||
SET_FLOAT( fTimeSpacing )
|
||||
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 == "boost" ) SET_FLOAT( fAccels[ACCEL_BOOST] )
|
||||
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 == "cross" ) SET_FLOAT( fScrolls[SCROLL_CROSS] )
|
||||
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 == "norolls" ) m_bTransforms[TRANSFORM_NOROLLS] = on;
|
||||
else if( sBit == "nomines" ) m_bTransforms[TRANSFORM_NOMINES] = on;
|
||||
|
||||
@@ -110,6 +110,7 @@ public:
|
||||
SCROLL_ALTERNATE,
|
||||
SCROLL_CROSS,
|
||||
SCROLL_CENTERED,
|
||||
//SCROLL_X,
|
||||
NUM_SCROLLS
|
||||
};
|
||||
enum ScoreDisplay {
|
||||
|
||||
+20
-22
@@ -117,8 +117,8 @@ void PlayerStageStats::AddStats( const PlayerStageStats& other )
|
||||
m_ComboList.push_back( newcombo );
|
||||
}
|
||||
|
||||
/* Merge identical combos. This normally only happens in course mode, when a combo
|
||||
* continues between songs. */
|
||||
/* Merge identical combos. This normally only happens in course mode, when
|
||||
* a combo continues between songs. */
|
||||
for( unsigned i=1; i<m_ComboList.size(); ++i )
|
||||
{
|
||||
Combo_t &prevcombo = m_ComboList[i-1];
|
||||
@@ -128,7 +128,7 @@ void PlayerStageStats::AddStats( const PlayerStageStats& other )
|
||||
if( fabsf(PrevComboEnd - ThisComboStart) > 0.001 )
|
||||
continue;
|
||||
|
||||
/* These are really the same combo. */
|
||||
// These are really the same combo.
|
||||
prevcombo.m_fSizeSeconds += combo.m_fSizeSeconds;
|
||||
prevcombo.m_cnt += combo.m_cnt;
|
||||
m_ComboList.erase( m_ComboList.begin()+i );
|
||||
@@ -222,7 +222,7 @@ float PlayerStageStats::MakePercentScore( int iActual, int iPossible )
|
||||
if( iActual == iPossible )
|
||||
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) );
|
||||
|
||||
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"
|
||||
|
||||
// TRICKY: printf will round, but we want to truncate. Otherwise, we may display a percent
|
||||
// score that's too high and doesn't match up with the calculated grade.
|
||||
// TRICKY: printf will round, but we want to truncate. therwise, we may display
|
||||
// a percent score that's too high and doesn't match up with the calculated grade.
|
||||
float fTruncInterval = powf( 0.1f, (float)iPercentTotalDigits-1 );
|
||||
|
||||
// TRICKY: ftruncf is rounding 1.0000000 to 0.99990004. Give a little boost to
|
||||
// fPercentDancePoints to correct for this.
|
||||
|
||||
// TRICKY: ftruncf is rounding 1.0000000 to 0.99990004. Give a little boost
|
||||
// to fPercentDancePoints to correct for this.
|
||||
fPercent += 0.000001f;
|
||||
|
||||
fPercent = ftruncf( fPercent, fTruncInterval );
|
||||
@@ -247,7 +247,7 @@ float PlayerStageStats::MakePercentScore( int iActual, int iPossible )
|
||||
RString PlayerStageStats::FormatPercentScore( float fPercentDancePoints )
|
||||
{
|
||||
int iPercentTotalDigits = 3 + CommonMetrics::PERCENT_SCORE_DECIMAL_PLACES; // "100" + "." + "00"
|
||||
|
||||
|
||||
RString s = ssprintf( "%*.*f%%", iPercentTotalDigits, (int)CommonMetrics::PERCENT_SCORE_DECIMAL_PLACES, fPercentDancePoints*100 );
|
||||
return s;
|
||||
}
|
||||
@@ -333,7 +333,7 @@ void PlayerStageStats::SetLifeRecordAt( float fLife, float fStepsSecond )
|
||||
// Don't save life stats in endless courses, or could run OOM in a few hours.
|
||||
if( GAMESTATE->m_pCurCourse && GAMESTATE->m_pCurCourse->IsEndless() )
|
||||
return;
|
||||
|
||||
|
||||
if( fStepsSecond < 0 )
|
||||
return;
|
||||
|
||||
@@ -346,13 +346,11 @@ void PlayerStageStats::SetLifeRecordAt( float fLife, float fStepsSecond )
|
||||
|
||||
MESSAGEMAN->Broadcast( Message_LifeMeterChangedP1 );
|
||||
|
||||
//
|
||||
// Memory optimization:
|
||||
// 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
|
||||
// earlier redundant records have already been removed.
|
||||
//
|
||||
map<float,float>::iterator C = m_fLifeRecord.end();
|
||||
--C;
|
||||
if( C == m_fLifeRecord.begin() ) // no earlier records left
|
||||
@@ -374,11 +372,11 @@ float PlayerStageStats::GetLifeRecordAt( float fStepsSecond ) const
|
||||
{
|
||||
if( m_fLifeRecord.empty() )
|
||||
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 );
|
||||
|
||||
/* 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() )
|
||||
--it;
|
||||
|
||||
@@ -390,22 +388,22 @@ float PlayerStageStats::GetLifeRecordLerpAt( float fStepsSecond ) const
|
||||
{
|
||||
if( m_fLifeRecord.empty() )
|
||||
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 );
|
||||
|
||||
/* 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;
|
||||
if( earlier != m_fLifeRecord.begin() )
|
||||
--earlier;
|
||||
|
||||
if( later == m_fLifeRecord.end() )
|
||||
return earlier->second;
|
||||
|
||||
|
||||
if( earlier->first == later->first ) // two samples from the same time. Don't divide by zero in SCALE
|
||||
return earlier->second;
|
||||
|
||||
/* earlier <= pos <= later */
|
||||
// earlier <= pos <= later
|
||||
return SCALE( fStepsSecond, earlier->first, later->first, earlier->second, later->second );
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ static const char *BannerCacheModeNames[] = {
|
||||
XToString( BannerCacheMode );
|
||||
StringToX( BannerCacheMode );
|
||||
LuaXType( BannerCacheMode );
|
||||
|
||||
/*
|
||||
static const char *BackgroundCacheModeNames[] = {
|
||||
"Off",
|
||||
"LowResPreload",
|
||||
@@ -92,7 +92,7 @@ static const char *BackgroundCacheModeNames[] = {
|
||||
XToString( BackgroundCacheMode );
|
||||
StringToX( BackgroundCacheMode );
|
||||
LuaXType( BackgroundCacheMode );
|
||||
|
||||
*/
|
||||
static const char *HighResolutionTexturesNames[] = {
|
||||
"Auto",
|
||||
"ForceOff",
|
||||
@@ -181,7 +181,7 @@ PrefsManager::PrefsManager() :
|
||||
m_bDelayedTextureDelete ( "DelayedTextureDelete", false ),
|
||||
m_bDelayedModelDelete ( "DelayedModelDelete", false ),
|
||||
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_bFastLoadAdditionalSongs ( "FastLoadAdditionalSongs", false ),
|
||||
|
||||
|
||||
+3
-1
@@ -66,6 +66,7 @@ enum BannerCacheMode
|
||||
NUM_BannerCacheMode,
|
||||
BannerCacheMode_Invalid
|
||||
};
|
||||
/*
|
||||
enum BackgroundCacheMode
|
||||
{
|
||||
BGCACHE_OFF,
|
||||
@@ -75,6 +76,7 @@ enum BackgroundCacheMode
|
||||
NUM_BackgroundCacheMode,
|
||||
BackgroundCacheMode_Invalid
|
||||
};
|
||||
*/
|
||||
enum HighResolutionTextures
|
||||
{
|
||||
HighResolutionTextures_Auto,
|
||||
@@ -167,7 +169,7 @@ public:
|
||||
Preference<bool> m_bDelayedTextureDelete;
|
||||
Preference<bool> m_bDelayedModelDelete;
|
||||
Preference<BannerCacheMode> m_BannerCache;
|
||||
Preference<BackgroundCacheMode> m_BackgroundCache;
|
||||
//Preference<BackgroundCacheMode> m_BackgroundCache;
|
||||
Preference<bool> m_bFastLoad;
|
||||
Preference<bool> m_bFastLoadAdditionalSongs;
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
* "v0.0": Final Releases
|
||||
*/
|
||||
#ifndef PRODUCT_VER_BARE
|
||||
#define PRODUCT_VER_BARE v1.0 beta 1
|
||||
#define PRODUCT_VER_BARE v1.0 beta 2
|
||||
#endif
|
||||
|
||||
// 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
@@ -5,9 +5,9 @@
|
||||
|
||||
; see ProductInfo.h for use descriptions
|
||||
!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_BITMAP "sm4"
|
||||
!define PRODUCT_BITMAP "ssc"
|
||||
|
||||
!define PRODUCT_URL "http://ssc.ajworld.net/sm-ssc/"
|
||||
!define UPDATES_URL "http://ssc.ajworld.net/sm-ssc/"
|
||||
|
||||
@@ -417,10 +417,8 @@ bool ProfileManager::CreateLocalProfile( RString sName, RString &sProfileIDOut )
|
||||
{
|
||||
ASSERT( !sName.empty() );
|
||||
|
||||
//
|
||||
// Find a directory directory name that's a number greater than all
|
||||
// existing numbers. This preserves the "order by create date".
|
||||
//
|
||||
int iMaxProfileNumber = -1;
|
||||
vector<RString> vs;
|
||||
GetLocalProfileIDs( vs );
|
||||
@@ -430,16 +428,12 @@ bool ProfileManager::CreateLocalProfile( RString sName, RString &sProfileIDOut )
|
||||
int iProfileNumber = iMaxProfileNumber + 1;
|
||||
RString sProfileID = ssprintf( "%08d", iProfileNumber );
|
||||
|
||||
//
|
||||
// Create the new profile.
|
||||
//
|
||||
Profile *pProfile = new Profile;
|
||||
pProfile->m_sDisplayName = sName;
|
||||
pProfile->m_sCharacterID = CHARMAN->GetRandomCharacter()->m_sCharacterID;
|
||||
|
||||
//
|
||||
// Save it to disk.
|
||||
//
|
||||
RString sProfileDir = LocalProfileIDToDir( sProfileID );
|
||||
if( !pProfile->SaveAllToDir(sProfileDir, PREFSMAN->m_bSignProfileData) )
|
||||
{
|
||||
@@ -500,7 +494,6 @@ bool ProfileManager::DeleteLocalProfile( RString sProfileID )
|
||||
if( (*i)->Get() == sProfileID )
|
||||
(*i)->Set( "" );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -510,8 +503,6 @@ bool ProfileManager::DeleteLocalProfile( RString sProfileID )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
LOG->Warn( "DeleteLocalProfile: ProfileID '%s' doesn't exist", sProfileID.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
+19
-19
@@ -174,10 +174,10 @@ void RageBitmapTexture::Create()
|
||||
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;
|
||||
|
||||
/* 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) )
|
||||
{
|
||||
pixfmt = PixelFormat_PAL;
|
||||
@@ -189,10 +189,10 @@ void RageBitmapTexture::Create()
|
||||
{
|
||||
case 16:
|
||||
{
|
||||
/* Bits of alpha in the source: */
|
||||
// Bits of alpha in the source:
|
||||
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 );
|
||||
|
||||
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) )
|
||||
{
|
||||
pixfmt = PixelFormat_RGBA8;
|
||||
@@ -222,14 +222,15 @@ void RageBitmapTexture::Create()
|
||||
pixfmt = PixelFormat_RGBA4;
|
||||
}
|
||||
|
||||
/* Dither if appropriate. XXX: This is a special case: don't bother dithering to
|
||||
* RGBA8888. 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
|
||||
/* Dither if appropriate.
|
||||
* XXX: This is a special case: don't bother dithering to RGBA8888.
|
||||
* 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. */
|
||||
if( actualID.bDither &&
|
||||
(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);
|
||||
RageSurface *dst = CreateSurface( pImg->w, pImg->h, pfd->bpp,
|
||||
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. Otherwise,
|
||||
// pixel/texel alignment will be off.
|
||||
//
|
||||
// Enforce frames in the image have even dimensions.
|
||||
// Otherwise, pixel/texel alignment will be off.
|
||||
int iDimensionMultiple = 2;
|
||||
|
||||
if( sHintString.find("doubleres") != string::npos )
|
||||
@@ -266,12 +265,12 @@ void RageBitmapTexture::Create()
|
||||
}
|
||||
|
||||
bool bRunCheck = true;
|
||||
|
||||
|
||||
// Don't check if the artist intentionally blanked the image by making it very tiny.
|
||||
if( this->GetSourceWidth()<=iDimensionMultiple || this->GetSourceHeight()<=iDimensionMultiple )
|
||||
bRunCheck = false;
|
||||
|
||||
// HACK: Don't check song graphics. Many of them are weird dimensions.
|
||||
|
||||
// HACK: Don't check song graphics. Many of them are weird dimensions.
|
||||
if( !TEXTUREMAN->GetOddDimensionWarning() )
|
||||
bRunCheck = false;
|
||||
|
||||
@@ -304,11 +303,12 @@ void RageBitmapTexture::Create()
|
||||
|
||||
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 );
|
||||
|
||||
/* if "doubleres" (high resolution) then we want the image to appear in-game with dimensions 1/2 of the source.
|
||||
* So, cut down the source dimension here after everythign above is finished operating with the real image
|
||||
/* if "doubleres" (high resolution) then we want the image to appear in-game
|
||||
* 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. */
|
||||
if( sHintString.find("doubleres") != string::npos )
|
||||
{
|
||||
|
||||
+32
-38
@@ -33,11 +33,11 @@ public:
|
||||
virtual void Allocate( const vector<msMesh> &vMeshes ) = 0; // allocate space
|
||||
virtual void Change( const vector<msMesh> &vMeshes ) = 0; // new data must be the same size as was passed to Set()
|
||||
virtual void Draw( int iMeshIndex ) const = 0;
|
||||
|
||||
|
||||
protected:
|
||||
size_t GetTotalVertices() const { if( m_vMeshInfo.empty() ) return 0; return m_vMeshInfo.back().iVertexStart + m_vMeshInfo.back().iVertexCount; }
|
||||
size_t GetTotalTriangles() const { if( m_vMeshInfo.empty() ) return 0; return m_vMeshInfo.back().iTriangleStart + m_vMeshInfo.back().iTriangleCount; }
|
||||
|
||||
|
||||
struct MeshInfo
|
||||
{
|
||||
int iVertexStart;
|
||||
@@ -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;
|
||||
|
||||
bool bWithDepthBuffer;
|
||||
@@ -150,10 +150,10 @@ struct RageTextureLock
|
||||
virtual ~RageTextureLock() { }
|
||||
|
||||
/* Given a surface with a format and no pixel data, lock the texture into the
|
||||
* surface. The data is write-only. */
|
||||
* surface. The data is write-only. */
|
||||
virtual void Lock( unsigned iTexHandle, RageSurface *pSurface ) = 0;
|
||||
|
||||
/* Unlock and update the texture. If bChanged is false, the texture update
|
||||
/* Unlock and update the texture. If bChanged is false, the texture update
|
||||
* may be omitted. */
|
||||
virtual void Unlock( RageSurface *pSurface, bool bChanged = true ) = 0;
|
||||
};
|
||||
@@ -184,22 +184,22 @@ public:
|
||||
// Return true if device was re-created and we need to reload textures.
|
||||
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 bool BeginFrame();
|
||||
virtual void EndFrame();
|
||||
virtual VideoModeParams GetActualVideoModeParams() const = 0;
|
||||
bool IsWindowed() const { return this->GetActualVideoModeParams().windowed; }
|
||||
|
||||
|
||||
virtual void SetBlendMode( BlendMode mode ) = 0;
|
||||
|
||||
virtual bool SupportsTextureFormat( PixelFormat pixfmt, bool realtime=false ) = 0;
|
||||
virtual bool SupportsThreadedRendering() { return false; }
|
||||
virtual bool SupportsPerVertexMatrixScale() = 0;
|
||||
|
||||
// If threaded rendering is supported, these will be called from the rendering
|
||||
// thread before and after rendering.
|
||||
// If threaded rendering is supported, these will be called from the
|
||||
// rendering thread before and after rendering.
|
||||
virtual void BeginConcurrentRenderingMainThread() { }
|
||||
virtual void EndConcurrentRenderingMainThread() { }
|
||||
virtual void BeginConcurrentRendering();
|
||||
@@ -208,8 +208,8 @@ public:
|
||||
/* return 0 if failed or internal texture resource handle
|
||||
* (unsigned in OpenGL, texture pointer in D3D) */
|
||||
virtual unsigned CreateTexture(
|
||||
PixelFormat pixfmt, // format of img and of texture in video mem
|
||||
RageSurface* img, // must be in pixfmt
|
||||
PixelFormat pixfmt, // format of img and of texture in video mem
|
||||
RageSurface* img, // must be in pixfmt
|
||||
bool bGenerateMipMaps
|
||||
) = 0;
|
||||
virtual void UpdateTexture(
|
||||
@@ -218,7 +218,7 @@ public:
|
||||
int xoffset, int yoffset, int width, int height
|
||||
) = 0;
|
||||
virtual void DeleteTexture( unsigned iTexHandle ) = 0;
|
||||
/* Return an object to lock pixels for streaming. If not supported, returns NULL.
|
||||
/* Return an object to lock pixels for streaming. If not supported, returns NULL.
|
||||
* Delete the object normally. */
|
||||
virtual RageTextureLock *CreateTextureLock() { return NULL; }
|
||||
virtual void ClearAllTextures() = 0;
|
||||
@@ -232,24 +232,22 @@ public:
|
||||
virtual bool IsEffectModeSupported( EffectMode effect ) { return effect == EffectMode_Normal; }
|
||||
|
||||
bool SupportsRenderToTexture() const { return false; }
|
||||
|
||||
/*
|
||||
* Create a render target, returning a texture handle. In addition to normal
|
||||
* texture functions, this can be passed to SetRenderTarget. Delete with
|
||||
* DeleteTexture. (UpdateTexture is not permitted.) Returns 0 if render-to-
|
||||
|
||||
/* Create a render target, returning a texture handle. In addition to normal
|
||||
* texture functions, this can be passed to SetRenderTarget. Delete with
|
||||
* DeleteTexture. (UpdateTexture is not permitted.) Returns 0 if render-to-
|
||||
* texture is unsupported.
|
||||
*/
|
||||
virtual unsigned CreateRenderTarget( const RenderTargetParam ¶m, int &iTextureWidthOut, int &iTextureHeightOut ) { return 0; }
|
||||
|
||||
/*
|
||||
* 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
|
||||
/* 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
|
||||
* 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 was false.
|
||||
*/
|
||||
virtual void SetRenderTarget( unsigned iHandle, bool bPreserveTexture = true ) { }
|
||||
|
||||
|
||||
virtual bool IsZTestEnabled() const = 0;
|
||||
virtual bool IsZWriteEnabled() const = 0;
|
||||
virtual void SetZWrite( bool b ) = 0;
|
||||
@@ -258,9 +256,9 @@ public:
|
||||
virtual void ClearZBuffer() = 0;
|
||||
|
||||
virtual void SetCullMode( CullMode mode ) = 0;
|
||||
|
||||
|
||||
virtual void SetAlphaTest( bool b ) = 0;
|
||||
|
||||
|
||||
virtual void SetMaterial(
|
||||
const RageColor &emissive,
|
||||
const RageColor &ambient,
|
||||
@@ -302,10 +300,10 @@ public:
|
||||
|
||||
enum GraphicsFileFormat
|
||||
{
|
||||
SAVE_LOSSLESS, // bmp
|
||||
SAVE_LOSSLESS_SENSIBLE, // png
|
||||
SAVE_LOSSY_LOW_QUAL, // jpg
|
||||
SAVE_LOSSY_HIGH_QUAL // jpg
|
||||
SAVE_LOSSLESS, // bmp
|
||||
SAVE_LOSSLESS_SENSIBLE, // png
|
||||
SAVE_LOSSY_LOW_QUAL, // jpg
|
||||
SAVE_LOSSY_HIGH_QUAL // jpg
|
||||
};
|
||||
bool SaveScreenshot( RString sPath, GraphicsFileFormat format );
|
||||
|
||||
@@ -335,16 +333,16 @@ protected:
|
||||
void SetDefaultRenderStates();
|
||||
|
||||
public:
|
||||
/* Statistics */
|
||||
// Statistics
|
||||
int GetFPS() 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 ProcessStatsOnFlip();
|
||||
virtual RString GetStats() const;
|
||||
void StatsAddVerts( int iNumVertsRendered );
|
||||
|
||||
/* World matrix stack functions. */
|
||||
// World matrix stack functions.
|
||||
void PushMatrix();
|
||||
void PopMatrix();
|
||||
void Translate( float x, float y, float z );
|
||||
@@ -360,19 +358,19 @@ public:
|
||||
void PreMultMatrix( const RageMatrix &f );
|
||||
void LoadIdentity();
|
||||
|
||||
/* Texture matrix functions */
|
||||
// Texture matrix functions
|
||||
void TexturePushMatrix();
|
||||
void TexturePopMatrix();
|
||||
void TextureTranslate( float x, float 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 CameraPopMatrix();
|
||||
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 );
|
||||
|
||||
/* Centering matrix */
|
||||
// Centering matrix
|
||||
void CenteringPushMatrix();
|
||||
void CenteringPopMatrix();
|
||||
void ChangeCentering( int trans_x, int trans_y, int add_width, int add_height );
|
||||
@@ -386,13 +384,11 @@ public:
|
||||
protected:
|
||||
RageMatrix GetPerspectiveMatrix( float fovy, float aspect, float zNear, float zFar );
|
||||
|
||||
// Different for D3D and OpenGL. Not sure why they're not compatible. -Chris
|
||||
// Different for D3D and OpenGL. Not sure why they're not compatible. -Chris
|
||||
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 );
|
||||
|
||||
//
|
||||
// Matrix that adjusts position and scale of image on the screen
|
||||
//
|
||||
RageMatrix GetCenteringMatrix( float fTranslateX, float fTranslateY, float fAddWidth, float fAddHeight ) const;
|
||||
void UpdateCentering();
|
||||
|
||||
@@ -403,10 +399,8 @@ protected:
|
||||
const RageMatrix* GetWorldTop() const;
|
||||
const RageMatrix* GetTextureTop() const;
|
||||
|
||||
//
|
||||
// To limit the framerate, call FrameLimitBeforeVsync before waiting
|
||||
// for vsync and FrameLimitAfterVsync after.
|
||||
//
|
||||
void FrameLimitBeforeVsync( int iFPS );
|
||||
void FrameLimitAfterVsync();
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@ RageFileObjInflate::RageFileObjInflate( RageFileBasic *pFile, int iUncompressedS
|
||||
decomp_buf_avail = 0;
|
||||
m_pInflate = new z_stream;
|
||||
memset( m_pInflate, 0, sizeof(z_stream) );
|
||||
|
||||
|
||||
m_iUncompressedSize = iUncompressedSize;
|
||||
|
||||
int err = inflateInit2( m_pInflate, -MAX_WBITS );
|
||||
|
||||
@@ -340,21 +340,19 @@ RageFileObjDirect::~RageFileObjDirect()
|
||||
if( !(m_iMode & RageFile::WRITE) || (m_iMode & RageFile::STREAMED) )
|
||||
return;
|
||||
|
||||
/* We now have path written to MakeTempFilename(m_sPath). Rename the temporary
|
||||
* file over the real path. */
|
||||
/* We now have path written to MakeTempFilename(m_sPath).
|
||||
* Rename the temporary file over the real path. */
|
||||
|
||||
do
|
||||
{
|
||||
if( bFailed || WriteFailed() )
|
||||
break;
|
||||
|
||||
/*
|
||||
* We now have path written to MakeTempFilename(m_sPath). Rename the temporary
|
||||
* file over the real path. This should be an atomic operation with a journalling
|
||||
* filesystem. That is, there should be no intermediate state a JFS might restore
|
||||
* the file we're writing (in the case of a crash/powerdown) to an empty or partial
|
||||
* file.
|
||||
*/
|
||||
/* We now have path written to MakeTempFilename(m_sPath). Rename the
|
||||
* temporary file over the real path. This should be an atomic operation
|
||||
* with a journalling filesystem. That is, there should be no
|
||||
* intermediate state a JFS might restore the file we're writing (in the
|
||||
* case of a crash/powerdown) to an empty or partial file. */
|
||||
|
||||
RString sOldPath = MakeTempFilename(m_sPath);
|
||||
RString sNewPath = m_sPath;
|
||||
@@ -389,12 +387,12 @@ RageFileObjDirect::~RageFileObjDirect()
|
||||
}
|
||||
}
|
||||
|
||||
/* Success. */
|
||||
// Success.
|
||||
return;
|
||||
#endif
|
||||
} 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) );
|
||||
}
|
||||
|
||||
@@ -410,7 +408,7 @@ int RageFileObjDirect::ReadInternal( void *pBuf, size_t iBytes )
|
||||
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 )
|
||||
{
|
||||
int iTries = 3, iRet;
|
||||
@@ -443,7 +441,7 @@ int RageFileObjDirect::WriteInternal( const void *pBuf, size_t iBytes )
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The buffer is cleared. If we still don't have space, it's bigger than
|
||||
/* The buffer is cleared. If we still don't have space, it's bigger than
|
||||
* the buffer size, so just write it directly. */
|
||||
int iRet = RetriedWrite( m_iFD, pBuf, iBytes );
|
||||
if( iRet == -1 )
|
||||
|
||||
+7
-10
@@ -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
|
||||
* 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);
|
||||
|
||||
/* If m_bDeleteWhenFinished, then nobody that has a reference to the sound should
|
||||
* be making copies. */
|
||||
/* If m_bDeleteWhenFinished, then nobody that has a reference to the sound
|
||||
* should be making copies. */
|
||||
ASSERT( !cpy.m_bDeleteWhenFinished );
|
||||
|
||||
m_Param = cpy.m_Param;
|
||||
@@ -126,8 +125,8 @@ void RageSound::Unload()
|
||||
m_sFilePath = "";
|
||||
}
|
||||
|
||||
/* The sound will self-delete itself when it stops playing. If the sound is not
|
||||
* playing, the sound will be deleted immediately. The caller loses ownership
|
||||
/* The sound will self-delete itself when it stops playing. If the sound is not
|
||||
* playing, the sound will be deleted immediately. The caller loses ownership
|
||||
* of the sound. */
|
||||
void RageSound::DeleteSelfWhenFinishedPlaying()
|
||||
{
|
||||
@@ -454,7 +453,6 @@ bool RageSound::Pause( bool bPause )
|
||||
|
||||
return SOUNDMAN->Pause( this, bPause );
|
||||
}
|
||||
|
||||
|
||||
float RageSound::GetLengthSeconds()
|
||||
{
|
||||
@@ -472,7 +470,7 @@ float RageSound::GetLengthSeconds()
|
||||
return -1;
|
||||
}
|
||||
|
||||
return iLength / 1000.f; /* ms -> secs */
|
||||
return iLength / 1000.f; // ms -> secs
|
||||
}
|
||||
|
||||
int RageSound::GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bApproximate ) const
|
||||
@@ -490,8 +488,7 @@ int RageSound::GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bA
|
||||
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.
|
||||
*
|
||||
* If non-NULL, Timestamp is set to the real clock time associated with the returned sound
|
||||
|
||||
+25
-31
@@ -28,30 +28,29 @@ struct RageSoundParams
|
||||
{
|
||||
RageSoundParams();
|
||||
|
||||
/* The amount of data to play (or loop): */
|
||||
// The amount of data to play (or loop):
|
||||
float m_StartSecond;
|
||||
float m_LengthSeconds;
|
||||
|
||||
/* Number of seconds to spend fading in. */
|
||||
// Number of seconds to spend fading in.
|
||||
float m_fFadeInSeconds;
|
||||
|
||||
/* Number of seconds to spend fading out. */
|
||||
// Number of seconds to spend fading out.
|
||||
float m_fFadeOutSeconds;
|
||||
|
||||
float m_Volume; // multiplies with SOUNDMAN->GetMixVolume()
|
||||
float m_fAttractVolume; // multiplies with m_Volume
|
||||
|
||||
/* Number of samples input and output when changing speed. Currently,
|
||||
* this is either 1/1, 5/4 or 4/5. */
|
||||
/* Number of samples input and output when changing speed.
|
||||
* Currently, this is either 1/1, 5/4 or 4/5. */
|
||||
float m_fPitch;
|
||||
float m_fSpeed;
|
||||
|
||||
/* Optional driver feature: time to actually start playing sounds. If zero, or if not
|
||||
* supported, the sound will start immediately. */
|
||||
/* Optional driver feature: time to actually start playing sounds.
|
||||
* If zero, or if not supported, the sound will start immediately. */
|
||||
RageTimer m_StartTime;
|
||||
|
||||
/*
|
||||
* M_STOP stops the sound at the end.
|
||||
/* M_STOP stops the sound at the end.
|
||||
* M_LOOP restarts.
|
||||
* M_CONTINUE feeds silence, which is useful to continue timing longer than the actual sound.
|
||||
* M_AUTO (default) stops, obeying filename hints.
|
||||
@@ -63,7 +62,7 @@ struct RageSoundParams
|
||||
M_AUTO
|
||||
} StopMode;
|
||||
|
||||
bool m_bIsCriticalSound; // "is a sound that should be played even during attract"
|
||||
bool m_bIsCriticalSound; // "is a sound that should be played even during attract"
|
||||
};
|
||||
|
||||
struct RageSoundLoadParams
|
||||
@@ -74,7 +73,7 @@ struct RageSoundLoadParams
|
||||
* small memory penalty if not used. */
|
||||
bool m_bSupportRateChanging;
|
||||
|
||||
/* If true, panning will be supported for this sound. */
|
||||
// If true, panning will be supported for this sound.
|
||||
bool m_bSupportPan;
|
||||
};
|
||||
|
||||
@@ -86,8 +85,7 @@ public:
|
||||
RageSound( 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
|
||||
* can be played without much performance penalty. This is useful for
|
||||
* efficiently playing keyed sounds, and for rapidly-repeating sound
|
||||
@@ -103,17 +101,15 @@ public:
|
||||
*/
|
||||
bool Load( RString sFile, bool bPrecache, const RageSoundLoadParams *pParams = NULL );
|
||||
|
||||
/*
|
||||
* Using this version means the "don't care" about caching. Currently,
|
||||
* this always will not cache the sound; this may become a preference.
|
||||
*/
|
||||
/* Using this version means the "don't care" about caching. Currently,
|
||||
* this always will not cache the sound; this may become a preference. */
|
||||
bool Load( RString sFile );
|
||||
|
||||
/* Load a RageSoundReader that you've set up yourself. Sample rate conversion will
|
||||
* be set up only if needed. Doesn't fail. */
|
||||
/* Load a RageSoundReader that you've set up yourself. Sample rate conversion
|
||||
* will be set up only if needed. Doesn't fail. */
|
||||
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; }
|
||||
|
||||
void Unload();
|
||||
@@ -129,7 +125,7 @@ public:
|
||||
void PlayCopy( const RageSoundParams *pParams = NULL ) const;
|
||||
void Stop();
|
||||
|
||||
/* Cleanly pause or unpause the sound. If the sound wasn't already playing,
|
||||
/* Cleanly pause or unpause the sound. If the sound wasn't already playing,
|
||||
* return true and do nothing. */
|
||||
bool Pause( bool bPause );
|
||||
|
||||
@@ -145,9 +141,7 @@ public:
|
||||
bool SetProperty( const RString &sProperty, float fValue );
|
||||
void SetStopModeFromString( const RString &sStopMode );
|
||||
|
||||
//
|
||||
// Lua
|
||||
//
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
@@ -155,7 +149,7 @@ private:
|
||||
|
||||
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_StreamToSourceMap;
|
||||
|
||||
@@ -164,7 +158,7 @@ private:
|
||||
void ApplyParams();
|
||||
RageSoundParams m_Param;
|
||||
|
||||
/* Current position of the output sound, in frames. If < 0, nothing will play
|
||||
/* Current position of the output sound, in frames. If < 0, nothing will play
|
||||
* until it becomes positive. */
|
||||
int64_t m_iStreamFrame;
|
||||
|
||||
@@ -183,17 +177,17 @@ private:
|
||||
int GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bApproximate = NULL ) const;
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
* signals the stream to stop; once it's flushed, SoundStopped will be called.
|
||||
* Until then, SOUNDMAN->GetPosition can still be called; the sound is still
|
||||
* playing. */
|
||||
/* Returns the number of bytes actually put into pBuffer. If 0 is returned,
|
||||
* it signals the stream to stop; once it's flushed, SoundStopped will be
|
||||
* called. Until then, SOUNDMAN->GetPosition can still be called; the sound
|
||||
* is still playing. */
|
||||
int GetDataToPlay( float *pBuffer, int iSize, int64_t &iStreamFrame, int &iBytesRead );
|
||||
void CommitPlayingPosition( int64_t iHardwareFrame, int64_t iStreamFrame, int iGotFrames );
|
||||
};
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
|
||||
#define DitherMatDim 4
|
||||
|
||||
|
||||
/* Fractions, 0/16 to 15/16: */
|
||||
// Fractions, 0/16 to 15/16:
|
||||
static const int DitherMat[DitherMatDim][DitherMatDim] =
|
||||
{
|
||||
{ 0, 8, 2, 10 },
|
||||
@@ -18,10 +17,10 @@ static const int DitherMat[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)
|
||||
{
|
||||
/* 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;
|
||||
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
|
||||
* 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;
|
||||
|
||||
/* Add bias. */
|
||||
|
||||
// Add bias.
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -64,45 +63,45 @@ void RageSurfaceUtils::OrderedDither( const RageSurface *src, RageSurface *dst )
|
||||
DitherMatCalc_initted = true;
|
||||
}
|
||||
|
||||
/* We can't dither to paletted surfaces. */
|
||||
// We can't dither to paletted surfaces.
|
||||
ASSERT( dst->format->BytesPerPixel > 1 );
|
||||
|
||||
uint32_t src_cbits[4], dst_cbits[4];
|
||||
RageSurfaceUtils::GetBitsPerChannel( src->format, src_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];
|
||||
for( int i = 0; i < 4; ++i )
|
||||
{
|
||||
int MaxInputIntensity = (1 << src_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 )
|
||||
conv[i] = 0;
|
||||
else
|
||||
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);
|
||||
|
||||
/* For each row: */
|
||||
// For each row:
|
||||
for( int row = 0; row < src->h; ++row )
|
||||
{
|
||||
const uint8_t *srcp = src->pixels + row * src->pitch;
|
||||
uint8_t *dstp = dst->pixels + row * dst->pitch;
|
||||
|
||||
/* For each pixel: */
|
||||
// For each pixel:
|
||||
for( int col = 0; col < src->w; ++col )
|
||||
{
|
||||
uint8_t colors[4];
|
||||
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 )
|
||||
{
|
||||
/* If the destination has less bits, dither: */
|
||||
// If the destination has less bits, dither:
|
||||
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;
|
||||
} else {
|
||||
/* Same as DitherPixel, except it doesn't actually dither; dithering
|
||||
* looks bad on the alpha channel. */
|
||||
/* Same as DitherPixel, except it doesn't actually dither;
|
||||
* dithering looks bad on the alpha channel. */
|
||||
int out_intensity = colors[3] * conv[3];
|
||||
|
||||
/* Round: */
|
||||
// Round:
|
||||
colors[3] = uint8_t((out_intensity + 32767) >> 16);
|
||||
}
|
||||
|
||||
/* Raw value -> int -> pixel */
|
||||
// Raw value -> int -> pixel
|
||||
RageSurfaceUtils::SetRawRGBAV(dstp, dst, colors);
|
||||
|
||||
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 )
|
||||
{
|
||||
/* Convert the number to the destination range. */
|
||||
// Convert the number to the destination range.
|
||||
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;
|
||||
|
||||
/* Add bias. */
|
||||
|
||||
// Add bias.
|
||||
out_intensity += accumError;
|
||||
|
||||
/* 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 );
|
||||
clamped_intensity &= 0xFF0000;
|
||||
|
||||
/* Truncate. */
|
||||
// Truncate.
|
||||
uint8_t ret = uint8_t(clamped_intensity >> 16);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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 )
|
||||
{
|
||||
/* We can't dither to paletted surfaces. */
|
||||
// We can't dither to paletted surfaces.
|
||||
ASSERT( dst->format->BytesPerPixel > 1 );
|
||||
|
||||
uint32_t src_cbits[4], dst_cbits[4];
|
||||
RageSurfaceUtils::GetBitsPerChannel( src->format, src_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];
|
||||
for( int i = 0; i < 4; ++i )
|
||||
{
|
||||
int MaxInputIntensity = (1 << src_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 )
|
||||
conv[i] = 0;
|
||||
else
|
||||
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);
|
||||
|
||||
/* For each row: */
|
||||
// For each row:
|
||||
for(int row = 0; row < src->h; ++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;
|
||||
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 )
|
||||
{
|
||||
uint8_t colors[4];
|
||||
@@ -219,11 +216,11 @@ void RageSurfaceUtils::ErrorDiffusionDither( const RageSurface *src, RageSurface
|
||||
{
|
||||
colors[3] = alpha_max;
|
||||
} else {
|
||||
/* Same as DitherPixel, except it doesn't actually dither; dithering
|
||||
* looks bad on the alpha channel. */
|
||||
/* Same as DitherPixel, except it doesn't actually dither;
|
||||
* dithering looks bad on the alpha channel. */
|
||||
int out_intensity = colors[3] * conv[3];
|
||||
|
||||
/* Round: */
|
||||
|
||||
// Round:
|
||||
colors[3] = uint8_t((out_intensity + 32767) >> 16);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,20 +106,18 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
|
||||
acolorhist_item *acolormap=NULL;
|
||||
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,
|
||||
Swap32BE(0xFF000000), Swap32BE(0x00FF0000), Swap32BE(0x0000FF00), Swap32BE(0x000000FF));
|
||||
|
||||
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
|
||||
* 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.
|
||||
* [GRR POSSIBLE BUG: what about 32^4 ?]
|
||||
*/
|
||||
* [GRR POSSIBLE BUG: what about 32^4 ?] */
|
||||
acolorhist_item *achv;
|
||||
int colors;
|
||||
while(1)
|
||||
@@ -143,7 +141,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
|
||||
}
|
||||
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 );
|
||||
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 );
|
||||
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;
|
||||
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
|
||||
= (PAM_GETR(acolormap[x].acolor)*255 + (maxval >> 1)) / maxval;
|
||||
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;
|
||||
|
||||
bool fs_direction = 0;
|
||||
@@ -176,7 +174,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
|
||||
|
||||
if( bDither )
|
||||
{
|
||||
/* Initialize Floyd-Steinberg error vectors. */
|
||||
// Initialize Floyd-Steinberg error vectors.
|
||||
thiserr = 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] };
|
||||
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 )
|
||||
{
|
||||
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] );
|
||||
}
|
||||
|
||||
/* 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 );
|
||||
if( ind == -1 )
|
||||
{
|
||||
/* No; search acolormap for closest match. */
|
||||
// No; search acolormap for closest match.
|
||||
static int square_table[512], *pSquareTable = NULL;
|
||||
if( pSquareTable == NULL )
|
||||
{
|
||||
@@ -255,7 +253,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
|
||||
|
||||
if( bDither )
|
||||
{
|
||||
/* Propagate Floyd-Steinberg error terms. */
|
||||
// Propagate Floyd-Steinberg error terms.
|
||||
if( !fs_direction )
|
||||
{
|
||||
for( int c = 0; c < 4; ++c )
|
||||
@@ -307,13 +305,9 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither
|
||||
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
|
||||
* Display," SIGGRAPH 1982 Proceedings, page 297.
|
||||
*/
|
||||
* Display," SIGGRAPH 1982 Proceedings, page 297. */
|
||||
|
||||
typedef struct box *box_vector;
|
||||
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 )
|
||||
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].colors = colors;
|
||||
bv[0].sum = sum;
|
||||
boxes = 1;
|
||||
|
||||
/* Main loop: split boxes until we have enough. */
|
||||
// Main loop: split boxes until we have enough.
|
||||
while( boxes < newcolors )
|
||||
{
|
||||
int indx, clrs;
|
||||
int sm;
|
||||
int halfsum, lowersum;
|
||||
|
||||
/* Find the first splittable box. */
|
||||
// Find the first splittable box.
|
||||
int bi;
|
||||
for( bi = 0; bi < boxes; ++bi )
|
||||
if ( bv[bi].colors >= 2 )
|
||||
break;
|
||||
if( bi == boxes )
|
||||
break; /* ran out of colors! */
|
||||
break; // ran out of colors!
|
||||
indx = bv[bi].ind;
|
||||
clrs = bv[bi].colors;
|
||||
sm = bv[bi].sum;
|
||||
|
||||
/*
|
||||
* Go through the box finding the minimum and maximum of each
|
||||
* component - the boundaries of the box.
|
||||
*/
|
||||
/* Go through the box finding the minimum and maximum of each
|
||||
* component - the boundaries of the box. */
|
||||
int mins[4], maxs[4];
|
||||
mins[0] = maxs[0] = achv[indx].acolor[0];
|
||||
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 );
|
||||
}
|
||||
|
||||
/* Find the largest dimension, and sort by that component. */
|
||||
// Find the largest dimension, and sort by that component.
|
||||
{
|
||||
int iMax = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now find the median based on the counts, so that about half the
|
||||
* pixels (not colors, pixels) are in each subdivision.
|
||||
*/
|
||||
/* Now find the median based on the counts, so that about half the
|
||||
* pixels (not colors, pixels) are in each subdivision. */
|
||||
lowersum = achv[indx].value;
|
||||
halfsum = sm / 2;
|
||||
int j;
|
||||
@@ -423,7 +413,7 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
|
||||
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].sum = lowersum;
|
||||
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 );
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
/* 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.
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* the beginning of this source file.
|
||||
*/
|
||||
* the beginning of this source file. */
|
||||
for( int bi = 0; bi < boxes; ++bi )
|
||||
{
|
||||
#ifdef REP_AVERAGE_COLORS
|
||||
@@ -462,7 +450,7 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
|
||||
b = b / clrs;
|
||||
a = a / clrs;
|
||||
PAM_ASSIGN( acolormap[bi].acolor, r, g, b, a );
|
||||
#endif /*REP_AVERAGE_COLORS*/
|
||||
#endif // REP_AVERAGE_COLORS
|
||||
#ifdef REP_AVERAGE_PIXELS
|
||||
int indx = bv[bi].ind;
|
||||
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 = min( a, (long) maxval );
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -520,7 +508,7 @@ static bool pam_computeacolorhash( const RageSurface *src, int maxacolors, int*
|
||||
|
||||
*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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
/* 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) );
|
||||
ASSERT( achv != NULL );
|
||||
|
||||
/* Loop through the hash table. */
|
||||
// Loop through the hash table.
|
||||
int j = 0;
|
||||
for( unsigned i = 0; i < HASH_SIZE; ++i )
|
||||
{
|
||||
for ( acolorhist_list achl = acht.hash[i]; achl != NULL; achl = achl->next )
|
||||
{
|
||||
/* Add the new entry. */
|
||||
// Add the new entry.
|
||||
achv[j] = achl->ch;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
||||
/* All done. */
|
||||
// All done.
|
||||
return achv;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,12 @@
|
||||
#include <vector>
|
||||
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
|
||||
* square of pixels.
|
||||
*
|
||||
* (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 )
|
||||
{
|
||||
@@ -35,7 +33,7 @@ static void InitVectors( vector<int> &s0, vector<int> &s1, vector<uint32_t> &per
|
||||
* either pixel. */
|
||||
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));
|
||||
s1.push_back(int(sax+xstep));
|
||||
|
||||
@@ -47,7 +45,7 @@ static void InitVectors( vector<int> &s0, vector<int> &s1, vector<uint32_t> &per
|
||||
} else {
|
||||
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;
|
||||
|
||||
/* 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
|
||||
{
|
||||
/*
|
||||
* Fencepost: If we have source:
|
||||
/* Fencepost: If we have source:
|
||||
* abcd
|
||||
* and dest:
|
||||
* xyz
|
||||
* 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
|
||||
* resize.)
|
||||
*/
|
||||
* resize.) */
|
||||
float sx = float(src-1) / (dst-1);
|
||||
for( int x = 0; x < dst; 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));
|
||||
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( 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 int height = dst->h;
|
||||
const int width = dst->w;
|
||||
@@ -107,7 +103,7 @@ static void ZoomSurface( const RageSurface * src, RageSurface * dst )
|
||||
|
||||
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 *c01 = csp + esx1[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;
|
||||
|
||||
/* Advance destination pointer. */
|
||||
// Advance destination pointer.
|
||||
++dp;
|
||||
}
|
||||
}
|
||||
@@ -145,7 +141,7 @@ void RageSurfaceUtils::Zoom( RageSurface *&src, int dstwidth, int dstheight )
|
||||
if( src->w == dstwidth && src->h == dstheight )
|
||||
return;
|
||||
|
||||
/* resize currently only does RGBA8888 */
|
||||
// resize currently only does RGBA8888
|
||||
if( src->fmt.BytesPerPixel != 4 )
|
||||
{
|
||||
RageSurfaceUtils::ConvertSurface( src, src->w, src->h, 32,
|
||||
@@ -158,7 +154,7 @@ void RageSurfaceUtils::Zoom( RageSurface *&src, int dstwidth, int dstheight )
|
||||
float yscale = float(dstheight)/src->h;
|
||||
|
||||
/* Our filter is a simple linear filter, so it can't scale to less than
|
||||
* 1:2 or more than 2:1 very well. If we need to go beyond that, do it
|
||||
* 1:2 or more than 2:1 very well. If we need to go beyond that, do it
|
||||
* iteratively. */
|
||||
xscale = clamp( xscale, .5f, 2.0f );
|
||||
yscale = clamp( yscale, .5f, 2.0f );
|
||||
|
||||
@@ -29,9 +29,7 @@ void RageTexture::CreateFrameRects()
|
||||
{
|
||||
GetFrameDimensionsFromFileName( GetID().filename, &m_iFramesWide, &m_iFramesHigh );
|
||||
|
||||
//
|
||||
// Fill in the m_FrameRects with the bounds of each frame in the animation.
|
||||
//
|
||||
m_TextureCoordRects.clear();
|
||||
|
||||
for( int j=0; j<m_iFramesHigh; j++ ) // traverse along Y
|
||||
|
||||
+4
-6
@@ -41,7 +41,7 @@ public:
|
||||
int GetImageFrameWidth() const {return GetImageWidth() / GetFramesWide();}
|
||||
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 GetImageToTexCoordsRatioX() const { return 1.0f / GetTextureWidth(); }
|
||||
float GetSourceToTexCoordsRatioX() const { return GetSourceToImageCoordsRatioX() * GetImageToTexCoordsRatioX(); }
|
||||
@@ -52,25 +52,23 @@ public:
|
||||
const RectF *GetTextureCoordRect( int frameNo ) const;
|
||||
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; }
|
||||
RageTextureID::TexPolicy &GetPolicy() { return m_ID.Policy; }
|
||||
int m_iRefCount;
|
||||
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; }
|
||||
|
||||
static void GetFrameDimensionsFromFileName( RString sPath, int* puFramesWide, int* puFramesHigh );
|
||||
|
||||
//
|
||||
// Lua
|
||||
//
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
/* We might change settings when loading (due to hints, hardware
|
||||
* limitations, etc). The data actually loaded is here: */
|
||||
* limitations, etc). The data actually loaded is here: */
|
||||
RageTextureID m_ID;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -11,7 +11,7 @@ void RageTextureID::Init()
|
||||
iGrayscaleBits = -1;
|
||||
bDither = false;
|
||||
bStretch = false;
|
||||
iColorDepth = -1; /* default */
|
||||
iColorDepth = -1; // default
|
||||
bHotPinkColorKey = false;
|
||||
AdditionalTextureHints = "";
|
||||
Policy = TEXTUREMAN->GetDefaultTexturePolicy();
|
||||
|
||||
+15
-15
@@ -10,11 +10,11 @@
|
||||
struct RageTextureID
|
||||
{
|
||||
RString filename;
|
||||
|
||||
/* Maximum size of the texture, per dimension. */
|
||||
|
||||
// Maximum size of the texture, per dimension.
|
||||
int iMaxSize;
|
||||
|
||||
/* Generate mipmaps for this texture */
|
||||
// Generate mipmaps for this texture
|
||||
bool bMipMaps;
|
||||
|
||||
/* Maximum number of bits for alpha. In 16-bit modes, lowering
|
||||
@@ -30,29 +30,29 @@ struct RageTextureID
|
||||
*
|
||||
* This may be set to 0, resulting in an alpha map with all pixels white. */
|
||||
int iGrayscaleBits;
|
||||
|
||||
/* Preferred color depth of the image. (This is overridden for
|
||||
|
||||
/* Preferred color depth of the image. (This is overridden for
|
||||
* paletted images and transparencies.) -1 for default. */
|
||||
int iColorDepth;
|
||||
|
||||
/* If true and color precision is being lost, dither. (slow) */
|
||||
|
||||
// If true and color precision is being lost, dither. (slow)
|
||||
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;
|
||||
|
||||
|
||||
/* If true, enable HOT PINK color keying. (deprecated but needed for
|
||||
* banners) */
|
||||
bool bHotPinkColorKey; /* #FF00FF */
|
||||
|
||||
/* These hints will be used in addition to any in the filename. */
|
||||
bool bHotPinkColorKey; // #FF00FF
|
||||
|
||||
// These hints will be used in addition to any in the filename.
|
||||
RString AdditionalTextureHints;
|
||||
|
||||
bool operator< (const RageTextureID &rhs) const;
|
||||
bool operator== (const RageTextureID &rhs) const;
|
||||
|
||||
/* Used by RageTextureManager. Order is important; see RageTextureManager.cpp.
|
||||
* Note that this property is not considered for ordering/equality. Loading
|
||||
/* Used by RageTextureManager. Order is important; see RageTextureManager.cpp.
|
||||
* Note that this property is not considered for ordering/equality. Loading
|
||||
* a texture with a different loading policy will reuse the same texture with
|
||||
* a different policy. */
|
||||
enum TexPolicy { TEX_VOLATILE, TEX_DEFAULT } Policy;
|
||||
|
||||
@@ -20,15 +20,15 @@ void RageTextureRenderTarget::Reload()
|
||||
Create();
|
||||
}
|
||||
|
||||
/* RageTextureID identifies a file and a mechanism for loading it. We don't use any
|
||||
* of that, except as a unique identifier for this texture, so it can be loaded
|
||||
* elsewhere. Render targets can't be loaded blindly like a regular texture, anyway,
|
||||
* since something has to render into it. */
|
||||
/* RageTextureID identifies a file and a mechanism for loading it. We don't use
|
||||
* any of that, except as a unique identifier for this texture, so it can be
|
||||
* loaded elsewhere. Render targets can't be loaded blindly like a regular
|
||||
* texture, anyway, since something has to render into it. */
|
||||
void RageTextureRenderTarget::Create()
|
||||
{
|
||||
/* All render targets support non-power-of-two targets, but some require that the
|
||||
* resulting texture dimensions be powers of two. CreateRenderTarget returns
|
||||
* the actual resolution. */
|
||||
/* All render targets support non-power-of-two targets,
|
||||
* but some require that the resulting texture dimensions be powers of two.
|
||||
* CreateRenderTarget returns the actual resolution. */
|
||||
m_iTexHandle = DISPLAY->CreateRenderTarget( m_Param, m_iTextureWidth, m_iTextureHeight );
|
||||
|
||||
m_iSourceWidth = m_Param.iWidth;
|
||||
@@ -49,8 +49,8 @@ void RageTextureRenderTarget::BeginRenderingTo( bool bPreserveTexture )
|
||||
{
|
||||
DISPLAY->SetRenderTarget( m_iTexHandle, bPreserveTexture );
|
||||
|
||||
/* We're rendering to a texture, not the framebuffer. Stash away the
|
||||
* centering matrix, and set it to identity. */
|
||||
/* We're rendering to a texture, not the framebuffer.
|
||||
* Stash away the centering matrix, and set it to identity. */
|
||||
DISPLAY->CenteringPushMatrix();
|
||||
DISPLAY->ChangeCentering( 0, 0, 0, 0 );
|
||||
|
||||
|
||||
@@ -21,9 +21,7 @@ public:
|
||||
|
||||
void UpdateText();
|
||||
|
||||
//
|
||||
// Commands
|
||||
//
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
|
||||
@@ -178,12 +178,13 @@ void ScreenNetEvaluation::UpdateStats()
|
||||
if( m_iCurrentPlayer >= (int) NSMAN->m_EvalPlayerData.size() )
|
||||
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_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 );
|
||||
|
||||
//Values greater than 6 will cause crash
|
||||
//Values greater than 6 will cause a crash
|
||||
if ( NSMAN->m_EvalPlayerData[m_iCurrentPlayer].difficulty < 6 )
|
||||
{
|
||||
m_DifficultyIcon[m_pActivePlayer].SetPlayer( m_pActivePlayer );
|
||||
@@ -192,12 +193,10 @@ void ScreenNetEvaluation::UpdateStats()
|
||||
|
||||
for( int j=0; j<NETNUMTAPSCORES; ++j )
|
||||
{
|
||||
// The name will be blank if ScreenEvaluation determined the
|
||||
// line should not be shown
|
||||
// The name will be blank if ScreenEvaluation determined the line
|
||||
// should not be shown.
|
||||
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] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ void ScreenOptionsExportPackage::BeginScreen()
|
||||
GetDirListing( *s + "*", m_vsPossibleDirsToExport, true, true );
|
||||
}
|
||||
|
||||
// Add courses. Only support courses that are in a group folder.
|
||||
// Add courses. Only support courses that are in a group folder.
|
||||
// Support for courses not in a group folder should be phased out.
|
||||
{
|
||||
vector<RString> vs;
|
||||
@@ -104,6 +104,7 @@ static bool ExportPackage( RString sPackageName, RString sDirToExport, RString &
|
||||
/*
|
||||
RageFile f;
|
||||
// TODO: Mount Desktop/ for each OS
|
||||
// SpecialDirs::GetDesktopDir() [windows only right now -aj]
|
||||
if( !f.Open("Desktop/"+sPackageName, RageFile::WRITE) )
|
||||
{
|
||||
sErrorOut = ssprintf( "Couldn't open %s for writing: %s", fn.c_str(), f.GetError().c_str() );
|
||||
|
||||
@@ -171,7 +171,7 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM )
|
||||
if( row.GetRowType() == OptionRow::RowType_Exit )
|
||||
{
|
||||
this->HandleScreenMessage( SM_GoToPrevScreen );
|
||||
return; // don't call base
|
||||
return; // don't call base
|
||||
}
|
||||
}
|
||||
else if( SM == SM_BackFromEnterNameForNew )
|
||||
@@ -179,7 +179,7 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM )
|
||||
if( !ScreenTextEntry::s_bCancelledLast )
|
||||
{
|
||||
ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this
|
||||
|
||||
|
||||
RString sNewName = ScreenTextEntry::s_sLastAnswer;
|
||||
ASSERT( GAMESTATE->m_sEditLocalProfileID.Get().empty() );
|
||||
|
||||
@@ -187,7 +187,11 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM )
|
||||
|
||||
// create
|
||||
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 );
|
||||
|
||||
if( iNumProfiles < NUM_PLAYERS )
|
||||
@@ -236,7 +240,7 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM )
|
||||
GAMESTATE->m_sEditLocalProfileID.Set( m_vsLocalProfileID[iIndex] );
|
||||
|
||||
PROFILEMAN->DeleteLocalProfile( GetLocalProfileIDWithFocus() );
|
||||
|
||||
|
||||
SCREENMAN->SetNewScreen( this->m_sName ); // reload
|
||||
}
|
||||
}
|
||||
@@ -294,6 +298,7 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM )
|
||||
{
|
||||
RString sTitle = pProfile->m_sDisplayName;
|
||||
RString sMessage = ssprintf( CONFIRM_DELETE_PROFILE.GetValue(), sTitle.c_str() );
|
||||
LOG->Trace("[ScreenOptionsManageProfiles] ProfileAction_Delete");
|
||||
ScreenPrompt::Prompt( SM_BackFromDeleteConfirm, sMessage, PROMPT_YES_NO );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -75,7 +75,7 @@ static void MoveMap( int &sel, T &opt, bool ToSel, const T *mapping, unsigned cn
|
||||
{
|
||||
sel = FindClosestEntry( opt, mapping, cnt );
|
||||
} else {
|
||||
/* sel -> opt */
|
||||
// sel -> opt
|
||||
opt = mapping[sel];
|
||||
}
|
||||
}
|
||||
@@ -86,12 +86,12 @@ static void MoveMap( int &sel, IPreference &opt, bool ToSel, const T *mapping, u
|
||||
if( ToSel )
|
||||
{
|
||||
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;
|
||||
FromString( sOpt, val );
|
||||
sel = FindClosestEntry( val, mapping, cnt );
|
||||
} else {
|
||||
/* sel -> opt */
|
||||
// sel -> opt
|
||||
RString sOpt = ToString( mapping[sel] );
|
||||
opt.FromString( sOpt );
|
||||
}
|
||||
@@ -115,7 +115,8 @@ static void MovePref( int &iSel, bool bToSel, const ConfOption *pConfOption )
|
||||
|
||||
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;
|
||||
FromString( pPref->ToString(), t );
|
||||
iSel = static_cast<int>( t );
|
||||
@@ -134,15 +135,17 @@ void MovePref<bool>( int &iSel, bool bToSel, const ConfOption *pConfOption )
|
||||
|
||||
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;
|
||||
FromString( pPref->ToString(), b );
|
||||
iSel = b ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we don't make a specific instantiation of MovePref<bool>, there is 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?
|
||||
// If we don't make a specific instantiation of MovePref<bool>, there is
|
||||
// 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 ) );
|
||||
}
|
||||
}
|
||||
@@ -220,7 +223,7 @@ static void Language( int &sel, bool ToSel, const ConfOption *pConfOption )
|
||||
if( !stricmp(vs[i], THEME->GetCurLanguage()) )
|
||||
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 )
|
||||
if( !stricmp(vs[i], SpecialFiles::BASE_LANGUAGE) )
|
||||
sel = i;
|
||||
@@ -233,7 +236,7 @@ static void Language( int &sel, bool ToSel, const ConfOption *pConfOption )
|
||||
}
|
||||
} else {
|
||||
const RString &sNewLanguage = vs[sel];
|
||||
|
||||
|
||||
PREFSMAN->m_sLanguage.Set( sNewLanguage );
|
||||
if( THEME->GetCurLanguage() != sNewLanguage )
|
||||
THEME->SwitchThemeAndLanguage( THEME->GetCurThemeName(), PREFSMAN->m_sLanguage, PREFSMAN->m_bPseudoLocalize );
|
||||
@@ -251,7 +254,7 @@ static void DisplayResolutionChoices( vector<RString> &out )
|
||||
{
|
||||
DisplayResolutions d;
|
||||
DISPLAY->GetDisplayResolutions( d );
|
||||
|
||||
|
||||
FOREACHS_CONST( DisplayResolution, d, iter )
|
||||
{
|
||||
RString s = ssprintf("%dx%d", iter->iWidth, iter->iHeight);
|
||||
@@ -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 )
|
||||
{
|
||||
// TODO: I hate the way the list of numbers is duplicated here and where the 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.
|
||||
// TODO: I hate the way the list of numbers is duplicated here and where the
|
||||
// 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 };
|
||||
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) );
|
||||
}
|
||||
|
||||
/* Input options */
|
||||
// Input options
|
||||
static void MusicWheelSwitchSpeed( int &sel, bool ToSel, const ConfOption *pConfOption )
|
||||
{
|
||||
const int mapping[] = { 5, 10, 15, 25 };
|
||||
MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) );
|
||||
}
|
||||
|
||||
/* Gameplay options */
|
||||
// Gameplay options
|
||||
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
|
||||
@@ -425,8 +428,7 @@ static void SongsPerPlayOrEventMode( int &sel, bool ToSel, const ConfOption *pCo
|
||||
PREFSMAN->m_bEventMode.Set( sel == 5 );
|
||||
}
|
||||
|
||||
/* Machine options */
|
||||
|
||||
// Machine options
|
||||
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 };
|
||||
@@ -445,7 +447,7 @@ static int GetTimingDifficulty()
|
||||
{
|
||||
int iTimingDifficulty = 0;
|
||||
TimingWindowScale( iTimingDifficulty, true, ConfOption::Find("TimingWindowScale") );
|
||||
iTimingDifficulty++; // TimingDifficulty returns an index
|
||||
iTimingDifficulty++; // TimingDifficulty returns an index
|
||||
return iTimingDifficulty;
|
||||
}
|
||||
LuaFunction( GetTimingDifficulty, GetTimingDifficulty() );
|
||||
@@ -453,7 +455,7 @@ static int GetLifeDifficulty()
|
||||
{
|
||||
int iLifeDifficulty = 0;
|
||||
LifeDifficulty( iLifeDifficulty, true, ConfOption::Find("LifeDifficulty") );
|
||||
iLifeDifficulty++; // LifeDifficulty returns an index
|
||||
iLifeDifficulty++; // LifeDifficulty returns an index
|
||||
return iLifeDifficulty;
|
||||
}
|
||||
LuaFunction( GetLifeDifficulty, GetLifeDifficulty() );
|
||||
@@ -475,9 +477,9 @@ static void DefaultFailType( int &sel, bool ToSel, const ConfOption *pConfOption
|
||||
|
||||
switch( sel )
|
||||
{
|
||||
case 0: po.m_FailType = PlayerOptions::FAIL_IMMEDIATE; break;
|
||||
case 0: po.m_FailType = PlayerOptions::FAIL_IMMEDIATE; break;
|
||||
case 1: po.m_FailType = PlayerOptions::FAIL_IMMEDIATE_CONTINUE; break;
|
||||
case 2: po.m_FailType = PlayerOptions::FAIL_AT_END; break;
|
||||
case 2: po.m_FailType = PlayerOptions::FAIL_AT_END; break;
|
||||
case 3: po.m_FailType = PlayerOptions::FAIL_OFF; break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
@@ -487,8 +489,7 @@ static void DefaultFailType( int &sel, bool ToSel, const ConfOption *pConfOption
|
||||
}
|
||||
}
|
||||
|
||||
/* Graphic options */
|
||||
|
||||
// Graphic options
|
||||
struct res_t
|
||||
{
|
||||
int w, h;
|
||||
@@ -506,17 +507,17 @@ struct res_t
|
||||
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; }
|
||||
};
|
||||
|
||||
static void DisplayResolutionM( int &sel, bool ToSel, const ConfOption *pConfOption )
|
||||
{
|
||||
vector<res_t> v;
|
||||
|
||||
|
||||
DisplayResolutions d;
|
||||
DISPLAY->GetDisplayResolutions( d );
|
||||
|
||||
|
||||
FOREACHS_CONST( DisplayResolution, d, iter )
|
||||
{
|
||||
v.push_back( res_t(iter->iWidth, iter->iHeight) );
|
||||
@@ -567,8 +568,8 @@ static void DisplayAspectRatio( int &sel, bool ToSel, const ConfOption *pConfOpt
|
||||
MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) );
|
||||
}
|
||||
|
||||
/* Simpler DisplayAspectRatio setting, which only offers "on" and "off". "On" can be 16:9
|
||||
* or 16:10. */
|
||||
/* Simpler DisplayAspectRatio setting, which only offers "on" and "off".
|
||||
* "On" can be 16:9 or 16:10. */
|
||||
static void WideScreen16_10( int &sel, bool ToSel, const ConfOption *pConfOption )
|
||||
{
|
||||
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) );
|
||||
}
|
||||
|
||||
/* SSC */
|
||||
/*
|
||||
// BackgroundCache code isn't live yet -aj
|
||||
/*
|
||||
static void BackgroundCache( int &sel, bool ToSel, const ConfOption *pConfOption )
|
||||
{
|
||||
const BackgroundCache mapping[] = { BackgroundCacheMode_Off, BackgroundCacheMode_LowResPreload, BackgroundCacheMode_LowResLoadOnDemand, BackgroundCacheMode_Full };
|
||||
MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) );
|
||||
}
|
||||
*/
|
||||
/* Sound options */
|
||||
|
||||
// Sound options
|
||||
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 };
|
||||
@@ -615,7 +615,7 @@ static void GlobalOffsetSeconds( int &sel, bool ToSel, const ConfOption *pConfOp
|
||||
float mapping[41];
|
||||
for( int i = 0; i < 41; ++i )
|
||||
mapping[i] = SCALE( i, 0.0f, 40.0f, -0.1f, +0.1f );
|
||||
|
||||
|
||||
MoveMap( sel, pConfOption, ToSel, mapping, ARRAYLEN(mapping) );
|
||||
}
|
||||
|
||||
@@ -625,18 +625,21 @@ static void InitializeConfOptions()
|
||||
if( !g_ConfOptions.empty() )
|
||||
return;
|
||||
|
||||
// There are a couple ways of getting the current preference column or turning a new choice in the interface
|
||||
// into a new preference. The easiest is when the interface choices are an exact mapping to the values the
|
||||
// preference can be. In that case, the easiest thing to do is use MovePref<bool or enum>. The next
|
||||
// easiest case is when there is a hardcoded mapping that is not 1-1, 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.
|
||||
// There are a couple ways of getting the current preference column or turning
|
||||
// a new choice in the interface into a new preference. The easiest is when
|
||||
// the interface choices are an exact mapping to the values the preference
|
||||
// can be. In that case, the easiest thing to do is use MovePref<bool or enum>.
|
||||
// The next easiest case is when there is a hardcoded mapping that is not 1-1,
|
||||
// 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 )
|
||||
/* Select game */
|
||||
// Select game
|
||||
ADD( ConfOption( "Game", GameSel, GameChoices ) );
|
||||
g_ConfOptions.back().m_iEffects = OPT_RESET_GAME;
|
||||
|
||||
/* Appearance options */
|
||||
// Appearance options
|
||||
ADD( ConfOption( "Language", Language, LanguageChoices ) );
|
||||
ADD( ConfOption( "Theme", Theme, ThemeChoices ) );
|
||||
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( "ShowLyrics", MovePref<bool>, "Hide","Show") );
|
||||
|
||||
/* Misc options */
|
||||
// Misc options
|
||||
ADD( ConfOption( "AutogenSteps", MovePref<bool>, "Off","On" ) );
|
||||
ADD( ConfOption( "OnlyPreferredDifficulties", MovePref<bool>, "Off","On" ) );
|
||||
g_ConfOptions.back().m_iEffects = OPT_APPLY_SONG;
|
||||
@@ -661,7 +664,7 @@ static void InitializeConfOptions()
|
||||
ADD( ConfOption( "AutogenGroupCourses", 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( "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%" ) );
|
||||
@@ -674,7 +677,7 @@ static void InitializeConfOptions()
|
||||
ADD( ConfOption( "ShowBeginnerHelper", MovePref<bool>, "Off","On" ) );
|
||||
ADD( ConfOption( "NumBackgrounds", NumBackgrounds, "|5","|10","|15","|20" ) );
|
||||
|
||||
/* Input options */
|
||||
// Input options
|
||||
ADD( ConfOption( "AutoMapOnJoyChange", MovePref<bool>, "Off","On (recommended)" ) );
|
||||
ADD( ConfOption( "OnlyDedicatedMenuButtons", MovePref<bool>, "Use Gameplay Buttons","Only Dedicated Buttons" ) );
|
||||
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( "MusicWheelSwitchSpeed", MusicWheelSwitchSpeed, "Slow","Normal","Fast","Really Fast" ) );
|
||||
|
||||
/* Gameplay options */
|
||||
// Gameplay options
|
||||
ADD( ConfOption( "Center1Player", MovePref<bool>, "Off","On" ) );
|
||||
ADD( ConfOption( "HiddenSongs", 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( "UseUnlockSystem", MovePref<bool>, "Off","On" ) );
|
||||
|
||||
/* Machine options */
|
||||
// Machine options
|
||||
ADD( ConfOption( "MenuTimer", MovePref<bool>, "Off","On" ) );
|
||||
ADD( ConfOption( "CoinMode", MovePref<CoinMode>, "Home","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( "GetRankingName", MovePref<GetRankingName>, "Off", "On", "Ranking Songs" ) );
|
||||
|
||||
/* Graphic options */
|
||||
// Graphic options
|
||||
ADD( ConfOption( "Windowed", MovePref<bool>, "Full Screen", "Windowed" ) );
|
||||
g_ConfOptions.back().m_iEffects = OPT_APPLY_GRAPHICS;
|
||||
ADD( ConfOption( "DisplayResolution", DisplayResolutionM, DisplayResolutionChoices ) );
|
||||
@@ -753,7 +756,7 @@ static void InitializeConfOptions()
|
||||
ADD( ConfOption( "ShowStats", 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( "SoundVolume", SoundVolume, "Silent","|10%","|20%","|30%","|40%","|50%","|60%","|70%","|80%","|90%","|100%" ) );
|
||||
g_ConfOptions.back().m_iEffects = OPT_APPLY_SOUND;
|
||||
@@ -768,13 +771,13 @@ static void InitializeConfOptions()
|
||||
ADD( ConfOption( "EnableAttackSounds", MovePref<bool>, "No","Yes" ) );
|
||||
ADD( ConfOption( "EnableMineHitSound", MovePref<bool>, "No","Yes" ) );
|
||||
|
||||
/* Editor options */
|
||||
// Editor options
|
||||
ADD( ConfOption( "EditorShowBGChangesPlay", MovePref<bool>, "Hide","Show") );
|
||||
|
||||
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
|
||||
{
|
||||
return m_iEffects | OPT_SAVE_PREFERENCES;
|
||||
|
||||
@@ -14,10 +14,10 @@ struct ConfOption
|
||||
{
|
||||
static ConfOption *Find( RString name );
|
||||
|
||||
/* Name of this option. */
|
||||
// Name of this option.
|
||||
RString name;
|
||||
|
||||
/* Name of the preference this option affects. */
|
||||
// Name of the preference this option affects.
|
||||
RString m_sPrefName;
|
||||
|
||||
typedef void (*MoveData_t)( int &sel, bool ToSel, const ConfOption *pConfOption );
|
||||
@@ -25,12 +25,12 @@ struct ConfOption
|
||||
int m_iEffects;
|
||||
bool m_bAllowThemeItems;
|
||||
|
||||
/* For dynamic options, update the options. Since this changes the available
|
||||
/* For dynamic options, update the options. Since this changes the available
|
||||
* options, this may invalidate the offsets returned by Get() and Put(). */
|
||||
void UpdateAvailableOptions();
|
||||
|
||||
/* Return the list of available selections; Get() and Put() use indexes into this
|
||||
* array. UpdateAvailableOptions() should be called before using this. */
|
||||
/* Return the list of available selections; Get() and Put() use indexes into
|
||||
* this array. UpdateAvailableOptions() should be called before using this. */
|
||||
void MakeOptionsList( vector<RString> &out ) const;
|
||||
|
||||
inline int Get() const { int sel; MoveData( sel, true, this ); return sel; }
|
||||
@@ -59,7 +59,7 @@ struct ConfOption
|
||||
MoveData = m;
|
||||
MakeOptionsListCB = lst;
|
||||
m_iEffects = 0;
|
||||
m_bAllowThemeItems = false; // don't theme dynamic choices
|
||||
m_bAllowThemeItems = false; // don't theme dynamic choices
|
||||
}
|
||||
|
||||
|
||||
|
||||
+22
-22
@@ -15,19 +15,18 @@
|
||||
#define UPDATE_ON_MESSAGE THEME->GetMetric (m_sName,"UpdateOnMessage")
|
||||
|
||||
#if defined(SSC_FUTURES)
|
||||
// ???: Instead of using NumLists, use a comma-separated list of list names?
|
||||
#define NUM_LISTS THEME->GetMetricI (m_sName,"NumLists")
|
||||
#define LIST_NAMES THEME->GetMetric (m_sName,"ListNames")
|
||||
#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")
|
||||
#endif
|
||||
|
||||
#if defined(SSC_FUTURES)
|
||||
#define LIST_CONDITION( i ) THEME->GetMetricR (m_sName,"List%iCondition",i)
|
||||
#define CHOICE_NAMES_MULTI( i ) THEME->GetMetric (m_sName,ssprintf("List%iChoiceNames",i))
|
||||
#define CHOICEMULTI( i, s ) THEME->GetMetric (m_sName,ssprintf("List%iChoice%s",i,s.c_str()))
|
||||
#define LIST_CONDITION( s ) THEME->GetMetricR (m_sName,"List%sCondition",s.c_str())
|
||||
#define CHOICE_NAMES_MULTI( s ) THEME->GetMetric (m_sName,ssprintf("List%sChoiceNames",s.c_str()))
|
||||
#define CHOICEMULTI( s1, s2 ) THEME->GetMetric (m_sName,ssprintf("List%sChoice%s",s1.c_str(),s2.c_str()))
|
||||
#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 CHOICEB( s ) THEME->GetMetric (m_sName,ssprintf("ChoiceB%s",s.c_str()))
|
||||
#endif
|
||||
@@ -50,10 +49,10 @@ void ScreenSelect::Init()
|
||||
|
||||
// Load choices
|
||||
{
|
||||
// Instead of using NUM_CHOICES, use a comma-separated list of choices. 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
|
||||
// of indices.
|
||||
// Instead of using NUM_CHOICES, use a comma-separated list of choices.
|
||||
// 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 of indices.
|
||||
vector<RString> asChoiceNames;
|
||||
split( CHOICE_NAMES, ",", asChoiceNames, true );
|
||||
|
||||
@@ -172,8 +171,7 @@ void ScreenSelect::Input( const InputEventPlus &input )
|
||||
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
|
||||
// when the player makes a selection on the screen.
|
||||
SCREENMAN->PlayStartSound();
|
||||
@@ -189,24 +187,26 @@ void ScreenSelect::Input( const InputEventPlus &input )
|
||||
if( !ALLOW_DISABLED_PLAYER_INPUT )
|
||||
return;
|
||||
|
||||
/* Never allow a START press by a player that's still not joined, even if ALLOW_DISABLED_PLAYER_INPUT
|
||||
* would allow other types of input. If we 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). */
|
||||
/* Never allow a START press by a player that's still not joined, even if
|
||||
* ALLOW_DISABLED_PLAYER_INPUT would allow other types of input. If we
|
||||
* 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 )
|
||||
return;
|
||||
}
|
||||
|
||||
ScreenWithMenuElements::Input( input ); // default input handler
|
||||
ScreenWithMenuElements::Input( input ); // default input handler
|
||||
}
|
||||
|
||||
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
|
||||
* have a shared selection. This can cause change messages to be broadcast
|
||||
* multiple times. Detect whether all players have the same choice, and
|
||||
* if so, call ApplyToAll instead.
|
||||
* have a shared selection. This can cause change messages to be
|
||||
* broadcast multiple times. Detect whether all players have the
|
||||
* same choice, and if so, call ApplyToAll instead.
|
||||
* TODO: Think of a better way to handle this.
|
||||
*/
|
||||
ASSERT( GAMESTATE->m_MasterPlayerNumber != PlayerNumber_Invalid );
|
||||
@@ -250,7 +250,7 @@ void ScreenSelect::HandleScreenMessage( const ScreenMessage SM )
|
||||
m_sNextScreen = gc.m_sScreen;
|
||||
if( !gc.m_bInvalid )
|
||||
gc.ApplyToAllPlayers();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+3
-3
@@ -18,13 +18,13 @@ public:
|
||||
virtual void Input( const InputEventPlus &input );
|
||||
virtual void HandleScreenMessage( const ScreenMessage SM );
|
||||
virtual void HandleMessage( const Message &msg );
|
||||
|
||||
|
||||
virtual void MenuBack( const InputEventPlus &input );
|
||||
|
||||
protected:
|
||||
virtual int GetSelectionIndex( PlayerNumber pn ) = 0;
|
||||
virtual void UpdateSelectableChoices() = 0; // derived screens must handle this
|
||||
|
||||
|
||||
unsigned int m_iSelectedList;
|
||||
#if defined(SSC_FUTURES)
|
||||
int m_iNumLists;
|
||||
@@ -34,7 +34,7 @@ protected:
|
||||
|
||||
vector<GameCommand> m_aGameCommands; // derived classes should look here for what choices are available
|
||||
#if defined(SSC_FUTURES)
|
||||
// this is gonna become awkward.. -aj
|
||||
// this is gonna become awkward... -aj
|
||||
#else
|
||||
vector<GameCommand> m_aGameCommandsB; // only used if the theme requires a second list
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "PlayerState.h"
|
||||
#include "CommonMetrics.h"
|
||||
#include "BannerCache.h"
|
||||
//#include "BackgroundCache.h"
|
||||
#include "Song.h"
|
||||
#include "InputEventPlus.h"
|
||||
#include "RageInput.h"
|
||||
@@ -119,6 +120,7 @@ void ScreenSelectMusic::Init()
|
||||
|
||||
m_TexturePreload.Load( m_sFallbackCDTitlePath );
|
||||
|
||||
// load banners
|
||||
if( PREFSMAN->m_BannerCache != BNCACHE_OFF )
|
||||
{
|
||||
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","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();
|
||||
//BACKGROUNDCACHE->Demand();
|
||||
|
||||
m_MusicWheel.SetName( "MusicWheel" );
|
||||
m_MusicWheel.Load( MUSIC_WHEEL_TYPE );
|
||||
@@ -248,7 +264,7 @@ ScreenSelectMusic::~ScreenSelectMusic()
|
||||
{
|
||||
LOG->Trace( "ScreenSelectMusic::~ScreenSelectMusic()" );
|
||||
BANNERCACHE->Undemand();
|
||||
|
||||
//BACKGROUNDCACHE->Undemand();
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// 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");
|
||||
msg.SetParam( "Player", input.pn );
|
||||
@@ -803,7 +821,7 @@ void ScreenSelectMusic::HandleMessage( const Message &msg )
|
||||
// steps selected, they are no longer playable now that P2 has joined.
|
||||
|
||||
// TODO: Invalidate the CurSteps only if they are no longer playable.
|
||||
// That way, after music change will clamp to the nearest in the StepsDisplayList.
|
||||
// That way, after music change will clamp to the nearest in the StepsDisplayList.
|
||||
GAMESTATE->m_pCurSteps[GAMESTATE->m_MasterPlayerNumber].SetWithoutBroadcast( NULL );
|
||||
FOREACH_ENUM( PlayerNumber, p )
|
||||
GAMESTATE->m_pCurSteps[p].SetWithoutBroadcast( NULL );
|
||||
@@ -1002,6 +1020,14 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
// I believe this is for those who like pump pro. -aj
|
||||
MESSAGEMAN->Broadcast("SongChosen");
|
||||
|
||||
/*
|
||||
if(TWO_PART_CONFIRMS_ONLY && SAMPLE_MUSIC_PREVIEW_MODE == SampleMusicPreviewMode_StartToPreview)
|
||||
{
|
||||
// start playing the preview music.
|
||||
g_bSampleMusicWaiting = true;
|
||||
}
|
||||
*/
|
||||
|
||||
break;
|
||||
|
||||
case SelectionState_SelectingSteps:
|
||||
@@ -1425,34 +1451,51 @@ void ScreenSelectMusic::AfterMusicChange()
|
||||
m_iSelection[p] = -1;
|
||||
|
||||
g_sCDTitlePath = ""; // none
|
||||
|
||||
|
||||
//if( SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong )
|
||||
//{
|
||||
m_fSampleStartSeconds = 0;
|
||||
m_fSampleLengthSeconds = -1;
|
||||
//}
|
||||
|
||||
switch( m_MusicWheel.GetSelectedType() )
|
||||
{
|
||||
case TYPE_SECTION:
|
||||
g_sBannerPath = SONGMAN->GetSongGroupBannerPath( m_MusicWheel.GetSelectedSection() );
|
||||
//if( SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong )
|
||||
m_sSampleMusicToPlay = m_sSectionMusicPath;
|
||||
break;
|
||||
case TYPE_SORT:
|
||||
bWantBanner = false; // we load it ourself
|
||||
m_Banner.LoadMode();
|
||||
//if( SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong )
|
||||
m_sSampleMusicToPlay = m_sSortMusicPath;
|
||||
break;
|
||||
case TYPE_ROULETTE:
|
||||
bWantBanner = false; // we load it ourself
|
||||
m_Banner.LoadRoulette();
|
||||
//if( SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong )
|
||||
m_sSampleMusicToPlay = m_sRouletteMusicPath;
|
||||
break;
|
||||
case TYPE_RANDOM:
|
||||
bWantBanner = false; // we load it ourself
|
||||
m_Banner.LoadRandom();
|
||||
//if( SAMPLE_MUSIC_PREVIEW_MODE != SampleMusicPreviewMode_LastSong )
|
||||
m_sSampleMusicToPlay = m_sRandomMusicPath;
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
case TYPE_SONG:
|
||||
case TYPE_PORTAL:
|
||||
|
||||
+25
-25
@@ -41,9 +41,9 @@ public:
|
||||
virtual void MenuStart( 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() { }
|
||||
|
||||
|
||||
bool GetGoToOptions() const { return m_bGoToOptions; }
|
||||
MusicWheel *GetMusicWheel() { return &m_MusicWheel; }
|
||||
|
||||
@@ -63,31 +63,31 @@ protected:
|
||||
void CheckBackgroundRequests( bool bForce );
|
||||
bool DetectCodes( const InputEventPlus &input );
|
||||
|
||||
vector<Steps*> m_vpSteps;
|
||||
vector<Trail*> m_vpTrails;
|
||||
int m_iSelection[NUM_PLAYERS];
|
||||
vector<Steps*> m_vpSteps;
|
||||
vector<Trail*> m_vpTrails;
|
||||
int m_iSelection[NUM_PLAYERS];
|
||||
|
||||
ThemeMetric<float> SAMPLE_MUSIC_DELAY_INIT;
|
||||
ThemeMetric<float> SAMPLE_MUSIC_DELAY;
|
||||
ThemeMetric<bool> SAMPLE_MUSIC_LOOPS;
|
||||
ThemeMetric<float> SAMPLE_MUSIC_DELAY_INIT;
|
||||
ThemeMetric<float> SAMPLE_MUSIC_DELAY;
|
||||
ThemeMetric<bool> SAMPLE_MUSIC_LOOPS;
|
||||
ThemeMetric<SampleMusicPreviewMode> SAMPLE_MUSIC_PREVIEW_MODE;
|
||||
ThemeMetric<float> SAMPLE_MUSIC_FALLBACK_FADE_IN_SECONDS;
|
||||
ThemeMetric<bool> DO_ROULETTE_ON_MENU_TIMER;
|
||||
ThemeMetric<bool> ALIGN_MUSIC_BEATS;
|
||||
ThemeMetric<RString> CODES;
|
||||
ThemeMetric<RString> MUSIC_WHEEL_TYPE;
|
||||
ThemeMetric<bool> OPTIONS_MENU_AVAILABLE;
|
||||
ThemeMetric<bool> SELECT_MENU_AVAILABLE;
|
||||
ThemeMetric<bool> MODE_MENU_AVAILABLE;
|
||||
ThemeMetric<bool> USE_OPTIONS_LIST;
|
||||
ThemeMetric<float> OPTIONS_LIST_TIMEOUT;
|
||||
ThemeMetric<bool> USE_PLAYER_SELECT_MENU;
|
||||
ThemeMetric<RString> SELECT_MENU_NAME;
|
||||
ThemeMetric<bool> SELECT_MENU_CHANGES_DIFFICULTY;
|
||||
ThemeMetric<bool> TWO_PART_SELECTION;
|
||||
ThemeMetric<bool> TWO_PART_CONFIRMS_ONLY;
|
||||
ThemeMetric<float> TWO_PART_TIMER_SECONDS;
|
||||
ThemeMetric<bool> WRAP_CHANGE_STEPS;
|
||||
ThemeMetric<float> SAMPLE_MUSIC_FALLBACK_FADE_IN_SECONDS;
|
||||
ThemeMetric<bool> DO_ROULETTE_ON_MENU_TIMER;
|
||||
ThemeMetric<bool> ALIGN_MUSIC_BEATS;
|
||||
ThemeMetric<RString> CODES;
|
||||
ThemeMetric<RString> MUSIC_WHEEL_TYPE;
|
||||
ThemeMetric<bool> OPTIONS_MENU_AVAILABLE;
|
||||
ThemeMetric<bool> SELECT_MENU_AVAILABLE;
|
||||
ThemeMetric<bool> MODE_MENU_AVAILABLE;
|
||||
ThemeMetric<bool> USE_OPTIONS_LIST;
|
||||
ThemeMetric<float> OPTIONS_LIST_TIMEOUT;
|
||||
ThemeMetric<bool> USE_PLAYER_SELECT_MENU;
|
||||
ThemeMetric<RString> SELECT_MENU_NAME;
|
||||
ThemeMetric<bool> SELECT_MENU_CHANGES_DIFFICULTY;
|
||||
ThemeMetric<bool> TWO_PART_SELECTION;
|
||||
ThemeMetric<bool> TWO_PART_CONFIRMS_ONLY;
|
||||
ThemeMetric<float> TWO_PART_TIMER_SECONDS;
|
||||
ThemeMetric<bool> WRAP_CHANGE_STEPS;
|
||||
|
||||
bool CanChangeSong() const { return m_SelectionState == SelectionState_SelectingSong; }
|
||||
bool CanChangeSteps() const { return TWO_PART_SELECTION ? m_SelectionState == SelectionState_SelectingSteps : m_SelectionState == SelectionState_SelectingSong; }
|
||||
|
||||
+12
-2
@@ -13,6 +13,7 @@
|
||||
#include "FontCharAliases.h"
|
||||
#include "TitleSubstitution.h"
|
||||
#include "BannerCache.h"
|
||||
//#include "BackgroundCache.h"
|
||||
#include "Sprite.h"
|
||||
#include "RageFileManager.h"
|
||||
#include "RageSurface.h"
|
||||
@@ -70,6 +71,7 @@ Song::Song()
|
||||
m_bIsSymLink = false;
|
||||
m_bHasMusic = false;
|
||||
m_bHasBanner = false;
|
||||
m_bHasBackground = false;
|
||||
}
|
||||
|
||||
Song::~Song()
|
||||
@@ -266,6 +268,11 @@ bool Song::LoadFromSongDir( RString sDir )
|
||||
/* Load the cached banners, if it's not loaded already. */
|
||||
if( PREFSMAN->m_BannerCache == BNCACHE_LOW_RES_PRELOAD && m_bHasBanner )
|
||||
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.) */
|
||||
AddAutoGenNotes();
|
||||
@@ -640,11 +647,14 @@ void Song::TidyUpData()
|
||||
/* These will be written to cache, for Song::LoadFromSongDir to use later. */
|
||||
m_bHasMusic = HasMusic();
|
||||
m_bHasBanner = HasBanner();
|
||||
m_bHasBackground = HasBackground();
|
||||
|
||||
if( HasBanner() )
|
||||
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
|
||||
// they are DWI style where the movie begins at beat 0.
|
||||
|
||||
+1
-1
@@ -158,7 +158,7 @@ public:
|
||||
|
||||
|
||||
/* For loading only: */
|
||||
bool m_bHasMusic, m_bHasBanner;
|
||||
bool m_bHasMusic, m_bHasBanner, m_bHasBackground;
|
||||
|
||||
bool HasMusic() const;
|
||||
bool HasInstrumentTrack( InstrumentTrack it ) const;
|
||||
|
||||
@@ -93,11 +93,12 @@ void SongCacheIndex::ReadCacheIndex()
|
||||
int iCacheVersion = -1;
|
||||
CacheIndex.GetValue( "Cache", "CacheVersion", iCacheVersion );
|
||||
if( iCacheVersion == FILE_CACHE_VERSION )
|
||||
return; /* OK */
|
||||
return; // OK
|
||||
|
||||
LOG->Trace( "Cache format is out of date. Deleting all cache files." );
|
||||
EmptyDir( SpecialFiles::CACHE_DIR );
|
||||
EmptyDir( SpecialFiles::CACHE_DIR+"Banners/" );
|
||||
//EmptyDir( SpecialFiles::CACHE_DIR+"Backgrounds/" );
|
||||
EmptyDir( SpecialFiles::CACHE_DIR+"Songs/" );
|
||||
EmptyDir( SpecialFiles::CACHE_DIR+"Courses/" );
|
||||
|
||||
|
||||
+100
-30
@@ -192,11 +192,37 @@ void SongManager::AddGroup( RString sDir, RString sGroupDirName )
|
||||
if( !arrayGroupBanners.empty() )
|
||||
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(),
|
||||
sBannerPath != ""? sBannerPath.c_str():"(none)" );
|
||||
m_sSongGroupNames.push_back( sGroupDirName );
|
||||
m_sSongGroupBannerPaths.push_back( sBannerPath );
|
||||
//m_sSongGroupBackgroundPaths.push_back( sBackgroundPath );
|
||||
}
|
||||
|
||||
static LocalizedString LOADING_SONGS ( "SongManager", "Loading songs..." );
|
||||
@@ -263,9 +289,9 @@ void SongManager::LoadStepManiaSongDir( RString sDir, LoadingWindow *ld )
|
||||
/* Add this group to the group array. */
|
||||
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) );
|
||||
|
||||
|
||||
/* Load the group sym links (if any)*/
|
||||
LoadGroupSymLinks(sDir, sGroupDirName);
|
||||
}
|
||||
@@ -312,21 +338,47 @@ void SongManager::LoadGroupSymLinks(RString sDir, RString sGroupFolder)
|
||||
|
||||
void SongManager::PreloadSongImages()
|
||||
{
|
||||
bool bSkipBanners = false;
|
||||
//bool bSkipBackgrounds = false;
|
||||
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
|
||||
* that we don't need to. */
|
||||
RageTexturePreloader preload;
|
||||
|
||||
const vector<Song*> &songs = GetAllSongs();
|
||||
for( unsigned i = 0; i < songs.size(); ++i )
|
||||
//if( !bSkipBanners && !bSkipBackgrounds )
|
||||
if( !bSkipBanners )
|
||||
{
|
||||
if( !songs[i]->HasBanner() )
|
||||
continue;
|
||||
const vector<Song*> &songs = GetAllSongs();
|
||||
for( unsigned i = 0; i < songs.size(); ++i )
|
||||
{
|
||||
// preload banners
|
||||
if( !songs[i]->HasBanner() && !songs[i]->HasBackground() )
|
||||
continue;
|
||||
|
||||
const RageTextureID ID = Sprite::SongBannerTexture( songs[i]->GetBannerPath() );
|
||||
preload.Load( ID );
|
||||
if( !bSkipBanners && songs[i]->HasBanner() )
|
||||
{
|
||||
const RageTextureID ID = Sprite::SongBannerTexture( songs[i]->GetBannerPath() );
|
||||
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;
|
||||
@@ -347,13 +399,16 @@ void SongManager::FreeSongs()
|
||||
{
|
||||
m_sSongGroupNames.clear();
|
||||
m_sSongGroupBannerPaths.clear();
|
||||
//m_sSongGroupBackgroundPaths.clear();
|
||||
|
||||
for( unsigned i=0; i<m_pSongs.size(); i++ )
|
||||
SAFE_DELETE( m_pSongs[i] );
|
||||
m_pSongs.clear();
|
||||
m_mapSongGroupIndex.clear();
|
||||
|
||||
// wait why is it cleared twice? -aj
|
||||
m_sSongGroupBannerPaths.clear();
|
||||
//m_sSongGroupBackgroundPaths.clear(); // when in Rome... -aj
|
||||
|
||||
m_pPopularSongs.clear();
|
||||
m_pShuffledSongs.clear();
|
||||
@@ -369,7 +424,18 @@ RString SongManager::GetSongGroupBannerPath( RString sSongGroup ) const
|
||||
|
||||
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
|
||||
{
|
||||
AddTo.insert(AddTo.end(), m_sSongGroupNames.begin(), m_sSongGroupNames.end() );
|
||||
@@ -385,9 +451,11 @@ RageColor SongManager::GetSongGroupColor( const RString &sSongGroup ) const
|
||||
for( unsigned i=0; i<m_sSongGroupNames.size(); i++ )
|
||||
{
|
||||
if( m_sSongGroupNames[i] == sSongGroup )
|
||||
{
|
||||
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()) );
|
||||
return RageColor(1,1,1,1);
|
||||
}
|
||||
@@ -398,10 +466,9 @@ RageColor SongManager::GetSongColor( const Song* pSong ) const
|
||||
|
||||
// Use unlock color if applicable
|
||||
const UnlockEntry *pUE = UNLOCKMAN->FindSong( pSong );
|
||||
if( pUE && USE_UNLOCK_COLOR.GetValue() )
|
||||
if( pUE && USE_UNLOCK_COLOR.GetValue() )
|
||||
return UNLOCK_COLOR.GetValue();
|
||||
|
||||
|
||||
if( USE_PREFERRED_SORT_COLOR )
|
||||
{
|
||||
FOREACH_CONST( PreferredSortSection, m_vPreferredSongSort, v )
|
||||
@@ -423,18 +490,18 @@ RageColor SongManager::GetSongColor( const Song* pSong ) const
|
||||
{
|
||||
|
||||
/* XXX:
|
||||
* Previously, this matched all notes, which set a song to "extra" if it
|
||||
* had any 10-foot steps at all, even edits or doubles.
|
||||
* Previously, this matched all notes, which set a song to "extra" if
|
||||
* 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
|
||||
* if a song has 10-foot steps on Doubles, it'll only show up red in Doubles.
|
||||
* That's not too bad, I think. This will also change it in the song scroll,
|
||||
* which is a little odd but harmless.
|
||||
* For now, only look at notes for the current note type. This means
|
||||
* that if a song has 10-foot steps on Doubles, it'll only show up red
|
||||
* in Doubles. That's not too bad, I think. This will also change it
|
||||
* 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
|
||||
* set up, which is too restrictive. How to handle this?
|
||||
* XXX: Ack. This means this function can only be called when we have
|
||||
* 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();
|
||||
for( unsigned i=0; i<vpSteps.size(); i++ )
|
||||
{
|
||||
@@ -446,8 +513,8 @@ RageColor SongManager::GetSongColor( const Song* pSong ) const
|
||||
continue;
|
||||
}
|
||||
|
||||
// if(pSteps->m_StepsType != st)
|
||||
// continue;
|
||||
//if(pSteps->m_StepsType != st)
|
||||
// continue;
|
||||
|
||||
if( pSteps->GetMeter() >= EXTRA_COLOR_METER )
|
||||
return (RageColor)EXTRA_COLOR;
|
||||
@@ -1287,7 +1354,7 @@ Song *SongManager::FindSong( RString sPath ) const
|
||||
else if( bits.size() == 2 )
|
||||
return FindSong( bits[0], bits[1] );
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Song *SongManager::FindSong( RString sGroup, RString sSong ) const
|
||||
@@ -1300,7 +1367,7 @@ Song *SongManager::FindSong( RString sGroup, RString sSong ) const
|
||||
return *s;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Course *SongManager::FindCourse( RString sPath ) const
|
||||
@@ -1314,7 +1381,7 @@ Course *SongManager::FindCourse( RString sPath ) const
|
||||
else if( bits.size() == 2 )
|
||||
return FindCourse( bits[0], bits[1] );
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Course *SongManager::FindCourse( RString sGroup, RString sName ) const
|
||||
@@ -1335,13 +1402,13 @@ void SongManager::UpdatePopular()
|
||||
for ( unsigned j=0; j < apBestSongs.size() ; ++j )
|
||||
{
|
||||
bool bFiltered = false;
|
||||
/* Filter out locked songs. */
|
||||
// Filter out locked songs.
|
||||
if( !apBestSongs[j]->NormallyDisplayed() )
|
||||
bFiltered = true;
|
||||
if( !bFiltered )
|
||||
continue;
|
||||
|
||||
/* Remove it. */
|
||||
// Remove it.
|
||||
swap( apBestSongs[j], apBestSongs.back() );
|
||||
apBestSongs.erase( apBestSongs.end()-1 );
|
||||
--j;
|
||||
@@ -1776,11 +1843,11 @@ public:
|
||||
DEFINE_METHOD( GetSongColor, GetSongColor( Luna<Song>::check(L,1) ) )
|
||||
DEFINE_METHOD( GetSongGroupColor, GetSongGroupColor( SArg(1) ) )
|
||||
DEFINE_METHOD( GetCourseColor, GetCourseColor( Luna<Course>::check(L,1) ) )
|
||||
|
||||
|
||||
// this binding has ABYSMAL performance, most likely due to the whole "hey
|
||||
// let's keep repopulating the vector every time this is called" thing.
|
||||
// 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 )
|
||||
{
|
||||
@@ -1799,6 +1866,8 @@ public:
|
||||
}
|
||||
*/
|
||||
|
||||
DEFINE_METHOD( ShortenGroupName, ShortenGroupName( SArg(1) ) )
|
||||
|
||||
LunaSongManager()
|
||||
{
|
||||
ADD_METHOD( GetAllSongs );
|
||||
@@ -1821,6 +1890,7 @@ public:
|
||||
ADD_METHOD( GetSongGroupColor );
|
||||
ADD_METHOD( GetCourseColor );
|
||||
//ADD_METHOD( GetSongRank );
|
||||
ADD_METHOD( ShortenGroupName );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+13
-14
@@ -97,23 +97,22 @@ RageTextureID Sprite::SongBGTexture( RageTextureID ID )
|
||||
|
||||
RageTextureID Sprite::SongBannerTexture( RageTextureID ID )
|
||||
{
|
||||
/* Song banners often have HOT PINK color keys. */
|
||||
|
||||
/* TODO: Change to use color keying only if the graphic is a diagonal banner. The color key convention is
|
||||
* causing small holes in moderm banners that use magenta, and it's not good to require graphic
|
||||
* makers to know about archaic color key conventions. -Chris */
|
||||
|
||||
// Older song banners often have HOT PINK color keys.
|
||||
/* Use color keying only if the graphic is a diagonal banner.
|
||||
* The color key convention is causing small holes in moderm banners that
|
||||
* use magenta, and it's not good to require graphic makers to know about
|
||||
* archaic color key conventions. -Chris */
|
||||
// I disabled this anyways, it's extremely annoying -Colby
|
||||
ID.bHotPinkColorKey = false;
|
||||
|
||||
/* Ignore the texture color depth preference and always use 32-bit textures
|
||||
* if possible. Banners are loaded while moving the wheel, so we want it to
|
||||
* if possible. Banners are loaded while moving the wheel, so we want it to
|
||||
* be as fast as possible. */
|
||||
ID.iColorDepth = 32;
|
||||
|
||||
/* If we don't support RGBA8 (and will probably fall back on RGBA4), we're probably
|
||||
* on something very old and slow, so let's opt for banding instead of slowing things
|
||||
* down further by dithering. */
|
||||
/* If we don't support RGBA8 (and will probably fall back on RGBA4), we're
|
||||
* probably on something very old and slow, so let's opt for banding
|
||||
* instead of slowing things down further by dithering. */
|
||||
// ID.bDither = true;
|
||||
|
||||
ID.Policy = RageTextureID::TEX_VOLATILE;
|
||||
@@ -438,9 +437,10 @@ void Sprite::DrawTexture( const TweenState *state )
|
||||
{
|
||||
Actor::SetGlobalRenderStates(); // set Actor-specified render states
|
||||
|
||||
RectF crop = state->crop;
|
||||
// bail if cropped all the way
|
||||
if( state->crop.left + state->crop.right >= 1 ||
|
||||
state->crop.top + state->crop.bottom >= 1 )
|
||||
if( crop.left + crop.right >= 1 ||
|
||||
crop.top + crop.bottom >= 1 )
|
||||
return;
|
||||
|
||||
// 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. */
|
||||
/* HACK: Clamp the crop values. It would be more accurate to clip the
|
||||
* vertices so that the diffuse value is adjusted. */
|
||||
RectF crop = state->crop;
|
||||
CLAMP( crop.left, 0, 1 );
|
||||
CLAMP( crop.right, 0, 1 );
|
||||
CLAMP( crop.top, 0, 1 );
|
||||
@@ -481,7 +480,7 @@ void Sprite::DrawTexture( const TweenState *state )
|
||||
|
||||
// Must call this after setting the texture or else texture
|
||||
// parameters have no effect.
|
||||
Actor::SetTextureRenderStates(); // set Actor-specified render states
|
||||
Actor::SetTextureRenderStates(); // set Actor-specified render states
|
||||
DISPLAY->SetEffectMode( m_EffectMode );
|
||||
|
||||
if( m_pTexture )
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ public:
|
||||
|
||||
// TODO: These are updated in ScreenGameplay::Update based on fDelta.
|
||||
// They should be made more accurate.
|
||||
float m_fGameplaySeconds; // how many seconds before gameplay ended. Updated by Gameplay, not scaled by music rate.
|
||||
float m_fGameplaySeconds; // how many seconds before gameplay ended. Updated by Gameplay, not scaled by music rate.
|
||||
float m_fStepsSeconds; // this is <= fGameplaySeconds unless the song has steps past the end
|
||||
float m_fMusicRate;
|
||||
|
||||
|
||||
+1
-1
@@ -839,7 +839,7 @@ void StepMania::ChangeCurrentGame( const Game* g )
|
||||
// process theme and language command line arguments;
|
||||
// these change the preferences in order for transparent loading -aj
|
||||
RString argTheme;
|
||||
if( GetCommandlineArgument( "theme",&argTheme) )
|
||||
if( GetCommandlineArgument( "theme",&argTheme) && argTheme != sTheme )
|
||||
{
|
||||
sTheme = argTheme;
|
||||
// set theme in preferences too for correct behavior -aj
|
||||
|
||||
@@ -1147,7 +1147,7 @@ RString ThemeManager::GetString( const RString &sMetricsGroup, const RString &sV
|
||||
ASSERT( g_pLoadedThemeData );
|
||||
RString s = GetMetricRaw( g_pLoadedThemeData->iniStrings, sMetricsGroup, sValueName );
|
||||
FontCharAliases::ReplaceMarkers( s );
|
||||
|
||||
|
||||
// Don't EvalulateString. Strings are raw and shouldn't allow Lua.
|
||||
//EvaluateString( s );
|
||||
|
||||
|
||||
+41
-21
@@ -44,7 +44,7 @@ void TimingData::AddTimeSignatureSegment( const TimeSignatureSegment &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;
|
||||
}
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
/* 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++ )
|
||||
{
|
||||
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 )
|
||||
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 )
|
||||
{
|
||||
BPMSegment b = m_BPMSegments[i];
|
||||
b.m_iStartRow = iStartIndexNextSegment;
|
||||
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,
|
||||
* since it lies outside the range. */
|
||||
/* Don't apply the BPM change to the first half of the segment we
|
||||
* just split, since it lies outside the range. */
|
||||
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 )
|
||||
{
|
||||
BPMSegment b = m_BPMSegments[i];
|
||||
@@ -201,7 +202,7 @@ BPMSegment& TimingData::GetBPMSegmentAtBeat( float fBeat )
|
||||
static BPMSegment empty;
|
||||
if( m_BPMSegments.empty() )
|
||||
return empty;
|
||||
|
||||
|
||||
int i = GetBPMSegmentIndexAtBeat( fBeat );
|
||||
return m_BPMSegments[i];
|
||||
}
|
||||
@@ -230,7 +231,7 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
|
||||
const float fStartBeatNextSegment = NoteRowToBeat( iStartRowNextSegment );
|
||||
const float fBPS = m_BPMSegments[i].m_fBPS;
|
||||
|
||||
for( unsigned j=0; j<m_StopSegments.size(); j++ ) // foreach freeze
|
||||
for( unsigned j=0; j<m_StopSegments.size(); j++ ) // foreach freeze
|
||||
{
|
||||
const bool bIsDelay = m_StopSegments[j].m_bDelay;
|
||||
if( !bIsFirstBPMSegment && iStartRowThisSegment >= m_StopSegments[j].m_iStartRow )
|
||||
@@ -265,8 +266,9 @@ 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
|
||||
{
|
||||
if( !bIsFirstBPMSegment && iStartRowThisSegment >= m_WarpSegments[j].m_iStartRow )
|
||||
continue;
|
||||
@@ -282,6 +284,13 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
|
||||
|
||||
const float fBeatsInThisSegment = fStartBeatNextSegment - fStartBeatThisSegment;
|
||||
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 )
|
||||
{
|
||||
// this BPMSegment IS the current segment
|
||||
@@ -290,11 +299,22 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
|
||||
bFreezeOut = false;
|
||||
bDelayOut = false;
|
||||
//bWarpOut = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// this BPMSegment is NOT the current segment
|
||||
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?
|
||||
vector<BPMSegment> vBPMS = m_BPMSegments;
|
||||
@@ -413,30 +433,30 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd )
|
||||
|
||||
if( iStartRow == 0 )
|
||||
{
|
||||
/* If we're shifting up at the beginning, we just shifted up the first BPMSegment. That
|
||||
* segment must always begin at 0. */
|
||||
/* If we're shifting up at the beginning, we just shifted up the first
|
||||
* BPMSegment. That segment must always begin at 0. */
|
||||
ASSERT( m_BPMSegments.size() > 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 )
|
||||
{
|
||||
/* Remember the BPM at the end of the region being deleted. */
|
||||
float fNewBPM = this->GetBPMAtBeat( NoteRowToBeat(iStartRow+iRowsToDelete) );
|
||||
|
||||
/* We're moving rows up. Delete any BPM changes and stops in the region being
|
||||
* deleted. */
|
||||
/* We're moving rows up. Delete any BPM changes and stops in the region
|
||||
* being deleted. */
|
||||
for( unsigned i = 0; i < m_BPMSegments.size(); i++ )
|
||||
{
|
||||
BPMSegment &bpm = m_BPMSegments[i];
|
||||
|
||||
/* Before deleted region: */
|
||||
// Before deleted region:
|
||||
if( bpm.m_iStartRow < iStartRow )
|
||||
continue;
|
||||
|
||||
/* Inside deleted region: */
|
||||
// Inside deleted region:
|
||||
if( bpm.m_iStartRow < iStartRow+iRowsToDelete )
|
||||
{
|
||||
m_BPMSegments.erase( m_BPMSegments.begin()+i, m_BPMSegments.begin()+i+1 );
|
||||
@@ -444,7 +464,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete )
|
||||
continue;
|
||||
}
|
||||
|
||||
/* After deleted region: */
|
||||
// After deleted region:
|
||||
bpm.m_iStartRow -= iRowsToDelete;
|
||||
}
|
||||
|
||||
@@ -452,11 +472,11 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete )
|
||||
{
|
||||
StopSegment &stop = m_StopSegments[i];
|
||||
|
||||
/* Before deleted region: */
|
||||
// Before deleted region:
|
||||
if( stop.m_iStartRow < iStartRow )
|
||||
continue;
|
||||
|
||||
/* Inside deleted region: */
|
||||
// Inside deleted region:
|
||||
if( stop.m_iStartRow < iStartRow+iRowsToDelete )
|
||||
{
|
||||
m_StopSegments.erase( m_StopSegments.begin()+i, m_StopSegments.begin()+i+1 );
|
||||
@@ -464,7 +484,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete )
|
||||
continue;
|
||||
}
|
||||
|
||||
/* After deleted region: */
|
||||
// After deleted region:
|
||||
stop.m_iStartRow -= iRowsToDelete;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -82,8 +82,8 @@ struct TimeSignatureSegment
|
||||
/*
|
||||
struct WarpSegment
|
||||
{
|
||||
WarpSegment() : m_iStartRow(-1), int m_iEndRow(-1) { }
|
||||
WarpSegment( int s, int e ){ m_iStartRow = max( 0, s ); m_iEndRow = max( 0, e ) }
|
||||
WarpSegment() : m_iStartRow(-1), m_iEndRow(-1) { }
|
||||
WarpSegment( int s, int e ){ m_iStartRow = max( 0, s ); m_iEndRow = max( 0, e ); }
|
||||
int m_iStartRow;
|
||||
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 m_iStartRow < other.m_iStartRow; }
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
class TimingData
|
||||
@@ -112,6 +112,7 @@ public:
|
||||
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)
|
||||
float GetStopAtRow( int iNoteRow, bool &bDelayOut ) const;
|
||||
void SetDelayAtRow( int iNoteRow, float fSeconds ); // sm-ssc
|
||||
void MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor );
|
||||
void AddBPMSegment( const BPMSegment &seg );
|
||||
void AddStopSegment( const StopSegment &seg );
|
||||
|
||||
+14
-8
@@ -88,14 +88,14 @@ void WheelBase::BeginScreen()
|
||||
|
||||
void WheelBase::SetItemPosition( Actor &item, float fPosOffsetsFromMiddle )
|
||||
{
|
||||
/* Don't supply and item index or num items. The number of items can be so
|
||||
/* Don't supply and item index or num items. The number of items can be so
|
||||
* large that transforms that depend on such large numbers are likely to break. */
|
||||
int iItemIndex = 0; // dummy
|
||||
int iNumItems = 1; // dummy
|
||||
|
||||
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.y = roundf( ts.pos.y );
|
||||
ts.pos.z = roundf( ts.pos.z );
|
||||
@@ -148,7 +148,7 @@ void WheelBase::Update( float 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() )
|
||||
SetPositions();
|
||||
|
||||
@@ -207,7 +207,7 @@ void WheelBase::Update( float fDeltaTime )
|
||||
|
||||
if( IsMoving() )
|
||||
{
|
||||
/* We're automatically moving. Move linearly, and don't clamp
|
||||
/* We're automatically moving. Move linearly, and don't clamp
|
||||
* to the selection. */
|
||||
float fSpinSpeed = m_SpinSpeed*m_Moving;
|
||||
m_fPositionOffsetFromSelection -= fSpinSpeed*fDeltaTime;
|
||||
@@ -215,8 +215,8 @@ void WheelBase::Update( float fDeltaTime )
|
||||
/* Make sure that we don't go further than 1 away, in case the
|
||||
* speed is very high or we miss a lot of frames. */
|
||||
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) ||
|
||||
(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 IsLocked( T* p, lua_State *L ){ lua_pushboolean( L, p->WheelIsLocked() ); return 1; }
|
||||
// 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()
|
||||
{
|
||||
@@ -534,7 +537,10 @@ public:
|
||||
ADD_METHOD( IsSettled );
|
||||
ADD_METHOD( IsLocked );
|
||||
// evil shit
|
||||
ADD_METHOD( Move );
|
||||
//ADD_METHOD( Move );
|
||||
//ADD_METHOD( ChangeMusic );
|
||||
//ADD_METHOD( ChangeMusicUnlessLocked );
|
||||
//ADD_METHOD( SetOpenSection );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -74,7 +74,6 @@ protected:
|
||||
int m_iSelection; // index into m_CurWheelItemBaseData
|
||||
RString m_sExpandedSectionName;
|
||||
|
||||
|
||||
int m_iSwitchesLeftInSpinDown;
|
||||
float m_fLockedWheelVelocity;
|
||||
// 0 = none; -1 or 1 = up/down
|
||||
|
||||
@@ -39,14 +39,14 @@ static bool DoCleanShutdown( int signal, siginfo_t *si, const ucontext_t *uc )
|
||||
if( IsFatalSignal(signal) )
|
||||
return false;
|
||||
|
||||
/* ^C. */
|
||||
// ^C.
|
||||
ArchHooks::SetUserQuit();
|
||||
return true;
|
||||
}
|
||||
|
||||
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) )
|
||||
return true;
|
||||
|
||||
@@ -63,14 +63,14 @@ static bool DoEmergencyShutdown( int signal, siginfo_t *si, const ucontext_t *us
|
||||
|
||||
void ArchHooks_MacOSX::Init()
|
||||
{
|
||||
/* First, handle non-fatal termination signals. */
|
||||
// First, handle non-fatal termination signals.
|
||||
SignalHandler::OnClose( DoCleanShutdown );
|
||||
CrashHandler::CrashHandlerHandleArgs( g_argc, g_argv );
|
||||
CrashHandler::InitializeCrashHandler();
|
||||
SignalHandler::OnClose( DoCrashSignalHandler );
|
||||
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
|
||||
// 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()
|
||||
{
|
||||
/* Get system version */
|
||||
// Get system version
|
||||
RString sSystemVersion;
|
||||
{
|
||||
long major = 0, minor = 0, bugFix = 0;
|
||||
@@ -236,7 +236,7 @@ void ArchHooks_MacOSX::DumpDebugInfo()
|
||||
|
||||
size_t size;
|
||||
#define GET_PARAM( name, var ) (size = sizeof(var), sysctlbyname(name, &var, &size, NULL, 0) )
|
||||
/* Get memory */
|
||||
// Get memory
|
||||
float fRam;
|
||||
char ramPower;
|
||||
{
|
||||
@@ -254,7 +254,7 @@ void ArchHooks_MacOSX::DumpDebugInfo()
|
||||
}
|
||||
}
|
||||
|
||||
/* Get processor information */
|
||||
// Get processor information
|
||||
int iMaxCPUs = 0;
|
||||
int iCPUs = 0;
|
||||
float fFreq;
|
||||
@@ -314,7 +314,7 @@ void ArchHooks_MacOSX::DumpDebugInfo()
|
||||
} while( false );
|
||||
#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( "Clock speed %.2f %cHz", fFreq, freqPower );
|
||||
LOG->Info( "%s", sSystemVersion.c_str());
|
||||
@@ -339,7 +339,7 @@ RString ArchHooks::GetPreferredLanguage()
|
||||
CFStringRef lang;
|
||||
|
||||
if( CFArrayGetCount(languages) > 0 &&
|
||||
(lang = (CFStringRef)CFArrayGetValueAtIndex(languages, 0)) != NULL )
|
||||
(lang = (CFStringRef)CFArrayGetValueAtIndex(languages, 0)) != NULL )
|
||||
{
|
||||
// MacRoman agrees with ASCII in the low-order 7 bits.
|
||||
const char *str = CFStringGetCStringPtr( lang, kCFStringEncodingMacRoman );
|
||||
@@ -354,7 +354,7 @@ RString ArchHooks::GetPreferredLanguage()
|
||||
bool ArchHooks_MacOSX::GoToURL( RString sUrl )
|
||||
{
|
||||
CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, (const UInt8*)sUrl.data(),
|
||||
sUrl.length(), kCFStringEncodingUTF8, NULL );
|
||||
sUrl.length(), kCFStringEncodingUTF8, NULL );
|
||||
OSStatus result = LSOpenCFURLRef( url, NULL );
|
||||
|
||||
CFRelease( url );
|
||||
|
||||
@@ -670,7 +670,7 @@ static wchar_t ScancodeAndKeysToChar( DWORD scancode, unsigned char keys[256] )
|
||||
{
|
||||
static HKL layout = GetKeyboardLayout(0); // 0 == current thread
|
||||
UINT vk = MapVirtualKeyEx( scancode, 1, layout );
|
||||
|
||||
|
||||
static bool bInitialized = false;
|
||||
|
||||
typedef int (WINAPI TOUNICODEEX)( IN UINT wVirtKey, IN UINT wScanCode, IN CONST BYTE *lpKeyState, OUT LPWSTR pwszBuff, IN int cchBuff, IN UINT wFlags, IN HKL dwhkl );
|
||||
|
||||
@@ -60,7 +60,7 @@ LowLevelWindow_X11::~LowLevelWindow_X11()
|
||||
if( !m_bWasWindowed )
|
||||
{
|
||||
XRRSetScreenConfig( Dpy, g_pScreenConfig, RootWindow(Dpy, DefaultScreen(Dpy)), g_iOldSize, g_OldRotation, CurrentTime );
|
||||
|
||||
|
||||
XUngrabKeyboard( Dpy, CurrentTime );
|
||||
}
|
||||
if( g_pContext )
|
||||
@@ -94,8 +94,7 @@ void *LowLevelWindow_X11::GetProcAddress( RString s )
|
||||
RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDeviceOut )
|
||||
{
|
||||
#if defined(UNIX)
|
||||
/*
|
||||
* nVidia cards:
|
||||
/* nVidia cards:
|
||||
*
|
||||
* 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
|
||||
@@ -118,13 +117,13 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
|
||||
|
||||
if( p.bpp == 32 )
|
||||
{
|
||||
visAttribs[i++] = GLX_RED_SIZE; visAttribs[i++] = 8;
|
||||
visAttribs[i++] = GLX_RED_SIZE; visAttribs[i++] = 8;
|
||||
visAttribs[i++] = GLX_GREEN_SIZE; visAttribs[i++] = 8;
|
||||
visAttribs[i++] = GLX_BLUE_SIZE; visAttribs[i++] = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
visAttribs[i++] = GLX_RED_SIZE; visAttribs[i++] = 5;
|
||||
visAttribs[i++] = GLX_RED_SIZE; visAttribs[i++] = 5;
|
||||
visAttribs[i++] = GLX_GREEN_SIZE; visAttribs[i++] = 6;
|
||||
visAttribs[i++] = GLX_BLUE_SIZE; visAttribs[i++] = 5;
|
||||
}
|
||||
@@ -143,7 +142,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
|
||||
// So, let's recreate the window when changing that state.
|
||||
if( !MakeWindow(Win, xvi->screen, xvi->depth, xvi->visual, p.width, p.height, !p.windowed) )
|
||||
return "Failed to create the window.";
|
||||
|
||||
|
||||
if( !MakeWindow(g_AltWindow, xvi->screen, xvi->depth, xvi->visual, p.width, p.height, !p.windowed) )
|
||||
FAIL_M( "Failed to create the alt window." ); // Should this be fatal?
|
||||
|
||||
@@ -178,8 +177,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
|
||||
}
|
||||
else
|
||||
{
|
||||
// We're remodeling the existing window, and not touching the
|
||||
// context.
|
||||
// We're remodeling the existing window, and not touching the context.
|
||||
bNewDeviceOut = false;
|
||||
}
|
||||
|
||||
@@ -196,9 +194,9 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
|
||||
int iSizesXct;
|
||||
XRRScreenSize *pSizesX = XRRSizes( Dpy, DefaultScreen(Dpy), &iSizesXct );
|
||||
ASSERT_M( iSizesXct != 0, "Couldn't get resolution list from X server" );
|
||||
|
||||
|
||||
int iSizeMatch = -1;
|
||||
|
||||
|
||||
for( int i = 0; i < iSizesXct; ++i )
|
||||
{
|
||||
if( pSizesX[i].width == p.width && pSizesX[i].height == p.height )
|
||||
@@ -211,10 +209,10 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
|
||||
// Set this mode.
|
||||
// XXX: This doesn't handle if the config has changed since we queried it (see man Xrandr)
|
||||
XRRSetScreenConfig( Dpy, g_pScreenConfig, RootWindow(Dpy, DefaultScreen(Dpy)), iSizeMatch, 1, CurrentTime );
|
||||
|
||||
|
||||
// Move the window to the corner that the screen focuses in on.
|
||||
XMoveWindow( Dpy, Win, 0, 0 );
|
||||
|
||||
|
||||
XRaiseWindow( Dpy, Win );
|
||||
|
||||
// We want to prevent the WM from catching anything that comes from the keyboard.
|
||||
@@ -275,21 +273,21 @@ void LowLevelWindow_X11::SwapBuffers()
|
||||
|
||||
if( PREFSMAN->m_bDisableScreenSaver )
|
||||
{
|
||||
/* Disable the screensaver. */
|
||||
// Disable the screensaver.
|
||||
#if defined(HAVE_LIBXTST)
|
||||
/* This causes flicker. */
|
||||
// This causes flicker.
|
||||
// XForceScreenSaver( Dpy, ScreenSaverReset );
|
||||
|
||||
/*
|
||||
* Instead, send a null relative mouse motion, to trick X into thinking there has been
|
||||
* user activity.
|
||||
|
||||
/* Instead, send a null relative mouse motion, to trick X into thinking
|
||||
* there has been user activity.
|
||||
*
|
||||
* This also handles XScreenSaver; XForceScreenSaver only handles the internal X11
|
||||
* screen blanker.
|
||||
* This also handles XScreenSaver; XForceScreenSaver only handles the
|
||||
* internal X11 screen blanker.
|
||||
*
|
||||
* This will delay the X blanker, DPMS and XScreenSaver from activating, and will
|
||||
* disable the blanker and XScreenSaver if they're already active (unless XSS is
|
||||
* locked). For some reason, it doesn't un-blank DPMS if it's already active.
|
||||
* This will delay the X blanker, DPMS and XScreenSaver from activating,
|
||||
* and will disable the blanker and XScreenSaver if they're already active
|
||||
* (unless XSS is locked). For some reason, it doesn't un-blank DPMS if
|
||||
* it's already active.
|
||||
*/
|
||||
|
||||
XLockDisplay( Dpy );
|
||||
@@ -311,7 +309,7 @@ void LowLevelWindow_X11::GetDisplayResolutions( DisplayResolutions &out ) const
|
||||
int iSizesXct;
|
||||
XRRScreenSize *pSizesX = XRRSizes( Dpy, DefaultScreen( Dpy ), &iSizesXct );
|
||||
ASSERT_M( iSizesXct != 0, "Couldn't get resolution list from X server" );
|
||||
|
||||
|
||||
for( int i = 0; i < iSizesXct; ++i )
|
||||
{
|
||||
DisplayResolution res = { pSizesX[i].width, pSizesX[i].height, true };
|
||||
@@ -334,8 +332,8 @@ public:
|
||||
unsigned GetTexture() const { return m_iTexHandle; }
|
||||
void StartRenderingTo();
|
||||
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; }
|
||||
|
||||
private:
|
||||
@@ -373,7 +371,7 @@ RenderTarget_X11::~RenderTarget_X11()
|
||||
* does not. */
|
||||
void RenderTarget_X11::Create( const RenderTargetParam ¶m, int &iTextureWidthOut, int &iTextureHeightOut )
|
||||
{
|
||||
//ASSERT( param.iWidth == power_of_two(param.iWidth) && param.iHeight == power_of_two(param.iHeight) );
|
||||
//ASSERT( param.iWidth == power_of_two(param.iWidth) && param.iHeight == power_of_two(param.iHeight) );
|
||||
|
||||
m_iWidth = param.iWidth;
|
||||
m_iHeight = param.iHeight;
|
||||
@@ -423,10 +421,10 @@ void RenderTarget_X11::Create( const RenderTargetParam ¶m, int &iTextureWidt
|
||||
glBindTexture( GL_TEXTURE_2D, m_iTexHandle );
|
||||
|
||||
LOG->Trace( "n %i, %ix%i", m_iTexHandle, param.iWidth, param.iHeight );
|
||||
while( glGetError() != GL_NO_ERROR )
|
||||
while( glGetError() != GL_NO_ERROR )
|
||||
;
|
||||
|
||||
int iTextureWidth = power_of_two( param.iWidth );
|
||||
int iTextureWidth = power_of_two( param.iWidth );
|
||||
int iTextureHeight = power_of_two( param.iHeight );
|
||||
iTextureWidthOut = iTextureWidth;
|
||||
iTextureHeightOut = iTextureHeight;
|
||||
@@ -458,7 +456,7 @@ void RenderTarget_X11::FinishRenderingTo()
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, m_iTexHandle );
|
||||
|
||||
while( glGetError() != GL_NO_ERROR )
|
||||
while( glGetError() != GL_NO_ERROR )
|
||||
;
|
||||
|
||||
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_iWidth, m_iHeight );
|
||||
@@ -476,7 +474,7 @@ void RenderTarget_X11::FinishRenderingTo()
|
||||
|
||||
bool LowLevelWindow_X11::SupportsRenderToTexture() const
|
||||
{
|
||||
/* Server must support pbuffers: */
|
||||
// Server must support pbuffers:
|
||||
const int iScreen = DefaultScreen( Dpy );
|
||||
float fVersion = strtof( glXQueryServerString(Dpy, iScreen, GLX_VERSION), NULL );
|
||||
if( fVersion < 1.3f )
|
||||
|
||||
@@ -206,8 +206,8 @@ static void AdjustVideoModeParams( VideoModeParams &p )
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the display mode to the given size, bit depth and refresh. The refresh
|
||||
* setting may be ignored. */
|
||||
/* Set the display mode to the given size, bit depth and refresh.
|
||||
* The refresh setting may be ignored. */
|
||||
RString GraphicsWindow::SetScreenMode( const VideoModeParams &p )
|
||||
{
|
||||
if( p.windowed )
|
||||
@@ -293,7 +293,7 @@ void GraphicsWindow::CreateGraphicsWindow( const VideoModeParams &p, bool bForce
|
||||
g_HDC = GetDC( g_hWndMain );
|
||||
}
|
||||
|
||||
/* Update the window title. */
|
||||
// Update the window title.
|
||||
do
|
||||
{
|
||||
if( m_bWideWindowClass )
|
||||
@@ -305,7 +305,7 @@ void GraphicsWindow::CreateGraphicsWindow( const VideoModeParams &p, bool bForce
|
||||
SetWindowTextA( g_hWndMain, ConvertUTF8ToACP(p.sWindowTitle) );
|
||||
} while(0);
|
||||
|
||||
/* Update the window icon. */
|
||||
// Update the window icon.
|
||||
if( g_hIcon != NULL )
|
||||
{
|
||||
SetClassLong( g_hWndMain, GCL_HICON, (LONG) LoadIcon(NULL,IDI_APPLICATION) );
|
||||
|
||||
Reference in New Issue
Block a user