unit UScreenEditSub;
interface
uses UMenu, UVideo, TextGL, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, USmpeg, UTexture, UMenuText,
ULyrics, Math, gl, UThemes, MidiOut, UHelp;
type
TVidVis = (none, windowed, full);
TMedleyNotes = record
start: TPos;
end_: TPos;
Preview: TPos;
isStart: boolean; //start beat is declared
isEnd: boolean; //end beat is declared
end;
TScreenEditSub = class(TMenu)
private
AktBeat: integer;
//Variable is True if no SOng is loaded
Error: Boolean;
MP3Volume: Integer;
TextNote: integer;
TextSentence: integer;
TextTitle: integer;
TextArtist: integer;
TextMp3: integer;
TextBPM: integer;
TextGAP: integer;
TextDebug: integer;
TextNStart: integer;
TextNDlugosc: integer;
TextNTon: integer;
TextNText: integer;
TextVideoGap:integer;
AktNuta: integer;
PlaySentence: boolean;
PlaySentenceMidi: boolean;
PlayOneNote: boolean;
PlayOneNoteMidi: boolean;
PlayStopTime: real;
LastClick: integer;
Click: boolean;
CopySrc: integer;
MidiOut: TMidiOutput;
MidiStart: real;
MidiStop: real;
MidiTime: real;
MidiPos: real;
MidiLastNote: integer;
TextEditMode: boolean;
BPMEditMode: boolean;
MedleyNotes: TMedleyNotes;
editText: string; //backup of current text in text-edit-mode
noteStart: integer; //Start note when playing sentence
lineStart: integer; //Start line when playing sentence
LineChanged: boolean;
VidVis: TVidVis; //video visiability
PlayVideo: boolean;
StartTry: boolean;
PlayTime: real;
procedure StartVideo;
procedure StartVideoPreview;
procedure NewBeat;
procedure ChangeBPM(newBPM: real);
procedure CzesciDivide;
procedure CzesciMultiply;
procedure LyricsCapitalize;
procedure LyricsCorrectSpaces;
procedure FixTimings;
procedure DivideSentence;
procedure JoinSentence;
procedure DivideNote;
procedure DeleteNote;
procedure TransposeNote(Transpose: integer);
procedure ChangeWholeTone(Tone: integer);
procedure MoveAllToEnd(Move: integer);
procedure MoveTextToRight;
procedure MarkSrc;
procedure PasteText;
procedure CopySentence(Src, Dst: integer);
procedure CopySentences(Src, Dst, Num: integer);
//Note Name Mod
function GetNoteName(Note: Integer): String;
function GetMedleyLength: real; //returns if availible the length of the medley in seconds, else 0
procedure DrawInfoBar(x, y, w, h: integer);
public
Tex_Background: TTexture;
FadeOut: boolean;
Path: string;
FileName: string;
SongIndex: integer; //SongIndex from CatSongs.Song
constructor Create; override;
procedure onShow; override;
function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
function ParseInputEditText(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
function ParseInputEditBPM(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
function Draw: boolean; override;
procedure onHide; override;
end;
const
ID='ID_001'; //for help system
implementation
uses UGraphic, UDraw, UMain, USkins, ULanguage;
// Method for input parsing. If False is returned, GetNextWindow
// should be checked to know the next window to load;
function TScreenEditSub.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
var
SDL_ModState: Word;
R: real;
SResult: boolean;
temp: integer;
begin
Result := true;
Text[TextDebug].Text := '';
if TextEditMode then
Result := ParseInputEditText(PressedKey, ScanCode, PressedDown)
else if BPMEditMode then
Result := ParseInputEditBPM(PressedKey, ScanCode, PressedDown)
else
begin
SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
If (PressedDown) then begin // Key Down
case PressedKey of
SDLK_TAB:
begin
ScreenPopupHelp.ShowPopup();
end;
SDLK_ESCAPE:
begin
Music.Close;
acClose;
FadeTo(@ScreenSong);
end;
SDLK_Q:
begin
Result := false;
end;
SDLK_BACKQUOTE:
begin
// Increase Note Length (same as Alt + Right)
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
end;
SDLK_EQUALS:
begin
// Increase BPM
if SDL_ModState = 0 then
AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 5) + 1) / 5; // (1/20)
if SDL_ModState = KMOD_LSHIFT then
AktSong.BPM[0].BPM := AktSong.BPM[0].BPM + 4; // (1/1)
if SDL_ModState = KMOD_LCTRL then
AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 25) + 1) / 25; // (1/100)
end;
SDLK_MINUS:
begin
// Decrease BPM
if SDL_ModState = 0 then
AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 5) - 1) / 5;
if SDL_ModState = KMOD_LSHIFT then
AktSong.BPM[0].BPM := AktSong.BPM[0].BPM - 4;
if SDL_ModState = KMOD_LCTRL then
AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 25) - 1) / 25;
end;
SDLK_0:
begin
// Increase GAP
if SDL_ModState = 0 then
AktSong.GAP := AktSong.GAP + 10;
if SDL_ModState = KMOD_LSHIFT then
AktSong.GAP := AktSong.GAP + 1000;
end;
SDLK_9:
begin
// Decrease GAP
if SDL_ModState = 0 then
AktSong.GAP := AktSong.GAP - 10;
if SDL_ModState = KMOD_LSHIFT then
AktSong.GAP := AktSong.GAP - 1000;
end;
SDLK_8:
begin
temp := round(AktSong.VideoGAP*100);
// Increase VideoGAP
if SDL_ModState = 0 then
temp := temp + 1; //10ms
if SDL_ModState = KMOD_LSHIFT then
temp := temp + 10; //100ms
if SDL_ModState = KMOD_LCTRL then
temp := temp + 100; //1000ms
AktSong.VideoGAP := temp/100;
if PlayVideo then
StartVideo;
end;
SDLK_7:
begin
temp := round(AktSong.VideoGAP*100);
// Decrease VideoGAP
if SDL_ModState = 0 then
temp := temp - 1; //10ms
if SDL_ModState = KMOD_LSHIFT then
temp := temp - 10; //100ms
if SDL_ModState = KMOD_LCTRL then
temp := temp - 100; //1000ms
AktSong.VideoGAP := temp/100;
if PlayVideo then
StartVideo;
end;
SDLK_KP_PLUS:
begin
// Increase tone of all notes
if SDL_ModState = 0 then
ChangeWholeTone(1);
if SDL_ModState = KMOD_LSHIFT then
ChangeWholeTone(12);
end;
SDLK_KP_MINUS:
begin
// Decrease tone of all notes
if SDL_ModState = 0 then
ChangeWholeTone(-1);
if SDL_ModState = KMOD_LSHIFT then
ChangeWholeTone(-12);
end;
SDLK_SLASH:
begin
if SDL_ModState = 0 then begin
// Insert start of sentece
if AktNuta > 0 then
DivideSentence;
end;
if SDL_ModState = KMOD_LSHIFT then begin
// Join next sentence with current
if Czesci[0].Akt < Czesci[0].High then
JoinSentence;
end;
if SDL_ModState = KMOD_LCTRL then begin
// divide note
DivideNote;
end;
end;
SDLK_S:
begin
//Medley MOD:
if (MedleyNotes.isStart and MedleyNotes.isEnd) and
(MedleyNotes.start.line < MedleyNotes.end_.line) then
begin
AktSong.Medley.Source := msTag;
AktSong.Medley.StartBeat:=Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].Start;
AktSong.Medley.EndBeat:=Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Start +
Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Dlugosc;
AktSong.Medley.FadeIn_time := DEFAULT_FADE_IN_TIME;
AktSong.Medley.FadeOut_time := DEFAULT_FADE_OUT_TIME;
end else begin
AktSong.Medley.Source := msNone;
AktSong.Medley.StartBeat:=0;
AktSong.Medley.EndBeat:=0;
end;
// Save Song
if SDL_ModState = KMOD_LSHIFT then
begin
if (AktSong.Medley.Source = msTag) then
begin
ScreenPopupError.ShowPopup(Language.Translate('Medley and Relative is not supported!'));
Exit;
end;
SResult := SaveSong(AktSong, Czesci[0], Path + FileName, true); //save with relative
end else
SResult := SaveSong(AktSong, Czesci[0], Path + FileName, false);
if SResult then
begin
Text[TextDebug].Text := Language.Translate('INFO_FILE_SAVED');
CatSongs.Song[SongIndex] := AktSong;
end else
begin
ScreenPopupError.ShowPopup(Language.Translate('ERROR_SAVE_FILE_FAILED'));
end;
Exit;
end;
// set Medley tags
SDLK_A:
begin
if AktSong.Relative then
begin
ScreenPopupError.ShowPopup(Language.Translate('Medley and Relative is not supported!'));
Exit;
end;
if SDL_ModState = KMOD_LSHIFT then //Medley End Note
begin
if MedleyNotes.isEnd then
begin
if (Czesci[0].Akt=MedleyNotes.end_.line) and (AktNuta=MedleyNotes.end_.note) then
begin
MedleyNotes.isEnd := false;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := false;
end else
begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].IsMedley := false;
MedleyNotes.end_.line := Czesci[0].Akt;
MedleyNotes.end_.note := AktNuta;
end;
end else
begin
MedleyNotes.isEnd := true;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
MedleyNotes.end_.line := Czesci[0].Akt;
MedleyNotes.end_.note := AktNuta;
end;
end else
begin //Medley Start Note
if MedleyNotes.isStart then
begin
if (Czesci[0].Akt=MedleyNotes.start.line) and (AktNuta=MedleyNotes.start.note) then
begin
MedleyNotes.isStart := false;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := false;
end else
begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].IsMedley := false;
MedleyNotes.start.line := Czesci[0].Akt;
MedleyNotes.start.note := AktNuta;
end;
end else
begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
MedleyNotes.isStart := true;
MedleyNotes.start.line := Czesci[0].Akt;
MedleyNotes.start.note := AktNuta;
end;
end;
//show length of medley
Text[TextDebug].Text := FormatFloat('MedleyLength: #0.00s', GetMedleyLength);
Exit;
end;
// jump to Medley tags
SDLK_J:
begin
if AktSong.Relative then
begin
ScreenPopupError.ShowPopup(Language.Translate('Medley and Relative is not supported!'));
Exit;
end;
if (SDL_ModState = KMOD_LSHIFT) and MedleyNotes.IsEnd then //Medley End Note
begin
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Czesci[0].Akt := MedleyNotes.end_.line;
AktNuta := MedleyNotes.end_.note;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.AddCzesc(Czesci[0].Akt);
Lyric.Selected := AktNuta;
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
end else if MedleyNotes.IsStart then
begin
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Czesci[0].Akt := MedleyNotes.start.line;
AktNuta := MedleyNotes.start.note;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.AddCzesc(Czesci[0].Akt);
Lyric.Selected := AktNuta;
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
end;
if (SDL_ModState = KMOD_LALT) then
begin
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
LineChanged:=false;
R := GetTimeFromBeat(Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].Start);
if R <= Music.Length then begin
Music.MoveTo(R);
noteStart := AktNuta;
lineStart := Czesci[0].Akt;
PlayStopTime := GetTimeFromBeat(
Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Start +
Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Dlugosc);
PlaySentence := true;
PlayOneNote := false;
Music.Play;
LastClick := -100;
end;
end;
//show length of medley
Text[TextDebug].Text := FormatFloat('MedleyLength: #0.00s', GetMedleyLength);
Exit;
end;
SDLK_K: //Preview Start
begin
if (SDL_ModState = KMOD_LSHIFT) then //jump to...
begin
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Czesci[0].Akt := MedleyNotes.Preview.line;
AktNuta := MedleyNotes.Preview.note;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.AddCzesc(Czesci[0].Akt);
Lyric.Selected := AktNuta;
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
end else
begin
if (Czesci[0].Akt = MedleyNotes.Preview.line) and (AktNuta = MedleyNotes.Preview.note) then //reset ?
begin
end else //set
begin
Czesci[0].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].IsStartPreview := false;
MedleyNotes.Preview.line := Czesci[0].Akt;
MedleyNotes.Preview.note := AktNuta;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsStartPreview := true;
AktSong.PreviewStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].start);
end;
end;
end;
SDLK_D:
begin
// Divide lengths by 2
if (SDL_ModState = KMOD_LSHIFT) then
CzesciDivide;
end;
SDLK_M:
begin
// Multiply lengths by 2
if (SDL_ModState = KMOD_LSHIFT) then
CzesciMultiply;
end;
SDLK_C:
begin
// Capitalize letter at the beginning of line
if SDL_ModState = 0 then
LyricsCapitalize;
// Correct spaces
if SDL_ModState = KMOD_LSHIFT then
LyricsCorrectSpaces;
// Copy sentence
if SDL_ModState = KMOD_LCTRL then
MarkSrc;
end;
SDLK_R: //reload
begin
MidiOut.Close;
MidiOut.Free;
Music.Close;
acClose;
onShow;
end;
SDLK_V:
begin
// Paste text
if SDL_ModState = KMOD_LCTRL then begin
if Czesci[0].Czesc[Czesci[0].Akt].IlNut >= Czesci[0].Czesc[CopySrc].IlNut then
PasteText
else
beep;
end;
if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
CopySentence(CopySrc, Czesci[0].Akt);
end;
if SDL_ModState = 0 then
StartVideo;
if SDL_ModState = KMOD_LSHIFT then
begin
StartVideo;
Click := true;
end;
end;
SDLK_4:
begin
if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
CopySentence(CopySrc, Czesci[0].Akt);
CopySentence(CopySrc+1, Czesci[0].Akt+1);
CopySentence(CopySrc+2, Czesci[0].Akt+2);
CopySentence(CopySrc+3, Czesci[0].Akt+3);
end;
if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
CopySentences(CopySrc, Czesci[0].Akt, 4);
end;
end;
SDLK_5:
begin
if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
CopySentence(CopySrc, Czesci[0].Akt);
CopySentence(CopySrc+1, Czesci[0].Akt+1);
CopySentence(CopySrc+2, Czesci[0].Akt+2);
CopySentence(CopySrc+3, Czesci[0].Akt+3);
CopySentence(CopySrc+4, Czesci[0].Akt+4);
end;
if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
CopySentences(CopySrc, Czesci[0].Akt, 5);
end;
end;
SDLK_T:
begin
// Fixes timings between sentences
FixTimings;
end;
SDLK_F4:
begin
// Enter Text Edit Mode
editText := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
TextEditMode := true;
end;
SDLK_F5:
begin
// Enter BPM Edit Mode
Text[TextBPM].Text := Text[TextBPM].Text + '|';
BPMEditMode := true;
end;
SDLK_P:
begin
if SDL_ModState = 0 then begin
// Play Sentence
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Click := true;
Music.Stop;
R := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
if R <= Music.Length then begin
Music.MoveTo(R);
PlayStopTime := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
PlaySentence := true;
PlayOneNote := false;
Music.Play;
LastClick := -100;
end;
end;
if SDL_ModState = KMOD_LSHIFT then begin
PlaySentenceMidi := true;
PlayOneNoteMidi := false;
MidiTime := USTime.GetTime;
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
LastClick := -100;
end;
if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then begin
PlaySentenceMidi := true;
PlayOneNoteMidi := false;
MidiTime := USTime.GetTime;
MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
LastClick := -100;
PlaySentence := true;
PlayOneNote := false;
Click := true;
Music.Stop;
Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote)+0{-0.10});
PlayStopTime := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec)+0;
Music.Play;
LastClick := -100;
end;
//new: play hole file + LALT
if SDL_ModState = KMOD_LALT then begin
// Play Sentence
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Click := true;
Music.Stop;
R := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
if R <= Music.Length then begin
Music.MoveTo(R);
PlayStopTime := Music.Length;
PlaySentence := true;
PlayOneNote := false;
Music.Play;
LastClick := -100;
end;
end;
if SDL_ModState = KMOD_LSHIFT or KMOD_LALT then begin
PlaySentenceMidi := true;
PlayOneNoteMidi := false;
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
MidiTime := USTime.GetTime;
MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
MidiStop := Music.Length;
LastClick := -100;
end;
if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL or KMOD_LALT then begin
PlaySentenceMidi := true;
PlayOneNoteMidi := false;
MidiTime := USTime.GetTime;
MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
MidiStop := Music.Length;
LastClick := -100;
PlaySentence := true;
PlayOneNote := false;
Click := true;
Music.Stop;
Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote)+0{-0.10});
PlayStopTime := Music.Length;
Music.Play;
LastClick := -100;
end;
if PlaySentenceMidi or PlaySentence then
begin
noteStart := AktNuta;
lineStart := Czesci[0].Akt;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
AktNuta := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.Selected := AktNuta;
LineChanged:=false;
PlayVideo := false;
end;
end;
SDLK_SPACE:
begin
//Thx to f1fth_freed0m for his One Note Midi Playback
if SDL_ModState = KMOD_LSHIFT then begin //Play One Notes Midi [Shift + Space]
PlaySentenceMidi := false;
PlayOneNoteMidi := true;
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
MidiTime := USTime.GetTime;
MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
LastClick := -100;
end
else if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then begin
//Play One Notes Midi + MP3 [CTRL + Shift + Space]
PlaySentenceMidi := false;
PlayOneNoteMidi := true;
MidiTime := USTime.GetTime;
MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
LastClick := -100;
PlaySentence := false;
PlayOneNote := true;
Click := true;
Music.Stop;
Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start));
PlayStopTime := (GetTimeFromBeat(
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start +
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc));
Music.Play;
LastClick := -100;
end
Else
begin
// Play One Notes MP3 [Space]
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false; // stop midi
PlayOneNoteMidi := false;
PlaySentence := false;
PlayOneNote := true;
Click := false;
Music.Stop;
Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start));
PlayStopTime := (GetTimeFromBeat(
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start +
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc));
Music.Play;
LastClick := -100;
end;
end;
SDLK_RETURN:
begin
end;
SDLK_LCTRL:
begin
end;
SDLK_DELETE:
begin
if SDL_ModState = KMOD_LCTRL then begin
// moves text to right in current sentence
DeleteNote;
end;
end;
SDLK_PERIOD:
begin
// moves text to right in current sentence
MoveTextToRight;
end;
SDLK_RIGHT:
begin
if PlaySentenceMidi or PlaySentence then
begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
if (lineStart = Czesci[0].Akt) then
AktNuta := noteStart;
Dec(AktNuta);
if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.Selected := AktNuta;
end;
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
LineChanged:=false;
PlaySentence := false;
PlayOneNote := false;
// right
if SDL_ModState = 0 then begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Inc(AktNuta);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.Selected := AktNuta;
end;
// ctrl + right
if SDL_ModState = KMOD_LCTRL then begin
if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc > 1 then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
if AktNuta = 0 then begin
Inc(Czesci[0].Czesc[Czesci[0].Akt].Start);
Inc(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
end;
FixTimings;
end;
end;
// shift + right
if SDL_ModState = KMOD_LSHIFT then begin
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
if AktNuta = 0 then begin
Inc(Czesci[0].Czesc[Czesci[0].Akt].Start);
Inc(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
end;
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
FixTimings;
end;
// alt + right
if SDL_ModState = KMOD_LALT then begin
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
FixTimings;
end;
// alt + ctrl + shift + right = move all from cursor to right
if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
MoveAllToEnd(1);
FixTimings;
end;
end;
SDLK_LEFT:
begin
if PlaySentenceMidi or PlaySentence then
begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
if (lineStart = Czesci[0].Akt) then
AktNuta := noteStart;
Inc(AktNuta);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.Selected := AktNuta;
end;
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
LineChanged:=false;
PlaySentence := false;
PlayOneNote := false;
// left
if SDL_ModState = 0 then begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Dec(AktNuta);
if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.Selected := AktNuta;
end;
// ctrl + left
if SDL_ModState = KMOD_LCTRL then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
if AktNuta = 0 then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Start);
Dec(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
end;
FixTimings;
end;
// shift + left
if SDL_ModState = KMOD_LSHIFT then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
// resizing sentences
if AktNuta = 0 then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Start);
Dec(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
end;
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
Dec(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
FixTimings;
end;
// alt + left
if SDL_ModState = KMOD_LALT then begin
if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc > 1 then begin
Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
Dec(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
end;
FixTimings;
end;
// alt + ctrl + shift + right = move all from cursor to left
if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
MoveAllToEnd(-1);
FixTimings;
end;
end;
SDLK_DOWN:
begin
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
LineChanged:=false;
PlaySentence := false;
PlayOneNote := false;
// skip to next sentence
if SDL_ModState = 0 then begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Inc(Czesci[0].Akt);
AktNuta := 0;
if Czesci[0].Akt > Czesci[0].High then
Czesci[0].Akt := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.AddCzesc(Czesci[0].Akt);
Lyric.Selected := 0;
end;
// decrease tone
if SDL_ModState = KMOD_LCTRL then begin
TransposeNote(-1);
end;
end;
SDLK_UP:
begin
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
LineChanged:=false;
PlaySentence := false;
PlayOneNote := false;
// skip to previous sentence
if SDL_ModState = 0 then begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Dec(Czesci[0].Akt);
AktNuta := 0;
if Czesci[0].Akt = -1 then
Czesci[0].Akt := Czesci[0].High;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.AddCzesc(Czesci[0].Akt);
Lyric.Selected := 0;
end;
// increase tone
if SDL_ModState = KMOD_LCTRL then begin
TransposeNote(1);
end;
end;
// Golden Note Patch
SDLK_G:
begin
case Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc of
0, 1: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 2;
2: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 1;
end; // case
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := False;
end;
// Freestyle Note Patch
SDLK_F:
begin
case Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc of
0:
begin;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 1;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := False;
end;
1,2:
begin;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := True;
end;
end; // case
end;
//MP3-Volume Up
SDLK_PAGEUP:
begin
if (MP3Volume<100) then
MP3Volume := MP3Volume+5;
Music.SetMusicVolume(MP3Volume);
Text[TextDebug].Text := 'MP3 Volume: ' + IntToStr(MP3Volume) + '%';
end;
//MP3-Volume Down
SDLK_PAGEDOWN:
begin
if (MP3Volume>0) then
MP3Volume := MP3Volume-5;
Music.SetMusicVolume(MP3Volume);
Text[TextDebug].Text := 'MP3 Volume: ' + IntToStr(MP3Volume) + '%';
end;
end;
end;
end; // if
end;
function TScreenEditSub.ParseInputEditText(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
var
SDL_ModState: Word;
begin
// used when in Text Edit Mode
Result := true;
SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
if Ini.Debug=1 then
Text[TextDebug].Text := 'PressedKey: ' + IntToStr(PressedKey) + ' ScanCode: ' + IntToStr(ScanCode);
// check normal keys
if not (ScanCode in [0..31, 127..159]) then //=isPrintable
begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst :=
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst + chr(ScanCode);
Lyric.ChangeCurText(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst);
Lyric.AddCzesc(Czesci[0].Akt);
Exit;
end;
If (PressedDown) Then
begin // Key Down
case PressedKey of
SDLK_ESCAPE:
begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst := editText;
Lyric.AddCzesc(Czesci[0].Akt);
TextEditMode := false;
end;
SDLK_F4, SDLK_RETURN:
begin
// Exit Text Edit Mode
TextEditMode := false;
end;
SDLK_BACKSPACE:
begin
Delete(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst,
Length(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst), 1);
Lyric.ChangeCurText(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst);
Lyric.AddCzesc(Czesci[0].Akt);
end;
SDLK_RIGHT:
begin
// right
if SDL_ModState = 0 then begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Inc(AktNuta);
if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.Selected := AktNuta;
editText := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
end;
end;
SDLK_LEFT:
begin
// left
if SDL_ModState = 0 then begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
Dec(AktNuta);
if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.Selected := AktNuta;
editText := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
end;
end;
end;
end;
end;
function TScreenEditSub.ParseInputEditBPM(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
var
SDL_ModState: Word;
strBPM: string;
temp: real;
begin
// used when in Text Edit Mode
Result := true;
SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
// check normal keys
if (ScanCode in [48..57, 44]) then
begin
strBPM := Text[TextBPM].Text;
Delete(strBPM, Length(strBPM), 1);
Text[TextBPM].Text := strBPM + chr(ScanCode) + '|';
Exit;
end;
If (PressedDown) Then
begin // Key Down
case PressedKey of
SDLK_ESCAPE:
begin
Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM / 4);
BPMEditMode := false;
end;
SDLK_F5, SDLK_RETURN:
begin
strBPM := Text[TextBPM].Text;
Delete(strBPM, Length(strBPM), 1);
Temp := StrToFloatDef(strBPM, 0);
if (temp>0) then
ChangeBPM(temp*4);
BPMEditMode := false;
end;
SDLK_BACKSPACE:
begin
strBPM := Text[TextBPM].Text;
Delete(strBPM, Length(strBPM)-1, 2);
Text[TextBPM].Text := strBPM + '|';
end;
end;
end;
end;
procedure TScreenEditSub.StartVideo;
var
R: real;
begin
// Play Sentences with Video
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Click := false;
Music.Stop;
if PlayVideo then
begin
Czesci[0].Akt := lineStart;
AktNuta := noteStart;
end;
R := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
if R <= Music.Length then
begin
Music.MoveTo(R);
PlayStopTime := Music.Length;
PlaySentence := true;
PlayOneNote := false;
Music.Play;
LastClick := -100;
end;
noteStart := AktNuta;
lineStart := Czesci[0].Akt;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
AktNuta := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.Selected := AktNuta;
LineChanged:=false;
PlayTime := 0;
PlayVideo := true;
StartVideoPreview;
end;
procedure TScreenEditSub.StartVideoPreview;
begin
if (PlayTime<0.2) and PlayVideo then
begin
acClose;
VidVis := none;
StartTry := true;
end else if StartTry then
begin
if (AktSong.Video <> '') and
FileExists(AktSong.Path + AktSong.Video) then
begin
acOpenFile(PAnsiChar(AktSong.Path + AktSong.Video));
acSkip2(AktSong.VideoGAP, Music.Position);
Czas.Teraz := Music.Position;
Czas.Razem := Music.Length;
StartTry := false;
try
acGetFrame(Czas.Teraz);
VidVis := windowed;
except
//If an Error occurs Reading Video: prevent Video from being Drawn again and Close Video
Log.LogError('Error drawing Video, Video has been disabled for this Song/Session.');
Log.LogError('Corrupted File: ' + AktSong.Video);
AktSong.Video := ''; //dirt fix
try
acClose;
VidVis := none;
except
end;
end;
end else
VidVis := none;
end;
end;
procedure TScreenEditSub.NewBeat;
begin
// click
{ for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeat) then begin
// old}
// Music.PlayClick;
end;
procedure TScreenEditSub.ChangeBPM(newBPM: real);
var
C: integer;
N: integer;
f: real;
begin
f := newBPM/AktSong.BPM[0].BPM; //z.B. neu/alt => 1/2 = 0.5 => *0.5
AktSong.BPM[0].BPM := newBPM;
for C := 0 to Czesci[0].High do
begin
Czesci[0].Czesc[C].Start := ceil(Czesci[0].Czesc[C].Start *f);
Czesci[0].Czesc[C].StartNote := ceil(Czesci[0].Czesc[C].StartNote *f);
for N := 0 to Czesci[0].Czesc[C].HighNut do
begin
Czesci[0].Czesc[C].Nuta[N].Start := ceil(Czesci[0].Czesc[C].Nuta[N].Start *f);
Czesci[0].Czesc[C].Nuta[N].Dlugosc := floor(Czesci[0].Czesc[C].Nuta[N].Dlugosc *f);
if (Czesci[0].Czesc[C].Nuta[N].Dlugosc=0) then
Czesci[0].Czesc[C].Nuta[N].Dlugosc := 1;
end; // N (notes)
Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Nuta[Czesci[0].Czesc[C].HighNut].Start +
Czesci[0].Czesc[C].Nuta[Czesci[0].Czesc[C].HighNut].Dlugosc;
end; // C (lines)
end;
procedure TScreenEditSub.CzesciDivide;
var
C: integer;
N: integer;
begin
AktSong.BPM[0].BPM := AktSong.BPM[0].BPM / 2;
for C := 0 to Czesci[0].High do begin
Czesci[0].Czesc[C].Start := Czesci[0].Czesc[C].Start div 2;
Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote div 2;
Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Koniec div 2;
for N := 0 to Czesci[0].Czesc[C].HighNut do begin
Czesci[0].Czesc[C].Nuta[N].Start := Czesci[0].Czesc[C].Nuta[N].Start div 2;
Czesci[0].Czesc[C].Nuta[N].Dlugosc := Round(Czesci[0].Czesc[C].Nuta[N].Dlugosc / 2);
end; // N
end; // C
end;
procedure TScreenEditSub.CzesciMultiply;
var
C: integer;
N: integer;
begin
AktSong.BPM[0].BPM := AktSong.BPM[0].BPM * 2;
for C := 0 to Czesci[0].High do begin
Czesci[0].Czesc[C].Start := Czesci[0].Czesc[C].Start * 2;
Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote * 2;
Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Koniec * 2;
for N := 0 to Czesci[0].Czesc[C].HighNut do begin
Czesci[0].Czesc[C].Nuta[N].Start := Czesci[0].Czesc[C].Nuta[N].Start * 2;
Czesci[0].Czesc[C].Nuta[N].Dlugosc := Czesci[0].Czesc[C].Nuta[N].Dlugosc * 2;
end; // N
end; // C
end;
procedure TScreenEditSub.LyricsCapitalize;
var
C: integer;
N: integer; // temporary
S: string;
begin
// temporary
{ for C := 0 to Czesci[0].High do
for N := 0 to Czesci[0].Czesc[C].HighNut do
Czesci[0].Czesc[C].Nuta[N].Tekst := AnsiLowerCase(Czesci[0].Czesc[C].Nuta[N].Tekst);}
for C := 0 to Czesci[0].High do begin
S := AnsiUpperCase(Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 1, 1));
S := S + Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 2, Length(Czesci[0].Czesc[C].Nuta[0].Tekst)-1);
Czesci[0].Czesc[C].Nuta[0].Tekst := S;
end; // C
Lyric.AddCzesc(Czesci[0].Akt);
end;
procedure TScreenEditSub.LyricsCorrectSpaces;
var
C: integer;
N: integer;
begin
for C := 0 to Czesci[0].High do begin
// correct starting spaces in the first word
while Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 1, 1) = ' ' do
Czesci[0].Czesc[C].Nuta[0].Tekst := Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 2, 100);
// move spaces on the start to the end of the previous note
for N := 1 to Czesci[0].Czesc[C].HighNut do begin
while (Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 1, 1) = ' ') do begin
Czesci[0].Czesc[C].Nuta[N].Tekst := Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 2, 100);
Czesci[0].Czesc[C].Nuta[N-1].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst + ' ';
end;
end; // N
// correct '-' to '- '
for N := 0 to Czesci[0].Czesc[C].HighNut do begin
if Czesci[0].Czesc[C].Nuta[N].Tekst = '-' then
Czesci[0].Czesc[C].Nuta[N].Tekst := '- ';
end; // N
// add space to the previous note when the current word is '- '
for N := 1 to Czesci[0].Czesc[C].HighNut do begin
if Czesci[0].Czesc[C].Nuta[N].Tekst = '- ' then
Czesci[0].Czesc[C].Nuta[N-1].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst + ' ';
end; // N
// correct too many spaces at the end of note
for N := 0 to Czesci[0].Czesc[C].HighNut do begin
while Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, Length(Czesci[0].Czesc[C].Nuta[N].Tekst)-1, 2) = ' ' do
Czesci[0].Czesc[C].Nuta[N].Tekst := Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 1, Length(Czesci[0].Czesc[C].Nuta[N].Tekst)-1);
end; // N
// and correct if there is no space at the end of sentence
N := Czesci[0].Czesc[C].HighNut;
if Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, Length(Czesci[0].Czesc[C].Nuta[N].Tekst), 1) <> ' ' then
Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N].Tekst + ' ';
end; // C
Lyric.AddCzesc(Czesci[0].Akt);
end;
procedure TScreenEditSub.FixTimings;
var
C: integer;
S: integer;
Min: integer;
Max: integer;
begin
for C := 1 to Czesci[0].High do begin
with Czesci[0].Czesc[C-1] do begin
Min := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc;
Max := Czesci[0].Czesc[C].StartNote;
case (Max - Min) of
0: S := Max;
1: S := Max;
2: S := Max - 1;
3: S := Max - 2;
else
S := Min + 2;
end; // case
Czesci[0].Czesc[C].Start := S;
end; // with
end; // for
end;
procedure TScreenEditSub.DivideSentence;
var
C: integer;
CStart: integer;
CNew: integer;
CLen: integer;
N: integer;
NStart: integer;
NHigh: integer;
NNewL: integer;
begin
// increase sentence length by 1
CLen := Length(Czesci[0].Czesc);
SetLength(Czesci[0].Czesc, CLen + 1);
Inc(Czesci[0].Ilosc);
Inc(Czesci[0].High);
// move needed sentences to one forward. newly has the copy of divided sentence
CStart := Czesci[0].Akt;
for C := CLen-1 downto CStart do
Czesci[0].Czesc[C+1] := Czesci[0].Czesc[C];
// clear and set new sentence
CNew := CStart + 1;
NStart := AktNuta;
Czesci[0].Czesc[CNew].Start := Czesci[0].Czesc[CStart].Nuta[NStart].Start;
Czesci[0].Czesc[CNew].StartNote := Czesci[0].Czesc[CStart].Nuta[NStart].Start;
Czesci[0].Czesc[CNew].Lyric := '';
Czesci[0].Czesc[CNew].LyricWidth := 0;
Czesci[0].Czesc[CNew].Koniec := 0;
Czesci[0].Czesc[CNew].BaseNote := 0; // 0.5.0: we modify it later in this procedure
Czesci[0].Czesc[CNew].IlNut := 0;
Czesci[0].Czesc[CNew].HighNut := -1;
SetLength(Czesci[0].Czesc[CNew].Nuta, 0);
// move right notes to new sentences
NHigh := Czesci[0].Czesc[CStart].HighNut;
for N := NStart to NHigh do begin
NNewL := Czesci[0].Czesc[CNew].IlNut;
SetLength(Czesci[0].Czesc[CNew].Nuta, NNewL + 1);
Czesci[0].Czesc[CNew].Nuta[NNewL] := Czesci[0].Czesc[CStart].Nuta[N];
// increase sentence counters
Inc(Czesci[0].Czesc[CNew].IlNut);
Inc(Czesci[0].Czesc[CNew].HighNut);
Czesci[0].Czesc[CNew].Koniec := Czesci[0].Czesc[CNew].Nuta[NNewL].Start +
Czesci[0].Czesc[CNew].Nuta[NNewL].Dlugosc;
end;
// clear old notes and set sentence counters
Czesci[0].Czesc[CStart].HighNut := NStart - 1;
Czesci[0].Czesc[CStart].IlNut := Czesci[0].Czesc[CStart].HighNut + 1;
Czesci[0].Czesc[CStart].Koniec := Czesci[0].Czesc[CStart].Nuta[NStart-1].Start +
Czesci[0].Czesc[CStart].Nuta[NStart-1].Dlugosc;
SetLength(Czesci[0].Czesc[CStart].Nuta, Czesci[0].Czesc[CStart].IlNut);
// 0.5.0: modify BaseNote
Czesci[0].Czesc[CNew].BaseNote := 120;
for N := 0 to Czesci[0].Czesc[CNew].IlNut do
if Czesci[0].Czesc[CNew].Nuta[N].Ton < Czesci[0].Czesc[CNew].BaseNote then
Czesci[0].Czesc[CNew].BaseNote := Czesci[0].Czesc[CNew].Nuta[N].Ton;
Czesci[0].Akt := Czesci[0].Akt + 1;
AktNuta := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.AddCzesc(Czesci[0].Akt);
end;
procedure TScreenEditSub.JoinSentence;
var
C: integer;
N: integer;
NStart: integer;
NDst: integer;
begin
C := Czesci[0].Akt;
// set new sentence
NStart := Czesci[0].Czesc[C].IlNut;
Czesci[0].Czesc[C].IlNut := Czesci[0].Czesc[C].IlNut + Czesci[0].Czesc[C+1].IlNut;
Czesci[0].Czesc[C].HighNut := Czesci[0].Czesc[C].HighNut + Czesci[0].Czesc[C+1].IlNut;
SetLength(Czesci[0].Czesc[C].Nuta, Czesci[0].Czesc[C].IlNut);
// move right notes to new sentences
for N := 0 to Czesci[0].Czesc[C+1].HighNut do begin
NDst := NStart + N;
Czesci[0].Czesc[C].Nuta[NDst] := Czesci[0].Czesc[C+1].Nuta[N];
end;
// increase sentence counters
NDst := Czesci[0].Czesc[C].HighNut;
Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Nuta[NDst].Start +
Czesci[0].Czesc[C].Nuta[NDst].Dlugosc;
// move needed sentences to one backward.
for C := Czesci[0].Akt + 1 to Czesci[0].High - 1 do
Czesci[0].Czesc[C] := Czesci[0].Czesc[C+1];
// increase sentence length by 1
SetLength(Czesci[0].Czesc, Length(Czesci[0].Czesc) - 1);
Dec(Czesci[0].Ilosc);
Dec(Czesci[0].High);
Lyric.AddCzesc(Czesci[0].Akt);
end;
procedure TScreenEditSub.DivideNote;
var
C: integer;
N: integer;
NLen: integer;
begin
C := Czesci[0].Akt;
NLen := Czesci[0].Czesc[C].IlNut + 1;
SetLength(Czesci[0].Czesc[C].Nuta, NLen);
Inc(Czesci[0].Czesc[C].HighNut);
Inc(Czesci[0].Czesc[C].IlNut);
// we copy all notes including selected one
for N := Czesci[0].Czesc[C].HighNut downto AktNuta+1 do begin
Czesci[0].Czesc[C].Nuta[N] := Czesci[0].Czesc[C].Nuta[N-1];
end;
// me slightly modify new note
Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc := ceil(Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc/2);
Czesci[0].Czesc[C].Nuta[AktNuta+1].Start := Czesci[0].Czesc[C].Nuta[AktNuta+1].Start +
Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc;
Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc := Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc -
Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc;
if (Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc>0) then
Czesci[0].Czesc[C].Nuta[AktNuta+1].Tekst := '~ '
else
Czesci[0].Czesc[C].Nuta[AktNuta+1].Tekst := ' ';
Czesci[0].Czesc[C].Nuta[AktNuta].Color := 0;
Czesci[0].Czesc[C].Nuta[AktNuta+1].Color := 2;
Inc(AktNuta);
Lyric.AddCzesc(Czesci[0].Akt);
end;
procedure TScreenEditSub.DeleteNote;
var
C: integer;
N: integer;
NLen: integer;
begin
C := Czesci[0].Akt;
//Do Not delete Last Note
if (Czesci[0].High > 0) OR (Czesci[0].Czesc[C].HighNut > 0) then
begin
// we copy all notes from the next to the selected one
for N := AktNuta+1 to Czesci[0].Czesc[C].HighNut do begin
Czesci[0].Czesc[C].Nuta[N-1] := Czesci[0].Czesc[C].Nuta[N];
end;
NLen := Czesci[0].Czesc[C].IlNut - 1;
if (NLen > 0) then
begin
SetLength(Czesci[0].Czesc[C].Nuta, NLen);
Dec(Czesci[0].Czesc[C].HighNut);
Dec(Czesci[0].Czesc[C].IlNut);
// me slightly modify new note
if AktNuta > Czesci[0].Czesc[C].HighNut then Dec(AktNuta);
Czesci[0].Czesc[C].Nuta[AktNuta].Color := 2;
end
//Last Note of current Sentence Deleted - > Delete Sentence
else
begin
//Move all Sentences after the current to the Left
for N := C+1 to Czesci[0].High do
Czesci[0].Czesc[N-1] := Czesci[0].Czesc[N];
//Delete Last Sentence
SetLength(Czesci[0].Czesc, Czesci[0].High);
Czesci[0].High := High(Czesci[0].Czesc);
Czesci[0].Ilosc := Length(Czesci[0].Czesc);
AktNuta := 0;
if (C > 0) then
Czesci[0].Akt := C - 1
else
Czesci[0].Akt := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
end;
end;
Lyric.AddCzesc(Czesci[0].Akt);
end;
procedure TScreenEditSub.TransposeNote(Transpose: integer);
begin
Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton, Transpose);
end;
procedure TScreenEditSub.ChangeWholeTone(Tone: integer);
var
C: integer;
N: integer;
begin
for C := 0 to Czesci[0].High do begin
Czesci[0].Czesc[C].BaseNote := Czesci[0].Czesc[C].BaseNote + Tone;
for N := 0 to Czesci[0].Czesc[C].HighNut do
Czesci[0].Czesc[C].Nuta[N].Ton := Czesci[0].Czesc[C].Nuta[N].Ton + Tone;
end;
end;
procedure TScreenEditSub.MoveAllToEnd(Move: integer);
var
C: integer;
N: integer;
NStart: integer;
begin
for C := Czesci[0].Akt to Czesci[0].High do begin
NStart := 0;
if C = Czesci[0].Akt then NStart := AktNuta;
for N := NStart to Czesci[0].Czesc[C].HighNut do begin
Inc(Czesci[0].Czesc[C].Nuta[N].Start, Move); // move note start
if N = 0 then begin // fix beginning
Inc(Czesci[0].Czesc[C].Start, Move);
Inc(Czesci[0].Czesc[C].StartNote, Move);
end;
if N = Czesci[0].Czesc[C].HighNut then // fix ending
Inc(Czesci[0].Czesc[C].Koniec, Move);
end; // for
end; // for
Lyric.AddCzesc(Czesci[0].Akt);
end;
procedure TScreenEditSub.MoveTextToRight;
var
C: integer;
N: integer;
NHigh: integer;
begin
{ C := Czesci[0].Akt;
for N := Czesci[0].Czesc[C].HighNut downto 1 do begin
Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst;
end; // for
Czesci[0].Czesc[C].Nuta[0].Tekst := '- ';}
C := Czesci[0].Akt;
NHigh := Czesci[0].Czesc[C].HighNut;
// last word
Czesci[0].Czesc[C].Nuta[NHigh].Tekst := Czesci[0].Czesc[C].Nuta[NHigh-1].Tekst + Czesci[0].Czesc[C].Nuta[NHigh].Tekst;
// other words
for N := NHigh - 1 downto AktNuta + 1 do begin
Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst;
end; // for
Czesci[0].Czesc[C].Nuta[AktNuta].Tekst := '- ';
Lyric.AddCzesc(Czesci[0].Akt);
end;
procedure TScreenEditSub.MarkSrc;
begin
CopySrc := Czesci[0].Akt;
end;
procedure TScreenEditSub.PasteText;
var
C: integer;
N: integer;
begin
C := Czesci[0].Akt;
for N := 0 to Czesci[0].Czesc[CopySrc].HighNut do
Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[CopySrc].Nuta[N].Tekst;
Lyric.AddCzesc(Czesci[0].Akt);
end;
procedure TScreenEditSub.CopySentence(Src, Dst: integer);
var
N: integer;
Time1: integer;
Time2: integer;
TD: integer;
begin
Time1 := Czesci[0].Czesc[Src].Nuta[0].Start;
Time2 := Czesci[0].Czesc[Dst].Nuta[0].Start;
TD := Time2-Time1;
SetLength(Czesci[0].Czesc[Dst].Nuta, Czesci[0].Czesc[Src].IlNut);
Czesci[0].Czesc[Dst].IlNut := Czesci[0].Czesc[Src].IlNut;
Czesci[0].Czesc[Dst].HighNut := Czesci[0].Czesc[Src].HighNut;
for N := 0 to Czesci[0].Czesc[Src].HighNut do begin
Czesci[0].Czesc[Dst].Nuta[N].Tekst := Czesci[0].Czesc[Src].Nuta[N].Tekst;
Czesci[0].Czesc[Dst].Nuta[N].Dlugosc := Czesci[0].Czesc[Src].Nuta[N].Dlugosc;
Czesci[0].Czesc[Dst].Nuta[N].Ton := Czesci[0].Czesc[Src].Nuta[N].Ton;
Czesci[0].Czesc[Dst].Nuta[N].Start := Czesci[0].Czesc[Src].Nuta[N].Start + TD;
end;
N := Czesci[0].Czesc[Src].HighNut;
Czesci[0].Czesc[Dst].Koniec := Czesci[0].Czesc[Dst].Nuta[N].Start + Czesci[0].Czesc[Dst].Nuta[N].Dlugosc;
end;
procedure TScreenEditSub.CopySentences(Src, Dst, Num: integer);
var
C: integer;
begin
// create place for new sentences
SetLength(Czesci[0].Czesc, Czesci[0].Ilosc + Num - 1);
// moves sentences next to the destination
for C := Czesci[0].High downto Dst + 1 do begin
Czesci[0].Czesc[C + Num - 1] := Czesci[0].Czesc[C];
end;
// prepares new sentences: sets sentence start and create first note
for C := 1 to Num-1 do begin
Czesci[0].Czesc[Dst + C].Start := Czesci[0].Czesc[Dst + C - 1].StartNote +
(Czesci[0].Czesc[Src + C].StartNote - Czesci[0].Czesc[Src + C - 1].StartNote);
SetLength(Czesci[0].Czesc[Dst + C].Nuta, 1);
Czesci[0].Czesc[Dst + C].IlNut := 1;
Czesci[0].Czesc[Dst + C].HighNut := 0;
Czesci[0].Czesc[Dst + C].Nuta[0].Start := Czesci[0].Czesc[Dst + C].Start;
Czesci[0].Czesc[Dst + C].Nuta[0].Dlugosc := 1;
Czesci[0].Czesc[Dst + C].StartNote := Czesci[0].Czesc[Dst + C].Start;
Czesci[0].Czesc[Dst + C].Koniec := Czesci[0].Czesc[Dst + C].Start + 1;
end;
// increase counters
Czesci[0].Ilosc := Czesci[0].Ilosc + Num - 1;
Czesci[0].High := Czesci[0].High + Num - 1;
for C := 0 to Num-1 do
CopySentence(Src + C, Dst + C);
end;
constructor TScreenEditSub.Create;
begin
inherited Create;
SetLength(Player, 1);
//Theme:
//bg
AddStatic(0, 0, 800, 600, 0.3, 0.5, 0.6, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
// Line
AddStatic(20, 5, 200, 40, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
AddText(40, 14, 1, 8, 0, 0, 0, 'Line:');
TextSentence := AddText(110, 14, 1, 8, 0, 0, 0, '0 / 0');
// Note
AddStatic(260, 5, 200, 40, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
AddText(282, 14, 1, 8, 0, 0, 0, 'Note:');
TextNote := AddText(360, 14, 1, 8, 0, 0, 0, '0 / 0');
// some borders
AddStatic(18, 53, 764, 240, 0, 0, 0, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
AddStatic(20, 55, 760, 236, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
AddStatic(18, 303, 764, 139, 0, 0, 0, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
AddStatic(20, 305, 760, 135, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
AddStatic(18, 498, 764, 44, 0, 0, 0, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
AddStatic(20, 500, 760, 40, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
AddText(30, 65, 0, 8, 0, 0, 0, 'Title:');
AddText(30, 90, 0, 8, 0, 0, 0, 'Artist:');
AddText(30, 115, 0, 8, 0, 0, 0, 'Mp3:');
AddText(30, 140, 0, 8, 0, 0, 0, 'BPM:');
AddText(30, 165, 0, 8, 0, 0, 0, 'GAP:');
TextTitle := AddText(180, 65, 0, 8, 0, 0, 0, 'a');
TextArtist := AddText(180, 90, 0, 8, 0, 0, 0, 'b');
TextMp3 := AddText(180, 115, 0, 8, 0, 0, 0, 'c');
TextBPM := AddText(180, 140, 0, 8, 0, 0, 0, 'd');
TextGAP := AddText(180, 165, 0, 8, 0, 0, 0, 'e');
{ AddInteraction(2, TextTitle);
AddInteraction(2, TextArtist);
AddInteraction(2, TextMp3);
AddInteraction(2, TextBPM);
AddInteraction(2, TextGAP);}
// note info
AddText(30, 190, 0, 8, 0, 0, 0, 'Start:');
AddText(30, 215, 0, 8, 0, 0, 0, 'Duration:');
AddText(30, 240, 0, 8, 0, 0, 0, 'Tone:');
AddText(30, 265, 0, 8, 0, 0, 0, 'Text:'); AddText(500, 265, 0, 8, 0, 0, 0, 'VideoGap:');
TextNStart := AddText(180, 190, 0, 8, 0, 0, 0, 'a');
TextNDlugosc := AddText(180, 215, 0, 8, 0, 0, 0, 'b');
TextNTon := AddText(180, 240, 0, 8, 0, 0, 0, 'c');
TextNText := AddText(180, 265, 0, 8, 0, 0, 0, 'd');
TextVideoGap := AddText(600, 265, 0, 8, 0, 0, 0, 'e');
// debug
TextDebug := AddText(30, 550, 0, 9, 0, 0, 0, '');
end;
procedure TScreenEditSub.onShow;
begin
Log.LogStatus('Initializing', 'TEditScreen.onShow');
try
ResetSingTemp;
AktSong := CatSongs.Song[SongIndex];
Error := not LoadSong(Path + FileName, SONG_LOAD_COMPLETE);
if not Error then
FindRefrainStart(AktSong);
except
Error := True;
end;
if Error then
begin
//Error Loading Song -> Go back to Song Screen and Show some Error Message
FadeTo(@ScreenSong);
ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
Exit;
end
else begin
MidiOut := TMidiOutput.Create(nil);
MidiOut.Open;
//Set Volume
MP3Volume := 50;
Music.SetVolume(MP3Volume);
if not Help.SetHelpID(ID) then
Log.LogError('No Entry for Help-ID ' + ID + ' (ScreenEditSub)');
Text[TextTitle].Text := AktSong.Title;
Text[TextArtist].Text := AktSong.Artist;
Text[TextMp3].Text := AktSong.Mp3;
Czesci[0].Akt := 0;
AktNuta := 0;
noteStart := 0; //when playing sentence
lineStart := 0;
Czesci[0].Czesc[0].Nuta[0].Color := 2;
if AktSong.Medley.Source <> msNone then
begin
MedleyNotes.isStart := true;
MedleyNotes.isEnd := true;
MedleyNotes.start := FindNote(AktSong.Medley.StartBeat);
MedleyNotes.end_ := FindNote(AktSong.Medley.EndBeat);
Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].IsMedley := true;
Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].IsMedley := true;
end;
//set Preview Start
MedleyNotes.Preview := FindNote(round(GetMidBeat(AktSong.PreviewStart-AktSong.Gap/1000)));
Czesci[0].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].IsStartPreview := true;
AktSong.PreviewStart := GetTimeFromBeat(Czesci[0].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].start);
Music.Open(Path + AktSong.Mp3);
//Set Down Music Volume for Better hearability of Midi Sounds
//Music.SetVolume(40);
Lyric.Clear;
Lyric.X := 400;
Lyric.Y := 500;
Lyric.Align := 1;
Lyric.Size := 14;
Lyric.ColR := 0;
Lyric.ColG := 0;
Lyric.ColB := 0;
Lyric.ColSR := Skin_FontHighlightR;
Lyric.ColSG := Skin_FontHighlightG;
Lyric.ColSB := Skin_FontHighlightB;
Lyric.Style := 0;
Lyric.AddCzesc(0);
Lyric.Selected := 0;
NotesH := 7;
NotesW := 4;
end;
// Interaction := 0;
TextEditMode := false;
BPMEditMode := false;
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
LineChanged:=false;
PlaySentence := false;
PlayOneNote := false;
StartTry := false;
PlayTime := 0;
PlayVideo := false;
end;
function TScreenEditSub.Draw: boolean;
var
Min: integer;
Sec: integer;
Tekst: string;
Pet: integer;
PlayClick: boolean;
line, note: integer;
end_: boolean;
Window: TRectCoords;
Blend: real;
begin
glClearColor(1,1,1,1);
PlayClick := false;
if PlaySentenceMidi or PlaySentence then
begin
MidiPos := USTime.GetTime - MidiTime + MidiStart;
PlayTime := PlayTime + TimeSkip;
// click
if PlaySentence then
begin
AktBeat := Floor(GetMidBeat(Music.Position - AktSong.GAP / 1000));
if Music.Position>PlayStopTime then
end_ := true
else
end_ := false;
end else
begin
AktBeat := Floor(GetMidBeat(MidiPos - AktSong.GAP / 1000));
if MidiPos>MidiStop then
end_ := true
else
end_ := false;
end;
if AktBeat <> LastClick then
begin
for line := 0 to Length(Czesci[0].Czesc) - 1 do
begin
for note := 0 to Length(Czesci[0].Czesc[line].Nuta) - 1 do
begin
//line change
if (Czesci[0].Czesc[line].Start = AktBeat) and (line <> Czesci[0].Akt) and not end_ then
begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
AktNuta := 0;
Czesci[0].Akt := line;
//Inc(Czesci[0].Akt);
//if Czesci[0].Akt > Length(Czesci[0].Czesc)-1 then //useful?
// Czesci[0].Akt := 0;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
Lyric.AddCzesc(Czesci[0].Akt);
Lyric.Selected := AktNuta;
LineChanged := true;
end;
if (Czesci[0].Czesc[line].Nuta[note].Start = AktBeat) then
begin
LastClick := AktBeat;
PlayClick := true;
end;
end;
end;
end;
end else
begin
LineChanged := false;
PlayVideo := false;
end;
// midi music
if PlaySentenceMidi then begin
// stop the music
if end_ then
begin
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
if (Czesci[0].Akt = lineStart) then
AktNuta := noteStart;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.Selected := AktNuta;
end;
// click
Text[TextDebug].Text := IntToStr(AktBeat);
if PlayClick then
begin
for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then
begin
if Pet > 0 then
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet-1].Ton + 60, 127);
MidiOut.PutShort($91, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Ton + 60, 127);
MidiLastNote := Pet;
end;
end;
end; // if PlaySentenceMidi
// mp3 music
if PlaySentence then
begin
// stop the music
if end_ then begin
Music.Stop;
PlaySentence := false;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
if (Czesci[0].Akt = lineStart) then
AktNuta := noteStart;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.Selected := AktNuta;
end;
if (Click) and (PlaySentence) then
begin
Text[TextDebug].Text := IntToStr(AktBeat);
if PlayClick then
Music.PlayClick;
end; // click
end;
// move "cursor"
if (PlaySentence or PlaySentenceMidi) then
begin
for line := 0 to Length(Czesci[0].Czesc) - 1 do
begin
for note := 0 to Length(Czesci[0].Czesc[line].Nuta) - 1 do
begin
//note change
if (Czesci[0].Czesc[line].Nuta[note].Start = AktBeat) and
((note <> AktNuta) or LineChanged) then
begin
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
if not LineChanged then
begin
AktNuta := note;
Czesci[0].Akt := line;
//Inc(AktNuta);
//if AktNuta > Length(Czesci[0].Czesc[Czesci[0].Akt].Nuta)-1 then
// Dec(AktNuta);
end else
LineChanged := false;
Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
Lyric.AddCzesc(Czesci[0].Akt);
Lyric.Selected := AktNuta;
end;
end;
end;
end;
// midi music
if PlayOneNoteMidi then
begin
MidiPos := USTime.GetTime - MidiTime + MidiStart;
// stop the music
if (MidiPos > MidiStop) then
begin
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlayOneNoteMidi := false;
end;
// click
AktBeat := Floor(GetMidBeat(MidiPos - AktSong.GAP / 1000));
Text[TextDebug].Text := IntToStr(AktBeat);
if AktBeat <> LastClick then
begin
for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
begin
if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then
begin
LastClick := AktBeat;
if Pet > 0 then
MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet-1].Ton + 60, 127);
MidiOut.PutShort($91, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Ton + 60, 127);
MidiLastNote := Pet;
end;
end;
end;
end; // if PlayOneNoteMidi
// mp3 music
if PlayOneNote then
begin
// stop the music
if (Music.Position > PlayStopTime) then
begin
Music.Stop;
PlayOneNote := false;
end;
// click
if (Click) and (PlaySentence) then
begin
AktBeat := Floor(GetMidBeat(Music.Position - AktSong.GAP / 1000));
Text[TextDebug].Text := IntToStr(AktBeat);
if AktBeat <> LastClick then
begin
for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
begin
if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then
begin
Music.PlayClick;
LastClick := AktBeat;
end;
end;
end;
end; // click
end; // if PlayOneNote
Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].IlNut);
// Song info
if not BPMEditMode then
Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM / 4);
Text[TextGAP].Text := FloatToStr(AktSong.GAP);
Text[TextVideoGap].Text := FloatToStr(AktSong.VideoGap);
//Error reading Variables when no Song is loaded
if not Error then
begin
// Note info
Text[TextNStart].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
Text[TextNDlugosc].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
Text[TextNTon].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' ( ' + GetNoteName(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' )';
Text[TextNText].Text := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
//F and G and Medley Mod:
if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].FreeStyle then
Text[TextNTon].Text := Text[TextNTon].Text + ' *F*'
else if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc = 2 then
Text[TextNTon].Text := Text[TextNTon].Text + ' *G*';
if MedleyNotes.isStart and (Czesci[0].Akt = MedleyNotes.start.line)
and (AktNuta = MedleyNotes.start.note) then
Text[TextNTon].Text := Text[TextNTon].Text + ' MedleyStart';
if MedleyNotes.isEnd and (Czesci[0].Akt = MedleyNotes.end_.line) and
(AktNuta = MedleyNotes.end_.note) then
Text[TextNTon].Text := Text[TextNTon].Text + ' MedleyEnd';
//preview mod
if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsStartPreview then
Text[TextNTon].Text := Text[TextNTon].Text + ' [PreviewStart]';
end;
// Text Edit Mode
if TextEditMode then
Text[TextNText].Text := Text[TextNText].Text + '|';
// draw static menu
inherited Draw;
// draw notes
SingDrawNoteLines(20, 305, 780, 15);
//Error Drawing when no Song is loaded
if not Error then
begin
SingDrawBeatDelimeters(40, 305, 760, 0);
EditDrawCzesc(40, 410, 760, 0, 15);
end;
// draw text
Lyric.Draw;
DrawInfoBar(20, 460, 760, 20);
glLineWidth(1); //bad fix...
if UVideo.VideoOpened and PlayVideo then
begin
Czas.Teraz := Czas.Teraz + TimeSkip;
try
acGetFrame(Czas.Teraz);
if VidVis=windowed then
begin
Window.Left := 500;
Window.Right := 770;
Window.Upper := 65;
Window.Lower := 250;
Window.windowed := true;
{if CoverTime>=Ini.PreviewFading then
begin
glColor4f(0, 0, 0, 1);
glbegin(gl_quads);
glVertex2f(Window.Left, Window.Upper);
glVertex2f(Window.Left, Window.Lower);
glVertex2f(Window.Right, Window.Lower);
glVertex2f(Window.Right, Window.Upper);
glEnd;
end; }
SetAspectCorrection(acoCrop);
Blend := (PlayTime-0.2);
if Blend<0 then
Blend := 0
else if Blend>1 then
Blend := 1;
acDrawGLi(ScreenAct, Window, Blend);
end else if VidVis=full then
begin
acDrawGL(ScreenAct);
end;
//ResetAspectCorrection;
if (Czas.Teraz>=Czas.Razem) then
begin
acClose;
VidVis := none;
end;
except
//If an Error occurs drawing: prevent Video from being Drawn again and Close Video
log.LogError('Error drawing Video, Video has been disabled for this Song/Session.');
Log.LogError('Corrupted File: ' + AktSong.Video);
try
acClose;
VidVis := none;
except
end;
end;
end else
StartVideoPreview;
end;
procedure TScreenEditSub.DrawInfoBar(x, y, w, h: integer);
var
start, end_: integer;
ww: integer;
pos: real;
br: real;
line, note: integer;
numLines, numNotes: integer;
begin
numLines := Length(Czesci[0].Czesc);
if(numLines=0) then
Exit;
start := Czesci[0].Czesc[0].Start;
end_ := Czesci[0].Czesc[numLines-1].Koniec;
ww := end_ - start;
glColor4f(0, 0, 0, 1);
glDisable(GL_BLEND);
glLineWidth(2);
glBegin(GL_LINE_LOOP);
glVertex2f(x-1, y-1);
glVertex2f(x+w+1, y-1);
glVertex2f(x+w+1, y+h+1);
glVertex2f(x-1, y+h+1);
glEnd;
glColor4f(0.9, 0.9, 0.9, 1);
glbegin(gl_quads);
glVertex2f(x, y);
glVertex2f(x, y+h);
glVertex2f(x+w, y+h);
glVertex2f(x+w, y);
glEnd;
for line := 0 to numLines - 1 do
begin
if (line = Czesci[0].Akt) and not (PlaySentence or PlaySentenceMidi) then
glColor4f(0.4, 0.4, 0, 1)
else
glColor4f(1, 0.6, 0, 1);
start := Czesci[0].Czesc[line].Nuta[0].Start;
end_ := Czesci[0].Czesc[line].Nuta[Czesci[0].Czesc[line].HighNut].Start+
Czesci[0].Czesc[line].Nuta[Czesci[0].Czesc[line].HighNut].Dlugosc;
pos := start/ww*w;
br := (end_-start)/ww*w;
glbegin(gl_quads);
glVertex2f(x+pos, y);
glVertex2f(x+pos, y+h);
glVertex2f(x+pos+br, y+h);
glVertex2f(x+pos+br, y);
glEnd;
{
numNotes := Length(Czesci[0].Czesc[line].Nuta);
for note := 0 to numNotes - 1 do
begin
end; }
end;
if(PlaySentence or PlaySentenceMidi) then
begin
glColor4f(0, 0, 0, 0.5);
pos := 0;
br := AktBeat/ww*w;
if (br>w) then
br := w;
end else
begin
glColor4f(1, 0, 0, 1);
pos := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start/ww*w;
br := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc/ww*w;
if (br<1) then
br := 1;
end;
glEnable(GL_BLEND);
glbegin(gl_quads);
glVertex2f(x+pos, y);
glVertex2f(x+pos, y+h);
glVertex2f(x+pos+br, y+h);
glVertex2f(x+pos+br, y);
glEnd;
glDisable(GL_BLEND);
end;
procedure TScreenEditSub.onHide;
begin
MidiOut.Close;
MidiOut.Free;
//Music.SetVolume(100);
end;
function TScreenEditSub.GetNoteName(Note: Integer): String;
var N1, N2: Integer;
begin
if (Note > 0) then
begin
N1 := Note mod 12;
N2 := Note div 12;
end
else
begin
N1 := (Note + (-Trunc(Note/12)+1)*12) mod 12;
N2 := -1;
end;
case N1 of
0: Result := 'c';
1: Result := 'c#';
2: Result := 'd';
3: Result := 'd#';
4: Result := 'e';
5: Result := 'f';
6: Result := 'f#';
7: Result := 'g';
8: Result := 'g#';
9: Result := 'a';
10: Result := 'b';
11: Result := 'h';
end;
case N2 of
0: Result := UpperCase(Result); //Normal Uppercase Note, 1: Normal lowercase Note
2: Result := Result + ''''; //One Striped
3: Result := Result + ''''''; //Two Striped
4: Result := Result + ''''''''; //etc.
5: Result := Result + '''''''''';
6: Result := Result + '''''''''''';
7: Result := Result + '''''''''''''';
end;
end;
function TScreenEditSub.GetMedleyLength: real;
begin
if MedleyNotes.isStart and MedleyNotes.isEnd then
begin
Result := GetTimeFromBeat(
Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Start +
Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Dlugosc) -
GetTimeFromBeat(Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].Start);
end else
Result := 0;
end;
end.