unit UPliki;
interface
{$I switches.inc}
uses USongs, SysUtils, ULog, UMusic;
procedure InitializePaths;
function ReadHeader(var Song: TSong): boolean;
function SkanujPlik(var Song: TSong): boolean;
procedure CzyscNuty;
function WczytajCzesci(Name: string): boolean;
function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean;
function SaveSongDebug(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean;
var
GamePath: string;
SoundPath: string;
SongPath: string;
LogPath: string;
ThemePath: string;
ScreenshotsPath: string;
CoversPath: string;
LanguagesPath: string;
PluginPath: string;
PlayListPath: string;
Plik: TextFile; // all procedures in this unit operates on this file
PlikC: char;
Lineno: integer;
// variables available for all procedures
Base: array[0..1] of integer;
Rel: array[0..1] of integer;
Mult: integer;
MultBPM: integer;
implementation
uses TextGL, UIni, UMain, math;
procedure InitializePaths;
begin
GamePath := ExtractFilePath(ParamStr(0));
SoundPath := GamePath + 'Sounds\';
SongPath := GamePath + 'Songs\';
LogPath := GamePath;
ThemePath := GamePath + 'Themes\';
ScreenshotsPath := GamePath + 'Screenshots\';
CoversPath := GamePath + 'Covers\';
LanguagesPath := GamePath + 'Languages\';
//Modi Loader
PluginPath := GamePath + 'Plugins\';
PlaylistPath := GamePath + 'Playlists\';
end;
function ReadHeader(var Song: TSong): boolean;
var
TempC: char;
Tekst: string;
Done: integer;
begin
// clear
Song.Title := '';
Song.Artist := '';
Song.Genre := 'Unknown';
Song.Edition := 'Unknown';
Song.Language := 'Unknown'; //Language Patch
Song.Mp3 := '';
Song.BPM := 0;
Song.GAP := 0;
Song.Start := 0;
Song.Finish := 0;
Song.Background := '';
Song.Video := '';
Song.VideoGAP := 0;
Song.NotesGAP := 0;
Song.Resolution := 4;
//Creator Patch
Song.Creator := '';
Done := 0;
//Editor Error Reporting Hack
LineNo := 0;
try
// read
Read(Plik, PlikC);
while (PlikC = '#') do begin
ReadLn(Plik, Tekst);
//Editor Error Reporting Hack
Inc (LineNo);
//Header Improvements Patch
if UpperCase(Copy(Tekst, 1, 6)) = 'TITLE:' then begin
Delete(Tekst, 1, 6);
Song.Title := Trim(Tekst);
Tekst := '';
Done := Done or 1;
end
else if UpperCase(Copy(Tekst, 1, 7)) = 'ARTIST:' then begin
Delete(Tekst, 1, 7);
Song.Artist := Trim(Tekst);
Tekst := '';
Done := Done or 2;
end
else if UpperCase(Copy(Tekst, 1, 4)) = 'MP3:' then begin
Delete(Tekst, 1, 4);
Song.Mp3 := Trim(Tekst);
Tekst := '';
Done := Done or 4;
end
else if UpperCase(Copy(Tekst, 1, 8)) = 'CREATOR:' then begin // this goes for edit
Delete(Tekst, 1, 8);
Song.Creator := Trim(Tekst);
Tekst := '';
end
else if UpperCase(Copy(Tekst, 1, 6)) = 'GENRE:' then begin // this goes for edit
Delete(Tekst, 1, 6);
Song.Genre := Trim(Tekst);
Tekst := '';
end
else if UpperCase(Copy(Tekst, 1, 8)) = 'EDITION:' then begin // this goes for edit
Delete(Tekst, 1, 8);
Song.Edition := Trim(Tekst);
Tekst := '';
end
else if UpperCase(Copy(Tekst, 1, 9)) = 'LANGUAGE:' then begin // this goes for edit
Delete(Tekst, 1, 9);
Song.Language := Trim(Tekst);
Tekst := '';
end
else if UpperCase(Copy(Tekst, 1, 6)) = 'COVER:' then begin
Delete(Tekst, 1, 6);
Song.Cover := Trim(Tekst);
Tekst := '';
end
else if UpperCase(Copy(Tekst, 1, 11)) = 'BACKGROUND:' then begin
Delete(Tekst, 1, 11);
Song.Background := Trim(Tekst);
Tekst := '';
end
else if UpperCase(Copy(Tekst, 1, 6)) = 'VIDEO:' then begin
Delete(Tekst, 1, 6);
Song.Video := Trim(Tekst);
Tekst := '';
end
else if UpperCase(Copy(Tekst, 1, 9)) = 'VIDEOGAP:' then begin
Delete(Tekst, 1, 9);
//Change . to , Mod by Whiteshark :P
if (Pos('.',Tekst) <> 0) then
begin
Tekst[Pos('.',Tekst)] := ',';
//Little Annonce for the User
Log.LogError('VideoGap Seperator wrong in SongHeader: ' + Song.FileName + ' [Corrected for this Session]');
end;
Song.VideoGAP := StrToFloat(Tekst);
Tekst := ''
end
else if UpperCase(Copy(Tekst, 1, 9)) = 'NOTESGAP:' then begin
Delete(Tekst, 1, 9);
Song.NotesGAP := StrToInt(Tekst);
Tekst := ''
end
else if UpperCase(Copy(Tekst, 1, 9)) = 'RELATIVE:' then begin
Delete(Tekst, 1, 9);
if LowerCase(Tekst) = 'yes' then Song.Relative := true;
end
else if UpperCase(Copy(Tekst, 1, 6)) = 'START:' then begin
Delete(Tekst, 1, 6);
Song.Start := StrToFloat(Tekst);
// Muzyka.Start := StrToInt(Tekst);
end
else if UpperCase(Copy(Tekst, 1, 4)) = 'END:' then begin
Delete(Tekst, 1, 4);
Song.Finish := StrToInt(Tekst);
end
else if UpperCase(Copy(Tekst, 1, 11)) = 'RESOLUTION:' then begin
Delete(Tekst, 1, 11);
Song.Resolution := StrToInt(Tekst);
end
else if UpperCase(Copy(Tekst, 1, 4)) = 'BPM:' then begin
Delete(Tekst, 1, 4);
// Muzyka.BPMOld := StrToFloat(Tekst) * Mult * MultBPM; // old system
(* new system with variable BPM *)
// Muzyka.BPMOld := 50;
//Change . to , Mod by Whiteshark :P
if (Pos('.',Tekst) <> 0) then
begin
Tekst[Pos('.',Tekst)] := ',';
//Little Annonce for the User
Log.LogError('BPM Seperator wrong in SongHeader: ' + Song.FileName + ' [Corrected for this Session]');
end;
SetLength(Song.BPM, 1);
Song.BPM[0].StartBeat := 0;
Song.BPM[0].BPM := StrToFloat(Tekst) * Mult * MultBPM;
Tekst := '';
Done := Done or 8;
end
else if UpperCase(Copy(Tekst, 1, 4)) = 'GAP:' then begin
Delete(Tekst, 1, 4);
Song.GAP := StrToFloat(Tekst);
Tekst := '';
// Muzyka.GAP := StrToFloat(Tekst);
// Done := Done or 16;
end;
//Header Improvements Patch Ende
Read(Plik, PlikC);
end;
//Editor Error Reporting Hack
except //An Error happened<- bad english :P
Log.LogError('An Error occured reading Line ' + inttostr(LineNo) + ' from SongHeader: ' + Song.FileName);
Halt;
end;
//Editor Error Reporting Hack End
if Song.Background = '' then begin
Song.Background := Songs.FindSongFile(Song.Path, '*[BG].jpg');
end;
if (Done and 15) = 15 then Result := true
else Result := false;
end;
function SkanujPlik(var Song: TSong): boolean;
var
Done: integer;
Tekst: string;
C: integer; // category
P: integer; // position
begin
// try
AssignFile(Plik, Song.Path + Song.FileName);
Reset(Plik);
Result := ReadHeader(Song);
{ ReadLn(Plik, Tekst);
while (Copy(Tekst, 1, 1) = '#') do begin
if Copy(Tekst, 1, 10) = '#CATEGORY:' then begin
Delete(Tekst, 1, 10);
Trim(Tekst);
while (Length(Tekst) > 0) do begin
C := Length(Song.Category);
SetLength(Song.Category, C+1);
P := Pos(',', Tekst);
if P = 0 then P := Length(Tekst);
Song.Category[C] := Copy(Tekst, 1, P);
Delete(Tekst, 1, P);
Trim(Tekst);
end;
end;}
end;
procedure CzyscNuty;
var
Pet: integer;
begin
SetLength(Czesci, Length(Player));
SetLength(AktSong.BPM, 0);
for Pet := 0 to High(Player) do begin
SetLength(Czesci[Pet].Czesc, 1);
SetLength(Czesci[Pet].Czesc[0].Nuta, 0);
Czesci[Pet].Czesc[0].Lyric := '';
Czesci[Pet].Czesc[0].LyricWidth := 0;
Player[pet].Score := 0;
Player[pet].IlNut := 0;
Player[pet].HighNut := -1;
end;
end;
procedure DodajNute(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string);
var
Space: boolean;
begin
case Ini.Solmization of
1: // european
begin
case (NoteP mod 12) of
0..1: LyricS := ' do ';
2..3: LyricS := ' re ';
4: LyricS := ' mi ';
5..6: LyricS := ' fa ';
7..8: LyricS := ' sol ';
9..10: LyricS := ' la ';
11: LyricS := ' si ';
end;
end;
2: // japanese
begin
case (NoteP mod 12) of
0..1: LyricS := ' do ';
2..3: LyricS := ' re ';
4: LyricS := ' mi ';
5..6: LyricS := ' fa ';
7..8: LyricS := ' so ';
9..10: LyricS := ' la ';
11: LyricS := ' shi ';
end;
end;
3: // american
begin
case (NoteP mod 12) of
0..1: LyricS := ' do ';
2..3: LyricS := ' re ';
4: LyricS := ' mi ';
5..6: LyricS := ' fa ';
7..8: LyricS := ' sol ';
9..10: LyricS := ' la ';
11: LyricS := ' ti ';
end;
end;
end; // case
// Log.LogStatus('Czesc: ' + IntToStr(Czesci[NrCzesci].High), 'DodajNute');
// Log.LogStatus('Dodano: [' + IntToStr(NrCzesci) + '] ' + IntToStr(StartP) + ' '
// + IntToStr(DurationP) + ' '+ IntToStr(NoteP) + ' ' + LyricS, 'DodajNute');
{ Delete(LyricS, 1, 1);
Space := false;
if Copy(LyricS, Length(LyricS), 1) = ' ' then begin
Space := true;
Delete(LyricS, Length(LyricS), 1);
end;
if LyricS = 'a' then LyricS := chr($B1);
if LyricS = 'i' then LyricS := chr($B2);
if LyricS = 'u' then LyricS := chr($B3);
if LyricS = 'e' then LyricS := chr($B4);
if LyricS = 'o' then LyricS := chr($B5);
if LyricS = 'ka' then LyricS := chr($B6);
if LyricS = 'ki' then LyricS := chr($B7);
if LyricS = 'ku' then LyricS := chr($B8);
if LyricS = 'ke' then LyricS := chr($B9);
if LyricS = 'ko' then LyricS := chr($BA);
if LyricS = 'ga' then LyricS := chr($B6) + chr($DE);
if LyricS = 'gi' then LyricS := chr($B7) + chr($DE);
if LyricS = 'gu' then LyricS := chr($B8) + chr($DE);
if LyricS = 'ge' then LyricS := chr($B9) + chr($DE);
if LyricS = 'go' then LyricS := chr($BA) + chr($DE);
if LyricS = 'sa' then LyricS := chr($BB);
if LyricS = 'shi' then LyricS := chr($BC);
if LyricS = 'su' then LyricS := chr($BD);
if LyricS = 'se' then LyricS := chr($BE);
if LyricS = 'so' then LyricS := chr($BF);
if LyricS = 'za' then LyricS := chr($BB) + chr($DE);
if LyricS = 'ji' then LyricS := chr($BC) + chr($DE);
if LyricS = 'zu' then LyricS := chr($BD) + chr($DE);
if LyricS = 'ze' then LyricS := chr($BE) + chr($DE);
if LyricS = 'zo' then LyricS := chr($BF) + chr($DE);
if LyricS = 'ta' then LyricS := chr($C0);
if LyricS = 'chi' then LyricS := chr($C1);
if LyricS = 'tsu' then LyricS := chr($C2);
if LyricS = 'te' then LyricS := chr($C3);
if LyricS = 'to' then LyricS := chr($C4);
if LyricS = 'da' then LyricS := chr($C0) + chr($DE);
// if LyricS = 'ji' then LyricS := chr($C1) + chr($DE);
// if LyricS = 'zu' then LyricS := chr($C2) + chr($DE);
if LyricS = 'de' then LyricS := chr($C3) + chr($DE);
if LyricS = 'do' then LyricS := chr($C4) + chr($DE);
if LyricS = 'na' then LyricS := chr($C5);
if LyricS = 'ni' then LyricS := chr($C6);
if LyricS = 'nu' then LyricS := chr($C7);
if LyricS = 'ne' then LyricS := chr($C8);
if LyricS = 'no' then LyricS := chr($C9);
if LyricS = 'ha' then LyricS := chr($CA);
if LyricS = 'hi' then LyricS := chr($CB);
if LyricS = 'hu' then LyricS := chr($CC);
if LyricS = 'he' then LyricS := chr($CD);
if LyricS = 'ho' then LyricS := chr($CE);
if LyricS = 'ba' then LyricS := chr($CA) + chr($DE);
if LyricS = 'bi' then LyricS := chr($CB) + chr($DE);
if LyricS = 'bu' then LyricS := chr($CC) + chr($DE);
if LyricS = 'be' then LyricS := chr($CD) + chr($DE);
if LyricS = 'bo' then LyricS := chr($CE) + chr($DE);
if LyricS = 'pa' then LyricS := chr($CA) + chr($DF);
if LyricS = 'pi' then LyricS := chr($CB) + chr($DF);
if LyricS = 'pu' then LyricS := chr($CC) + chr($DF);
if LyricS = 'pe' then LyricS := chr($CD) + chr($DF);
if LyricS = 'po' then LyricS := chr($CE) + chr($DF);
if LyricS = 'ma' then LyricS := chr($CF);
if LyricS = 'mi' then LyricS := chr($D0);
if LyricS = 'mu' then LyricS := chr($D1);
if LyricS = 'me' then LyricS := chr($D2);
if LyricS = 'mo' then LyricS := chr($D3);
if LyricS = 'ya' then LyricS := chr($D4);
if LyricS = 'yu' then LyricS := chr($D5);
if LyricS = 'yo' then LyricS := chr($D6);
if LyricS = 'ra' then LyricS := chr($D7);
if LyricS = 'ri' then LyricS := chr($D8);
if LyricS = 'ru' then LyricS := chr($D9);
if LyricS = 're' then LyricS := chr($DA);
if LyricS = 'ro' then LyricS := chr($DB);
if LyricS = 'wa' then LyricS := chr($DC);
if LyricS = 'n' then LyricS := chr($DD);
LyricS := ' ' + LyricS;
if Space then LyricS := LyricS + ' ';}
with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].High] do begin
SetLength(Nuta, Length(Nuta) + 1);
IlNut := IlNut + 1;
HighNut := HighNut + 1;
Muzyka.IlNut := Muzyka.IlNut + 1;
Nuta[HighNut].Start := StartP;
if IlNut = 1 then begin
StartNote := Nuta[HighNut].Start;
if Czesci[NrCzesci].Ilosc = 1 then
Start := -100;
// Start := Nuta[HighNut].Start;
end;
Nuta[HighNut].Dlugosc := DurationP;
Muzyka.DlugoscNut := Muzyka.DlugoscNut + Nuta[HighNut].Dlugosc;
// back to the normal system with normal, golden and now freestyle notes
case TypeP of
'F': Nuta[HighNut].Wartosc := 0;
':': Nuta[HighNut].Wartosc := 1;
'*': Nuta[HighNut].Wartosc := 2;
end;
Czesci[NrCzesci].Wartosc := Czesci[NrCzesci].Wartosc + Nuta[HighNut].Dlugosc * Nuta[HighNut].Wartosc;
Nuta[HighNut].Ton := NoteP;
if Nuta[HighNut].Ton < Base[NrCzesci] then Base[NrCzesci] := Nuta[HighNut].Ton;
Nuta[HighNut].TonGamy := Nuta[HighNut].TonGamy mod 12;
Nuta[HighNut].Tekst := Copy(LyricS, 2, 100);
Lyric := Lyric + Nuta[HighNut].Tekst;
if TypeP = 'F' then
Nuta[HighNut].FreeStyle := true;
Koniec := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc;
end; // with
end;
procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer);
var
I: Integer;
begin
// Log.LogStatus('IlCzesci: ' + IntToStr(Czesci[NrCzesciP].Ilosc), 'NewSentece');
// Log.LogStatus('Dane: ' + IntToStr(NrCzesciP) + ' ' + IntToStr(Param1) + ' ' + IntToStr(Param2) , 'NewSentece');
// stara czesc //Alter Satz //Update Old Part
Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].BaseNote := Base[NrCzesciP];
Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].LyricWidth := glTextWidth(PChar(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Lyric));
//Total Notes Patch
Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := 0;
for I := low(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) to high(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) do
begin
Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Dlugosc * Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Wartosc;
end;
//Log.LogError('Total Notes(' + inttostr(Czesci[NrCzesciP].High) +'): ' + inttostr(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes));
//Total Notes Patch End
// nowa czesc //Neuer Satz //Update New Part
SetLength(Czesci[NrCzesciP].Czesc, Czesci[NrCzesciP].Ilosc + 1);
Czesci[NrCzesciP].High := Czesci[NrCzesciP].High + 1;
Czesci[NrCzesciP].Ilosc := Czesci[NrCzesciP].Ilosc + 1;
Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].HighNut := -1;
if not AktSong.Relative then
Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1;
if AktSong.Relative then begin
Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1;
Rel[NrCzesciP] := Rel[NrCzesciP] + Param2;
end;
Base[NrCzesciP] := 100; // high number
end;
function WczytajCzesci(Name: string): boolean;
var
TempC: char;
Tekst: string;
CP: integer; // Current Player (0 or 1)
Pet: integer;
Both: boolean;
Param1: integer;
Param2: integer;
Param3: integer;
ParamS: string;
I: Integer;
begin
Result := false;
if not FileExists(Name) then begin
Log.LogError('File not found: "' + Name + '"', 'WczytajCzesci');
exit;
end;
try
MultBPM := 4; // 4 - mnoznik dla czasu nut
Mult := 1; // 4 - dokladnosc pomiaru nut
Base[0] := 100; // high number
// Base[1] := 100; // high number
Czesci[0].Wartosc := 0;
// Czesci[1].Wartosc := 0; // here was the error in 0.3.2
AktSong.Relative := false;
Rel[0] := 0;
// Rel[1] := 0;
CP := 0;
Both := false;
if Length(Player) = 2 then Both := true;
FileMode := fmOpenRead;
AssignFile(Plik, Name);
Reset(Plik);
ReadHeader(AktSong);
(* if AktSong.Title = 'Hubba Hubba Zoot Zoot' then begin
Mult := 2;
AktSong.BPM[0].BPM := AktSong.BPM[0].BPM * 2;
end;*)
SetLength(Czesci, 2);
for Pet := 0 to High(Czesci) do begin
SetLength(Czesci[Pet].Czesc, 1);
Czesci[Pet].High := 0;
Czesci[Pet].Ilosc := 1;
Czesci[Pet].Akt := 0;
Czesci[Pet].Resolution := AktSong.Resolution;
Czesci[Pet].NotesGAP := AktSong.NotesGAP;
Czesci[Pet].Czesc[0].IlNut := 0;
Czesci[Pet].Czesc[0].HighNut := -1;
end;
// TempC := ':';
TempC := PlikC; // read from backup variable, don't use default ':' value
while (TempC <> 'E') do begin
Inc(LineNo);
if (TempC = ':') or (TempC = '*') or (TempC = 'F') then begin
// wczytuje nute
Read(Plik, Param1);
Read(Plik, Param2);
Read(Plik, Param3);
Read(Plik, ParamS);
// dodaje nute
if not Both then
// P1
DodajNute(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS)
else begin
// P1 + P2
DodajNute(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS);
DodajNute(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS);
end;
end; // if
if TempC = '-' then begin
// reads sentence
Read(Plik, Param1);
if AktSong.Relative then Read(Plik, Param2); // read one more data for relative system
// new sentence
if not Both then
// P1
NewSentence(0, (Param1 + Rel[0]) * Mult, Param2)
else begin
// P1 + P2
NewSentence(0, (Param1 + Rel[0]) * Mult, Param2);
NewSentence(1, (Param1 + Rel[1]) * Mult, Param2);
end;
end; // if
if TempC = 'B' then begin
SetLength(AktSong.BPM, Length(AktSong.BPM) + 1);
Read(Plik, AktSong.BPM[High(AktSong.BPM)].StartBeat);
AktSong.BPM[High(AktSong.BPM)].StartBeat := AktSong.BPM[High(AktSong.BPM)].StartBeat + Rel[0];
Read(Plik, Tekst);
AktSong.BPM[High(AktSong.BPM)].BPM := StrToFloat(Tekst);
AktSong.BPM[High(AktSong.BPM)].BPM := AktSong.BPM[High(AktSong.BPM)].BPM * Mult * MultBPM;
end;
if not Both then begin
Czesci[CP].Czesc[Czesci[CP].High].BaseNote := Base[CP];
Czesci[CP].Czesc[Czesci[CP].High].LyricWidth := glTextWidth(PChar(Czesci[CP].Czesc[Czesci[CP].High].Lyric));
//Total Notes Patch
Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := 0;
for I := low(Czesci[CP].Czesc[Czesci[CP].High].Nuta) to high(Czesci[CP].Czesc[Czesci[CP].High].Nuta) do
begin
Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := Czesci[CP].Czesc[Czesci[CP].High].TotalNotes + Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Dlugosc * Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Wartosc;
end;
//Total Notes Patch End
end else begin
for Pet := 0 to High(Czesci) do begin
Czesci[Pet].Czesc[Czesci[Pet].High].BaseNote := Base[Pet];
Czesci[Pet].Czesc[Czesci[Pet].High].LyricWidth := glTextWidth(PChar(Czesci[Pet].Czesc[Czesci[Pet].High].Lyric));
//Total Notes Patch
Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := 0;
for I := low(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) to high(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) do
begin
Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes + Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Dlugosc * Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Wartosc;
end;
//Total Notes Patch End
end;
end;
Read(Plik, TempC);
end; // while}
CloseFile(Plik);
except
Log.LogError('Error Loading File: "' + Name + '" in Line ' + inttostr(LineNo));
exit;
end;
Result := true;
end;
function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean;
var
C: integer;
N: integer;
S: string;
B: integer;
RelativeSubTime: integer;
NoteState: String;
begin
// Relative := true; // override (idea - use shift+S to save with relative)
AssignFile(Plik, Name);
Rewrite(Plik);
WriteLn(Plik, '#TITLE:' + Song.Title + '');
WriteLn(Plik, '#ARTIST:' + Song.Artist);
if Song.Creator <> '' then WriteLn(Plik, '#CREATOR:' + Song.Creator);
if Song.Edition <> 'Unknown' then WriteLn(Plik, '#EDITION:' + Song.Edition);
if Song.Genre <> 'Unknown' then WriteLn(Plik, '#GENRE:' + Song.Genre);
if Song.Language <> 'Unknown' then WriteLn(Plik, '#LANGUAGE:' + Song.Language);
if Song.Cover <> '' then WriteLn(Plik, '#COVER:' + Song.Cover);
WriteLn(Plik, '#MP3:' + Song.Mp3);
if Song.Background <> '' then WriteLn(Plik, '#BACKGROUND:' + Song.Background);
if Song.Video <> '' then WriteLn(Plik, '#VIDEO:' + Song.Video);
if Song.VideoGAP <> 0 then WriteLn(Plik, '#VIDEOGAP:' + FloatToStr(Song.VideoGAP));
if Song.Resolution <> 4 then WriteLn(Plik, '#RESOLUTION:' + IntToStr(Song.Resolution));
if Song.NotesGAP <> 0 then WriteLn(Plik, '#NOTESGAP:' + IntToStr(Song.NotesGAP));
if Song.Start <> 0 then WriteLn(Plik, '#START:' + FloatToStr(Song.Start));
if Song.Finish <> 0 then WriteLn(Plik, '#END:' + IntToStr(Song.Finish));
if Relative then WriteLn(Plik, '#RELATIVE:yes');
WriteLn(Plik, '#BPM:' + FloatToStr(Song.BPM[0].BPM / 4));
WriteLn(Plik, '#GAP:' + FloatToStr(Song.GAP));
RelativeSubTime := 0;
for B := 1 to High(AktSong.BPM) do
WriteLn(Plik, 'B ' + FloatToStr(AktSong.BPM[B].StartBeat) + ' ' + FloatToStr(AktSong.BPM[B].BPM/4));
for C := 0 to Czesc.High do begin
for N := 0 to Czesc.Czesc[C].HighNut do begin
with Czesc.Czesc[C].Nuta[N] do begin
//Golden + Freestyle Note Patch
case Czesc.Czesc[C].Nuta[N].Wartosc of
0: NoteState := 'F ';
1: NoteState := ': ';
2: NoteState := '* ';
end; // case
S := NoteState + IntToStr(Start-RelativeSubTime) + ' ' + IntToStr(Dlugosc) + ' ' + IntToStr(Ton) + ' ' + Tekst;
WriteLn(Plik, S);
end; // with
end; // N
if C < Czesc.High then begin // don't write end of last sentence
if not Relative then
S := '- ' + IntToStr(Czesc.Czesc[C+1].Start)
else begin
S := '- ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime) +
' ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime);
RelativeSubTime := Czesc.Czesc[C+1].Start;
end;
WriteLn(Plik, S);
end;
end; // C
WriteLn(Plik, 'E');
CloseFile(Plik);
end;
function SaveSongDebug(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean;
var
C: integer;
N: integer;
S: string;
STon: integer;
SLen: integer;
NTot: integer;
PlikB: TextFile;
LastTime: integer;
begin
AssignFile(Plik, Name);
Rewrite(Plik);
AssignFile(PlikB, 'C:\song db.asm');
Rewrite(PlikB);
NTot := 0;
LastTime := 0;
for C := 0 to Czesc.High do begin
WriteLn(Plik, '; ' + IntToStr(C));
for N := 0 to Czesc.Czesc[C].HighNut do begin
with Czesc.Czesc[C].Nuta[N] do begin
// timespace
if LastTime < Start then begin
STon := 0;
SLen := Round((Start - LastTime) * 16320 / 255 / 12);
WriteLn(PlikB, ' .dw ' + IntToStr(STon + SLen*256) + ' ; timespace (0, ' + IntToStr(SLen) + ')');
end;
// ton
STon := Round(98940/(2*261.62*Power(1.05946309436, Ton)));
S := ' ldi R18, ' + IntToStr(STon);
if STon > 255 then begin
beep;
S := '!!!!' + S;
end;
WriteLn(Plik, S);
// length
//ldi R19, 43
SLen := Round(Dlugosc * 16320 / STon / 12);
S := ' ldi R19, ' + IntToStr(SLen);
if SLen > 255 then begin
beep;
S := '!!!!' + S;
end;
WriteLn(Plik, S);
// function
S := ' rcall playtone';
WriteLn(Plik, S);
// song dw
WriteLn(PlikB, ' .dw ' + IntToStr(STon + SLen*256));
LastTime := Start + Dlugosc;
Inc(NTot);
end; // with
end; // N
WriteLn(Plik, '');
WriteLn(PlikB, '');
end; // C
WriteLn(Plik, '; nut ' + IntToStr(NTot));
WriteLn(Plik, '; bajt�w ' + IntToStr(8*NTot));
WriteLn(PlikB, ' .dw 0');
WriteLn(PlikB, '; nut ' + IntToStr(NTot));
WriteLn(PlikB, '; bajt�w ' + IntToStr(2*NTot));
CloseFile(Plik);
CloseFile(PlikB);
end;
end.