add NotesLoader/WriterJson
This commit is contained in:
Vendored
+7
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user