diff options
Diffstat (limited to '')
-rw-r--r-- | Game/Code/Screens/UScreenEditConvert.pas | 1158 |
1 files changed, 581 insertions, 577 deletions
diff --git a/Game/Code/Screens/UScreenEditConvert.pas b/Game/Code/Screens/UScreenEditConvert.pas index 0c8244ab..e370ad67 100644 --- a/Game/Code/Screens/UScreenEditConvert.pas +++ b/Game/Code/Screens/UScreenEditConvert.pas @@ -1,577 +1,581 @@ -unit UScreenEditConvert;
-
-interface
-
-{$I switches.inc}
-
-uses UMenu,
- SDL,
- {$IFDEF UseMIDIPort}
- MidiFile,
- MidiOut,
- {$ENDIF}
- ULog,
- USongs,
- UMusic,
- UThemes;
-
-type
- TNote = record
- Event: integer;
- EventType: integer;
- Channel: integer;
- Start: real;
- Len: real;
- Data1: integer;
- Data2: integer;
- Str: string;
- end;
-
- TTrack = record
- Note: array of TNote;
- Name: string;
- Hear: boolean;
- Status: byte; // 0 - none, 1 - notes, 2 - lyrics, 3 - notes + lyrics
- end;
-
- TNuta = record
- Start: integer;
- Len: integer;
- Tone: integer;
- Lyric: string;
- NewSentence: boolean;
- end;
-
- TArrayTrack = array of TTrack;
-
- TScreenEditConvert = class(TMenu)
- public
- ATrack: TArrayTrack; // actual track
-// Track: TArrayTrack;
- Channel: TArrayTrack;
- ColR: array[0..100] of real;
- ColG: array[0..100] of real;
- ColB: array[0..100] of real;
- Len: real;
- Sel: integer;
- Selected: boolean;
-// FileName: string;
-
- {$IFDEF UseMIDIPort}
- MidiFile: TMidiFile;
- MidiTrack: TMidiTrack;
- MidiEvent: pMidiEvent;
- MidiOut: TMidiOutput;
- {$ENDIF}
-
- Song: TSong;
- Czesc: TCzesci;
- BPM: real;
- Ticks: real;
- Nuta: array of TNuta;
-
- procedure AddLyric(Start: integer; Tekst: string);
- procedure Extract;
-
- {$IFDEF UseMIDIPort}
- procedure MidiFile1MidiEvent(event: PMidiEvent);
- {$ENDIF}
-
- function SelectedNumber: integer;
- constructor Create; override;
- procedure onShow; override;
- function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure onHide; override;
- end;
-
-implementation
-uses UGraphic,
- SysUtils,
- UDrawTexture,
- TextGL,
- UFiles,
- UMain,
- UIni,
- OpenGL12,
- USkins;
-
-function TScreenEditConvert.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
-var
- T: integer;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- case PressedKey of
- SDLK_Q:
- begin
- Result := false;
- end;
-
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- {$IFDEF UseMIDIPort}
- MidiFile.StopPlaying;
- {$ENDIF}
- AudioPlayback.PlayBack;
- FadeTo(@ScreenEdit);
- end;
-
- SDLK_RETURN:
- begin
- if Interaction = 0 then
- begin
- AudioPlayback.PlayStart;
- ScreenOpen.BackScreen := @ScreenEditConvert;
- FadeTo(@ScreenOpen);
- end;
-
- if Interaction = 1 then
- begin
- Selected := false;
- {$IFDEF UseMIDIPort}
- MidiFile.OnMidiEvent := MidiFile1MidiEvent;
-// MidiFile.GoToTime(MidiFile.GetTrackLength div 2);
- MidiFile.StartPlaying;
- {$ENDIF}
- end;
-
- if Interaction = 2 then begin
- Selected := true;
- {$IFDEF UseMIDIPort}
- MidiFile.OnMidiEvent := nil;
- {$ENDIF}
- {for T := 0 to High(ATrack) do begin
- if ATrack[T].Hear then begin
- MidiTrack := MidiFile.GetTrack(T);
- MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
- end;
- end;
- MidiFile.StartPlaying;//}
- end;
-
- if Interaction = 3 then begin
- if SelectedNumber > 0 then begin
- Extract;
- SaveSong(Song, Czesc, ChangeFileExt(FileName, '.txt'), false);
- end;
- end;
-
- end;
-
- SDLK_SPACE:
- begin
-// ATrack[Sel].Hear := not ATrack[Sel].Hear;
- ATrack[Sel].Status := (ATrack[Sel].Status + 1) mod 4;
-
-{ if Selected then begin
- MidiTrack := MidiFile.GetTrack(Sel);
- if Track[Sel].Hear then
- MidiTrack.OnMidiEvent := MidiFile1MidiEvent
- else
- MidiTrack.OnMidiEvent := nil;
- end;}
- end;
-
- SDLK_RIGHT:
- begin
- InteractNext;
- end;
-
- SDLK_LEFT:
- begin
- InteractPrev;
- end;
-
- SDLK_DOWN:
- begin
- Inc(Sel);
- if Sel > High(ATrack) then Sel := 0;
- end;
- SDLK_UP:
- begin
- Dec(Sel);
- if Sel < 0 then Sel := High(ATrack);
- end;
- end;
- end;
-end;
-
-procedure TScreenEditConvert.AddLyric(Start: integer; Tekst: string);
-var
- N: integer;
-begin
- for N := 0 to High(Nuta) do begin
- if Nuta[N].Start = Start then begin
- // check for new sentece
- if Copy(Tekst, 1, 1) = '\' then Delete(Tekst, 1, 1);
- if Copy(Tekst, 1, 1) = '/' then begin
- Delete(Tekst, 1, 1);
- Nuta[N].NewSentence := true;
- end;
-
- // overwrite lyric od append
- if Nuta[N].Lyric = '-' then
- Nuta[N].Lyric := Tekst
- else
- Nuta[N].Lyric := Nuta[N].Lyric + Tekst;
- end;
- end;
-end;
-
-procedure TScreenEditConvert.Extract;
-var
- T: integer;
- C: integer;
- N: integer;
- Nu: integer;
- NutaTemp: TNuta;
- Move: integer;
- Max, Min: integer;
-begin
- // song info
- Song.Title := '';
- Song.Artist := '';
- Song.Mp3 := '';
- Song.Resolution := 4;
- SetLength(Song.BPM, 1);
- Song.BPM[0].BPM := BPM*4;
-
- SetLength(Nuta, 0);
-
- // extract notes
- for T := 0 to High(ATrack) do begin
-// if ATrack[T].Hear then begin
- if ((ATrack[T].Status div 1) and 1) = 1 then begin
- for N := 0 to High(ATrack[T].Note) do begin
- if (ATrack[T].Note[N].EventType = 9) and (ATrack[T].Note[N].Data2 > 0) then begin
- Nu := Length(Nuta);
- SetLength(Nuta, Nu + 1);
- Nuta[Nu].Start := Round(ATrack[T].Note[N].Start / Ticks);
- Nuta[Nu].Len := Round(ATrack[T].Note[N].Len / Ticks);
- Nuta[Nu].Tone := ATrack[T].Note[N].Data1 - 12*5;
- Nuta[Nu].Lyric := '-';
- end;
- end;
- end;
- end;
-
- // extract lyrics
- for T := 0 to High(ATrack) do begin
-// if ATrack[T].Hear then begin
- if ((ATrack[T].Status div 2) and 1) = 1 then begin
- for N := 0 to High(ATrack[T].Note) do begin
- if (ATrack[T].Note[N].EventType = 15) then begin
-// Log.LogStatus('<' + Track[T].Note[N].Str + '>', 'MIDI');
- AddLyric(Round(ATrack[T].Note[N].Start / Ticks), ATrack[T].Note[N].Str);
- end;
- end;
- end;
- end;
-
- // sort notes
- for N := 0 to High(Nuta) do
- for Nu := 0 to High(Nuta)-1 do
- if Nuta[Nu].Start > Nuta[Nu+1].Start then begin
- NutaTemp := Nuta[Nu];
- Nuta[Nu] := Nuta[Nu+1];
- Nuta[Nu+1] := NutaTemp;
- end;
-
- // move to 0 at beginning
- Move := Nuta[0].Start;
- for N := 0 to High(Nuta) do
- Nuta[N].Start := Nuta[N].Start - Move;
-
- // copy notes
- SetLength(Czesc.Czesc, 1);
- Czesc.Ilosc := 1;
- Czesc.High := 0;
-
- C := 0;
- N := 0;
- Czesc.Czesc[C].IlNut := 0;
- Czesc.Czesc[C].HighNut := -1;
-
- for Nu := 0 to High(Nuta) do begin
- if Nuta[Nu].NewSentence then begin // nowa linijka
- SetLength(Czesc.Czesc, Length(Czesc.Czesc)+1);
- Czesc.Ilosc := Czesc.Ilosc + 1;
- Czesc.High := Czesc.High + 1;
- C := C + 1;
- N := 0;
- SetLength(Czesc.Czesc[C].Nuta, 0);
- Czesc.Czesc[C].IlNut := 0;
- Czesc.Czesc[C].HighNut := -1;
-
- //Calculate Start of the Last Sentence
- if (C > 0) and (Nu > 0) then
- begin
- Max := Nuta[Nu].Start;
- Min := Nuta[Nu-1].Start + Nuta[Nu-1].Len;
-
- case (Max - Min) of
- 0: Czesc.Czesc[C].Start := Max;
- 1: Czesc.Czesc[C].Start := Max;
- 2: Czesc.Czesc[C].Start := Max - 1;
- 3: Czesc.Czesc[C].Start := Max - 2;
- else
- if ((Max - Min) > 4) then
- Czesc.Czesc[C].Start := Min + 2
- else
- Czesc.Czesc[C].Start := Max;
-
- end; // case
-
- end;
- end;
-
- // tworzy miejsce na nowa nute
- SetLength(Czesc.Czesc[C].Nuta, Length(Czesc.Czesc[C].Nuta)+1);
- Czesc.Czesc[C].IlNut := Czesc.Czesc[C].IlNut + 1;
- Czesc.Czesc[C].HighNut := Czesc.Czesc[C].HighNut + 1;
-
- // dopisuje
- Czesc.Czesc[C].Nuta[N].Start := Nuta[Nu].Start;
- Czesc.Czesc[C].Nuta[N].Dlugosc := Nuta[Nu].Len;
- Czesc.Czesc[C].Nuta[N].Ton := Nuta[Nu].Tone;
- Czesc.Czesc[C].Nuta[N].Tekst := Nuta[Nu].Lyric;
- //All Notes are Freestyle when Converted Fix:
- Czesc.Czesc[C].Nuta[N].Wartosc := 1;
- Inc(N);
- end;
-end;
-
-function TScreenEditConvert.SelectedNumber: integer;
-var
- T: integer; // track
-begin
- Result := 0;
- for T := 0 to High(ATrack) do
-// if ATrack[T].Hear then Inc(Result);
- if ((ATrack[T].Status div 1) and 1) = 1 then Inc(Result);
-end;
-
-{$IFDEF UseMIDIPort}
-procedure TScreenEditConvert.MidiFile1MidiEvent(event: PMidiEvent);
-begin
-// Log.LogStatus(IntToStr(event.event), 'MIDI');
- MidiOut.PutShort(event.event, event.data1, event.data2);
-end;
-{$ENDIF}
-
-constructor TScreenEditConvert.Create;
-var
- P: integer;
-begin
- inherited Create;
- AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(15, 5, 0, 0, 0, 'Open');
-// Button[High(Button)].Text[0].Size := 11;
-
- AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(25, 5, 0, 0, 0, 'Play');
-
- AddButton(280, 20, 200, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(25, 5, 0, 0, 0, 'Play Selected');
-
- AddButton(500, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(20, 5, 0, 0, 0, 'Save');
-
-
-{ MidiOut := TMidiOutput.Create(nil);
-// MidiOut.Close;
-// MidiOut.DeviceID := 0;
- if Ini.Debug = 1 then
- MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
- Log.LogStatus(MidiOut.ProductName, 'MIDI');
- MidiOut.Open;
-// MidiOut.SetVolume(100, 100); // temporary}
-
- FileName := GamePath + 'file.mid';
- {$IFDEF UseMIDIPort}
- MidiFile := TMidiFile.Create(nil);
- {$ENDIF}
-
- for P := 0 to 100 do begin
- ColR[P] := Random(10)/10;
- ColG[P] := Random(10)/10;
- ColB[P] := Random(10)/10;
- end;
-
-end;
-
-procedure TScreenEditConvert.onShow;
-var
- T: integer; // track
- N: integer; // note
- C: integer; // channel
- CN: integer; // channel note
-begin
-{$IFDEF UseMIDIPort}
- MidiOut := TMidiOutput.Create(nil);
- if Ini.Debug = 1 then
- MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
- Log.LogStatus(MidiOut.ProductName, 'MIDI');
- MidiOut.Open;
-
-
- if FileExists(FileName) then
- begin
- MidiFile.Filename := FileName;
- MidiFile.ReadFile;
-
-
- Len := 0;
- Sel := 0;
- BPM := MidiFile.Bpm;
- Ticks := MidiFile.TicksPerQuarter / 4;
-
-{ for T := 0 to MidiFile.NumberOfTracks-1 do begin
- SetLength(Track, Length(Track)+1);
- MidiTrack := MidiFile.GetTrack(T);
- MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
- Track[T].Name := MidiTrack.getName;
-
- for N := 0 to MidiTrack.getEventCount-1 do begin
- SetLength(Track[T].Note, Length(Track[T].Note)+1);
- MidiEvent := MidiTrack.GetEvent(N);
- Track[T].Note[N].Start := MidiEvent.time;
- Track[T].Note[N].Len := MidiEvent.len;
- Track[T].Note[N].Event := MidiEvent.event;
- Track[T].Note[N].EventType := MidiEvent.event div 16;
- Track[T].Note[N].Channel := MidiEvent.event and 15;
- Track[T].Note[N].Data1 := MidiEvent.data1;
- Track[T].Note[N].Data2 := MidiEvent.data2;
- Track[T].Note[N].Str := MidiEvent.str;
-
- if Track[T].Note[N].Start + Track[T].Note[N].Len > Len then
- Len := Track[T].Note[N].Start + Track[T].Note[N].Len;
- end;
- end;}
-
-
- SetLength(Channel, 16);
- for T := 0 to 15 do
- begin
- Channel[T].Name := IntToStr(T+1);
- SetLength(Channel[T].Note, 0);
- Channel[T].Status := 0;
- end;
-
- for T := 0 to MidiFile.NumberOfTracks-1 do begin
- MidiTrack := MidiFile.GetTrack(T);
- MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
-
- for N := 0 to MidiTrack.getEventCount-1 do begin
- MidiEvent := MidiTrack.GetEvent(N);
- C := MidiEvent.event and 15;
-
- CN := Length(Channel[C].Note);
- SetLength(Channel[C].Note, CN+1);
-
- Channel[C].Note[CN].Start := MidiEvent.time;
- Channel[C].Note[CN].Len := MidiEvent.len;
- Channel[C].Note[CN].Event := MidiEvent.event;
- Channel[C].Note[CN].EventType := MidiEvent.event div 16;
- Channel[C].Note[CN].Channel := MidiEvent.event and 15;
- Channel[C].Note[CN].Data1 := MidiEvent.data1;
- Channel[C].Note[CN].Data2 := MidiEvent.data2;
- Channel[C].Note[CN].Str := MidiEvent.str;
-
- if Channel[C].Note[CN].Start + Channel[C].Note[CN].Len > Len then
- Len := Channel[C].Note[CN].Start + Channel[C].Note[CN].Len;
- end;
- end;
- ATrack := Channel;
-
- end;
-
- Interaction := 0;
-{$ENDIF}
-end;
-
-function TScreenEditConvert.Draw: boolean;
-var
- Pet: integer;
- Pet2: integer;
- Bottom: real;
- X: real;
- Y: real;
- H: real;
- YSkip: real;
-begin
- // draw static menu
- inherited Draw;
-
- Y := 100;
-
- H := Length(ATrack)*40;
- if H > 480 then H := 480;
- Bottom := Y + H;
-
- YSkip := H / Length(ATrack);
-
- // select
- DrawQuad(10, Y+Sel*YSkip, 780, YSkip, 0.8, 0.8, 0.8);
-
- // selected - now me use Status System
- for Pet := 0 to High(ATrack) do
- if ATrack[Pet].Hear then
- DrawQuad(10, Y+Pet*YSkip, 50, YSkip, 0.8, 0.3, 0.3);
- glColor3f(0, 0, 0);
- for Pet := 0 to High(ATrack) do begin
- if ((ATrack[Pet].Status div 1) and 1) = 1 then begin
- SetFontPos(25, Y + Pet*YSkip + 10);
- SetFontSize(5);
- glPrint('N');
- end;
- if ((ATrack[Pet].Status div 2) and 1) = 1 then begin
- SetFontPos(40, Y + Pet*YSkip + 10);
- SetFontSize(5);
- glPrint('L');
- end;
- end;
-
- DrawLine(10, Y, 10, Bottom, 0, 0, 0);
- DrawLine(60, Y, 60, Bottom, 0, 0, 0);
- DrawLine(790, Y, 790, Bottom, 0, 0, 0);
-
- for Pet := 0 to Length(ATrack) do
- DrawLine(10, Y+Pet*YSkip, 790, Y+Pet*YSkip, 0, 0, 0);
-
- for Pet := 0 to High(ATrack) do begin
- SetFontPos(11, Y + 10 + Pet*YSkip);
- SetFontSize(5);
- glPrint(pchar(ATrack[Pet].Name));
- end;
-
- for Pet := 0 to High(ATrack) do
- for Pet2 := 0 to High(ATrack[Pet].Note) do begin
- if ATrack[Pet].Note[Pet2].EventType = 9 then
- DrawQuad(60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + (Pet+1)*YSkip - ATrack[Pet].Note[Pet2].Data1*35/127, 3, 3, ColR[Pet], ColG[Pet], ColB[Pet]);
- if ATrack[Pet].Note[Pet2].EventType = 15 then
- DrawLine(60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + 0.75 * YSkip + Pet*YSkip, 60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + YSkip + Pet*YSkip, ColR[Pet], ColG[Pet], ColB[Pet]);
- end;
-
- // playing line
- {$IFDEF UseMIDIPort}
- X := 60 + MidiFile.GetCurrentTime/MidiFile.GetTrackLength*730;
- {$ENDIF}
- DrawLine(X, Y, X, Bottom, 0.3, 0.3, 0.3);
-
-
-end;
-
-procedure TScreenEditConvert.onHide;
-begin
-{$IFDEF UseMIDIPort}
- MidiOut.Close;
- MidiOut.Free;
-{$ENDIF}
-end;
-
-end.
+unit UScreenEditConvert; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses UMenu, + SDL, + {$IFDEF UseMIDIPort} + MidiFile, + MidiOut, + {$ENDIF} + ULog, + USongs, + UMusic, + UThemes; + +type + TNote = record + Event: integer; + EventType: integer; + Channel: integer; + Start: real; + Len: real; + Data1: integer; + Data2: integer; + Str: string; + end; + + TTrack = record + Note: array of TNote; + Name: string; + Hear: boolean; + Status: byte; // 0 - none, 1 - notes, 2 - lyrics, 3 - notes + lyrics + end; + + TNuta = record + Start: integer; + Len: integer; + Tone: integer; + Lyric: string; + NewSentence: boolean; + end; + + TArrayTrack = array of TTrack; + + TScreenEditConvert = class(TMenu) + public + ATrack: TArrayTrack; // actual track +// Track: TArrayTrack; + Channel: TArrayTrack; + ColR: array[0..100] of real; + ColG: array[0..100] of real; + ColB: array[0..100] of real; + Len: real; + Sel: integer; + Selected: boolean; +// FileName: string; + + {$IFDEF UseMIDIPort} + MidiFile: TMidiFile; + MidiTrack: TMidiTrack; + MidiEvent: pMidiEvent; + MidiOut: TMidiOutput; + {$ENDIF} + + Song: TSong; + Czesc: TCzesci; + BPM: real; + Ticks: real; + Nuta: array of TNuta; + + procedure AddLyric(Start: integer; Tekst: string); + procedure Extract; + + {$IFDEF UseMIDIPort} + procedure MidiFile1MidiEvent(event: PMidiEvent); + {$ENDIF} + + function SelectedNumber: integer; + constructor Create; override; + procedure onShow; override; + function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override; + function Draw: boolean; override; + procedure onHide; override; + end; + +implementation +uses UGraphic, + SysUtils, + UDrawTexture, + TextGL, + UFiles, + UMain, + UIni, + OpenGL12, + USkins; + +function TScreenEditConvert.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; +var + T: integer; +begin + Result := true; + If (PressedDown) Then + begin // Key Down + case PressedKey of + SDLK_Q: + begin + Result := false; + end; + + + SDLK_ESCAPE, + SDLK_BACKSPACE : + begin + {$IFDEF UseMIDIPort} + MidiFile.StopPlaying; + {$ENDIF} + AudioPlayback.PlayBack; + FadeTo(@ScreenEdit); + end; + + SDLK_RETURN: + begin + if Interaction = 0 then + begin + AudioPlayback.PlayStart; + ScreenOpen.BackScreen := @ScreenEditConvert; + FadeTo(@ScreenOpen); + end; + + if Interaction = 1 then + begin + Selected := false; + {$IFDEF UseMIDIPort} + MidiFile.OnMidiEvent := MidiFile1MidiEvent; +// MidiFile.GoToTime(MidiFile.GetTrackLength div 2); + MidiFile.StartPlaying; + {$ENDIF} + end; + + if Interaction = 2 then begin + Selected := true; + {$IFDEF UseMIDIPort} + MidiFile.OnMidiEvent := nil; + {$ENDIF} + {for T := 0 to High(ATrack) do begin + if ATrack[T].Hear then begin + MidiTrack := MidiFile.GetTrack(T); + MidiTrack.OnMidiEvent := MidiFile1MidiEvent; + end; + end; + MidiFile.StartPlaying;//} + end; + + if Interaction = 3 then begin + if SelectedNumber > 0 then begin + Extract; + SaveSong(Song, Czesc, ChangeFileExt(FileName, '.txt'), false); + end; + end; + + end; + + SDLK_SPACE: + begin +// ATrack[Sel].Hear := not ATrack[Sel].Hear; + ATrack[Sel].Status := (ATrack[Sel].Status + 1) mod 4; + +{ if Selected then begin + MidiTrack := MidiFile.GetTrack(Sel); + if Track[Sel].Hear then + MidiTrack.OnMidiEvent := MidiFile1MidiEvent + else + MidiTrack.OnMidiEvent := nil; + end;} + end; + + SDLK_RIGHT: + begin + InteractNext; + end; + + SDLK_LEFT: + begin + InteractPrev; + end; + + SDLK_DOWN: + begin + Inc(Sel); + if Sel > High(ATrack) then Sel := 0; + end; + SDLK_UP: + begin + Dec(Sel); + if Sel < 0 then Sel := High(ATrack); + end; + end; + end; +end; + +procedure TScreenEditConvert.AddLyric(Start: integer; Tekst: string); +var + N: integer; +begin + for N := 0 to High(Nuta) do begin + if Nuta[N].Start = Start then begin + // check for new sentece + if Copy(Tekst, 1, 1) = '\' then Delete(Tekst, 1, 1); + if Copy(Tekst, 1, 1) = '/' then begin + Delete(Tekst, 1, 1); + Nuta[N].NewSentence := true; + end; + + // overwrite lyric od append + if Nuta[N].Lyric = '-' then + Nuta[N].Lyric := Tekst + else + Nuta[N].Lyric := Nuta[N].Lyric + Tekst; + end; + end; +end; + +procedure TScreenEditConvert.Extract; +var + T: integer; + C: integer; + N: integer; + Nu: integer; + NutaTemp: TNuta; + Move: integer; + Max, Min: integer; +begin + // song info + Song.Title := ''; + Song.Artist := ''; + Song.Mp3 := ''; + Song.Resolution := 4; + SetLength(Song.BPM, 1); + Song.BPM[0].BPM := BPM*4; + + SetLength(Nuta, 0); + + // extract notes + for T := 0 to High(ATrack) do begin +// if ATrack[T].Hear then begin + if ((ATrack[T].Status div 1) and 1) = 1 then begin + for N := 0 to High(ATrack[T].Note) do begin + if (ATrack[T].Note[N].EventType = 9) and (ATrack[T].Note[N].Data2 > 0) then begin + Nu := Length(Nuta); + SetLength(Nuta, Nu + 1); + Nuta[Nu].Start := Round(ATrack[T].Note[N].Start / Ticks); + Nuta[Nu].Len := Round(ATrack[T].Note[N].Len / Ticks); + Nuta[Nu].Tone := ATrack[T].Note[N].Data1 - 12*5; + Nuta[Nu].Lyric := '-'; + end; + end; + end; + end; + + // extract lyrics + for T := 0 to High(ATrack) do begin +// if ATrack[T].Hear then begin + if ((ATrack[T].Status div 2) and 1) = 1 then begin + for N := 0 to High(ATrack[T].Note) do begin + if (ATrack[T].Note[N].EventType = 15) then begin +// Log.LogStatus('<' + Track[T].Note[N].Str + '>', 'MIDI'); + AddLyric(Round(ATrack[T].Note[N].Start / Ticks), ATrack[T].Note[N].Str); + end; + end; + end; + end; + + // sort notes + for N := 0 to High(Nuta) do + for Nu := 0 to High(Nuta)-1 do + if Nuta[Nu].Start > Nuta[Nu+1].Start then begin + NutaTemp := Nuta[Nu]; + Nuta[Nu] := Nuta[Nu+1]; + Nuta[Nu+1] := NutaTemp; + end; + + // move to 0 at beginning + Move := Nuta[0].Start; + for N := 0 to High(Nuta) do + Nuta[N].Start := Nuta[N].Start - Move; + + // copy notes + SetLength(Czesc.Czesc, 1); + Czesc.Ilosc := 1; + Czesc.High := 0; + + C := 0; + N := 0; + Czesc.Czesc[C].IlNut := 0; + Czesc.Czesc[C].HighNut := -1; + + for Nu := 0 to High(Nuta) do begin + if Nuta[Nu].NewSentence then begin // nowa linijka + SetLength(Czesc.Czesc, Length(Czesc.Czesc)+1); + Czesc.Ilosc := Czesc.Ilosc + 1; + Czesc.High := Czesc.High + 1; + C := C + 1; + N := 0; + SetLength(Czesc.Czesc[C].Nuta, 0); + Czesc.Czesc[C].IlNut := 0; + Czesc.Czesc[C].HighNut := -1; + + //Calculate Start of the Last Sentence + if (C > 0) and (Nu > 0) then + begin + Max := Nuta[Nu].Start; + Min := Nuta[Nu-1].Start + Nuta[Nu-1].Len; + + case (Max - Min) of + 0: Czesc.Czesc[C].Start := Max; + 1: Czesc.Czesc[C].Start := Max; + 2: Czesc.Czesc[C].Start := Max - 1; + 3: Czesc.Czesc[C].Start := Max - 2; + else + if ((Max - Min) > 4) then + Czesc.Czesc[C].Start := Min + 2 + else + Czesc.Czesc[C].Start := Max; + + end; // case + + end; + end; + + // tworzy miejsce na nowa nute + SetLength(Czesc.Czesc[C].Nuta, Length(Czesc.Czesc[C].Nuta)+1); + Czesc.Czesc[C].IlNut := Czesc.Czesc[C].IlNut + 1; + Czesc.Czesc[C].HighNut := Czesc.Czesc[C].HighNut + 1; + + // dopisuje + Czesc.Czesc[C].Nuta[N].Start := Nuta[Nu].Start; + Czesc.Czesc[C].Nuta[N].Dlugosc := Nuta[Nu].Len; + Czesc.Czesc[C].Nuta[N].Ton := Nuta[Nu].Tone; + Czesc.Czesc[C].Nuta[N].Tekst := Nuta[Nu].Lyric; + //All Notes are Freestyle when Converted Fix: + Czesc.Czesc[C].Nuta[N].Wartosc := 1; + Inc(N); + end; +end; + +function TScreenEditConvert.SelectedNumber: integer; +var + T: integer; // track +begin + Result := 0; + for T := 0 to High(ATrack) do +// if ATrack[T].Hear then Inc(Result); + if ((ATrack[T].Status div 1) and 1) = 1 then Inc(Result); +end; + +{$IFDEF UseMIDIPort} +procedure TScreenEditConvert.MidiFile1MidiEvent(event: PMidiEvent); +begin +// Log.LogStatus(IntToStr(event.event), 'MIDI'); + MidiOut.PutShort(event.event, event.data1, event.data2); +end; +{$ENDIF} + +constructor TScreenEditConvert.Create; +var + P: integer; +begin + inherited Create; + AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF')); + AddButtonText(15, 5, 0, 0, 0, 'Open'); +// Button[High(Button)].Text[0].Size := 11; + + AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF')); + AddButtonText(25, 5, 0, 0, 0, 'Play'); + + AddButton(280, 20, 200, 40, Skin.GetTextureFileName('ButtonF')); + AddButtonText(25, 5, 0, 0, 0, 'Play Selected'); + + AddButton(500, 20, 100, 40, Skin.GetTextureFileName('ButtonF')); + AddButtonText(20, 5, 0, 0, 0, 'Save'); + + +{ MidiOut := TMidiOutput.Create(nil); +// MidiOut.Close; +// MidiOut.DeviceID := 0; + if Ini.Debug = 1 then + MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table + Log.LogStatus(MidiOut.ProductName, 'MIDI'); + MidiOut.Open; +// MidiOut.SetVolume(100, 100); // temporary} + + FileName := GamePath + 'file.mid'; + {$IFDEF UseMIDIPort} + MidiFile := TMidiFile.Create(nil); + {$ENDIF} + + for P := 0 to 100 do begin + ColR[P] := Random(10)/10; + ColG[P] := Random(10)/10; + ColB[P] := Random(10)/10; + end; + +end; + +procedure TScreenEditConvert.onShow; +var + T: integer; // track + N: integer; // note + C: integer; // channel + CN: integer; // channel note +begin +{$IFDEF UseMIDIPort} + MidiOut := TMidiOutput.Create(nil); + if Ini.Debug = 1 then + MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table + Log.LogStatus(MidiOut.ProductName, 'MIDI'); + MidiOut.Open; + + + if FileExists(FileName) then + begin + MidiFile.Filename := FileName; + MidiFile.ReadFile; + + + Len := 0; + Sel := 0; + BPM := MidiFile.Bpm; + Ticks := MidiFile.TicksPerQuarter / 4; + +{ for T := 0 to MidiFile.NumberOfTracks-1 do begin + SetLength(Track, Length(Track)+1); + MidiTrack := MidiFile.GetTrack(T); + MidiTrack.OnMidiEvent := MidiFile1MidiEvent; + Track[T].Name := MidiTrack.getName; + + for N := 0 to MidiTrack.getEventCount-1 do begin + SetLength(Track[T].Note, Length(Track[T].Note)+1); + MidiEvent := MidiTrack.GetEvent(N); + Track[T].Note[N].Start := MidiEvent.time; + Track[T].Note[N].Len := MidiEvent.len; + Track[T].Note[N].Event := MidiEvent.event; + Track[T].Note[N].EventType := MidiEvent.event div 16; + Track[T].Note[N].Channel := MidiEvent.event and 15; + Track[T].Note[N].Data1 := MidiEvent.data1; + Track[T].Note[N].Data2 := MidiEvent.data2; + Track[T].Note[N].Str := MidiEvent.str; + + if Track[T].Note[N].Start + Track[T].Note[N].Len > Len then + Len := Track[T].Note[N].Start + Track[T].Note[N].Len; + end; + end;} + + + SetLength(Channel, 16); + for T := 0 to 15 do + begin + Channel[T].Name := IntToStr(T+1); + SetLength(Channel[T].Note, 0); + Channel[T].Status := 0; + end; + + for T := 0 to MidiFile.NumberOfTracks-1 do begin + MidiTrack := MidiFile.GetTrack(T); + MidiTrack.OnMidiEvent := MidiFile1MidiEvent; + + for N := 0 to MidiTrack.getEventCount-1 do begin + MidiEvent := MidiTrack.GetEvent(N); + C := MidiEvent.event and 15; + + CN := Length(Channel[C].Note); + SetLength(Channel[C].Note, CN+1); + + Channel[C].Note[CN].Start := MidiEvent.time; + Channel[C].Note[CN].Len := MidiEvent.len; + Channel[C].Note[CN].Event := MidiEvent.event; + Channel[C].Note[CN].EventType := MidiEvent.event div 16; + Channel[C].Note[CN].Channel := MidiEvent.event and 15; + Channel[C].Note[CN].Data1 := MidiEvent.data1; + Channel[C].Note[CN].Data2 := MidiEvent.data2; + Channel[C].Note[CN].Str := MidiEvent.str; + + if Channel[C].Note[CN].Start + Channel[C].Note[CN].Len > Len then + Len := Channel[C].Note[CN].Start + Channel[C].Note[CN].Len; + end; + end; + ATrack := Channel; + + end; + + Interaction := 0; +{$ENDIF} +end; + +function TScreenEditConvert.Draw: boolean; +var + Pet: integer; + Pet2: integer; + Bottom: real; + X: real; + Y: real; + H: real; + YSkip: real; +begin + // draw static menu + inherited Draw; + + Y := 100; + + H := Length(ATrack)*40; + if H > 480 then H := 480; + Bottom := Y + H; + + YSkip := H / Length(ATrack); + + // select + DrawQuad(10, Y+Sel*YSkip, 780, YSkip, 0.8, 0.8, 0.8); + + // selected - now me use Status System + for Pet := 0 to High(ATrack) do + if ATrack[Pet].Hear then + DrawQuad(10, Y+Pet*YSkip, 50, YSkip, 0.8, 0.3, 0.3); + glColor3f(0, 0, 0); + for Pet := 0 to High(ATrack) do begin + if ((ATrack[Pet].Status div 1) and 1) = 1 then begin + SetFontPos(25, Y + Pet*YSkip + 10); + SetFontSize(5); + glPrint('N'); + end; + if ((ATrack[Pet].Status div 2) and 1) = 1 then begin + SetFontPos(40, Y + Pet*YSkip + 10); + SetFontSize(5); + glPrint('L'); + end; + end; + + DrawLine(10, Y, 10, Bottom, 0, 0, 0); + DrawLine(60, Y, 60, Bottom, 0, 0, 0); + DrawLine(790, Y, 790, Bottom, 0, 0, 0); + + for Pet := 0 to Length(ATrack) do + DrawLine(10, Y+Pet*YSkip, 790, Y+Pet*YSkip, 0, 0, 0); + + for Pet := 0 to High(ATrack) do begin + SetFontPos(11, Y + 10 + Pet*YSkip); + SetFontSize(5); + glPrint(pchar(ATrack[Pet].Name)); + end; + + for Pet := 0 to High(ATrack) do + for Pet2 := 0 to High(ATrack[Pet].Note) do begin + if ATrack[Pet].Note[Pet2].EventType = 9 then + DrawQuad(60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + (Pet+1)*YSkip - ATrack[Pet].Note[Pet2].Data1*35/127, 3, 3, ColR[Pet], ColG[Pet], ColB[Pet]); + if ATrack[Pet].Note[Pet2].EventType = 15 then + DrawLine(60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + 0.75 * YSkip + Pet*YSkip, 60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + YSkip + Pet*YSkip, ColR[Pet], ColG[Pet], ColB[Pet]); + end; + + // playing line + {$IFDEF UseMIDIPort} + X := 60 + MidiFile.GetCurrentTime/MidiFile.GetTrackLength*730; + {$ENDIF} + DrawLine(X, Y, X, Bottom, 0.3, 0.3, 0.3); + + +end; + +procedure TScreenEditConvert.onHide; +begin +{$IFDEF UseMIDIPort} + MidiOut.Close; + MidiOut.Free; +{$ENDIF} +end; + +end. |