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

culminating in syncing with sm-ssc v1.0 public beta 2
This commit is contained in:
AJ Kelly
2010-03-31 17:37:09 -05:00
parent b279635401
commit 642f4b107c
80 changed files with 1200 additions and 918 deletions
+47 -32
View File
@@ -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
-2
View File
@@ -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
View File
@@ -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;
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
-2
View File
@@ -32,9 +32,7 @@ public:
virtual ControllerStateDisplay *Copy() const;
//
// Lua
//
virtual void PushSelf( lua_State *L );
protected:
+19
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+7 -13
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();
+1 -1
View File
@@ -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,
+5 -3
View File
@@ -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 );
+7 -22
View File
@@ -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
View File
@@ -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
View File
@@ -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,
};
+3 -3
View File
@@ -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
View File
@@ -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 &timestamp )
{
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() );
}
+1
View File
@@ -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;
-4
View File
@@ -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;
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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 &current_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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 );
}
}
+1
View File
@@ -23,6 +23,7 @@ enum PaneCategory
PaneCategory_Rolls,
PaneCategory_Mines,
PaneCategory_Hands,
//PaneCategory_Lifts,
PaneCategory_MachineHighScore,
PaneCategory_MachineHighName,
PaneCategory_ProfileHighScore,
+1 -1
View File
@@ -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;
+12
View File
@@ -163,6 +163,7 @@ void PlayerOptions::GetMods( vector<RString> &AddTo, bool bForceNoteSkin ) const
AddPart( AddTo, m_fScrolls[SCROLL_ALTERNATE], "Alternate" );
AddPart( AddTo, m_fScrolls[SCROLL_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;
+1
View File
@@ -110,6 +110,7 @@ public:
SCROLL_ALTERNATE,
SCROLL_CROSS,
SCROLL_CENTERED,
//SCROLL_X,
NUM_SCROLLS
};
enum ScoreDisplay {
+20 -22
View File
@@ -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 );
}
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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/"
-9
View File
@@ -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
View File
@@ -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
View File
@@ -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 &param, 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();
};
+1 -1
View File
@@ -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 );
+11 -13
View File
@@ -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
View File
@@ -1,5 +1,4 @@
/*
* Handle loading and decoding of sounds.
/* Handle loading and decoding of sounds.
*
* For small files, pre-decode the entire file into a regular buffer. We
* 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
View File
@@ -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 );
};
+36 -39
View File
@@ -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);
}
+39 -51
View File
@@ -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;
}
+12 -16
View File
@@ -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 );
-2
View File
@@ -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
View File
@@ -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:
+1 -1
View File
@@ -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
View File
@@ -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;
+9 -9
View File
@@ -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 );
-2
View File
@@ -21,9 +21,7 @@ public:
void UpdateText();
//
// Commands
//
virtual void PushSelf( lua_State *L );
private:
+6 -7
View File
@@ -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] );
}
}
+2 -1
View File
@@ -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() );
+9 -4
View File
@@ -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;
+53 -50
View File
@@ -75,7 +75,7 @@ static void MoveMap( int &sel, T &opt, bool ToSel, const T *mapping, unsigned cn
{
sel = FindClosestEntry( opt, mapping, cnt );
} 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;
+6 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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
+48 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+2 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 );
}
};
-1
View File
@@ -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
+10 -10
View File
@@ -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 );
+29 -31
View File
@@ -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 &param, 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 &param, 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 )
+4 -4
View File
@@ -206,8 +206,8 @@ static void AdjustVideoModeParams( VideoModeParams &p )
}
}
/* Set the display mode to the given size, bit depth and refresh. The refresh
* 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) );