add NotesLoader/WriterJson

This commit is contained in:
AJ Kelly
2011-05-10 18:59:09 -05:00
parent a6ea7bdf50
commit aa58884f8f
8 changed files with 757 additions and 2 deletions
+7
View File
@@ -234,6 +234,13 @@ namespace Json {
double asDouble() const;
bool asBool() const;
bool TryGet( std::string &out ) const { if(!isString()) return false; out=asString(); return true; }
bool TryGet( int &out ) const { if(!isInt()) return false; out=asInt(); return true; }
bool TryGet( UInt &out ) const { if(!isUInt()) return false; out=asUInt(); return true; }
bool TryGet( double &out ) const { if(!isDouble()) return false; out=asDouble(); return true; }
bool TryGet( float &out ) const { if(!isDouble()) return false; out=(float)asDouble(); return true; }
bool TryGet( bool &out ) const { if(!isBool()) return false; out=asBool(); return true; }
bool isNull() const;
bool isBool() const;
bool isInt() const;
+184 -2
View File
@@ -1,9 +1,10 @@
/** @brief Utilities for handling JSON data. */
#ifndef JsonUtil_H
#define JsonUtil_H
class RageFileBasic;
#include "../extern/jsoncpp/include/json/value.h"
/** @brief Utilities for handling JSON data. */
#include "json/value.h"
namespace JsonUtil
{
bool LoadFromString( Json::Value &root, RString sData, RString &sErrorOut );
@@ -31,6 +32,86 @@ namespace JsonUtil
fn(*v[i], root[i]);
}
template<typename V, typename T>
static void SerializeArray(const V &v, void fn(const T &, Json::Value &), Json::Value &root)
{
root = Json::Value(Json::arrayValue);
root.resize( v.size() );
int i=0;
for( typename V::const_iterator iter=v.begin(); iter!=v.end(); iter++ )
fn( *iter, root[i++] );
}
template <typename V>
static void SerializeArrayValues(const V &v, Json::Value &root)
{
root = Json::Value(Json::arrayValue);
root.resize( v.size() );
int i=0;
for( typename V::const_iterator iter=v.begin(); iter!=v.end(); iter++ )
root[i++] = *iter;
}
template <typename V>
static void SerializeArrayObjects(const V &v, Json::Value &root)
{
root = Json::Value(Json::arrayValue);
root.resize( v.size() );
int i=0;
for( typename V::const_iterator iter=v.begin(); iter!=v.end(); iter++ )
iter->Serialize( root[i++] );
}
template <typename M, typename E, typename F>
static void SerializeStringToObjectMap(const M &m, F fnEnumToString(E e), Json::Value &root)
{
for( typename M::const_iterator iter=m.begin(); iter!=m.end(); iter++ )
iter->second.Serialize( root[ fnEnumToString(iter->first) ] );
}
template <typename M, typename E, typename F>
static void SerializeStringToValueMap(const M &m, F fnToString(E e), Json::Value &root)
{
for( typename M::const_iterator iter=m.begin(); iter!=m.end(); iter++ )
root[ fnToString(iter->first) ] = iter->second;
}
template <typename M>
static void SerializeValueToValueMap(const M &m, Json::Value &root)
{
for( typename M::const_iterator iter=m.begin(); iter!=m.end(); iter++ )
root[ (iter->first) ] = iter->second;
}
// Serialize a map that has a non-string key type
template <typename V>
static void SerializeObjectToObjectMapAsArray(const V &v, const RString &sKeyName, const RString &sValueName, Json::Value &root)
{
root = Json::Value(Json::arrayValue);
root.resize( v.size() );
int i=0;
for( typename V::const_iterator iter=v.begin(); iter!=v.end(); iter++ )
{
Json::Value &v = root[i++];
iter->first.Serialize( v[sKeyName] );
iter->second.Serialize( v[sValueName] );
}
}
template <typename V>
static void SerializeObjectToValueMapAsArray(const V &v, const RString &sKeyName, const RString &sValueName, Json::Value &root)
{
root = Json::Value(Json::arrayValue);
root.resize( v.size() );
int i=0;
for( typename V::const_iterator iter=v.begin(); iter!=v.end(); iter++ )
{
Json::Value &v = root[i++];
iter->first.Serialize( v[sKeyName] );
v[sValueName] = iter->second;
}
}
template<class T>
static void SerializeVectorValues(const vector<T> &v, Json::Value &root)
{
@@ -48,6 +129,14 @@ namespace JsonUtil
fn(v[i], root[i]);
}
template <typename V>
static void DeserializeArrayObjects( V &v, const Json::Value &root)
{
v.resize( root.size() );
for( unsigned i=0; i<v.size(); i++ )
v[i].Deserialize( root[i] );
}
template<class T>
static void DeserializeVectorPointers(vector<T*> &v, void fn(T &, const Json::Value &), const Json::Value &root)
{
@@ -61,6 +150,99 @@ namespace JsonUtil
}
}
template<class T>
static void DeserializeArrayValues(vector<T> &v, const Json::Value &root)
{
v.clear();
for( unsigned i=0; i<root.size(); i++ )
{
T t;
if( root[i].TryGet( t ) )
v.push_back( t );
}
}
// don't pull in the set header here
template<typename S, typename T>
static void DeserializeArrayValuesIntoSet(S &s, const Json::Value &root)
{
s.clear();
for( unsigned i=0; i<root.size(); i++ )
{
T t;
if( root[i].TryGet( t ) )
s.insert( t );
}
}
template<typename T>
static void DeserializeArrayValuesIntoVector(vector<T> &v, const Json::Value &root)
{
v.clear();
for( unsigned i=0; i<root.size(); i++ )
{
T t;
if( root[i].TryGet( t ) )
v.push_back( t );
}
}
template <typename M>
static void DeserializeValueToValueMap(M &m, const Json::Value &root)
{
for( Json::Value::const_iterator iter = root.begin(); iter != root.end(); iter++ )
(*iter).TryGet( m[ iter.memberName() ] );
}
template <typename M, typename E, typename F>
static void DeserializeStringToValueMap(M &m, F fnToValue(E e), const Json::Value &root)
{
for( Json::Value::const_iterator iter = root.begin(); iter != root.end(); iter++ )
(*iter).TryGet( m[ fnToValue(iter.memberName()) ] );
}
template <typename M, typename E, typename F>
static void DeserializeStringToObjectMap(M &m, F fnToValue(E e), const Json::Value &root)
{
for( Json::Value::const_iterator iter = root.begin(); iter != root.end(); iter++ )
m[ fnToValue(iter.memberName()) ].Deserialize( *iter );
}
// Serialize a map that has a non-string key type
template <typename K, typename V>
static void DeserializeObjectToObjectMapAsArray(map<K,V> &m, const RString &sKeyName, const RString &sValueName, const Json::Value &root)
{
m.clear();
ASSERT( root.type() == Json::arrayValue );
for( Json::Value::const_iterator iter = root.begin(); iter != root.end(); iter++ )
{
ASSERT( (*iter).type() == Json::objectValue );
K k;
if( !k.Deserialize( (*iter)[sKeyName] ) )
continue;
V v;
if( !v.Deserialize( (*iter)[sValueName] ) )
continue;
m[k] = v;
}
}
template <typename K, typename V>
static void DeserializeObjectToValueMapAsArray(map<K,V> &m, const RString &sKeyName, const RString &sValueName, const Json::Value &root)
{
for( unsigned i=0; i<root.size(); i++ )
{
const Json::Value &root2 = root[i];
K k;
if( !k.Deserialize( root2[sKeyName] ) )
continue;
V v;
if( !root2[sValueName].TryGet(v) )
continue;
m[k] = v;
}
}
template<class T>
static void DeserializeVectorValues(vector<T> &v, const Json::Value &root)
{
+238
View File
@@ -0,0 +1,238 @@
#include "global.h"
#include "NotesLoaderJson.h"
#include "Json/Value.h"
#include "TimingData.h"
#include "RageUtil.h"
#include "JsonUtil.h"
#include "BackgroundUtil.h"
#include "NoteData.h"
#include "Song.h"
#include "Steps.h"
#include "GameManager.h"
void NotesLoaderJson::GetApplicableFiles( const RString &sPath, vector<RString> &out )
{
GetDirListing( sPath + RString("*.json"), out );
}
void Deserialize(BPMSegment &seg, const Json::Value &root)
{
seg.m_iStartRow = BeatToNoteRow((float)root["Beat"].asDouble());
seg.m_fBPS = (float)(root["BPM"].asDouble() / 60);
}
static void Deserialize(StopSegment &seg, const Json::Value &root)
{
seg.m_iStartRow = BeatToNoteRow((float)(root["Beat"].asDouble()));
seg.m_fStopSeconds = (float)root["Seconds"].asDouble();
}
static void Deserialize(TimingData &td, const Json::Value &root)
{
JsonUtil::DeserializeVectorObjects( td.m_BPMSegments, Deserialize, root["BpmSegments"] );
JsonUtil::DeserializeVectorObjects( td.m_StopSegments, Deserialize, root["StopSegments"] );
}
static void Deserialize(LyricSegment &o, const Json::Value &root)
{
o.m_fStartTime = (float)root["StartTime"].asDouble();
o.m_sLyric = root["Lyric"].asString();
o.m_Color.FromString( root["Color"].asString() );
}
static void Deserialize(BackgroundDef &o, const Json::Value &root)
{
o.m_sEffect = root["Effect"].asString();
o.m_sFile1 = root["File1"].asString();
o.m_sFile2 = root["File2"].asString();
o.m_sColor1 = root["Color1"].asString();
}
static void Deserialize(BackgroundChange &o, const Json::Value &root )
{
Deserialize( o.m_def, root["Def"] );
o.m_fStartBeat = (float)root["StartBeat"].asDouble();
o.m_fRate = (float)root["Rate"].asDouble();
o.m_sTransition = root["Transition"].asString();
}
static void Deserialize( TapNote &o, const Json::Value &root )
{
//if( o.type != TapNote::tap )
if( root.isInt() )
o.type = (TapNote::Type)root["Type"].asInt();
//if( o.type == TapNote::hold_head )
o.subType = (TapNote::SubType)root["SubType"].asInt();
//root["Source"] = (int)source;
//if( !o.sAttackModifiers.empty() )
o.sAttackModifiers = root["AttackModifiers"].asString();
//if( o.fAttackDurationSeconds > 0 )
o.fAttackDurationSeconds = (float)root["AttackDurationSeconds"].asDouble();
//if( o.bKeysound )
o.iKeysoundIndex = root["KeysoundIndex"].asInt();
//if( o.iDuration > 0 )
o.iDuration = root["Duration"].asInt();
//if( o.pn != PLAYER_INVALID )
o.pn = (PlayerNumber)root["PlayerNumber"].asInt();
}
static void Deserialize( StepsType st, NoteData &nd, const Json::Value &root )
{
int iTracks = nd.GetNumTracks();
nd.SetNumTracks( iTracks );
for( unsigned i=0; i<root.size(); i++ )
{
Json::Value root2 = root[i];
float fBeat = (float)root2[(unsigned)0].asDouble();
int iRow = BeatToNoteRow(fBeat);
int iTrack = root2[1].asInt();
const Json::Value &root3 = root2[2];
TapNote tn;
Deserialize( tn, root3 );
nd.SetTapNote( iTrack, iRow, tn );
}
}
static void Deserialize( RadarValues &o, const Json::Value &root )
{
FOREACH_ENUM( RadarCategory, rc )
{
o.m_Values.f[rc] = (float)root[ RadarCategoryToString(rc) ].asDouble();
}
}
static void Deserialize( Steps &o, const Json::Value &root )
{
o.m_StepsType = GAMEMAN->StringToStepsType(root["StepsType"].asString());
o.Decompress();
NoteData nd;
Deserialize( o.m_StepsType, nd, root["NoteData"] );
o.SetNoteData( nd );
//o.SetHash( root["Hash"].asInt() );
o.SetDescription( root["Description"].asString() );
o.SetDifficulty( StringToDifficulty(root["Difficulty"].asString()) );
o.SetMeter( root["Meter"].asInt() );
RadarValues rv[NUM_PLAYERS];
FOREACH_PlayerNumber( pn )
{
Deserialize( rv[pn], root["RadarValues"] );
}
o.SetCachedRadarValues( rv );
}
static void Deserialize( Song &out, const Json::Value &root )
{
out.SetSongDir( root["SongDir"].asString() );
out.m_sGroupName = root["GroupName"].asString();
out.m_sMainTitle = root["Title"].asString();
out.m_sSubTitle = root["SubTitle"].asString();
out.m_sArtist = root["Artist"].asString();
out.m_sMainTitleTranslit = root["TitleTranslit"].asString();
out.m_sSubTitleTranslit = root["SubTitleTranslit"].asString();
out.m_sGenre = root["Genre"].asString();
out.m_sCredit = root["Credit"].asString();
out.m_sBannerFile = root["Banner"].asString();
out.m_sBackgroundFile = root["Background"].asString();
out.m_sLyricsFile = root["LyricsFile"].asString();
out.m_sCDTitleFile = root["CDTitle"].asString();
out.m_sMusicFile = root["Music"].asString();
out.m_Timing.m_fBeat0OffsetInSeconds = (float)root["Offset"].asDouble();
out.m_fMusicSampleStartSeconds = (float)root["SampleStart"].asDouble();
out.m_fMusicSampleLengthSeconds = (float)root["SampleLength"].asDouble();
RString sSelectable = root["Selectable"].asString();
if( !stricmp(sSelectable,"YES") )
out.m_SelectionDisplay = out.SHOW_ALWAYS;
else if(!stricmp(sSelectable,"NO"))
out.m_SelectionDisplay = out.SHOW_NEVER;
out.m_fFirstBeat = (float)root["FirstBeat"].asDouble();
out.m_fLastBeat = (float)root["LastBeat"].asDouble();
out.m_sSongFileName = root["SongFileName"].asString();
out.m_bHasMusic = root["HasMusic"].asBool();
out.m_bHasBanner = root["HasBanner"].asBool();
out.m_fMusicLengthSeconds = (float)root["MusicLengthSeconds"].asDouble();
RString sDisplayBPMType = root["DisplayBpmType"].asString();
if( sDisplayBPMType == "*" )
out.m_DisplayBPMType = DISPLAY_BPM_RANDOM;
else
out.m_DisplayBPMType = DISPLAY_BPM_SPECIFIED;
if( out.m_DisplayBPMType == DISPLAY_BPM_SPECIFIED )
{
out.m_fSpecifiedBPMMin = (float)root["SpecifiedBpmMin"].asDouble();
out.m_fSpecifiedBPMMax = (float)root["SpecifiedBpmMax"].asDouble();
}
Deserialize( out.m_Timing, root["TimingData"] );
JsonUtil::DeserializeVectorObjects( out.m_LyricSegments, Deserialize, root["LyricSegments"] );
{
const Json::Value &root2 = root["BackgroundChanges"];
FOREACH_BackgroundLayer( bl )
{
const Json::Value &root3 = root2[bl];
vector<BackgroundChange> &vBgc = out.GetBackgroundChanges(bl);
JsonUtil::DeserializeVectorObjects( vBgc, Deserialize, root3 );
}
}
{
vector<BackgroundChange> &vBgc = out.GetForegroundChanges();
JsonUtil::DeserializeVectorObjects( vBgc, Deserialize, root["ForegroundChanges"] );
}
JsonUtil::DeserializeArrayValuesIntoVector( out.m_vsKeysoundFile, root["KeySounds"] );
{
vector<Steps*> vpSteps;
JsonUtil::DeserializeVectorPointers<Steps>( vpSteps, Deserialize, root["Charts"] );
FOREACH( Steps*, vpSteps, iter )
out.AddSteps( *iter );
}
}
bool NotesLoaderJson::LoadFromJsonFile( const RString &sPath, Song &out )
{
Json::Value root;
if( !JsonUtil::LoadFromFileShowErrors(root,sPath) )
return false;
Deserialize(out, root);
return true;
}
bool NotesLoaderJson::LoadFromDir( const RString &sPath, Song &out )
{
return LoadFromJsonFile(sPath, out);
}
/*
* (c) 2001-2004 Chris Danford, Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+41
View File
@@ -0,0 +1,41 @@
/* JsonLoader - Reads a Song from a .json file. */
#ifndef NotesLoaderJson_H
#define NotesLoaderJson_H
#include "NotesLoader.h"
class Song;
namespace NotesLoaderJson
{
void GetApplicableFiles( const RString &sPath, vector<RString> &out );
bool LoadFromDir( const RString &sPath, Song &out );
bool LoadFromJsonFile( const RString &sPath, Song &out );
};
#endif
/*
* (c) 2001-2004 Chris Danford, Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+230
View File
@@ -0,0 +1,230 @@
#include "global.h"
#include "NotesWriterJson.h"
#include "TimingData.h"
#include "Json/Value.h"
#include "JsonUtil.h"
#include "Song.h"
#include "BackgroundUtil.h"
#include "Steps.h"
#include "NoteData.h"
#include "GameManager.h"
void Serialize(const BPMSegment &seg, Json::Value &root)
{
root["Beat"] = NoteRowToBeat(seg.m_iStartRow);
root["BPM"] = seg.m_fBPS * 60;
}
static void Serialize(const StopSegment &seg, Json::Value &root)
{
root["Beat"] = NoteRowToBeat(seg.m_iStartRow);
root["Seconds"] = seg.m_fStopSeconds;
}
static void Serialize(const TimingData &td, Json::Value &root)
{
JsonUtil::SerializeVectorObjects( td.m_BPMSegments, Serialize, root["BpmSegments"] );
JsonUtil::SerializeVectorObjects( td.m_StopSegments, Serialize, root["StopSegments"] );
}
static void Serialize(const LyricSegment &o, Json::Value &root)
{
root["StartTime"] = (float)o.m_fStartTime;
root["Lyric"] = o.m_sLyric;
root["Color"] = o.m_Color.ToString();
}
static void Serialize(const BackgroundDef &o, Json::Value &root)
{
root["Effect"] = o.m_sEffect;
root["File1"] = o.m_sFile1;
root["File2"] = o.m_sFile2;
root["Color1"] = o.m_sColor1;
}
static void Serialize(const BackgroundChange &o, Json::Value &root )
{
Serialize( o.m_def, root["Def"] );
root["StartBeat"] = o.m_fStartBeat;
root["Rate"] = o.m_fRate;
root["Transition"] = o.m_sTransition;
}
static void Serialize( const TapNote &o, Json::Value &root )
{
root = Json::Value(Json::objectValue);
if( o.type != TapNote::tap )
root["Type"] = (int)o.type;
if( o.type == TapNote::hold_head )
root["SubType"] = (int)o.subType;
//root["Source"] = (int)source;
if( !o.sAttackModifiers.empty() )
root["AttackModifiers"] = o.sAttackModifiers;
if( o.fAttackDurationSeconds > 0 )
root["AttackDurationSeconds"] = o.fAttackDurationSeconds;
if( o.iKeysoundIndex != -1 )
root["KeysoundIndex"] = o.iKeysoundIndex;
if( o.iDuration > 0 )
root["Duration"] = o.iDuration;
if( o.pn != PLAYER_INVALID )
root["PlayerNumber"] = (int)o.pn;
}
static void Serialize( const NoteData &o, Json::Value &root )
{
root = Json::Value(Json::arrayValue);
int iNumTracks = o.GetNumTracks();
for(int t=0; t<iNumTracks; t++ )
{
NoteData::TrackMap::iterator begin, end;
o.GetTapNoteRangeInclusive(t, 0, -1, begin, end );
//NoteData::TrackMap tm = o.GetTrack(t);
//FOREACHM_CONST( int, TapNote, tm, iter )
for( ; begin != end; ++begin )
{
int iRow = begin->first;
TapNote tn = begin->second;
root.resize( root.size()+1 );
Json::Value &root2 = root[ root.size()-1 ];
root2 = Json::Value(Json::arrayValue);
root2.resize(3);
root2[(unsigned)0] = NoteRowToBeat(iRow);
root2[1] = t;
Serialize( tn, root2[2] );
}
}
}
static void Serialize( const RadarValues &o, Json::Value &root )
{
FOREACH_ENUM( RadarCategory, rc )
{
root[ RadarCategoryToString(rc) ] = o.m_Values.f[rc];
}
}
static void Serialize( const Steps &o, Json::Value &root )
{
root["StepsType"] = StringConversion::ToString(o.m_StepsType);
o.Decompress();
NoteData nd;
o.GetNoteData( nd );
Serialize( nd, root["NoteData"] );
root["Hash"] = o.GetHash();
root["Description"] = o.GetDescription();
root["Difficulty"] = DifficultyToString(o.GetDifficulty());
root["Meter"] = o.GetMeter();
Serialize( o.GetRadarValues( PLAYER_1 ), root["RadarValues"] );
}
bool NotesWriterJson::WriteSong( const RString &sFile, const Song &out, bool bWriteSteps )
{
Json::Value root;
root["SongDir"] = out.GetSongDir();
root["GroupName"] = out.m_sGroupName;
root["Title"] = out.m_sMainTitle;
root["SubTitle"] = out.m_sSubTitle;
root["Artist"] = out.m_sArtist;
root["TitleTranslit"] = out.m_sMainTitleTranslit;
root["SubTitleTranslit"] = out.m_sSubTitleTranslit;
root["Genre"] = out.m_sGenre;
root["Credit"] = out.m_sCredit;
root["Banner"] = out.m_sBannerFile;
root["Background"] = out.m_sBackgroundFile;
root["LyricsFile"] = out.m_sLyricsFile;
root["CDTitle"] = out.m_sCDTitleFile;
root["Music"] = out.m_sMusicFile;
root["Offset"] = out.m_Timing.m_fBeat0OffsetInSeconds;
root["SampleStart"] = out.m_fMusicSampleStartSeconds;
root["SampleLength"] = out.m_fMusicSampleLengthSeconds;
if( out.m_SelectionDisplay == Song::SHOW_ALWAYS )
root["Selectable"] = "YES";
else if( out.m_SelectionDisplay == Song::SHOW_NEVER )
root["Selectable"] = "NO";
else
root["Selectable"] = "YES";
root["FirstBeat"] = out.m_fFirstBeat;
root["LastBeat"] = out.m_fLastBeat;
root["SongFileName"] = out.m_sSongFileName;
root["HasMusic"] = out.m_bHasMusic;
root["HasBanner"] = out.m_bHasBanner;
root["MusicLengthSeconds"] = out.m_fMusicLengthSeconds;
root["DisplayBpmType"] = StringConversion::ToString(out.m_DisplayBPMType);
if( out.m_DisplayBPMType == DISPLAY_BPM_SPECIFIED )
{
root["SpecifiedBpmMin"] = out.m_fSpecifiedBPMMin;
root["SpecifiedBpmMax"] = out.m_fSpecifiedBPMMax;
}
Serialize( out.m_Timing, root["TimingData"] );
JsonUtil::SerializeVectorObjects( out.m_LyricSegments, Serialize, root["LyricSegments"] );
{
Json::Value &root2 = root["BackgroundChanges"];
FOREACH_BackgroundLayer( bl )
{
Json::Value &root3 = root2[bl];
const vector<BackgroundChange> &vBgc = out.GetBackgroundChanges(bl);
JsonUtil::SerializeVectorObjects( vBgc, Serialize, root3 );
}
}
{
const vector<BackgroundChange> &vBgc = out.GetForegroundChanges();
JsonUtil::SerializeVectorObjects( vBgc, Serialize, root["ForegroundChanges"] );
}
JsonUtil::SerializeArrayValues( out.m_vsKeysoundFile, root["KeySounds"] );
if( bWriteSteps )
{
vector<const Steps*> vpSteps;
FOREACH_CONST( Steps*, out.GetAllSteps(), iter )
{
if( (*iter)->IsAutogen() )
continue;
vpSteps.push_back( *iter );
}
JsonUtil::SerializeVectorPointers<Steps>( vpSteps, Serialize, root["Charts"] );
}
return JsonUtil::WriteFile( root, sFile, false );
}
bool NotesWriterJson::WriteSteps( const RString &sFile, const Steps &out )
{
Json::Value root;
Serialize( out, root );
return JsonUtil::WriteFile( root, sFile, false );
}
/*
* (c) 2001-2004 Chris Danford, Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+40
View File
@@ -0,0 +1,40 @@
/* NotesWriterJson - Writes a Song to a .json file. */
#ifndef NotesWriterJson_H
#define NotesWriterJson_H
class Song;
class Steps;
namespace NotesWriterJson
{
static bool WriteSong( const RString &sFile, const Song &out, bool bWriteSteps );
static bool WriteSteps( const RString &sFile, const Steps &out );
};
#endif
/*
* (c) 2001-2010 Chris Danford, Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+1
View File
@@ -73,6 +73,7 @@ class Song
RString m_sSongDir;
public:
void SetSongDir( const RString sDir ) { m_sSongDir = sDir; }
RString GetSongDir() { return m_sSongDir; }
/** @brief When should this song be displayed in the music wheel? */
enum SelectionDisplay
+16
View File
@@ -1575,6 +1575,14 @@
RelativePath="NotesLoaderDWI.h"
>
</File>
<File
RelativePath=".\NotesLoaderJson.cpp"
>
</File>
<File
RelativePath=".\NotesLoaderJson.h"
>
</File>
<File
RelativePath="NotesLoaderKSF.cpp"
>
@@ -1755,6 +1763,14 @@
RelativePath="NotesWriterDWI.h"
>
</File>
<File
RelativePath=".\NotesWriterJson.cpp"
>
</File>
<File
RelativePath=".\NotesWriterJson.h"
>
</File>
<File
RelativePath="NotesWriterSM.cpp"
>