From 51ed8fe6f2ea9892e905e81cf5bad3960537eb40 Mon Sep 17 00:00:00 2001 From: brunzelchen Date: Fri, 19 Feb 2010 17:18:42 +0000 Subject: Challenge MOD r7 alpha based on Ultrastar Deluxe v1.0.1a for changes read Changelog.txt in folder Game git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/1.0.1 Challenge MOD@2107 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Screens/UScreenEditSub.pas | 1854 ++++++++++++++++++++++++++++++++++ 1 file changed, 1854 insertions(+) create mode 100644 Game/Code/Screens/UScreenEditSub.pas (limited to 'Game/Code/Screens/UScreenEditSub.pas') diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas new file mode 100644 index 00000000..3b132810 --- /dev/null +++ b/Game/Code/Screens/UScreenEditSub.pas @@ -0,0 +1,1854 @@ +unit UScreenEditSub; + +interface + +uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, USmpeg, UTexture, UMenuText, + ULyrics, Math, gl, UThemes, MidiOut, UHelp; + +type + TMedleyNotes = record + start: TPos; + end_: TPos; + Preview: TPos; + isStart: boolean; //start beat is declared + isEnd: boolean; //end beat is declared + end; + + TScreenEditSub = class(TMenu) + const + ID='ID_001'; //for help system + + private + //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; + AktNuta: integer; + PlaySentence: boolean; + PlaySentenceMidi: boolean; + PlayStopTime: real; + LastClick: integer; + Click: boolean; + CopySrc: integer; + + MidiOut: TMidiOutput; + MidiStart: real; + MidiStop: real; + MidiTime: real; + MidiPos: real; + MidiLastNote: integer; + + + TextEditMode: boolean; + MedleyNotes: TMedleyNotes; + + editText: string; //backup of current text in text-edit-mode + noteStart: integer; //Start note when playing sentence + LineChanged: boolean; + + procedure NewBeat; + 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 + 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 Draw: boolean; override; + procedure onHide; override; + end; + +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; +begin + Result := true; + + Text[TextDebug].Text := ''; + + if TextEditMode then begin + Result := ParseInputEditText(PressedKey, ScanCode, PressedDown); + end 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 + 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_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; + + 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; + end else if MedleyNotes.IsStart 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; + 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 + end; + + if (SDL_ModState = KMOD_LALT) then + begin + PlaySentenceMidi := 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); + 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; + 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; + + 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 + 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 + CzesciDivide; + end; + + SDLK_M: + begin + // Multiply lengths by 2 + 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 + onHide; + 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; + 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_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; + 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; + Music.Play; + LastClick := -100; + end; + end; + + if SDL_ModState = KMOD_LSHIFT then begin + PlaySentenceMidi := true; + MidiTime := USTime.GetTime; + Music.Stop; + PlaySentence := 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; + 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; + 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; + 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; + Music.Play; + LastClick := -100; + end; + end; + + if SDL_ModState = KMOD_LSHIFT or KMOD_LALT then begin + PlaySentenceMidi := true; + Music.Stop; + PlaySentence := 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; + MidiTime := USTime.GetTime; + MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote); + MidiStop := Music.Length; + LastClick := -100; + + PlaySentence := true; + 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; + 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; + 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 := true; + Music.Stop; + PlaySentence := 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 := 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 := 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 + PlaySentence := 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; + + + if PlaySentence or PlaySentenceMidi then + begin + noteStart := AktNuta; + LineChanged:=false; + 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 + // 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; + + MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127); + PlaySentenceMidi := false; + Music.Stop; + LineChanged:=false; + PlaySentence := false; + 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; + 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; + + MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127); + PlaySentenceMidi := false; + Music.Stop; + LineChanged:=false; + PlaySentence := false; + end; + + SDLK_DOWN: + begin + // skip to next sentence + if SDL_ModState = 0 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; + 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; + Music.Stop; + PlaySentence := false; + end; + + // decrease tone + if SDL_ModState = KMOD_LCTRL then begin + TransposeNote(-1); + end; + + end; + + SDLK_UP: + begin + // skip to previous sentence + if SDL_ModState = 0 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; + 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; + Music.Stop; + PlaySentence := false; + 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.SetVolume(MP3Volume); + Text[TextDebug].Text := 'MP3 Volume: ' + IntToStr(MP3Volume) + '%'; + end; + + //MP3-Volume Down + SDLK_PAGEDOWN: + begin + if (MP3Volume>0) then + MP3Volume := MP3Volume-5; + Music.SetVolume(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; + +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.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 := 1; + Inc(Czesci[0].Czesc[C].Nuta[AktNuta+1].Start); + Dec(Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc); + Czesci[0].Czesc[C].Nuta[AktNuta+1].Tekst := '- '; + Czesci[0].Czesc[C].Nuta[AktNuta+1].Color := 2; + 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:'); + + 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'); + + // 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 + 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; +end; + +function TScreenEditSub.Draw: boolean; +var + Min: integer; + Sec: integer; + Tekst: string; + Pet: integer; + AktBeat: integer; + PlayClick: boolean; + line, note: integer; + end_: boolean; +begin + glClearColor(1,1,1,1); + + PlayClick := false; + if PlaySentenceMidi or PlaySentence then + begin + MidiPos := USTime.GetTime - MidiTime + MidiStart; + // 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; + 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 + LineChanged := false; + + // 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; + 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; + 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 + Inc(AktNuta) + 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; + + 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 + Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM / 4); + Text[TextGAP].Text := FloatToStr(AktSong.GAP); + + //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; + +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. -- cgit v1.2.3