void Output(Directory PathOut) { Directory Sn = Song->SongName; Sn.Normalize(true); GString name = Utility::Format("%s/ %s (%s) - %s.bms", PathOut.c_path(), Sn.c_path(), Parent->Name, Parent->Author); #ifndef _WIN32 std::ofstream out(name.c_str()); #else std::ofstream out(Utility::Widen(name).c_str()); #endif try { if (!out.is_open()) throw std::exception( (Utility::Format("failed to open file %S", name).c_str() ) ); if (BPS.size() == 0) throw std::exception("There are no timing points!"); WriteBMSOutput(); out << OutFile.str(); } catch (std::exception &e) { Log::Printf("Error while converting: %s\n", e.what()); } }
// Inserts a filename, if it already exists, updates it. // Returns the ID of the filename. int SongDatabase::InsertFilename(Directory Fn) { int ret; int idOut; int lmt; SC(sqlite3_bind_text(st_FilenameQuery, 1, Fn.c_path(), Fn.path().length(), SQLITE_STATIC)); if (sqlite3_step(st_FilenameQuery) == SQLITE_ROW) { idOut = sqlite3_column_int(st_FilenameQuery, 0); lmt = sqlite3_column_int(st_FilenameQuery, 1); int lastLmt = Utility::GetLMT(Fn.path()); // Update the last-modified-time of this file, and its hash if it has changed. if (lmt != lastLmt) { GString Hash = Utility::GetSha256ForFile(Fn); SC(sqlite3_bind_int(st_UpdateLMT, 1, lastLmt)); SC(sqlite3_bind_text(st_UpdateLMT, 2, Hash.c_str(), Hash.length(), SQLITE_STATIC)); SC(sqlite3_bind_text(st_UpdateLMT, 3, Fn.c_path(), Fn.path().length(), SQLITE_STATIC)); SCS(sqlite3_step(st_UpdateLMT)); SC(sqlite3_reset(st_UpdateLMT)); } }else { GString Hash = Utility::GetSha256ForFile(Fn); // There's no entry, got to insert it. SC(sqlite3_bind_text(st_FilenameInsertQuery, 1, Fn.c_path(), Fn.path().length(), SQLITE_STATIC)); SC(sqlite3_bind_int(st_FilenameInsertQuery, 2, Utility::GetLMT(Fn.path()))); SC(sqlite3_bind_text(st_FilenameInsertQuery, 3, Hash.c_str(), Hash.length(), SQLITE_STATIC)); SCS(sqlite3_step(st_FilenameInsertQuery)); // This should not fail. Otherwise, there are bigger problems to worry about... SC(sqlite3_reset(st_FilenameInsertQuery)); // okay, then return the ID. SC(sqlite3_reset(st_FilenameQuery)); SC(sqlite3_bind_text(st_FilenameQuery, 1, Fn.c_path(), Fn.path().length(), SQLITE_STATIC)); sqlite3_step(st_FilenameQuery); idOut = sqlite3_column_int(st_FilenameQuery, 0); } SC(sqlite3_reset(st_FilenameQuery)); return idOut; }
void ConvertToNPSGraph(VSRG::Song *Sng, Directory PathOut) { for (auto i = 0; i < Sng->Difficulties.size(); i++) { std::ofstream out; auto Diff = Sng->GetDifficulty(i); Directory Sn = Sng->SongName; Sn.Normalize(true); GString name = Utility::Format("%s/ %s (%s) - %s.svg", PathOut.c_path(), Sn.c_path(), Diff->Name, Diff->Author); out.open(name.c_str()); double interv = CfgValNPS("IntervalTime", 1); double margin = CfgValNPS("PeakMargin", 1.2f); out << NPSGraph(Sng).GetSVGText(i, interv, margin); } }
void ImageList::AddToList(const GString Filename, const GString Prefix) { Directory ResFilename = Directory(Prefix) / Filename; ResFilename.Normalize(true); if (Images.find(ResFilename) == Images.end()) { ImageLoader::AddToPending(ResFilename.c_path()); Images[ResFilename] = nullptr; } }
void ImageList::AddToListIndex(const GString Filename, const GString Prefix, int Index) { Directory ResFilename = Directory(Prefix) / Filename; ResFilename.Normalize(true); if (ImagesIndex.find(Index) == ImagesIndex.end()) { ImageLoader::AddToPending(ResFilename.c_path()); Images[ResFilename] = nullptr; ImagesIndex[Index] = nullptr; ImagesIndexPending[Index] = ResFilename; } }
BitmapFont *BitmapFont::FromLua(LuaManager* Lua, std::string TableName) { BitmapFont* Ret = new BitmapFont(); Lua->UseArray(TableName); Directory Locat = Lua->GetFieldS("Location", GameState::GetInstance().GetSkinPrefix() + "font.tga"); int CharWidth = Lua->GetFieldI("CharWidth"); int CharHeight = Lua->GetFieldI("CharHeight"); int CellWidth = Lua->GetFieldI("CellWidth"); int CellHeight = Lua->GetFieldI("CellHeight"); int RenderWidth = Lua->GetFieldI("RenderWidth"); int RenderHeight = Lua->GetFieldI("RenderHeight"); int FontStart = Lua->GetFieldI("FontStart"); Lua->Pop(); Ret->LoadFontImage(Locat.c_path(), Vec2(CharWidth, CharHeight), Vec2(CellWidth, CellHeight), Vec2(RenderWidth, RenderHeight), FontStart); return Ret; }
bool SongDatabase::CacheNeedsRenewal(Directory Dir) { int CurLMT = Utility::GetLMT(Dir.path()); bool NeedsRenewal; int res, ret; SC(sqlite3_bind_text(st_LMTQuery, 1, Dir.c_path(), Dir.path().length(), SQLITE_STATIC)); res = sqlite3_step(st_LMTQuery); if (res == SQLITE_ROW) // entry exists { int OldLMT = sqlite3_column_int(st_LMTQuery, 0); bool IsLMTCurrent = (CurLMT==OldLMT); // file was not modified since last time NeedsRenewal = !IsLMTCurrent; }else { NeedsRenewal = true; } SC(sqlite3_reset(st_LMTQuery)); return NeedsRenewal; }
int SongDatabase::GetSongIDForFile(Directory File, VSRG::Song* In) { int ret; int Out = -1; SC(sqlite3_bind_text(st_GetSIDFromFilename, 1, File.c_path(), File.path().length(), SQLITE_STATIC)); int r = sqlite3_step(st_GetSIDFromFilename); if (r == SQLITE_ROW) { // We found a song with ID and everything.. Out = sqlite3_column_int(st_GetSIDFromFilename, 0); } else { assert(In); // Okay, this is a query isn't it? Why doesn't the song exist? // Okay then, insert the song. // So now the latest entry is what we're going to insert difficulties and files into. SC(sqlite3_bind_text(st_SngInsertQuery, 1, In->SongName.c_str(), In->SongName.length(), SQLITE_STATIC)); SC(sqlite3_bind_text(st_SngInsertQuery, 2, In->SongAuthor.c_str(), In->SongAuthor.length(), SQLITE_STATIC)); SC(sqlite3_bind_text(st_SngInsertQuery, 3, In->Subtitle.c_str(), In->Subtitle.length(), SQLITE_STATIC)); SC(sqlite3_bind_text(st_SngInsertQuery, 4, In->SongFilename.c_str(), In->SongFilename.length(), SQLITE_STATIC)); SC(sqlite3_bind_text(st_SngInsertQuery, 5, In->BackgroundFilename.c_str(), In->BackgroundFilename.length(), SQLITE_STATIC)); SC(sqlite3_bind_int(st_SngInsertQuery, 6, In->Mode)); SC(sqlite3_bind_text(st_SngInsertQuery, 7, In->SongPreviewSource.c_str(), In->SongPreviewSource.length(), SQLITE_STATIC)); SC(sqlite3_bind_double(st_SngInsertQuery, 8, In->PreviewTime)); SCS(sqlite3_step(st_SngInsertQuery)); SC(sqlite3_reset(st_SngInsertQuery)); sqlite3_step(st_GetLastSongID); Out = sqlite3_column_int(st_GetLastSongID, 0); sqlite3_reset(st_GetLastSongID); } sqlite3_reset(st_GetSIDFromFilename); if (In) In->ID = Out; return Out; }
bool ScreenGameplay7K::LoadSongAudio() { if (!Music) { Music = std::make_shared<AudioStream>(); Music->SetPitch(Speed); if (MySong->SongFilename.length() && Music->Open((MySong->SongDirectory / MySong->SongFilename).c_path())) { Log::Printf("Stream for %s succesfully opened.\n", MySong->SongFilename.c_str()); } else { if (!CurrentDiff->IsVirtual) { // Caveat: Try to autodetect an mp3/ogg file. std::vector<std::string> DirCnt; auto SngDir = MySong->SongDirectory; SngDir.ListDirectory(DirCnt, Directory::FS_REG); for (auto i = DirCnt.begin(); i != DirCnt.end(); ++i) { if (Directory(*i).GetExtension() == "mp3" || Directory(*i).GetExtension() == "ogg") if (Music->Open((SngDir / *i).c_path())) return true; } Music = nullptr; Log::Printf("Unable to load song (Path: %s)\n", MySong->SongFilename.c_str()); return false; // Quit; couldn't find audio for a chart that requires it. } } } // Load samples. if (strstr(MySong->SongFilename.c_str(), ".ojm")) { Log::Printf("Loading OJM.\n"); OJMAudio = std::make_shared<AudioSourceOJM>(this); OJMAudio->SetPitch(Speed); OJMAudio->Open((MySong->SongDirectory / MySong->SongFilename).c_path()); for (int i = 1; i <= 2000; i++) { std::shared_ptr<SoundSample> Snd = OJMAudio->GetFromIndex(i); if (Snd != nullptr) Keysounds[i].push_back(Snd); } } else if (CurrentDiff->SoundList.size() || CurrentDiff->Data->TimingInfo->GetType() == VSRG::TI_BMS) { Log::Printf("Loading samples... "); if (CurrentDiff->Data->TimingInfo->GetType() == VSRG::TI_BMS) { Directory dir = MySong->SongDirectory; bool isBMSON = ((VSRG::BMSTimingInfo*)CurrentDiff->Data->TimingInfo.get())->IsBMSON; if (isBMSON) { int wavs = 0; std::map<int, SoundSample> audio; auto &slicedata = CurrentDiff->Data->SliceData; // do bmson loading for (auto wav : slicedata.Slices) { for (auto sounds : wav.second) { CheckInterruption(); // load basic sound if (!audio[sounds.first].IsValid()) { Directory path = (dir / slicedata.AudioFiles[sounds.first]); audio[sounds.first].SetPitch(Speed); if (!audio[sounds.first].Open(path.c_path())) throw std::exception(Utility::Format("Unable to load %s.", slicedata.AudioFiles[sounds.first]).c_str()); Log::Printf("BMSON: Load sound %s\n", path.c_path()); } audio[sounds.first].Slice(sounds.second.Start, sounds.second.End); Keysounds[wav.first].push_back(audio[sounds.first].CopySlice()); wavs++; } Keysounds[wav.first].shrink_to_fit(); } Log::Printf("BMSON: Generated %d sound objects.\n", wavs); } } for (auto i = CurrentDiff->SoundList.begin(); i != CurrentDiff->SoundList.end(); ++i) { auto ks = std::make_shared<SoundSample>(); ks->SetPitch(Speed); #ifdef WIN32 std::wstring sd = Utility::Widen(MySong->SongDirectory) + L"/" + Utility::Widen(i->second); ks->Open(Utility::Narrow(sd).c_str()); #else ks->Open((MySong->SongDirectory + "/" + i->second).c_str()); #endif Keysounds[i->first].push_back(ks); CheckInterruption(); } } return true; }