Files
itgmania212121/stepmania/src/Notes.cpp
T

340 lines
7.6 KiB
C++
Raw Normal View History

2002-05-20 08:59:37 +00:00
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: Notes
2002-07-27 19:29:51 +00:00
Desc: See header.
2002-05-20 08:59:37 +00:00
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
2002-07-27 19:29:51 +00:00
Chris Danford
2003-01-02 22:10:51 +00:00
Glenn Maynard
2002-05-20 08:59:37 +00:00
-----------------------------------------------------------------------------
*/
#include "Notes.h"
#include "Song.h"
#include "Notes.h"
#include "IniFile.h"
#include "math.h" // for fabs()
#include "RageUtil.h"
#include "RageLog.h"
2002-07-03 03:13:13 +00:00
#include "NoteData.h"
2002-05-20 08:59:37 +00:00
#include "GameInput.h"
2002-07-27 19:29:51 +00:00
#include "RageException.h"
#include "MsdFile.h"
2002-08-23 00:22:27 +00:00
#include "GameManager.h"
2002-10-06 16:56:58 +00:00
#include "ThemeManager.h"
2002-05-20 08:59:37 +00:00
2002-10-06 16:56:58 +00:00
#define COLOR_EASY THEME->GetMetricC("Notes","ColorEasy")
#define COLOR_MEDIUM THEME->GetMetricC("Notes","ColorMedium")
#define COLOR_HARD THEME->GetMetricC("Notes","ColorHard")
#define COLOR_S_HARD THEME->GetMetricC("Notes","ColorSHard")
#define COLOR_CHALLENGE THEME->GetMetricC("Notes","ColorChallenge")
#define COLOR_BATTLE THEME->GetMetricC("Notes","ColorBattle")
2002-05-20 08:59:37 +00:00
Notes::Notes()
{
2002-08-23 00:22:27 +00:00
/* FIXME: should we init this to NOTES_TYPE_INVALID?
* I have a feeling that it's the right thing to do but that
* it'd trip obscure asserts all over the place, so I'll wait
* until after b6 to do this. -glenn */
2002-06-30 23:19:33 +00:00
m_NotesType = NOTES_TYPE_DANCE_SINGLE;
2002-09-29 05:06:18 +00:00
m_Difficulty = CLASS_INVALID;
2002-05-20 08:59:37 +00:00
m_iMeter = 0;
for(int i = 0; i < NUM_RADAR_VALUES; ++i)
m_fRadarValues[i] = -1; /* unknown */
2002-06-30 23:19:33 +00:00
2002-05-20 08:59:37 +00:00
m_iNumTimesPlayed = 0;
m_iMaxCombo = 0;
m_iTopScore = 0;
m_TopGrade = GRADE_NO_DATA;
2002-12-14 21:43:00 +00:00
notes = NULL;
notes_comp = NULL;
2003-01-02 22:10:51 +00:00
parent = NULL;
2002-05-20 08:59:37 +00:00
}
Notes::~Notes()
{
2002-12-14 21:43:00 +00:00
delete notes;
delete notes_comp;
2002-05-20 08:59:37 +00:00
}
2002-07-03 21:27:26 +00:00
void Notes::SetNoteData( NoteData* pNewNoteData )
{
2002-08-23 00:22:27 +00:00
ASSERT( pNewNoteData->m_iNumTracks == GameManager::NotesTypeToNumTracks(m_NotesType) );
2002-12-14 21:43:00 +00:00
2003-01-02 22:10:51 +00:00
DeAutogen();
2002-12-14 21:43:00 +00:00
delete notes_comp;
notes_comp = NULL;
delete notes;
notes = new NoteData(*pNewNoteData);
2002-07-03 21:27:26 +00:00
}
2002-05-20 08:59:37 +00:00
void Notes::GetNoteData( NoteData* pNoteDataOut ) const
2002-07-03 03:13:13 +00:00
{
2002-12-14 21:43:00 +00:00
Decompress();
pNoteDataOut->m_iNumTracks = notes->m_iNumTracks;
*pNoteDataOut = *notes;
2002-07-03 03:13:13 +00:00
}
2002-05-20 08:59:37 +00:00
2002-12-14 21:33:29 +00:00
void Notes::SetSMNoteData( const CString &out )
{
2002-12-14 21:43:00 +00:00
delete notes;
notes = NULL;
if(!notes_comp)
notes_comp = new CString;
*notes_comp = out;
2002-12-14 21:33:29 +00:00
}
CString Notes::GetSMNoteData() const
{
2002-12-14 21:43:00 +00:00
if(!notes_comp)
{
if(!notes) return ""; /* no data is no data */
notes_comp = new CString(NoteDataUtil::GetSMNoteDataString(*notes));
}
return *notes_comp;
2002-12-14 21:33:29 +00:00
}
2002-09-29 05:06:18 +00:00
// Color is a function of Difficulty and Intended Style
2002-10-06 16:56:58 +00:00
NotesDisplayType Notes::GetNotesDisplayType() const
2002-09-08 22:02:39 +00:00
{
2003-01-02 22:10:51 +00:00
CString sDescription = GetDescription();
2002-09-08 22:02:39 +00:00
sDescription.MakeLower();
2002-10-06 16:56:58 +00:00
if( -1 != sDescription.Find("battle") ) return NOTES_DISPLAY_BATTLE;
else if( -1 != sDescription.Find("couple") ) return NOTES_DISPLAY_BATTLE;
else if( -1 != sDescription.Find("smaniac") ) return NOTES_DISPLAY_S_HARD;
else if( -1 != sDescription.Find("challenge") ) return NOTES_DISPLAY_CHALLENGE;
2003-01-02 22:10:51 +00:00
switch( GetDifficulty() )
2002-10-06 16:56:58 +00:00
{
case DIFFICULTY_EASY: return NOTES_DISPLAY_EASY;
case DIFFICULTY_MEDIUM: return NOTES_DISPLAY_MEDIUM;
case DIFFICULTY_HARD: return NOTES_DISPLAY_HARD;
default: ASSERT(0); return NOTES_DISPLAY_EASY;
}
}
RageColor Notes::GetColor() const
2002-10-06 16:56:58 +00:00
{
switch( GetNotesDisplayType() )
{
case NOTES_DISPLAY_EASY: return COLOR_EASY;
case NOTES_DISPLAY_MEDIUM: return COLOR_MEDIUM;
case NOTES_DISPLAY_HARD: return COLOR_HARD;
case NOTES_DISPLAY_S_HARD: return COLOR_S_HARD;
case NOTES_DISPLAY_CHALLENGE: return COLOR_CHALLENGE;
case NOTES_DISPLAY_BATTLE: return COLOR_BATTLE;
default: return COLOR_EASY;
}
2002-09-08 22:02:39 +00:00
}
2002-07-03 03:13:13 +00:00
void Notes::TidyUpData()
{
2003-01-02 22:10:51 +00:00
if( GetDifficulty() == CLASS_INVALID )
SetDifficulty(DifficultyFromDescriptionAndMeter( GetDescription(), GetMeter() ));
2002-05-20 08:59:37 +00:00
2003-01-02 22:10:51 +00:00
if( GetMeter() < 1 || GetMeter() > 10 )
2002-07-03 03:13:13 +00:00
{
2003-01-02 22:10:51 +00:00
switch( GetDifficulty() )
2002-06-30 23:19:33 +00:00
{
2003-01-02 22:10:51 +00:00
case DIFFICULTY_EASY: SetMeter(3); break;
case DIFFICULTY_MEDIUM: SetMeter(5); break;
case DIFFICULTY_HARD: SetMeter(8); break;
2002-07-03 03:13:13 +00:00
default: ASSERT(0);
2002-06-30 23:19:33 +00:00
}
}
2002-05-20 08:59:37 +00:00
}
2002-09-29 05:06:18 +00:00
Difficulty Notes::DifficultyFromDescriptionAndMeter( CString sDescription, int iMeter )
2002-06-27 17:49:10 +00:00
{
2002-06-30 23:19:33 +00:00
sDescription.MakeLower();
2002-06-27 17:49:10 +00:00
2002-07-27 19:29:51 +00:00
const int DESCRIPTIONS_PER_CLASS = 4;
2002-09-29 05:06:18 +00:00
const CString sDescriptionParts[NUM_DIFFICULTIES][DESCRIPTIONS_PER_CLASS] = {
2002-06-27 17:49:10 +00:00
{
2002-07-23 01:41:40 +00:00
"easy",
2002-06-27 17:49:10 +00:00
"basic",
"light",
2002-10-06 16:56:58 +00:00
"GARBAGE", // don't worry - this will never match because the compare string is all lowercase
2002-06-27 17:49:10 +00:00
},
{
2002-07-23 01:41:40 +00:00
"medium",
2002-06-27 17:49:10 +00:00
"another",
"trick",
"standard",
},
{
2002-07-23 01:41:40 +00:00
"hard",
2002-06-27 17:49:10 +00:00
"ssr",
"maniac",
"heavy",
},
};
2002-09-29 05:06:18 +00:00
for( int i=0; i<NUM_DIFFICULTIES; i++ )
2002-07-27 19:29:51 +00:00
for( int j=0; j<DESCRIPTIONS_PER_CLASS; j++ )
2002-06-30 23:19:33 +00:00
if( sDescription.Find(sDescriptionParts[i][j]) != -1 )
2002-10-06 16:56:58 +00:00
return (Difficulty)i;
2002-06-27 17:49:10 +00:00
// guess difficulty class from meter
2002-09-29 05:06:18 +00:00
if( iMeter <= 3 ) return DIFFICULTY_EASY;
else if( iMeter <= 6 ) return DIFFICULTY_MEDIUM;
else return DIFFICULTY_HARD;
2002-06-27 17:49:10 +00:00
}
2002-05-20 08:59:37 +00:00
//////////////////////////////////////////////
//
//////////////////////////////////////////////
2002-10-24 08:17:09 +00:00
bool CompareNotesPointersByRadarValues(const Notes* pNotes1, const Notes* pNotes2)
2002-07-11 19:02:26 +00:00
{
float fScore1 = 0;
float fScore2 = 0;
for( int r=0; r<NUM_RADAR_VALUES; r++ )
{
2003-01-02 22:10:51 +00:00
fScore1 += pNotes1->GetRadarValues()[r];
fScore2 += pNotes2->GetRadarValues()[r];
2002-07-11 19:02:26 +00:00
}
2002-10-24 08:17:09 +00:00
return fScore1 < fScore2;
2002-07-11 19:02:26 +00:00
}
2002-10-24 08:17:09 +00:00
bool CompareNotesPointersByMeter(const Notes *pNotes1, const Notes* pNotes2)
2002-05-20 08:59:37 +00:00
{
2003-01-02 22:10:51 +00:00
if( pNotes1->GetMeter() < pNotes2->GetMeter() )
2002-10-24 08:17:09 +00:00
return true;
2003-01-02 22:10:51 +00:00
if( pNotes1->GetMeter() > pNotes2->GetMeter() )
2002-10-24 08:17:09 +00:00
return false;
return CompareNotesPointersByRadarValues( pNotes1, pNotes2 );
2002-05-20 08:59:37 +00:00
}
2002-10-24 08:17:09 +00:00
bool CompareNotesPointersByDifficulty(const Notes *pNotes1, const Notes *pNotes2)
2002-05-20 08:59:37 +00:00
{
2003-01-02 22:10:51 +00:00
if( pNotes1->GetDifficulty() < pNotes2->GetDifficulty() )
2002-10-24 08:17:09 +00:00
return true;
2003-01-02 22:10:51 +00:00
if( pNotes1->GetDifficulty() > pNotes2->GetDifficulty() )
2002-10-24 08:17:09 +00:00
return false;
return CompareNotesPointersByMeter( pNotes1, pNotes2 );
2002-08-01 13:42:56 +00:00
}
void SortNotesArrayByDifficulty( CArray<Notes*,Notes*> &arraySteps )
2002-05-20 08:59:37 +00:00
{
2002-10-24 08:40:27 +00:00
sort( arraySteps.begin(), arraySteps.end(), CompareNotesPointersByDifficulty );
2002-05-20 08:59:37 +00:00
}
2002-12-14 21:43:00 +00:00
void Notes::Decompress() const
{
if(notes) return;
2003-01-02 22:10:51 +00:00
if(parent)
{
NoteData pdata;
parent->GetNoteData(&pdata);
notes = new NoteData;
notes->m_iNumTracks = GameManager::NotesTypeToNumTracks(m_NotesType);
if(pdata.m_iNumTracks == notes->m_iNumTracks)
notes->CopyRange( &pdata, 0, pdata.GetLastRow(), 0 );
else
notes->LoadTransformedSlidingWindow( &pdata, notes->m_iNumTracks );
return;
}
if(!notes_comp) return; /* no data is no data */
2002-12-14 21:43:00 +00:00
notes = new NoteData;
notes->m_iNumTracks = GameManager::NotesTypeToNumTracks(m_NotesType);
NoteDataUtil::LoadFromSMNoteDataString(*notes, *notes_comp);
}
void Notes::Compress() const
{
if(!notes_comp)
{
if(!notes) return; /* no data is no data */
notes_comp = new CString(NoteDataUtil::GetSMNoteDataString(*notes));
}
delete notes;
notes = NULL;
}
2003-01-02 22:10:51 +00:00
/* Copy our parent's data. This is done when we're being changed from autogen
* to normal. (needed?) */
void Notes::DeAutogen()
{
if(!parent)
return; /* OK */
m_iMeter = Real()->m_iMeter;
m_sDescription = Real()->m_sDescription;
m_Difficulty = Real()->m_Difficulty;
for(int i = 0; i < NUM_RADAR_VALUES; ++i)
m_fRadarValues[i] = Real()->m_fRadarValues[i];
delete notes;
notes = NULL;
if(!notes_comp)
notes_comp = new CString;
*notes_comp = parent->GetSMNoteData();
parent = NULL;
}
void Notes::AutogenFrom( Notes *parent_, NotesType ntTo )
{
parent = parent_;
m_NotesType = ntTo;
}
const Notes *Notes::Real() const
{
if(parent) return parent;
return this;
}
bool Notes::IsAutogen() const
{
return parent != NULL;
}
void Notes::SetDescription(CString desc)
{
DeAutogen();
m_sDescription = desc;
}
void Notes::SetDifficulty(Difficulty d)
{
DeAutogen();
m_Difficulty = d;
}
void Notes::SetMeter(int meter)
{
DeAutogen();
m_iMeter = meter;
}
void Notes::SetRadarValue(int r, float val)
{
DeAutogen();
ASSERT(r < NUM_RADAR_VALUES);
m_fRadarValues[r] = val;
}