no message

This commit is contained in:
Chris Danford
2002-07-03 03:13:13 +00:00
parent 302aefa0f8
commit c6f4421f32
13 changed files with 400 additions and 508 deletions
+116 -157
View File
@@ -22,194 +22,57 @@ http://www.stepmania.com
Readme Table of Contents
************************************************************
1. About StepMania
2. Minimum Requirements
3. DirectX
4. Installation
5. Connecting Dance Pads
6. Compatibility Issues
7. FAQ / Troubleshooting
8. StepMania Packages - .smzip
9. Questions, Bugs, and Suggestions
10. How StepMania Loads Songs
1. About StepMania
2. Minimum Requirements
3. DirectX
4. Installation
5. How StepMania Loads Songs
5. Connecting Dance Pads
6. Compatibility Issues
7. FAQ / Troubleshooting
8. StepMania Packages - .smzip
9. Questions, Bugs, Suggestions, and Help
11. Song and Notes File Formats
12. Game and Style File Formats
13. Building StepMania from Source Code
14. Version History
************************************************************
1. About StepMania
1. About StepMania
************************************************************
StepMania is a music/rhythm game. The goal of the game is to play the notes on the screen in time with the music.
StepMania game system is capable of playing many game types. Currently, it supports games Dance Dance Revolution, Pump It Up, BeatMania, Guitar Freaks, Drum Manaia, Para Para Paradise, EZ 2 Dancer, and more.
StepMania game system is capable of playing many game types. Currently, it supports games Dance Dance Revolution and Pump It Up, with future support for EZ 2 Dancer, BeatMania, Guitar Freaks, Drum Mania, Para Para Paradise and more.
************************************************************
2. Minimum Requirements
2. Minimum Requirements
************************************************************
* Windows 98, Windows ME, Windows 2000, or Windows XP.
* Required: Pentium II, Pentium III, Celeron, Athlon, or compatible processor, 266MHz minimum (400 MHz highly recommended). MMX technology required.
* Required: Pentium II, Pentium III, Celeron, Athlon, or compatible processor, 266MHz minimum (400 MHz highly recommended).
* 64 MB of RAM.
* 75 MB of hard drive space.
* 16-bit video card (24-bit or higher recommended).
* Video card that supports High Color (16-bit color).
* DirectX 8.1 compatible video card with drivers.
* DirectX 8.1 compatible sound card with drivers.
* DivX 5 video codec (Free or Pro).
* DivX 5 video codec (for movie visualizations).
************************************************************
3. DirectX
************************************************************
DirectX 8.1 is required before installing StepMania. If DirectX 8.1 is not installed on your computer, the installer will display a warning and abort the installation.
DirectX 8.1 is required before installing StepMania. If DirectX 8.1 is not installed on your computer, the StepMania installer will display a warning and abort the installation.
************************************************************
4. Installation
************************************************************
To install StepMania, download the file stepmania3xx.exe to a known location on your hard drive, then double-click the file icon to begin the installation. The installer will force the removal of an older version of the program if one is present. The default installation directory is 'C:\Program Files\StepMania'.
To install StepMania, download the file stepmania3.exe to a known location on your hard drive, then double-click the file icon to begin the installation. The installer automatically remove an older version of the program if one is present. The default installation directory is 'C:\Program Files\StepMania'.
************************************************************
5. Connecting Dance Pads
************************************************************
* Not recommended: PlayStation->USB converter
Using a PlayStation->USB converter is not recommended to play dancing games on the PC. All known USB converters are not capable of registering simultaneous presses of Left+Right, and Up+Down. This restriction will cause the player to miss many notes that they would have hit otherwise.
* Recommended: PlayStation->Parallel adaptor
PlayStation->Parallel converters do not have the simultaneous button problem that USB converters do. The disadvantage is that the drivers required to use these devices are finicky compared to the plug-and-play installation of a USB adaptor.
You can obtain a PlayStation->Parallel converter from just about any popular game importer:
http://www3.goldenshop.com.hk/AI-trad/pc/pc_pcdirpad.htm
http://www.lik-sang.com/catalog/product_info.php?category=55&products_id=236&
For Windows 98 and Windows Me users, the recommended driver is “DirectPad Pro 5.0 for Win9x”.
For Windows 2000 and Windows XP, the recommended drivers are NTPad XP 1.x.
Both drivers can be downloaded from Aldos web site: http://www.aldostools.com/dpad.html
************************************************************
6. Compatibility Issues
************************************************************
Some video card/driver combinations have visual errors when running StepMania. It you experience any visual errors, please visit your video card manufacturer's web site and download the latest Direct3D 8.1 drivers. Below is a list of known issues that are thought to be video card driver bugs:
* S3 Savage family cards (e.g. Diamond Stealth)
Symptom: The right edge of some graphics appears "cut off".
Explanation: Drivers do not properly handle textures > 512x512, resulting in cropped textures. Please use the Minimum detail profile to force the maximum texture size <= 512x512.
* SiS cards
Symptom: Garbled fonts.
Explanation: Drivers have errors in handling texture coordinates. Only known solution is to upgrade drivers.
* Any card older than two years
Symptom: Various graphical glitches.
Explanation: These problems are most often video card driver bugs. Please upgrade to the latest drivers, which will hopefully fix the errors.
************************************************************
7. FAQ / Troubleshooting
************************************************************
> Problem: The error "Cannot find Dinput8.dll" appears when launching the game.
You need to download DirectX 8.1.
> How do you tell if it's basic/trick/maniac?
It's kind of complicated actually. It looks at a string I call the "steps description".
- For BMS files, the steps description is parsed out of the song title. For example, in "B4U -Maniac-", "Maniac" would be parsed out.
- For DWI files, the steps description is proceeds the step data and can be only one of "BASIC", "ANOTHER", or "MANIAC".
The steps description determines which "bouncy icon" to use next the meter that shows the number of feet for a steps pattern. This is why steps with the description "Another" can have a different icon from steps with description "Trick".
From the steps description, the steps are categorized into one of 4 classes: easy, medium, hard, or other. This classification determines the ordering on the Select Music screen. For example, both "Maniac" and "SSR" steps would be categorized as hard.
> Music rates of over 100% do not work on my computer. Why?
Some sound cards do not support this function. For example, my Sound Blaster 64 works fine, but my Turtle Beach Santa Cruz can't change the playback rate.
> StepMania reports no 3D device is available even though I have Direc3D 8 drivers
In some cases, DirectX 8 will report that no 3D acceleration is available even if you have the latest drivers and a capable graphics card. To see if your computer is exhibiting this problem, click Start Menu->Run, type dxdiag, and press Enter. Select Display tab, then click on "Test Direct3D". You should get a "Direct3D test results: All tests were successful." message). If Direct3D does not work, there is something wrong in your system configuration.
In many cases, this problem can be fixed by completely removing DirectX from your system, and then re-installing DirectX. To remove DirectX, use the DirectX Buster utility available from this site. After running DirectX Buster, start at Step 1 above and re-install DirectX 8.1.
> Why will a PSX->USB convertor not work for StepMania?
I have tried many PSX->USB converters, and they all have the same problem when used with dance mats. I have not tried a Brightech adaptor myself, but I am told by a reseller that it has this same problem.
When using a dance mat, the player must be able to hit 2 directions at the same time. For example, the player must press the Left + Right buttons at the same time. Also, the player must be able to press the Up + Down buttons at the same time.
All USB converters I have seen convert the 4 Playstation directional buttons (L,R,U,D) into two axes (X and Y axes) before reporting this data to the PC. This is a major problem for the dance mat. For example, if the player presses Up and Down at the same time, the PC application sees only a single number along the Y axis and cannot detect that two buttons were pressed. This means one of the player's two presses cannot be detected by the application, and the player will miss the step.
This problem could be fixed if the Playstation directional buttons (L,R,U,D) were reported to the PC as 4 individual buttons instead of two axes. For example, this would allow the PC application to read the Up and Down buttons individually and fix the problem I mentioned above.
Some PSX->USB converters report the directional pad to the PC as 4 buttons when using a Dual Shock controller in "ANALOG" mode. This solution is almost perfect, expect that dance pads do not have the ANALOG button to turn on this mode. So, dance mats are forced to use non-analog mode, where the directional buttons are reported as 2 axes. A simple fix would be to have a physical switch on the PSX->USB adaptor that would force ANALOG mode to be on. This would enable PSX controllers that do not have an ANALOG button to have their directional pad reported to the PC as 4 buttons.
> How can I improve performance
Improving performance
You should check that you have the latest drivers installed for your motherboard and especially for the AGP bus. These drivers make sure that all communication between the graphics adapter, CPU and memory are done using the most efficient way, for example by enabling full AGP support. If your system is based on an AMD Processor, updating the drivers is of utmost importance, since most Microsoft Windows versions have limited out-of-the-box support for motherboard chipsets commonly used with AMD processors. These are known as AGP Miniport drivers.
Here's a short list of sites where you can find suitable drivers for most common system configurations:
AMD Athlon/Duron systems with an AMD 760 or 750 chipset (AGP-Driver / Miniport) http://www.amd.com/products/cpg/bin/
AMD Athlon/Duron systems with a VIA chipset (VIA 4-in-1 Driver) http://www.viatech.com/jsp/en/dr/driver.jsp
Intel Pentium II, III, 4 or Celeron-based systems with Intel chipsets (440BX, 810, 815, 820, 850) (Intel Chipset Software) http://support.intel.com/support/chipsets/driver.htm
Also, please check that you have "AGP Texture Acceleration Enabled" in DirectX. Here's how to check if it's enabled:
Click on your windows "Start"
Choose "Run..."
Type: dxdiag
Press "OK"
Then when dxdiag has loaded, select the "Display" tab
Make sure that the "AGP Texture Acceleration" is ENABLED. If it's not, please enable it.
************************************************************
8. StepMania Packages - .smzip
************************************************************
The StepMania package format was created to make the distribution of songs and other add-ons very easy. StepMania package files have the extension '.smzip' and can be installed by double-clicking on the .smzip file. When the StepMania installer runs, it will associate will associate the .smzip file type with the program 'smpackage.exe' in the StepMania installation directory.
The file format for an .smzip file is actually the PK-Zip standard. This means you can rename any .smzip file to have the extension '.zip', then open the file in another compression package (e.g. WinZip).
The StepMania Package Manager (smpackage.exe) has two functions:
* It launches and installs a package when a .smzip file is double-clicked.
* It can create smzip packages from songs installed in your Songs folder.
To launch the Package Manager in order to export packages of Songs, Click Start Menu->Programs->StepMania->Package Manager.
A StepMania package is 'installed' by extracting all files in the package to the StepMania program directory. This allows songs, themes, new game types, and visualizations to all be installed by the Package Manager. For example, if you wanted to install a new song from a package, you would set the relative path of files for that song to "Songs\Group Name\Song Name", so that the files will be extracted to the appropriate sub folders when installed by the Package Manager. Note that the Package Manager will automatically set the correct paths when you create new packages from within the Package Manager.
************************************************************
9. Questions, Bugs, and Suggestions
************************************************************
If you have a question or problem about StepMania, please try asking your question to the StepMania message board at http://ddrpccentral.teamgwailo.com/cgi-bin/YaBB/YaBB.pl?board=stepmania
If you have found a bug, please file a bug report into the SourceForge bug tracking system. This will allow the developers to track and fix bugs much more efficiently. http://sourceforge.net/tracker/?group_id=37892&atid=421366
* In a bug report, please specify your video card brand and model, and your OS version.
* PLEASE, PLEASE enter your e-mail address on the bug reports. In many cases, we need more information from the bug reporter.
* If your problem is related to a timing issue with a song, please zip up the song and attach it to the bug report using the form above. Also, please make sure the timing issue is specific to StepMania (e.g. the song works correctly in Delight^2 or DWI, but is off in StepMania).
Likewise, please use SourceForge's feature request system to enter new feature requests.
Feel free to discuss the bugs or feature requests on the message board though.  
http://sourceforge.net/tracker/?atid=421369&group_id=37892&func=browse
************************************************************
10. How StepMania Loads Songs
5. How StepMania Loads Songs
************************************************************
StepMania supports two completely independent directory structures for organizing your songs:
@@ -250,9 +113,104 @@ Banners (optional) - For StepMania, these files can be in PNG, JPG, GIF, or BMP
Music (required) - For StepMania, these files can be in PNG, JPG, GIF, or BMP format. To be compatible with DWI though, they must be PNG, be rotated 45 degrees counter-clockwise and have dimensions 175x175. (Note that StepMania will automatically detect and correct the rotation of any DWI-formatted banners.
DWI file (required) - See the Dance With Intensity readme for more information on the DWI file format.
Goals of a new file format:
 support multiple game types
************************************************************
5. Connecting Dance Pads
************************************************************
There are several devices that allow you to connect PlayStation dance pads to your PC.
* Not recommended: generic PlayStation->USB converter
Using a generic PlayStation->USB converter is not recommended to play any dancing game on the PC. The vast majority of these converters are not capable of registering simultaneous presses of Left+Right or Up+Down. This restriction will cause the player to miss many notes where two buttons must be hit simultaneously.
* Highly Recommended: Special PlayStation->USB adaptor
There is just one brand of PlayStation->USB adaptor that functions perfectly with StepMania. These adaptors are available for purchase at the StepMania web site (www.stepmania.com) and through some importers (www.liksang.com). The adaptor is made by “Boom”, and it small and black with a detachable USB cable. These adaptors cost about $15 and allow you to attach one dance pad per adaptor. The primary advantage of these adaptors is that they do not require special drivers and require no configuring.
* Semi-Recommended: PlayStation->Parallel adaptor
PlayStation->Parallel converters do not have the simultaneous button problem that USB converters do. The disadvantage of these adaptors is that home-made drivers are required to use these devices. These drivers are often finicky and incompatible with some sound cards. PlayStation->Parallel adaptors can be purchased from the StepMania web site or any importer.
For Windows 98 and Windows Me users, the recommended driver is “DirectPad Pro 5.0 for Win9x”. For Windows 2000 and Windows XP, the recommended drivers are NTPad XP 1.x. Both of these drivers can be downloaded from Aldos web site: http://www.aldostools.com/dpad.html
************************************************************
6. Compatibility Issues
************************************************************
Some video card/driver combinations have visual errors when running StepMania. If you experience any visual errors, please visit your video card manufacturer's web site and download the latest Direct3D 8.1 drivers. Below is a list of known issues that are thought to be video card driver bugs:
* S3 Savage family cards (e.g. Diamond Stealth)
Symptom: The right edge of some graphics appears "cut off".
Explanation: Drivers do not properly handle textures > 512x512, resulting in cropped textures. Please use the Low texture detail option to force texture to be 512x512 or smaller.
* SiS cards
Symptom: Garbled fonts.
Explanation: Drivers have errors in handling texture coordinates. Only known solution is to upgrade drivers.
* Any card older than two years
Symptom: Various graphical glitches.
Explanation: These problems are most often video card driver bugs. Please upgrade to the latest drivers, which will hopefully fix the errors.
************************************************************
7. FAQ / Troubleshooting
************************************************************
* The error "Cannot find Dinput8.dll" appears when launching the game.
You need to download DirectX 8.1. http://www.microsoft.com/directx
* Music rates of over 100% do not work on my computer. Why?
Some very old sound cards do not support sound playback rates that are greater than the original sample rate. This problem is likely to be corrected by newer sound card drivers.
* StepMania reports “Direct3D Create Device failed”.
This error means that your video card or drivers do not support Direct3D 8. Download the latest drivers for your video card. If your video card is older than 2 or 3 years, Direct3D 8 drivers may not be available. Sorry.
* Im looking to purchase a video card. What works well with StepMania?
Just about any video card manufactured in the last year will run StepMania flawlessly at 60 frames per second. I recommend any card with an nVidia GeForce chip or an ATI Radeon chip.
* How can I improve performance with my existing video card
1. Install the latest drivers for your video card.
2. Press F5 in the game to toggle between high detail and low detail modes.
************************************************************
8. StepMania Packages - .smzip
************************************************************
The StepMania package format was created to make the distribution of songs and other add-ons very easy. StepMania package files have the extension '.smzip' and can be installed by double-clicking the .smzip file.
A StepMania package is 'installed' by extracting all files in the package to the StepMania program directory. This allows songs, courses, themes, and visualizations to all be installed by the Package Manager.
The file format of an .smzip file is actually the PK-Zip standard. This means you can rename any .smzip file to have the extension '.zip', and then open the file in any compression package (e.g. WinZip).
The StepMania Package Manager (smpackage.exe) can also create song packages for you. Simply launch the Package Manager (Start Menu->Programs->StepMania->Package Manager), click the song you want to create a package for, click the Export button, and a .smzip package will be placed on your desktop.
************************************************************
9. Questions, Bugs, Suggestions, and Help
************************************************************
If you have a question or problem about StepMania, please try asking your question to the StepMania message board. A link is available from the StepMania web site http://www.stepmania.com.
If you have found a bug, please file a bug report into the SourceForge bug tracking system (http://sourceforge.net/tracker/?group_id=37892&atid=421366). This will allow the developers to track and fix bugs much more efficiently.
* In a bug report, please specify your video card brand and model, and your OS version.
* PLEASE, PLEASE enter your e-mail address on the bug reports. In many cases, we need more information from the bug reporter.
Please use SourceForge's feature request system to enter new feature requests (http://sourceforge.net/tracker/?atid=421369&group_id=37892&func=browse). Also, please discuss feature ideas on the StepMania message board or the StepMania developers list ([email protected]).  
If you would like to help with development of StepMania, please send an email to the StepMania developers list ([email protected]) or to Chris ([email protected]).
************************************************************
11. Song and Notes File Formats
************************************************************
@@ -356,6 +314,7 @@ CHANGE: "Graphic Detail" presets
BUG FIX: Installer DirectX check now works
NEW FEATURE: Aracde and Free Play game modes
------------------------Version 1.90-------------------------
OPTIMIZATION: Major speedup to BitmapText loading
CHANGE: Menus changes to accomodate MAX-style menus
+17 -9
View File
@@ -64,7 +64,8 @@ enum NoteType
NOTE_8TH, // eighth notes
NOTE_12TH, // triplets
NOTE_16TH, // sixteenth notes
NUM_NOTE_TYPES
NUM_NOTE_TYPES,
NOTE_INVALID
};
inline D3DXCOLOR NoteTypeToColor( NoteType nt )
@@ -91,16 +92,23 @@ inline float NoteTypeToBeat( NoteType nt )
}
};
inline NoteType GetNoteType( int iNoteIndex )
{
if( iNoteIndex % (ELEMENTS_PER_MEASURE/4) == 0)
return NOTE_4TH;
else if( iNoteIndex % (ELEMENTS_PER_MEASURE/8) == 0)
return NOTE_8TH;
else if( iNoteIndex % (ELEMENTS_PER_MEASURE/12) == 0)
return NOTE_12TH;
else if( iNoteIndex % (ELEMENTS_PER_MEASURE/16) == 0)
return NOTE_16TH;
ASSERT(0);
return NOTE_INVALID;
};
inline bool IsNoteOfType( int iNoteIndex, NoteType t )
{
switch( t )
{
case NOTE_4TH: return iNoteIndex % (ELEMENTS_PER_MEASURE/4) == 0;
case NOTE_8TH: return iNoteIndex % (ELEMENTS_PER_MEASURE/8) == 0;
case NOTE_12TH: return iNoteIndex % (ELEMENTS_PER_MEASURE/12) == 0;
case NOTE_16TH: return iNoteIndex % (ELEMENTS_PER_MEASURE/16) == 0;
default: ASSERT( false ); return false;
}
return GetNoteType(iNoteIndex) == t;
};
inline D3DXCOLOR GetNoteColorFromIndex( int iStepIndex )
+127 -12
View File
@@ -37,6 +37,114 @@ NoteData::~NoteData()
}
void NoteData::LoadFromSMNoteDataString( CString sSMNoteData )
{
// strip comments out of sSMNoteData
while( sSMNoteData.Find("//") != -1 )
{
int iIndexCommentStart = sSMNoteData.Find("//");
int iIndexCommentEnd = sSMNoteData.Find("\n", iIndexCommentStart);
if( iIndexCommentEnd == -1 ) // comment doesn't have an end?
sSMNoteData.Delete( iIndexCommentStart, 2 );
else
sSMNoteData.Delete( iIndexCommentStart, iIndexCommentEnd-iIndexCommentStart );
}
CStringArray asMeasures;
split( sSMNoteData, ",", asMeasures, true ); // ignore empty is important
for( int m=0; m<asMeasures.GetSize(); m++ ) // foreach measure
{
CString &sMeasureString = asMeasures[m];
sMeasureString.TrimLeft();
sMeasureString.TrimRight();
CStringArray asMeasureLines;
split( sMeasureString, "\n", asMeasureLines, true ); // ignore empty is important
for( int l=0; l<asMeasureLines.GetSize(); l++ )
{
CString &sMeasureLine = asMeasureLines[l];
sMeasureLine.TrimLeft();
sMeasureLine.TrimRight();
const float fPercentIntoMeasure = l/(float)asMeasureLines.GetSize();
const float fBeat = (m + fPercentIntoMeasure) * BEATS_PER_MEASURE;
const int iIndex = BeatToNoteRow( fBeat );
if( m_iNumTracks != sMeasureLine.GetLength() )
throw RageException( "Actual number of note columns (%d) is different from the NotesType (%d).", m_iNumTracks, sMeasureLine.GetLength() );
for( int c=0; c<sMeasureLine.GetLength(); c++ )
m_TapNotes[c][iIndex] = sMeasureLine[c];
}
}
}
CString NoteData::GetSMNoteDataString()
{
this->ConvertHoldNotesTo2sAnd3s();
float fLastBeat = GetLastBeat();
int iLastMeasure = int( fLastBeat/BEATS_PER_MEASURE );
CStringArray asMeasureStrings;
for( int m=0; m<=iLastMeasure; m++ ) // foreach measure
{
int iMeasureStartIndex = m * ELEMENTS_PER_MEASURE;
int iMeasureLastIndex = (m+1) * ELEMENTS_PER_MEASURE - 1;
// probe to find the smallest note type
NoteType nt;
int iNoteIndexSpacing;
for( nt=(NoteType)0; nt<NUM_NOTE_TYPES; nt=NoteType(nt+1) )
{
float fBeatSpacing = NoteTypeToBeat( nt );
iNoteIndexSpacing = roundf( fBeatSpacing * ELEMENTS_PER_BEAT );
bool bFoundSmallerNote = false;
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i++ ) // for each index in this measure
{
if( i % iNoteIndexSpacing == 0 )
continue; // skip
if( !IsRowEmpty(i) )
{
bFoundSmallerNote = true;
break;
}
}
if( bFoundSmallerNote )
continue; // keep searching
else
break; // stop searching
}
if( nt == NUM_NOTE_TYPES ) // we didn't find one
iNoteIndexSpacing = 1;
CStringArray asMeasureLines;
asMeasureLines.Add( ssprintf(" // measure %d", m+1) );
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i+=iNoteIndexSpacing )
{
CString sLineString;
for( int c=0; c<m_iNumTracks; c++ )
sLineString += m_TapNotes[c][i];
asMeasureLines.Add( sLineString );
}
CString sMeasureString = join( "\n", asMeasureLines );
asMeasureStrings.Add( sMeasureString );
}
this->Convert2sAnd3sToHoldNotes();
return join( "\n,", asMeasureStrings );
}
void NoteData::ClearRange( int iNoteIndexBegin, int iNoteIndexEnd )
{
// delete old TapNotes in the range
@@ -601,8 +709,8 @@ float NoteData::GetStreamRadarValue( float fSongSeconds )
// density of steps
int iNumNotes = GetNumTapNotes() + GetNumHoldNotes();
float fNotesPerSecond = iNumNotes/fSongSeconds;
float fReturn = fNotesPerSecond / 5;
return min( fReturn, 1.2f );
float fReturn = fNotesPerSecond / 10;
return min( fReturn, 1.0f );
}
float NoteData::GetVoltageRadarValue( float fSongSeconds )
@@ -610,7 +718,7 @@ float NoteData::GetVoltageRadarValue( float fSongSeconds )
// peak density of steps
float fMaxDensityPerSecSoFar = 0;
for( int i=0; i<MAX_BEATS; i+=8 )
for( int i=0; i<MAX_BEATS; i+=16 )
{
int iNumNotesThisMeasure = GetNumTapNotes((float)i,(float)i+8) + GetNumHoldNotes((float)i,(float)i+8);
@@ -622,30 +730,37 @@ float NoteData::GetVoltageRadarValue( float fSongSeconds )
fMaxDensityPerSecSoFar = fDensityPerSecThisMeasure;
}
float fReturn = fMaxDensityPerSecSoFar*10;
return min( fReturn, 1.2f );
float fReturn = fMaxDensityPerSecSoFar*5;
return min( fReturn, 1.0f );
}
float NoteData::GetAirRadarValue( float fSongSeconds )
{
// number of doubles
int iNumDoubles = GetNumDoubles();
float fReturn = iNumDoubles / fSongSeconds * 2;
return min( fReturn, 1.2f );
float fReturn = iNumDoubles / fSongSeconds;
return min( fReturn, 1.0f );
}
float NoteData::GetChaosRadarValue( float fSongSeconds )
{
// irregularity of steps
float fReturn = fabsf( GetStreamRadarValue(fSongSeconds) - GetVoltageRadarValue(fSongSeconds) ) * 2.5f;
return min( fReturn, 1.2f );
// count number of triplets
int iNumTriplets = 0;
for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ )
{
if( !IsRowEmpty(r) && IsNoteOfType(r, NOTE_12TH) )
iNumTriplets++;
}
float fReturn = iNumTriplets / fSongSeconds;
return min( fReturn, 1.0f );
}
float NoteData::GetFreezeRadarValue( float fSongSeconds )
{
// number of hold steps
float fReturn = GetNumHoldNotes() / fSongSeconds * 3;
return min( fReturn, 1.2f );
float fReturn = GetNumHoldNotes() / fSongSeconds;
return min( fReturn, 1.0f );
}
+3 -1
View File
@@ -39,7 +39,6 @@ inline float NoteRowToBeat( int iNoteIndex ) { return NoteRowToBeat( (float)iN
class NoteData
{
public:
@@ -52,6 +51,9 @@ public:
HoldNote m_HoldNotes[MAX_HOLD_NOTE_ELEMENTS];
int m_iNumHoldNotes;
void LoadFromSMNoteDataString( CString sSMNoteData );
CString GetSMNoteDataString();
void ClearRange( int iNoteIndexBegin, int iNoteIndexEnd );
void ClearAll() { ClearRange( 0, MAX_TAP_NOTE_ROWS ); };
void CopyRange( NoteData* pFrom, int iFromIndexBegin, int iFromIndexEnd, int iToIndexBegin = -1 );
+19 -14
View File
@@ -99,8 +99,8 @@ float NoteDataWithScoring::GetActualStreamRadarValue( float fSongSeconds )
// density of steps
int iNumSuccessfulNotes = GetNumSuccessfulTapNotes() + GetNumSuccessfulHoldNotes();
float fNotesPerSecond = iNumSuccessfulNotes/fSongSeconds;
float fReturn = fNotesPerSecond / 5;
return min( fReturn, 1.2f );
float fReturn = fNotesPerSecond / 10;
return min( fReturn, 1.0f );
}
float NoteDataWithScoring::GetActualVoltageRadarValue( float fSongSeconds )
@@ -108,7 +108,7 @@ float NoteDataWithScoring::GetActualVoltageRadarValue( float fSongSeconds )
// peak density of steps
float fMaxDensityPerSecSoFar = 0;
for( int i=0; i<MAX_BEATS; i+=8 )
for( int i=0; i<MAX_BEATS; i+=16 )
{
int iNumNotesThisMeasure = GetNumSuccessfulTapNotes((float)i,(float)i+8) + GetNumSuccessfulHoldNotes((float)i,(float)i+8);
@@ -120,30 +120,35 @@ float NoteDataWithScoring::GetActualVoltageRadarValue( float fSongSeconds )
fMaxDensityPerSecSoFar = fDensityPerSecThisMeasure;
}
float fReturn = fMaxDensityPerSecSoFar*10;
return min( fReturn, 1.2f );
float fReturn = fMaxDensityPerSecSoFar*5;
return min( fReturn, 1.0f );
}
float NoteDataWithScoring::GetActualAirRadarValue( float fSongSeconds )
{
// number of doubles
int iNumDoubles = GetNumSuccessfulDoubles();
float fReturn = iNumDoubles / fSongSeconds * 2;
return min( fReturn, 1.2f );
float fReturn = iNumDoubles / fSongSeconds;
return min( fReturn, 1.0f );
}
float NoteDataWithScoring::GetActualChaosRadarValue( float fSongSeconds )
{
// irregularity of steps
float fReturn = GetChaosRadarValue(fSongSeconds) -
(GetStreamRadarValue(fSongSeconds)-GetActualStreamRadarValue(fSongSeconds)) -
(GetVoltageRadarValue(fSongSeconds)-GetActualVoltageRadarValue(fSongSeconds));
return min( fReturn, 1.2f );
// count number of triplets
int iNumTripletsCompleted = 0;
for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ )
{
if( !IsRowComplete(r) && IsNoteOfType(r, NOTE_12TH) )
iNumTripletsCompleted++;
}
float fReturn = iNumTripletsCompleted / fSongSeconds;
return min( fReturn, 1.0f );
}
float NoteDataWithScoring::GetActualFreezeRadarValue( float fSongSeconds )
{
// number of hold steps
float fReturn = GetNumSuccessfulHoldNotes() / fSongSeconds * 3;
return min( fReturn, 1.2f );
float fReturn = GetNumSuccessfulHoldNotes() / fSongSeconds;
return min( fReturn, 1.0f );
}
+7
View File
@@ -28,6 +28,13 @@ struct NoteDataWithScoring : public NoteData
int GetNumSuccessfulDoubles( const float fStartBeat = 0, const float fEndBeat = MAX_BEATS );
int GetNumSuccessfulHoldNotes( const float fStartBeat = 0, const float fEndBeat = MAX_BEATS );
inline bool IsRowComplete( int index )
{
for( int t=0; t<m_iNumTracks; t++ )
if( m_TapNotes[t][index] != '0' && m_TapNoteScores[t][index] < TNS_GREAT )
return false;
return true;
}
float GetActualRadarValue( RadarCategory rv, float fSongSeconds )
{
+67 -262
View File
@@ -17,6 +17,7 @@
#include "math.h" // for fabs()
#include "RageUtil.h"
#include "RageLog.h"
#include "NoteData.h"
#include "GameInput.h"
@@ -43,7 +44,7 @@ enum {
Notes::Notes()
{
m_NotesType = NOTES_TYPE_DANCE_SINGLE;
m_DifficultyClass = CLASS_EASY;
m_DifficultyClass = CLASS_INVALID;
m_iMeter = 0;
for( int r=0; r<NUM_RADAR_VALUES; r++ )
m_fRadarValues[r] = 0;
@@ -52,13 +53,10 @@ Notes::Notes()
m_iMaxCombo = 0;
m_iTopScore = 0;
m_TopGrade = GRADE_NO_DATA;
m_pNoteData = NULL;
}
Notes::~Notes()
{
DeleteNoteData();
}
@@ -116,19 +114,7 @@ bool Notes::LoadFromBMSFile( const CString &sPath )
{
LOG->WriteLine( "Notes::LoadFromBMSFile( '%s' )", sPath );
// make sure NoteData is loaded
ASSERT( m_pNoteData == NULL );
m_pNoteData = new NoteData;
int tempNotes[MAX_NOTE_TRACKS][MAX_TAP_NOTE_ROWS];
for( int t=0; t<MAX_NOTE_TRACKS; t++ )
{
for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ )
tempNotes[t][i] = '0';
}
NoteData tempNoteData;
CStdioFile file;
if( !file.Open( sPath, CFile::modeRead|CFile::shareDenyNone ) )
@@ -216,7 +202,7 @@ bool Notes::LoadFromBMSFile( const CString &sPath )
int iMeasureNo = atoi( value_name.Mid(1,3) );
int iTrackNum = atoi( value_name.Mid(4,2) );
CString sNoteData = value_data;
CString &sNoteData = value_data;
CArray<bool, bool&> arrayNotes;
for( int i=0; i<sNoteData.GetLength(); i+=2 )
@@ -241,7 +227,7 @@ bool Notes::LoadFromBMSFile( const CString &sPath )
mapBMSTrackToDanceNote( iTrackNum, iColumnNumber, cNoteChar );
if( iColumnNumber != -1 )
tempNotes[iColumnNumber][iNoteIndex] = cNoteChar;
tempNoteData.m_TapNotes[iColumnNumber][iNoteIndex] = cNoteChar;
}
}
}
@@ -253,15 +239,15 @@ bool Notes::LoadFromBMSFile( const CString &sPath )
{
for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ ) // for each TapNote
{
if( tempNotes[DANCE_NOTE_PAD1_UPRIGHT][i] != '0' ) // if up+right is a step
if( tempNoteData.m_TapNotes[DANCE_NOTE_PAD1_UPRIGHT][i] != '0' ) // if up+right is a step
{
tempNotes[DANCE_NOTE_PAD1_UP][i] = tempNotes[DANCE_NOTE_PAD1_UPRIGHT][i]; // add up
tempNotes[DANCE_NOTE_PAD1_UPRIGHT][i] = '0'; // subtract up+right
tempNoteData.m_TapNotes[DANCE_NOTE_PAD1_UP][i] = tempNoteData.m_TapNotes[DANCE_NOTE_PAD1_UPRIGHT][i]; // add up
tempNoteData.m_TapNotes[DANCE_NOTE_PAD1_UPRIGHT][i] = '0'; // subtract up+right
}
if( tempNotes[DANCE_NOTE_PAD2_UPRIGHT][i] != '0' ) // if up+right is a step
if( tempNoteData.m_TapNotes[DANCE_NOTE_PAD2_UPRIGHT][i] != '0' ) // if up+right is a step
{
tempNotes[DANCE_NOTE_PAD2_UP][i] = tempNotes[DANCE_NOTE_PAD2_UPRIGHT][i]; // add up
tempNotes[DANCE_NOTE_PAD2_UPRIGHT][i] = '0'; // subtract up+right
tempNoteData.m_TapNotes[DANCE_NOTE_PAD2_UP][i] = tempNoteData.m_TapNotes[DANCE_NOTE_PAD2_UPRIGHT][i]; // add up
tempNoteData.m_TapNotes[DANCE_NOTE_PAD2_UPRIGHT][i] = '0'; // subtract up+right
}
}
}
@@ -308,91 +294,21 @@ bool Notes::LoadFromBMSFile( const CString &sPath )
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 5;
}
// copy the tempData we collected into NoteData
NoteData tempNoteData2;
int iTransformNewToOld[MAX_NOTE_TRACKS];
POSITION pos = mapDanceNoteToNoteDataColumn.GetStartPosition();
while( pos != NULL ) // iterate over all k/v pairs in map
{
int iTempCol;
int iNoteDataCol;
mapDanceNoteToNoteDataColumn.GetNextAssoc( pos, iTempCol, iNoteDataCol );
for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ ) // foreach TapNote element
{
m_pNoteData->m_TapNotes[iNoteDataCol][i] = tempNotes[iTempCol][i];
}
int iOldTrack;
int iNewTrack;
mapDanceNoteToNoteDataColumn.GetNextAssoc( pos, iOldTrack, iNewTrack );
iTransformNewToOld[iNewTrack] = iOldTrack;
}
m_pNoteData->m_iNumTracks = mapDanceNoteToNoteDataColumn.GetCount();
tempNoteData2.LoadTransformed( &tempNoteData, mapDanceNoteToNoteDataColumn.GetCount(), iTransformNewToOld );
m_pNoteData->Convert2sAnd3sToHoldNotes();
// search for runs of 32nd notes of all the same note type, and convert them to freezes
for( int iCol=0; iCol<mapDanceNoteToNoteDataColumn.GetCount(); iCol++ )
{
int iIndexRunStart = -1; // -1 means we're not in the middle of a run
for( float fBeat=0; fBeat<MAX_BEATS; fBeat += 1/32.0f ) // foreach 32nd note
{
int i = BeatToNoteRow( fBeat );
if( m_pNoteData->m_TapNotes[iCol][i] == '1' ) // there is a step here
{
if( iIndexRunStart == -1 ) // we are not in the middle of a run
{
iIndexRunStart = i;
}
else // we are in the middle of a run
{
; // do nothing. Keep reading in until we hit the end of the run.
}
}
else // there isn't a step here
{
if( iIndexRunStart == -1 ) // we are not in the middle of a run
{
; // do nothing
}
else // we are in the middle of a run
{
// this ends the run
if( i - iIndexRunStart < 2 ) // reject runs of length 1
{
; // do nothing
}
else // this run is longer than 1
{
// add this HoldNote to the list
int iIndexRunEnd = i - 1;
HoldNote hn = { iCol, iIndexRunStart, iIndexRunEnd };
m_pNoteData->AddHoldNote( hn );
LOG->WriteLine( "Found a run on track %d: start: %d, end: %d.", hn.m_iTrack, hn.m_iStartIndex, hn.m_iEndIndex );
}
iIndexRunStart = -1; // reset so we can look for more runs
}
}
}
// done looking for runs
}
m_DifficultyClass = DifficultyClassFromDescriptionAndMeter( m_sDescription, m_iMeter );
if( m_iMeter == 0 )
{
switch( m_DifficultyClass )
{
case CLASS_EASY: m_iMeter = 3; break;
case CLASS_MEDIUM: m_iMeter = 5; break;
case CLASS_HARD: m_iMeter = 8; break;
default: ASSERT(0);
}
}
TidyUpData();
return true;
}
@@ -457,7 +373,7 @@ bool Notes::LoadFromDWITokens(
else if( sMode == "#DOUBLE" ) m_NotesType = NOTES_TYPE_DANCE_DOUBLE;
else if( sMode == "#COUPLE" ) m_NotesType = NOTES_TYPE_DANCE_COUPLE;
else if( sMode == "#SOLO" ) m_NotesType = NOTES_TYPE_DANCE_SOLO;
else LOG->WriteLine( "Unrecognized DWI mode '%s'", sMode );
else throw RageException( "Unrecognized DWI mode '%s'", sMode );
CMap<int, int, int, int> mapDanceNoteToNoteDataColumn;
@@ -495,15 +411,13 @@ bool Notes::LoadFromDWITokens(
m_iMeter = iNumFeet;
m_DifficultyClass = DifficultyClassFromDescriptionAndMeter( m_sDescription, m_iMeter );
//m_DifficultyClass = DifficultyClassFromDescriptionAndMeter( m_sDescription, m_iMeter );
m_sCredit = "";
ASSERT( m_pNoteData == NULL ); // if not, then we're loading this Notes twice
m_pNoteData = new NoteData;
m_pNoteData->m_iNumTracks = mapDanceNoteToNoteDataColumn.GetCount();
NoteData tempNoteData;
tempNoteData.m_iNumTracks = mapDanceNoteToNoteDataColumn.GetCount();
for( int pad=0; pad<2; pad++ ) // foreach pad
{
@@ -569,12 +483,12 @@ bool Notes::LoadFromDWITokens(
if( note1 != DANCE_NOTE_NONE )
{
int iCol1 = mapDanceNoteToNoteDataColumn[note1];
m_pNoteData->m_TapNotes[iCol1][iIndex] = '2';
tempNoteData.m_TapNotes[iCol1][iIndex] = '2';
}
if( note2 != DANCE_NOTE_NONE )
{
int iCol2 = mapDanceNoteToNoteDataColumn[note2];
m_pNoteData->m_TapNotes[iCol2][iIndex] = '2';
tempNoteData.m_TapNotes[iCol2][iIndex] = '2';
}
}
@@ -589,12 +503,12 @@ bool Notes::LoadFromDWITokens(
if( note1 != DANCE_NOTE_NONE )
{
int iCol1 = mapDanceNoteToNoteDataColumn[note1];
m_pNoteData->m_TapNotes[iCol1][iIndex] = '1';
tempNoteData.m_TapNotes[iCol1][iIndex] = '1';
}
if( note2 != DANCE_NOTE_NONE )
{
int iCol2 = mapDanceNoteToNoteDataColumn[note2];
m_pNoteData->m_TapNotes[iCol2][iIndex] = '1';
tempNoteData.m_TapNotes[iCol2][iIndex] = '1';
}
fCurrentBeat += fCurrentIncrementer;
@@ -604,9 +518,13 @@ bool Notes::LoadFromDWITokens(
}
}
m_pNoteData->Convert2sAnd3sToHoldNotes(); // this will expand the HoldNote begin markers we wrote into actual HoldNotes
tempNoteData.Convert2sAnd3sToHoldNotes(); // this will expand the HoldNote begin markers we wrote into actual HoldNotes
ASSERT( m_pNoteData->m_iNumTracks > 0 );
ASSERT( tempNoteData.m_iNumTracks > 0 );
m_sSMNoteData = tempNoteData.GetSMNoteDataString();
TidyUpData();
return true;
}
@@ -618,11 +536,10 @@ void Notes::LoadFromSMTokens(
const CString &sDifficultyClass,
const CString &sMeter,
const CString &sRadarValues,
const CString &sNoteData,
const bool bLoadNoteData
const CString &sNoteData
)
{
LOG->WriteLine( "Notes::LoadFromSMTokens( %d )", bLoadNoteData );
LOG->WriteLine( "Notes::LoadFromSMTokens()" );
m_NotesType = StringToNotesType(sNotesType);
m_sDescription = sDescription;
@@ -634,63 +551,10 @@ void Notes::LoadFromSMTokens(
if( saValues.GetSize() == NUM_RADAR_VALUES )
for( int r=0; r<NUM_RADAR_VALUES; r++ )
m_fRadarValues[r] = (float)atof(saValues[r]);
if( m_iMeter < 1 || m_iMeter > 10 )
m_iMeter = 4;
if( m_DifficultyClass == CLASS_INVALID )
m_DifficultyClass = DifficultyClassFromDescriptionAndMeter( sDescription, m_iMeter );
m_sSMNoteData = sNoteData;
//
// Load NoteData
//
if( !bLoadNoteData )
{
SAFE_DELETE( m_pNoteData );
return; // don't continue
}
// else bLoadNoteData...
if( m_pNoteData != NULL ) // already loaded
return;
// else not already loaded...
m_pNoteData = new NoteData();
m_pNoteData->m_iNumTracks = NotesTypeToNumTracks( m_NotesType );
CStringArray asNoteData;
split( sNoteData, ",", asNoteData, true );
for( int i=0; i<asNoteData.GetSize(); i+=2 )
{
int iNumRowsInMeasure = atoi( asNoteData[i] );
CString sMeasureString = asNoteData[i+1];
sMeasureString.TrimLeft();
sMeasureString.TrimRight();
CStringArray arrayNoteLines;
split( sMeasureString, "\n", arrayNoteLines, true ); // ignore empty is important here
if( arrayNoteLines.GetSize() != iNumRowsInMeasure )
throw RageException( "Actual number of note rows (%d) doesn't match what tag says (%d).", arrayNoteLines.GetSize(), iNumRowsInMeasure );
for( int l=0; l<iNumRowsInMeasure; l++ )
{
const float fPercentIntoMeasure = l/(float)arrayNoteLines.GetSize();
const float fBeat = (i/2 + fPercentIntoMeasure) * BEATS_PER_MEASURE;
const int iIndex = BeatToNoteRow( fBeat );
CString sNoteLine = arrayNoteLines[l];
sNoteLine.TrimRight();
if( m_pNoteData->m_iNumTracks != sNoteLine.GetLength() )
throw RageException( "Actual number of note columns (%d) is different from the NotesType (%d).", m_pNoteData->m_iNumTracks, sNoteLine.GetLength() );
for( int c=0; c<sNoteLine.GetLength(); c++ )
m_pNoteData->m_TapNotes[c][iIndex] = sNoteLine[c];
}
}
TidyUpData();
}
void Notes::WriteSMNotesTag( FILE* fp )
@@ -708,73 +572,39 @@ void Notes::WriteSMNotesTag( FILE* fp )
asRadarValues.Add( ssprintf("%.1f", m_fRadarValues[r]) );
fprintf( fp, " %s:\n", join(",",asRadarValues) );
//
// fill in sNoteDataOut
//
ASSERT( m_pNoteData != NULL );
m_pNoteData->ConvertHoldNotesTo2sAnd3s();
float fLastBeat = m_pNoteData->GetLastBeat();
int iLastMeasure = int( fLastBeat/BEATS_PER_MEASURE );
for( int m=0; m<=iLastMeasure; m++ ) // foreach measure
{
int iMeasureStartIndex = m * ELEMENTS_PER_MEASURE;
int iMeasureLastIndex = (m+1) * ELEMENTS_PER_MEASURE - 1;
// probe to find the smallest note type
NoteType nt;
int iNoteIndexSpacing;
for( nt=(NoteType)0; nt<NUM_NOTE_TYPES; nt=NoteType(nt+1) )
{
float fBeatSpacing = NoteTypeToBeat( nt );
iNoteIndexSpacing = roundf( fBeatSpacing * ELEMENTS_PER_BEAT );
bool bFoundSmallerNote = false;
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i++ ) // for each index in this measure
{
if( i % iNoteIndexSpacing == 0 )
continue; // skip
if( !m_pNoteData->IsRowEmpty(i) )
{
bFoundSmallerNote = true;
break;
}
}
if( bFoundSmallerNote )
continue; // keep searching
else
break; // stop searching
}
if( nt == NUM_NOTE_TYPES ) // we didn't find one
iNoteIndexSpacing = 1;
fprintf( fp, "%d, // measure %d\n", ELEMENTS_PER_MEASURE/iNoteIndexSpacing, m+1 );
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i+=iNoteIndexSpacing )
{
CString sLineString;
for( int c=0; c<m_pNoteData->m_iNumTracks; c++ )
sLineString += m_pNoteData->m_TapNotes[c][i];
fprintf( fp, "%s", sLineString );
if( i <= iMeasureLastIndex-iNoteIndexSpacing )
fprintf( fp, "\n" );
}
if( m != iLastMeasure )
fprintf( fp, ",\n" );
}
fprintf( fp, ";\n" );
m_pNoteData->Convert2sAnd3sToHoldNotes();
fprintf( fp, " %s;\n", m_sSMNoteData );
}
void Notes::GetNoteData( NoteData* pNoteDataOut )
{
pNoteDataOut->m_iNumTracks = NotesTypeToNumTracks( m_NotesType );
pNoteDataOut->LoadFromSMNoteDataString( m_sSMNoteData );
}
void Notes::SetNoteData( NoteData* pNewNoteData )
{
ASSERT( pNewNoteData->m_iNumTracks == NotesTypeToNumTracks(m_NotesType) );
m_sSMNoteData = pNewNoteData->GetSMNoteDataString();
}
void Notes::TidyUpData()
{
if( m_DifficultyClass == CLASS_INVALID )
m_DifficultyClass = DifficultyClassFromDescriptionAndMeter( m_sDescription, m_iMeter );
if( m_iMeter < 1 || m_iMeter > 10 )
{
switch( m_DifficultyClass )
{
case CLASS_EASY: m_iMeter = 3; break;
case CLASS_MEDIUM: m_iMeter = 5; break;
case CLASS_HARD: m_iMeter = 8; break;
default: ASSERT(0);
}
}
}
DifficultyClass Notes::DifficultyClassFromDescriptionAndMeter( CString sDescription, int iMeter )
{
sDescription.MakeLower();
@@ -809,35 +639,10 @@ DifficultyClass Notes::DifficultyClassFromDescriptionAndMeter( CString sDescript
}
bool Notes::IsNoteDataLoaded()
{
return m_pNoteData != NULL;
}
NoteData* Notes::GetNoteData()
{
ASSERT( m_pNoteData != NULL );
return m_pNoteData;
}
void Notes::SetNoteData( NoteData* pNewNoteData )
{
NoteData* pNoteData = GetNoteData();
pNoteData->CopyAll( pNewNoteData );
}
void Notes::DeleteNoteData()
{
SAFE_DELETE( m_pNoteData );
}
//////////////////////////////////////////////
//
//////////////////////////////////////////////
int CompareNotesPointersByMeter(const void *arg1, const void *arg2)
{
Notes* pNotes1 = *(Notes**)arg1;
+10 -10
View File
@@ -14,7 +14,7 @@
#include "GameConstantsAndTypes.h"
#include "Grade.h"
#include "NoteData.h"
class NoteData;
struct Notes
@@ -39,8 +39,7 @@ public:
const CString &sDifficultyClass,
const CString &sMeter,
const CString &sRadarValues,
const CString &sNoteDataOut,
const bool bLoadNoteData
const CString &sNoteDataOut
);
void WriteSMNotesTag( FILE* fp );
@@ -52,6 +51,11 @@ public:
int m_iMeter; // difficulty from 1-10
float m_fRadarValues[NUM_RADAR_VALUES]; // between 0.0-1.2 starting from 12-o'clock rotating clockwise
CString m_sSMNoteData;
void GetNoteData( NoteData* pNoteDataOut );
void SetNoteData( NoteData* pNewNoteData );
// Color is a function of DifficultyClass and Intended Style
D3DXCOLOR GetColor()
{
@@ -73,14 +77,10 @@ public:
int m_iMaxCombo;
int m_iNumTimesPlayed;
bool IsNoteDataLoaded();
NoteData* GetNoteData();
void SetNoteData( NoteData* pNewNoteData );
void DeleteNoteData();
protected:
void TidyUpData();
static DifficultyClass DifficultyClassFromDescriptionAndMeter( CString sDescription, int iMeter );
NoteData* m_pNoteData;
};
+8 -5
View File
@@ -88,7 +88,6 @@ ScreenEdit::ScreenEdit()
LOG->WriteLine( "ScreenEdit::ScreenEdit()" );
m_pSong = SONGMAN->GetCurrentSong();
m_pSong->LoadNoteData();
m_pNotes = SONGMAN->m_pCurNotes[PLAYER_1];
if( m_pNotes == NULL )
@@ -97,6 +96,10 @@ ScreenEdit::ScreenEdit()
m_pSong->m_arrayNotes.Add( m_pNotes );
}
NoteData noteData;
m_pNotes->GetNoteData( &noteData );
m_Mode = MODE_EDIT;
m_fBeat = 0.0f;
@@ -120,7 +123,7 @@ ScreenEdit::ScreenEdit()
m_NoteFieldEdit.SetXY( EDIT_X, EDIT_GRAY_Y );
m_NoteFieldEdit.SetZoom( 0.5f );
m_NoteFieldEdit.Load( m_pNotes->GetNoteData(), PLAYER_1, GAMEMAN->GetCurrentStyleDef(), m_PlayerOptions, 10, 12, NoteField::MODE_EDITING );
m_NoteFieldEdit.Load( &noteData, PLAYER_1, GAMEMAN->GetCurrentStyleDef(), m_PlayerOptions, 10, 12, NoteField::MODE_EDITING );
m_rectRecordBack.StretchTo( CRect(SCREEN_LEFT, SCREEN_TOP, SCREEN_RIGHT, SCREEN_BOTTOM) );
m_rectRecordBack.SetDiffuseColor( D3DXCOLOR(0,0,0,0) );
@@ -131,11 +134,11 @@ ScreenEdit::ScreenEdit()
m_NoteFieldRecord.SetXY( EDIT_X, EDIT_GRAY_Y );
m_NoteFieldRecord.SetZoom( 1.0f );
m_NoteFieldRecord.Load( m_pNotes->GetNoteData(), PLAYER_1, GAMEMAN->GetCurrentStyleDef(), m_PlayerOptions, 2, 5, NoteField::MODE_EDITING );
m_NoteFieldRecord.Load( &noteData, PLAYER_1, GAMEMAN->GetCurrentStyleDef(), m_PlayerOptions, 2, 5, NoteField::MODE_EDITING );
m_Clipboard.m_iNumTracks = m_NoteFieldEdit.m_iNumTracks;
m_Player.Load( PLAYER_1, GAMEMAN->GetCurrentStyleDef(), m_pNotes->GetNoteData(), PlayerOptions(), NULL, NULL, 1 );
m_Player.Load( PLAYER_1, GAMEMAN->GetCurrentStyleDef(), &noteData, PlayerOptions(), NULL, NULL, 1 );
m_Player.SetXY( PLAYER_X, PLAYER_Y );
m_Fade.SetClosed();
@@ -399,7 +402,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
}
break;
case DIK_ESCAPE:
m_pSong->LoadFromSMFile( m_pSong->GetCacheFilePath(), true );
m_pSong->LoadFromSMFile( m_pSong->GetCacheFilePath() );
SCREENMAN->SetNewScreen( new ScreenEditMenu );
break;
case DIK_S:
+4 -4
View File
@@ -292,7 +292,6 @@ void ScreenGameplay::LoadNextSong()
m_pCurSong = m_apSongQueue[m_apSongQueue.GetSize()-1];
m_apSongQueue.RemoveAt(m_apSongQueue.GetSize()-1);
m_pCurSong->LoadNoteData();
Notes* pNotes[NUM_PLAYERS];
for( p=0; p<NUM_PLAYERS; p++ )
@@ -313,10 +312,11 @@ void ScreenGameplay::LoadNextSong()
m_DifficultyBanner[p].SetFromNotes( PlayerNumber(p), pNotes[p] );
NoteData* pOriginalNoteData = pNotes[p]->GetNoteData();
NoteData originalNoteData;
pNotes[p]->GetNoteData( &originalNoteData );
NoteData newNoteData;
pStyleDef->GetTransformedNoteDataForStyle( (PlayerNumber)p, pOriginalNoteData, &newNoteData );
pStyleDef->GetTransformedNoteDataForStyle( (PlayerNumber)p, &originalNoteData, &newNoteData );
m_Player[p].Load(
(PlayerNumber)p,
@@ -325,7 +325,7 @@ void ScreenGameplay::LoadNextSong()
PREFSMAN->m_PlayerOptions[p],
&m_LifeMeter[p],
&m_ScoreDisplay[p],
pNotes[p]->GetNoteData()->GetNumTapNotes()
originalNoteData.GetNumTapNotes()
);
}
+13 -27
View File
@@ -16,9 +16,10 @@
#include "RageLog.h"
#include "IniFile.h"
#include "Song.h"
#include "NoteData.h"
const int FILE_CACHE_VERSION = 25; // increment this when the SM file format changes
const int FILE_CACHE_VERSION = 26; // increment this to force a cache reload (useful when the SM file format changes)
int CompareBPMSegments(const void *arg1, const void *arg2)
@@ -267,7 +268,7 @@ bool Song::LoadFromSongDir( CString sDir )
ini.GetValueI( "Cache", "CacheVersion", iCacheVersion );
if( iCacheVersion != FILE_CACHE_VERSION )
{
LOG->WriteLine( "Cache format is out of date. Deleting all cache files" );
LOG->WriteLine( "Cache format is out of date. Deleting all cache files." );
CStringArray asCacheFileNames;
GetDirListing( "Cache\\*.*", asCacheFileNames );
for( int i=0; i<asCacheFileNames.GetSize(); i++ )
@@ -281,7 +282,7 @@ bool Song::LoadFromSongDir( CString sDir )
{
if( !DoesFileExist(GetCacheFilePath()) )
goto load_without_cache;
LoadFromSMFile( GetCacheFilePath(), false ); // don't load NoteData
LoadFromSMFile( GetCacheFilePath() ); // don't load NoteData
// Save length of music
if( GetMusicPath() != "" )
@@ -318,7 +319,7 @@ load_without_cache:
else if( iNumDWIFiles > 1 )
throw RageException( "There is more than one DWI file in '%s'. There should be only one!", sDir );
else if( iNumSMFiles == 1 )
LoadFromSMFile( sDir + arraySMFileNames[0], true ); // do load note data
LoadFromSMFile( sDir + arraySMFileNames[0] ); // do load note data
else if( iNumDWIFiles == 1 )
LoadFromDWIFile( sDir + arrayDWIFileNames[0] );
else if( iNumBMSFiles > 0 )
@@ -328,12 +329,7 @@ load_without_cache:
TidyUpData();
//
// In order to save memory, we're going to save the file back to the cache,
// then unload all the large NoteData.
//
SaveToCacheFile();
LoadFromSMFile( GetCacheFilePath(), false ); // don't load NoteData
SaveToCacheFile(); // save a cahce file so we don't have to parse it all over again next time
return true;
}
@@ -786,9 +782,9 @@ bool Song::LoadFromDWIFile( CString sPath )
}
bool Song::LoadFromSMFile( CString sPath, bool bLoadNoteData )
bool Song::LoadFromSMFile( CString sPath )
{
LOG->WriteLine( "Song::LoadFromSMDir(%s, %d)", sPath, bLoadNoteData );
LOG->WriteLine( "Song::LoadFromSMDir(%s)", sPath );
m_BPMSegments.RemoveAll();
m_FreezeSegments.RemoveAll();
@@ -954,8 +950,8 @@ bool Song::LoadFromSMFile( CString sPath, bool bLoadNoteData )
arrayValueTokens[4],
arrayValueTokens[5],
arrayValueTokens[6],
arrayValueTokens[7],
bLoadNoteData );
arrayValueTokens[7]
);
}
else
@@ -1075,10 +1071,11 @@ void Song::TidyUpData()
for( int i=0; i<m_arrayNotes.GetSize(); i++ )
{
Notes* pNotes = m_arrayNotes[i];
ASSERT( pNotes->m_pNoteData != NULL );
NoteData tempNoteData;
pNotes->GetNoteData( &tempNoteData );
for( int r=0; r<NUM_RADAR_VALUES; r++ )
pNotes->m_fRadarValues[r] = pNotes->GetNoteData()->GetRadarValue( (RadarCategory)r, m_fMusicLengthSeconds );
pNotes->m_fRadarValues[r] = tempNoteData.GetRadarValue( (RadarCategory)r, m_fMusicLengthSeconds );
}
}
@@ -1183,16 +1180,6 @@ void Song::SaveToSMFile( CString sPath )
fclose( fp );
}
void Song::LoadNoteData()
{
if( m_arrayNotes.GetSize() > 0 )
{
if( m_arrayNotes[0]->m_pNoteData != NULL ) // if already loaded
return;
LoadFromSMFile( GetCacheFilePath(), true );
}
}
Grade Song::GetGradeForDifficultyClass( NotesType nt, DifficultyClass dc )
{
CArray<Notes*, Notes*> aNotes;
@@ -1210,7 +1197,6 @@ Grade Song::GetGradeForDifficultyClass( NotesType nt, DifficultyClass dc )
/////////////////////////////////////
// Sorting
/////////////////////////////////////
+8 -4
View File
@@ -208,6 +208,14 @@ SOURCE=.\RageUtil.h
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Course.cpp
# End Source File
# Begin Source File
SOURCE=.\Course.h
# End Source File
# Begin Source File
SOURCE=.\Font.cpp
# End Source File
# Begin Source File
@@ -1044,10 +1052,6 @@ SOURCE=.\ScreenStage.h
# End Source File
# Begin Source File
SOURCE=.\ScreenSynchronizeMenu.h
# End Source File
# Begin Source File
SOURCE=.\ScreenTitleMenu.cpp
# End Source File
# Begin Source File
+1 -3
View File
@@ -43,7 +43,7 @@ public:
bool LoadFromDWIFile( CString sPath );
bool LoadFromBMSDir( CString sDir );
bool LoadFromSMFile( CString sPath, bool bLoadNoteData );
bool LoadFromSMFile( CString sPath );
void TidyUpData(); // call after loading to clean up invalid data
@@ -53,8 +53,6 @@ public:
CString GetSongFilePath();
CString GetCacheFilePath();
void LoadNoteData();
public:
CString m_sSongDir;
CString m_sGroupName;