diff options
Diffstat (limited to 'src/screens')
34 files changed, 1182 insertions, 906 deletions
diff --git a/src/screens/UScreenCredits.pas b/src/screens/UScreenCredits.pas index def6b7de..b1333b4a 100644 --- a/src/screens/UScreenCredits.pas +++ b/src/screens/UScreenCredits.pas @@ -35,15 +35,16 @@ interface uses SysUtils, - UMenu, SDL, SDL_Image, + gl, + UMenu, UDisplay, UTexture, - gl, UMusic, UFiles, UThemes, + UPath, UGraphicClasses; type @@ -98,10 +99,10 @@ type Fadeout: boolean; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; function Draw: boolean; override; - procedure onShow; override; - procedure onHide; override; + procedure OnShow; override; + procedure OnHide; override; procedure DrawCredits; procedure Draw_FunkyText; end; @@ -138,17 +139,17 @@ const OUTRO_EXD_FILE = 'outro-exit-dark.png'; Timings: array[0..21] of cardinal=( - 20, // 0 Delay vor Start + 20, // 0 Delay before Start - 149, // 1 Ende erster Intro Zoom - 155, // 2 Start 2. Action im Intro - 170, // 3 Ende Separation im Intro - 271, // 4 Anfang Zoomout im Intro + 149, // 1 End first Intro Zoom + 155, // 2 Start 2. Action in Intro + 170, // 3 End Separation in Intro + 271, // 4 beginning Zoomout in Intro 0, // 5 unused - 261, // 6 Start fade-to-white im Intro + 261, // 6 Start fade-to-white in Intro 271, // 7 Start Main Part - 280, // 8 Start On-Beat-Sternchen Main Part + 280, // 8 Start On-Beat-Star Main Part 396, // 9 Start BlindGuard 666, // 10 Start blindy @@ -162,7 +163,7 @@ const 2826, // 18 Ende Whiteshark 3096, // 19 Start FadeOut Mainscreen 3366, // 20 Ende Credits Tune - 60); // 21 start flare im intro + 60); // 21 start flare in intro implementation @@ -176,9 +177,9 @@ uses Textgl, ULanguage, UCommon, - UPath; + UPathUtils; -function TScreenCredits.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenCredits.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then @@ -204,38 +205,38 @@ end; constructor TScreenCredits.Create; var - CreditsPath: string; + CreditsPath: IPath; begin inherited Create; - CreditsPath := ResourcesPath + 'credits/'; - - credits_bg_tex := Texture.LoadTexture(CreditsPath + CRDTS_BG_FILE, TEXTURE_TYPE_PLAIN, 0); - credits_bg_ovl := Texture.LoadTexture(CreditsPath + CRDTS_OVL_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - - credits_blindguard := Texture.LoadTexture(CreditsPath + CRDTS_blindguard_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - credits_blindy := Texture.LoadTexture(CreditsPath + CRDTS_blindy_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - credits_canni := Texture.LoadTexture(CreditsPath + CRDTS_canni_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - credits_commandio := Texture.LoadTexture(CreditsPath + CRDTS_commandio_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - credits_lazyjoker := Texture.LoadTexture(CreditsPath + CRDTS_lazyjoker_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - credits_mog := Texture.LoadTexture(CreditsPath + CRDTS_mog_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - credits_mota := Texture.LoadTexture(CreditsPath + CRDTS_mota_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - credits_skillmaster := Texture.LoadTexture(CreditsPath + CRDTS_skillmaster_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - credits_whiteshark := Texture.LoadTexture(CreditsPath + CRDTS_whiteshark_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - - intro_layer01 := Texture.LoadTexture(CreditsPath + INTRO_L01_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - intro_layer02 := Texture.LoadTexture(CreditsPath + INTRO_L02_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - intro_layer03 := Texture.LoadTexture(CreditsPath + INTRO_L03_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - intro_layer04 := Texture.LoadTexture(CreditsPath + INTRO_L04_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - intro_layer05 := Texture.LoadTexture(CreditsPath + INTRO_L05_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - intro_layer06 := Texture.LoadTexture(CreditsPath + INTRO_L06_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - intro_layer07 := Texture.LoadTexture(CreditsPath + INTRO_L07_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - intro_layer08 := Texture.LoadTexture(CreditsPath + INTRO_L08_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - intro_layer09 := Texture.LoadTexture(CreditsPath + INTRO_L09_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - - outro_bg := Texture.LoadTexture(CreditsPath + OUTRO_BG_FILE, TEXTURE_TYPE_PLAIN, 0); - outro_esc := Texture.LoadTexture(CreditsPath + OUTRO_ESC_FILE, TEXTURE_TYPE_TRANSPARENT, 0); - outro_exd := Texture.LoadTexture(CreditsPath + OUTRO_EXD_FILE, TEXTURE_TYPE_TRANSPARENT, 0); + CreditsPath := ResourcesPath.Append('credits', pdAppend); + + credits_bg_tex := Texture.LoadTexture(CreditsPath.Append(CRDTS_BG_FILE), TEXTURE_TYPE_PLAIN, 0); + credits_bg_ovl := Texture.LoadTexture(CreditsPath.Append(CRDTS_OVL_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + + credits_blindguard := Texture.LoadTexture(CreditsPath.Append(CRDTS_blindguard_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + credits_blindy := Texture.LoadTexture(CreditsPath.Append(CRDTS_blindy_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + credits_canni := Texture.LoadTexture(CreditsPath.Append(CRDTS_canni_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + credits_commandio := Texture.LoadTexture(CreditsPath.Append(CRDTS_commandio_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + credits_lazyjoker := Texture.LoadTexture(CreditsPath.Append(CRDTS_lazyjoker_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + credits_mog := Texture.LoadTexture(CreditsPath.Append(CRDTS_mog_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + credits_mota := Texture.LoadTexture(CreditsPath.Append(CRDTS_mota_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + credits_skillmaster := Texture.LoadTexture(CreditsPath.Append(CRDTS_skillmaster_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + credits_whiteshark := Texture.LoadTexture(CreditsPath.Append(CRDTS_whiteshark_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + + intro_layer01 := Texture.LoadTexture(CreditsPath.Append(INTRO_L01_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + intro_layer02 := Texture.LoadTexture(CreditsPath.Append(INTRO_L02_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + intro_layer03 := Texture.LoadTexture(CreditsPath.Append(INTRO_L03_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + intro_layer04 := Texture.LoadTexture(CreditsPath.Append(INTRO_L04_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + intro_layer05 := Texture.LoadTexture(CreditsPath.Append(INTRO_L05_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + intro_layer06 := Texture.LoadTexture(CreditsPath.Append(INTRO_L06_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + intro_layer07 := Texture.LoadTexture(CreditsPath.Append(INTRO_L07_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + intro_layer08 := Texture.LoadTexture(CreditsPath.Append(INTRO_L08_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + intro_layer09 := Texture.LoadTexture(CreditsPath.Append(INTRO_L09_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + + outro_bg := Texture.LoadTexture(CreditsPath.Append(OUTRO_BG_FILE), TEXTURE_TYPE_PLAIN, 0); + outro_esc := Texture.LoadTexture(CreditsPath.Append(OUTRO_ESC_FILE), TEXTURE_TYPE_TRANSPARENT, 0); + outro_exd := Texture.LoadTexture(CreditsPath.Append(OUTRO_EXD_FILE), TEXTURE_TYPE_TRANSPARENT, 0); CRDTS_Stage:=InitialDelay; end; @@ -246,7 +247,7 @@ begin Draw := true; end; -procedure TScreenCredits.onShow; +procedure TScreenCredits.OnShow; begin inherited; @@ -255,13 +256,13 @@ begin deluxe_slidein := 0; Credits_Alpha := 0; // Music.SetLoop(true); loop loops not, shit - AudioPlayback.Open(soundpath + 'wome-credits-tune.mp3'); // thank you wetue + AudioPlayback.Open(soundpath.Append('wome-credits-tune.mp3')); // thank you wetue // Music.Play; CTime := 0; // setlength(CTime_hold,0); end; -procedure TScreenCredits.onHide; +procedure TScreenCredits.OnHide; begin AudioPlayback.Stop; end; @@ -1386,7 +1387,7 @@ begin begin CTime_hold := 0; AudioPlayback.Stop; - AudioPlayback.Open(soundpath + 'credits-outro-tune.mp3'); + AudioPlayback.Open(SoundPath.Append('credits-outro-tune.mp3')); AudioPlayback.SetVolume(0.2); AudioPlayback.SetLoop(true); AudioPlayback.Play; diff --git a/src/screens/UScreenEdit.pas b/src/screens/UScreenEdit.pas index 5112e17a..2111adef 100644 --- a/src/screens/UScreenEdit.pas +++ b/src/screens/UScreenEdit.pas @@ -45,8 +45,7 @@ type TextDescriptionLong: integer; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; - PressedDown: boolean): boolean; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; procedure InteractNext; override; procedure InteractPrev; override; procedure InteractInc; override; @@ -60,10 +59,10 @@ uses UGraphic, UMusic, USkins, + UUnicodeUtils, SysUtils; -function TScreenEdit.ParseInput(PressedKey: cardinal; CharCode: WideChar; - PressedDown: boolean): boolean; +function TScreenEdit.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; var SDL_ModState: word; begin @@ -75,8 +74,8 @@ begin if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; diff --git a/src/screens/UScreenEditConvert.pas b/src/screens/UScreenEditConvert.pas index e4a691cf..b2fb7773 100644 --- a/src/screens/UScreenEditConvert.pas +++ b/src/screens/UScreenEditConvert.pas @@ -25,6 +25,29 @@ unit UScreenEditConvert; +{* + * See + * MIDI Recommended Practice (RP-017): SMF Lyric Meta Event Definition + * http://www.midi.org/techspecs/rp17.php + * MIDI Recommended Practice (RP-026): SMF Language and Display Extensions + * http://www.midi.org/techspecs/rp26.php + * MIDI File Format + * http://www.sonicspot.com/guide/midifiles.html + * KMIDI File Format + * http://gnese.free.fr/Projects/KaraokeTime/Fichiers/karfaq.html + * http://journals.rpungin.fotki.com/karaoke/category/midi + * + * There are two widely spread karaoke formats: + * - KMIDI (.kar), an inofficial midi extension by Tune 1000 + * - Standard Midi files with lyric meta-tags (SMF with lyrics, .mid). + * + * KMIDI uses two tracks, the first just contains a header (mostly track 2) and + * the second the lyrics (track 3). It uses text meta tags for the lyrics. + * SMF uses just one track (normally track 1) and uses lyric meta tags for storage. + * + * Most files are in the KMIDI format. Some Midi files contain both lyric types. + *} + interface {$IFDEF FPC} @@ -45,10 +68,11 @@ uses USongs, USong, UMusic, - UThemes; + UThemes, + UPath; type - TNote = record + TMidiNote = record Event: integer; EventType: integer; Channel: integer; @@ -56,70 +80,65 @@ type Len: real; Data1: integer; Data2: integer; - Str: string; + Str: UTF8String; // normally ASCII end; + TLyricType = (ltKMIDI, ltSMFLyric); + TTrack = record - Note: array of TNote; - Name: string; - Hear: boolean; - Status: set of (notes, lyrics); + Note: array of TMidiNote; + Name: UTF8String; // normally ASCII + Status: set of (tsNotes, tsLyrics); //< track contains notes, lyrics or both + LyricType: set of TLyricType; + NoteType: (ntNone, ntAvail); end; - TNuta = record + TNote = record Start: integer; Len: integer; Tone: integer; - Lyric: string; + Lyric: UTF8String; NewSentence: boolean; end; TArrayTrack = array of TTrack; TScreenEditConvert = class(TMenu) - public - ATrack: TArrayTrack; // actual track -// Track: TArrayTrack; - Channel: TArrayTrack; + private + Tracks: TArrayTrack; // current track 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; + SelTrack: integer; // index of selected track + fFileName: IPath; {$IFDEF UseMIDIPort} MidiFile: TMidiFile; - MidiTrack: TMidiTrack; - MidiEvent: pMidiEvent; MidiOut: TMidiOutput; {$ENDIF} - - Song: TSong; - Lines: TLines; + BPM: real; Ticks: real; - Note: array of TNuta; + Note: array of TNote; - procedure AddLyric(Start: integer; Text: string); - procedure Extract; + procedure AddLyric(Start: integer; LyricType: TLyricType; Text: UTF8String); + procedure Extract(out Song: TSong; out Lines: TLines); {$IFDEF UseMIDIPort} procedure MidiFile1MidiEvent(event: PMidiEvent); {$ENDIF} - - function SelectedNumber: integer; + + function CountSelectedTracks: integer; + + public constructor Create; override; - procedure onShow; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; + procedure OnShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; function Draw: boolean; override; - procedure onHide; override; + procedure OnHide; override; end; -var - ConversionFileName: string; - implementation uses @@ -131,17 +150,42 @@ uses UGraphic, UIni, UMain, - UPath, - USkins; - -function TScreenEditConvert.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; + UPathUtils, + USkins, + ULanguage, + UTextEncoding, + UUnicodeUtils; + +const + // MIDI/KAR lyrics are specified to be ASCII only. + // Assume backward compatible CP1252 encoding. + DEFAULT_ENCODING = encCP1252; + +const + MIDI_EVENTTYPE_NOTEOFF = $8; + MIDI_EVENTTYPE_NOTEON = $9; + MIDI_EVENTTYPE_META_SYSEX = $F; + + MIDI_EVENT_META = $FF; + MIDI_META_TEXT = $1; + MIDI_META_LYRICS = $5; + +function TScreenEditConvert.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; +{$IFDEF UseMIDIPort} +var + SResult: TSaveSongResult; + Playing: boolean; + MidiTrack: TMidiTrack; + Song: TSong; + Lines: TLines; +{$ENDIF} begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -153,9 +197,10 @@ begin SDLK_ESCAPE, SDLK_BACKSPACE : begin - {$IFDEF UseMIDIPort} - MidiFile.StopPlaying; - {$ENDIF} + {$IFDEF UseMIDIPort} + if (MidiFile <> nil) then + MidiFile.StopPlaying; + {$ENDIF} AudioPlayback.PlaySound(SoundLib.Back); FadeTo(@ScreenEdit); end; @@ -165,70 +210,97 @@ begin if Interaction = 0 then begin AudioPlayback.PlaySound(SoundLib.Start); + ScreenOpen.Filename := GamePath.Append('file.mid'); ScreenOpen.BackScreen := @ScreenEditConvert; FadeTo(@ScreenOpen); - end; - - if Interaction = 1 then + end + else if Interaction = 1 then begin - Selected := false; - {$IFDEF UseMIDIPort} - MidiFile.OnMidiEvent := MidiFile1MidiEvent; -// MidiFile.GoToTime(MidiFile.GetTrackLength div 2); - MidiFile.StartPlaying; + {$IFDEF UseMIDIPort} + if (MidiFile <> nil) then + begin + MidiFile.OnMidiEvent := MidiFile1MidiEvent; + //MidiFile.GoToTime(MidiFile.GetTrackLength div 2); + MidiFile.StartPlaying; + end; {$ENDIF} - end; - - if Interaction = 2 then + end + else if Interaction = 2 then begin - Selected := true; {$IFDEF UseMIDIPort} - MidiFile.OnMidiEvent := nil; - {$ENDIF} - {for T := 0 to High(ATrack) do + if (MidiFile <> nil) then begin - if ATrack[T].Hear then - begin - MidiTrack := MidiFile.GetTrack(T); - MidiTrack.OnMidiEvent := MidiFile1MidiEvent; - end; + MidiFile.OnMidiEvent := nil; + MidiFile.StartPlaying; end; - MidiFile.StartPlaying;//} - end; - - if Interaction = 3 then + {$ENDIF} + end + else if Interaction = 3 then begin - if SelectedNumber > 0 then + {$IFDEF UseMIDIPort} + if CountSelectedTracks > 0 then + begin + Extract(Song, Lines); + SResult := SaveSong(Song, Lines, fFileName.SetExtension('.txt'), + false); + FreeAndNil(Song); + if (SResult = ssrOK) then + ScreenPopupInfo.ShowPopup(Language.Translate('INFO_FILE_SAVED')) + else + ScreenPopupError.ShowPopup(Language.Translate('ERROR_SAVE_FILE_FAILED')); + end + else begin - Extract; - SaveSong(Song, Lines, ChangeFileExt(ConversionFileName, '.txt'), false); + ScreenPopupError.ShowPopup(Language.Translate('EDITOR_ERROR_NO_TRACK_SELECTED')); end; + {$ENDIF} end; end; SDLK_SPACE: begin -// ATrack[Sel].Hear := not ATrack[Sel].Hear; - if Notes in ATrack[Sel].Status then + {$IFDEF UseMIDIPort} + if (MidiFile <> nil) then begin - ATrack[Sel].Status := ATrack[Sel].Status - [Notes]; - if Lyrics in ATrack[Sel].Status then - ATrack[Sel].Status := ATrack[Sel].Status - [Lyrics] - else - ATrack[Sel].Status := ATrack[Sel].Status + [Lyrics]; - end - else - ATrack[Sel].Status := ATrack[Sel].Status + [Notes]; + if (Tracks[SelTrack].NoteType = ntAvail) and + (Tracks[SelTrack].LyricType <> []) then + begin + if (Tracks[SelTrack].Status = []) then + Tracks[SelTrack].Status := [tsNotes] + else if (Tracks[SelTrack].Status = [tsNotes]) then + Tracks[SelTrack].Status := [tsLyrics] + else if (Tracks[SelTrack].Status = [tsLyrics]) then + Tracks[SelTrack].Status := [tsNotes, tsLyrics] + else if (Tracks[SelTrack].Status = [tsNotes, tsLyrics]) then + Tracks[SelTrack].Status := []; + end + else if (Tracks[SelTrack].NoteType = ntAvail) then + begin + if (Tracks[SelTrack].Status = []) then + Tracks[SelTrack].Status := [tsNotes] + else + Tracks[SelTrack].Status := []; + end + else if (Tracks[SelTrack].LyricType <> []) then + begin + if (Tracks[SelTrack].Status = []) then + Tracks[SelTrack].Status := [tsLyrics] + else + Tracks[SelTrack].Status := []; + end; -{ if Selected then - begin - MidiTrack := MidiFile.GetTrack(Sel); - if Track[Sel].Hear then + Playing := (MidiFile.GetCurrentTime > 0); + MidiFile.StopPlaying(); + MidiTrack := MidiFile.GetTrack(SelTrack); + if tsNotes in Tracks[SelTrack].Status then MidiTrack.OnMidiEvent := MidiFile1MidiEvent else MidiTrack.OnMidiEvent := nil; - end;} + if (Playing) then + MidiFile.ContinuePlaying(); + end; + {$ENDIF} end; SDLK_RIGHT: @@ -243,102 +315,161 @@ begin SDLK_DOWN: begin - Inc(Sel); - if Sel > High(ATrack) then - Sel := 0; + Inc(SelTrack); + if SelTrack > High(Tracks) then + SelTrack := 0; end; SDLK_UP: begin - Dec(Sel); - if Sel < 0 then - Sel := High(ATrack); + Dec(SelTrack); + if SelTrack < 0 then + SelTrack := High(Tracks); end; end; end; end; -procedure TScreenEditConvert.AddLyric(Start: integer; Text: string); +procedure TScreenEditConvert.AddLyric(Start: integer; LyricType: TLyricType; Text: UTF8String); var N: integer; begin - for N := 0 to High(Note) do + // find corresponding note + N := 0; + while (N <= High(Note)) do begin if Note[N].Start = Start then - begin - // check for new sentece - if Copy(Text, 1, 1) = '\' then - Delete(Text, 1, 1); - if Copy(Text, 1, 1) = '/' then - begin - Delete(Text, 1, 1); - Note[N].NewSentence := true; - end; + Break; + Inc(N); + end; - // overwrite lyric od append - if Note[N].Lyric = '-' then - Note[N].Lyric := Text - else - Note[N].Lyric := Note[N].Lyric + Text; + // check if note was found + if (N > High(Note)) then + Exit; + + // set text + if (LyricType = ltKMIDI) then + begin + // end of paragraph + if Copy(Text, 1, 1) = '\' then + begin + Delete(Text, 1, 1); + end + // end of line + else if Copy(Text, 1, 1) = '/' then + begin + Delete(Text, 1, 1); + Note[N].NewSentence := true; + end; + end + else // SMFLyric + begin + // Line Feed -> end of paragraph + if Copy(Text, 1, 1) = #$0A then + begin + Delete(Text, 1, 1); + end + // Carriage Return -> end of line + else if Copy(Text, 1, 1) = #$0D then + begin + Delete(Text, 1, 1); + Note[N].NewSentence := true; end; end; + + // overwrite lyric or append + if Note[N].Lyric = '-' then + Note[N].Lyric := Text + else + Note[N].Lyric := Note[N].Lyric + Text; end; -procedure TScreenEditConvert.Extract; +procedure TScreenEditConvert.Extract(out Song: TSong; out Lines: TLines); + var T: integer; C: integer; N: integer; Nu: integer; - NoteTemp: TNuta; + NoteTemp: TNote; Move: integer; Max, Min: integer; + LyricType: TLyricType; + Text: UTF8String; begin // song info - Song.Title := ''; - Song.Artist := ''; - Song.Mp3 := ''; + Song := TSong.Create(); + Song.Clear(); Song.Resolution := 4; SetLength(Song.BPM, 1); Song.BPM[0].BPM := BPM*4; - SetLength(Note, 0); // extract notes - for T := 0 to High(ATrack) do + for T := 0 to High(Tracks) do begin -// if ATrack[T].Hear then -// begin - if Notes in ATrack[T].Status then + if tsNotes in Tracks[T].Status then begin - for N := 0 to High(ATrack[T].Note) do + for N := 0 to High(Tracks[T].Note) do begin - if (ATrack[T].Note[N].EventType = 9) and (ATrack[T].Note[N].Data2 > 0) then + if (Tracks[T].Note[N].EventType = MIDI_EVENTTYPE_NOTEON) and + (Tracks[T].Note[N].Data2 > 0) then begin Nu := Length(Note); SetLength(Note, Nu + 1); - Note[Nu].Start := Round(ATrack[T].Note[N].Start / Ticks); - Note[Nu].Len := Round(ATrack[T].Note[N].Len / Ticks); - Note[Nu].Tone := ATrack[T].Note[N].Data1 - 12*5; + Note[Nu].Start := Round(Tracks[T].Note[N].Start / Ticks); + Note[Nu].Len := Round(Tracks[T].Note[N].Len / Ticks); + Note[Nu].Tone := Tracks[T].Note[N].Data1 - 12*5; Note[Nu].Lyric := '-'; end; end; end; end; - // extract lyrics - for T := 0 to High(ATrack) do + // extract lyrics (and artist + title info) + for T := 0 to High(Tracks) do begin -// if ATrack[T].Hear then -// begin - if Lyrics in ATrack[T].Status then + if not (tsLyrics in Tracks[T].Status) then + Continue; + + for N := 0 to High(Tracks[T].Note) do begin - for N := 0 to High(ATrack[T].Note) do + if (Tracks[T].Note[N].Event = MIDI_EVENT_META) then begin - if (ATrack[T].Note[N].EventType = 15) then + // determine and validate lyric meta tag + if (ltKMIDI in Tracks[T].LyricType) and + (Tracks[T].Note[N].Data1 = MIDI_META_TEXT) then begin -// Log.LogStatus('<' + Track[T].Note[N].Str + '>', 'MIDI'); - AddLyric(Round(ATrack[T].Note[N].Start / Ticks), ATrack[T].Note[N].Str); + Text := Tracks[T].Note[N].Str; + + // check for meta info + if (Length(Text) > 2) and (Text[1] = '@') then + begin + case Text[2] of + 'L': Song.Language := Copy(Text, 3, Length(Text)); // language + 'T': begin // title info + if (Song.Artist = '') then + Song.Artist := Copy(Text, 3, Length(Text)) + else if (Song.Title = '') then + Song.Title := Copy(Text, 3, Length(Text)); + end; + end; + Continue; + end; + + LyricType := ltKMIDI; + end + else if (ltSMFLyric in Tracks[T].LyricType) and + (Tracks[T].Note[N].Data1 = MIDI_META_LYRICS) then + begin + LyricType := ltSMFLyric; + end + else + begin + // unknown meta event + Continue; end; + + AddLyric(Round(Tracks[T].Note[N].Start / Ticks), LyricType, Tracks[T].Note[N].Str); end; end; end; @@ -360,8 +491,12 @@ begin // copy notes SetLength(Lines.Line, 1); - Lines.Number := 1; - Lines.High := 0; + Lines.Number := 1; + Lines.High := 0; + Lines.Current := 0; + Lines.Resolution := 0; + Lines.NotesGAP := 0; + Lines.ScoreValue := 0; C := 0; N := 0; @@ -403,35 +538,37 @@ begin // create space for new note SetLength(Lines.Line[C].Note, Length(Lines.Line[C].Note)+1); + Inc(Lines.Line[C].HighNote); // initialize note Lines.Line[C].Note[N].Start := Note[Nu].Start; Lines.Line[C].Note[N].Length := Note[Nu].Len; Lines.Line[C].Note[N].Tone := Note[Nu].Tone; - Lines.Line[C].Note[N].Text := Note[Nu].Lyric; - //All Notes are Freestyle when Converted Fix: + Lines.Line[C].Note[N].Text := DecodeStringUTF8(Note[Nu].Lyric, DEFAULT_ENCODING); Lines.Line[C].Note[N].NoteType := ntNormal; Inc(N); end; end; -function TScreenEditConvert.SelectedNumber: integer; +function TScreenEditConvert.CountSelectedTracks: integer; var T: integer; // track begin Result := 0; - for T := 0 to High(ATrack) do -// if ATrack[T].Hear then -// Inc(Result); - if Notes in ATrack[T].Status then + for T := 0 to High(Tracks) do + if tsNotes in Tracks[T].Status 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); + //Log.LogStatus(IntToStr(event.event), 'MIDI'); + try + MidiOut.PutShort(event.event, event.data1, event.data2); + except + MidiFile.StopPlaying(); + end; end; {$ENDIF} @@ -442,7 +579,7 @@ 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; + //Button[High(Button)].Text[0].Size := 11; AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF')); AddButtonText(25, 5, 0, 0, 0, 'Play'); @@ -453,19 +590,7 @@ begin 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} - - ConversionFileName := GamePath + 'file.mid'; - {$IFDEF UseMIDIPort} - MidiFile := TMidiFile.Create(nil); - {$ENDIF} + fFileName := PATH_NONE; for P := 0 to 100 do begin @@ -476,96 +601,124 @@ begin end; -procedure TScreenEditConvert.onShow; +procedure TScreenEditConvert.OnShow; var T: integer; // track N: integer; // note - C: integer; // channel - CN: integer; // channel note + {$IFDEF UseMIDIPort} + MidiTrack: TMidiTrack; + MidiEvent: PMidiEvent; + {$ENDIF} + FileOpened: boolean; + KMIDITrackIndex, SMFTrackIndex: integer; begin inherited; + Interaction := 0; + {$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'); + Log.LogInfo(MidiOut.ProductName, 'MIDI'); MidiOut.Open; + MidiFile := nil; + SetLength(Tracks, 0); + + // Filename is only <> PATH_NONE if we called the OpenScreen before + fFilename := ScreenOpen.Filename; + if (fFilename = PATH_NONE) then + Exit; + ScreenOpen.Filename := PATH_NONE; - if FileExists(ConversionFileName) then + FileOpened := false; + if fFileName.Exists then begin - MidiFile.Filename := ConversionFileName; - MidiFile.ReadFile; + MidiFile := TMidiFile.Create(nil); + MidiFile.Filename := fFileName; + try + MidiFile.ReadFile; + FileOpened := true; + except + MidiFile.Free; + end; + end; - Len := 0; - Sel := 0; - BPM := MidiFile.Bpm; - Ticks := MidiFile.TicksPerQuarter / 4; + if (not FileOpened) then + begin + ScreenPopupError.ShowPopup(Language.Translate('ERROR_FILE_NOT_FOUND')); + Exit; + end; -{ 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; + Len := 0; + SelTrack := 0; + BPM := MidiFile.Bpm; + Ticks := MidiFile.TicksPerQuarter / 4; - 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;} + KMIDITrackIndex := -1; + SMFTrackIndex := -1; - SetLength(Channel, 16); - for T := 0 to 15 do - begin - Channel[T].Name := IntToStr(T+1); - SetLength(Channel[T].Note, 0); - Channel[T].Status := []; - end; + SetLength(Tracks, MidiFile.NumberOfTracks); + for T := 0 to MidiFile.NumberOfTracks-1 do + Tracks[T].LyricType := []; - for T := 0 to MidiFile.NumberOfTracks-1 do + for T := 0 to MidiFile.NumberOfTracks-1 do + begin + MidiTrack := MidiFile.GetTrack(T); + MidiTrack.OnMidiEvent := nil; + Tracks[T].Name := DecodeStringUTF8(MidiTrack.getName, DEFAULT_ENCODING); + Tracks[T].NoteType := ntNone; + Tracks[T].Status := []; + + SetLength(Tracks[T].Note, MidiTrack.getEventCount()); + for N := 0 to MidiTrack.getEventCount-1 do begin - MidiTrack := MidiFile.GetTrack(T); - MidiTrack.OnMidiEvent := MidiFile1MidiEvent; - - for N := 0 to MidiTrack.getEventCount-1 do + MidiEvent := MidiTrack.GetEvent(N); + + Tracks[T].Note[N].Start := MidiEvent.time; + Tracks[T].Note[N].Len := MidiEvent.len; + Tracks[T].Note[N].Event := MidiEvent.event; + Tracks[T].Note[N].EventType := MidiEvent.event shr 4; + Tracks[T].Note[N].Channel := MidiEvent.event and $0F; + Tracks[T].Note[N].Data1 := MidiEvent.data1; + Tracks[T].Note[N].Data2 := MidiEvent.data2; + Tracks[T].Note[N].Str := DecodeStringUTF8(MidiEvent.str, DEFAULT_ENCODING); + + if (Tracks[T].Note[N].Event = MIDI_EVENT_META) then + begin + case (Tracks[T].Note[N].Data1) of + MIDI_META_TEXT: begin + // KMIDI lyrics (uses MIDI_META_TEXT events) + if (StrLComp(PAnsiChar(Tracks[T].Note[N].Str), '@KMIDI KARAOKE FILE', 19) = 0) and + (High(Tracks) >= T+1) then + begin + // The '@KMIDI ...' mark is in the first track (mostly named 'Soft Karaoke') + // but the lyrics are in the second track (named 'Words') + Tracks[T+1].LyricType := Tracks[T+1].LyricType + [ltKMIDI]; + KMIDITrackIndex := T+1; + end; + end; + MIDI_META_LYRICS: begin + // lyrics in Standard Midi File format found (uses MIDI_META_LYRICS events) + Tracks[T].LyricType := Tracks[T].LyricType + [ltSMFLyric]; + SMFTrackIndex := T; + end; + end; + end + else if (Tracks[T].Note[N].EventType = MIDI_EVENTTYPE_NOTEON) then 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; + // notes available + Tracks[T].NoteType := ntAvail; end; - end; - ATrack := Channel; + if Tracks[T].Note[N].Start + Tracks[T].Note[N].Len > Len then + Len := Tracks[T].Note[N].Start + Tracks[T].Note[N].Len; + end; end; - Interaction := 0; + // set default lyric track. Prefer KMIDI. + if (KMIDITrackIndex > -1) then + Tracks[KMIDITrackIndex].Status := Tracks[KMIDITrackIndex].Status + [tsLyrics] + else if (SMFTrackIndex > -1) then + Tracks[SMFTrackIndex].Status := Tracks[SMFTrackIndex].Status + [tsLyrics]; {$ENDIF} end; @@ -578,41 +731,44 @@ var Y: real; Height: real; YSkip: real; + TrackName: UTF8String; begin // draw static menu inherited Draw; Y := 100; - Height := min(480, 40 * Length(ATrack)); + Height := min(480, 40 * Length(Tracks)); Bottom := Y + Height; - if Length(ATrack) = 0 then // prevent crash with uncomplete code. - begin - Log.LogDebug ('UScreenEditConvert -> TScreenEditConvert.Draw:', 'Length(ATrack) = 0'); - YSkip := 40; - end - else - YSkip := Height / Length(ATrack); + YSkip := Height / Length(Tracks); - // select - DrawQuad(10, Y + Sel*YSkip, 780, YSkip, 0.8, 0.8, 0.8); + // highlight selected track + DrawQuad(10, Y+SelTrack*YSkip, 780, YSkip, 0.8, 0.8, 0.8); - // selected - now me use Status System - for Count := 0 to High(ATrack) do - if ATrack[Count].Hear then + // track-selection info + for Count := 0 to High(Tracks) do + if Tracks[Count].Status <> [] then DrawQuad(10, Y + Count*YSkip, 50, YSkip, 0.8, 0.3, 0.3); glColor3f(0, 0, 0); - for Count := 0 to High(ATrack) do + for Count := 0 to High(Tracks) do begin - if Notes in ATrack[Count].Status then + if Tracks[Count].NoteType = ntAvail then begin + if tsNotes in Tracks[Count].Status then + glColor3f(0, 0, 0) + else + glColor3f(0.7, 0.7, 0.7); SetFontPos(25, Y + Count*YSkip + 10); SetFontSize(15); glPrint('N'); end; - if Lyrics in ATrack[Count].Status then + if Tracks[Count].LyricType <> [] then begin + if tsLyrics in Tracks[Count].Status then + glColor3f(0, 0, 0) + else + glColor3f(0.7, 0.7, 0.7); SetFontPos(40, Y + Count*YSkip + 10); SetFontSize(15); glPrint('L'); @@ -623,51 +779,48 @@ begin DrawLine( 60, Y, 60, Bottom, 0, 0, 0); DrawLine(790, Y, 790, Bottom, 0, 0, 0); - for Count := 0 to Length(ATrack) do + for Count := 0 to Length(Tracks) do DrawLine(10, Y + Count*YSkip, 790, Y + Count*YSkip, 0, 0, 0); - for Count := 0 to High(ATrack) do + for Count := 0 to High(Tracks) do begin - SetFontPos(11, Y + 10 + Count*YSkip); + SetFontPos(65, Y + Count*YSkip); SetFontSize(15); - glPrint(ATrack[Count].Name); + glPrint(Tracks[Count].Name); end; - for Count := 0 to High(ATrack) do - for Count2 := 0 to High(ATrack[Count].Note) do + for Count := 0 to High(Tracks) do + begin + for Count2 := 0 to High(Tracks[Count].Note) do begin - if ATrack[Count].Note[Count2].EventType = 9 then - DrawQuad(60 + ATrack[Count].Note[Count2].Start/Len*725, - Y + (Count+1)*YSkip - ATrack[Count].Note[Count2].Data1*35/127, - 3, - 3, - ColR[Count], - ColG[Count], - ColB[Count]); - if ATrack[Count].Note[Count2].EventType = 15 then - DrawLine(60 + ATrack[Count].Note[Count2].Start/Len*725, - Y + 0.75*YSkip + Count*YSkip, - 60 + ATrack[Count].Note[Count2].Start/Len*725, - Y + YSkip + Count*YSkip, - ColR[Count], - ColG[Count], - ColB[Count]); + if Tracks[Count].Note[Count2].EventType = MIDI_EVENTTYPE_NOTEON then + DrawQuad(60 + Tracks[Count].Note[Count2].Start/Len * 725, + Y + (Count+1)*YSkip - Tracks[Count].Note[Count2].Data1*35/127, + 3, 3, + ColR[Count], ColG[Count], ColB[Count]); + if Tracks[Count].Note[Count2].EventType = 15 then + DrawLine(60 + Tracks[Count].Note[Count2].Start/Len * 725, Y + 0.75 * YSkip + Count*YSkip, + 60 + Tracks[Count].Note[Count2].Start/Len * 725, Y + YSkip + Count*YSkip, + ColR[Count], ColG[Count], ColB[Count]); end; + end; // playing line {$IFDEF UseMIDIPort} - X := 60 + MidiFile.GetCurrentTime/MidiFile.GetTrackLength*730; + if (MidiFile <> nil) then + X := 60 + MidiFile.GetCurrentTime/MidiFile.GetTrackLength*730; {$ENDIF} DrawLine(X, Y, X, Bottom, 0.3, 0.3, 0.3); Result := true; end; -procedure TScreenEditConvert.onHide; +procedure TScreenEditConvert.OnHide; begin {$IFDEF UseMIDIPort} + FreeAndNil(MidiFile); MidiOut.Close; - MidiOut.Free; + FreeAndNil(MidiOut); {$ENDIF} end; diff --git a/src/screens/UScreenEditHeader.pas b/src/screens/UScreenEditHeader.pas index ad0fc40a..c581215b 100644 --- a/src/screens/UScreenEditHeader.pas +++ b/src/screens/UScreenEditHeader.pas @@ -38,6 +38,7 @@ uses SDL, USongs, USong, + UPath, UThemes; type @@ -72,8 +73,8 @@ type procedure SetRoundButtons; constructor Create; override; - procedure onShow; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; + procedure OnShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; { function Draw: boolean; override; procedure Finish;} end; @@ -86,17 +87,18 @@ uses SysUtils, UFiles, USkins, - UTexture; + UTexture, + UUnicodeUtils; -function TScreenEditHeader.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenEditHeader.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; var T: integer; begin Result := true; if (PressedDown) then // Key Down begin // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -105,10 +107,10 @@ begin // check special keys case PressedKey of - SDLK_ESCAPE : + SDLK_ESCAPE: begin -// Music.PlayBack; -// FadeTo(@MainScreen); + //Music.PlayBack; + //FadeTo(@MainScreen); Result := false; end; @@ -116,7 +118,7 @@ begin begin if Interaction = 1 then begin -// Save; + //Save; end; end; @@ -159,19 +161,19 @@ begin T := Interaction - 2 + TextTitle; if (Interaction >= 2) and (Interaction <= 13) and (Length(Text[T].Text) >= 1) then begin - Text[T].DeleteLastL; + Text[T].DeleteLastLetter; SetRoundButtons; end; end; end; case CharCode of - #32..#255: + 32..255: begin if (Interaction >= 2) and (Interaction <= 13) then begin Text[Interaction - 2 + TextTitle].Text := - Text[Interaction - 2 + TextTitle].Text + CharCode; + Text[Interaction - 2 + TextTitle].Text + UCS4ToUTF8String(CharCode); SetRoundButtons; end; end; @@ -223,18 +225,18 @@ begin TextGAP := AddText(340, 110 + 13*30, 0, 30, 0, 0, 0, ''); TextBPM := AddText(340, 110 + 14*30, 0, 30, 0, 0, 0, ''); - StaticTitle := AddStatic(130, 115 + 0*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticArtist := AddStatic(130, 115 + 1*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticMp3 := AddStatic(130, 115 + 2*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticBackground := AddStatic(130, 115 + 4*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticVideo := AddStatic(130, 115 + 5*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticVideoGAP := AddStatic(130, 115 + 6*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticRelative := AddStatic(130, 115 + 8*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticResolution := AddStatic(130, 115 + 9*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticNotesGAP := AddStatic(130, 115 + 10*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticStart := AddStatic(130, 115 + 12*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticGAP := AddStatic(130, 115 + 13*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); - StaticBPM := AddStatic(130, 115 + 14*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticTitle := AddStatic(130, 115 + 0*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticArtist := AddStatic(130, 115 + 1*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticMp3 := AddStatic(130, 115 + 2*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticBackground := AddStatic(130, 115 + 4*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticVideo := AddStatic(130, 115 + 5*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticVideoGAP := AddStatic(130, 115 + 6*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticRelative := AddStatic(130, 115 + 8*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticResolution := AddStatic(130, 115 + 9*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticNotesGAP := AddStatic(130, 115 + 10*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticStart := AddStatic(130, 115 + 12*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticGAP := AddStatic(130, 115 + 13*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); + StaticBPM := AddStatic(130, 115 + 14*30, 20, 20, 1, 1, 1, Path('RoundButton'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); AddInteraction(iText, TextTitle); AddInteraction(iText, TextArtist); @@ -250,7 +252,7 @@ begin AddInteraction(iText, TextBPM); end; -procedure TScreenEditHeader.onShow; +procedure TScreenEditHeader.OnShow; begin inherited; diff --git a/src/screens/UScreenEditSub.pas b/src/screens/UScreenEditSub.pas index 3e1f3c1c..00e62c16 100644 --- a/src/screens/UScreenEditSub.pas +++ b/src/screens/UScreenEditSub.pas @@ -116,11 +116,11 @@ type Tex_Background: TTexture; FadeOut: boolean; constructor Create; override; - procedure onShow; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - function ParseInputEditText(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; + procedure OnShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + function ParseInputEditText(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; function Draw: boolean; override; - procedure onHide; override; + procedure OnHide; override; end; implementation @@ -130,14 +130,44 @@ uses UDraw, UNote, USkins, - ULanguage; + ULanguage, + UTextEncoding, + UUnicodeUtils, + UPath; + + +procedure OnSaveEncodingError(Value: boolean; Data: Pointer); +var + SResult: TSaveSongResult; + FilePath: IPath; + Success: boolean; +begin + Success := false; + if (Value) then + begin + CurrentSong.Encoding := encUTF8; + FilePath := CurrentSong.Path.Append(CurrentSong.FileName); + // create backup file + FilePath.CopyFile(Path(FilePath.ToUTF8 + '.ansi.bak'), false); + // store in UTF-8 encoding + SResult := SaveSong(CurrentSong, Lines[0], FilePath, + boolean(Data)); + Success := (SResult = ssrOK); + end; + + if (Success) then + ScreenPopupInfo.ShowPopup(Language.Translate('INFO_FILE_SAVED')) + else + ScreenPopupError.ShowPopup(Language.Translate('ERROR_SAVE_FILE_FAILED')); +end; // Method for input parsing. If false is returned, GetNextWindow // should be checked to know the next window to load; -function TScreenEditSub.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenEditSub.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; var SDL_ModState: word; R: real; + SResult: TSaveSongResult; begin Result := true; @@ -152,40 +182,47 @@ begin + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS}); if (PressedDown) then // Key Down - begin // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + begin + // check normal keys + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; end; - 'S': + Ord('S'): begin // Save Song - if SDL_ModState = KMOD_LSHIFT then - SaveSong(CurrentSong, Lines[0], CurrentSong.Path + CurrentSong.FileName, true) + SResult := SaveSong(CurrentSong, Lines[0], CurrentSong.Path.Append(CurrentSong.FileName), + (SDL_ModState = KMOD_LSHIFT)); + if (SResult = ssrOK) then + begin + ScreenPopupInfo.ShowPopup(Language.Translate('INFO_FILE_SAVED')); + end + else if (SResult = ssrEncodingError) then + begin + ScreenPopupCheck.ShowPopup(Language.Translate('ENCODING_ERROR_ASK_FOR_UTF8'), OnSaveEncodingError, + Pointer(SDL_ModState = KMOD_LSHIFT), true); + end else - SaveSong(CurrentSong, Lines[0], CurrentSong.Path + CurrentSong.FileName, false); - - {if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL + KMOD_LALT then - // Save Song - SaveSongDebug(CurrentSong, Lines[0], 'C:\song.asm', false);} - + begin + ScreenPopupError.ShowPopup(Language.Translate('ERROR_SAVE_FILE_FAILED')); + end; Exit; end; - 'D': + Ord('D'): begin // Divide lengths by 2 DivideBPM; Exit; end; - 'M': + Ord('M'): begin // Multiply lengths by 2 MultiplyBPM; Exit; end; - 'C': + Ord('C'): begin // Capitalize letter at the beginning of line if SDL_ModState = 0 then @@ -201,7 +238,7 @@ begin Exit; end; - 'V': + Ord('V'): begin // Paste text if SDL_ModState = KMOD_LCTRL then @@ -217,13 +254,13 @@ begin CopySentence(CopySrc, Lines[0].Current); end; end; - 'T': + Ord('T'): begin // Fixes timings between sentences FixTimings; Exit; end; - 'P': + Ord('P'): begin if SDL_ModState = 0 then begin @@ -269,8 +306,8 @@ begin Exit; end; - // Golden Note Patch - 'G': + // Golden Note + Ord('G'): begin if (Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType = ntGolden) then Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntNormal @@ -280,8 +317,8 @@ begin Exit; end; - // Freestyle Note Patch - 'F': + // Freestyle Note + Ord('F'): begin if (Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType = ntFreestyle) then Lines[0].Line[Lines[0].Current].Note[CurrentNote].NoteType := ntNormal @@ -580,10 +617,11 @@ begin // skip to next sentence if SDL_ModState = 0 then - begin {$IFDEF UseMIDIPort} + begin + {$IFDEF UseMIDIPort} MidiOut.PutShort($81, Lines[0].Line[Lines[0].Current].Note[MidiLastNote].Tone + 60, 127); PlaySentenceMidi := false; - {$endif} + {$ENDIF} Lines[0].Line[Lines[0].Current].Note[CurrentNote].Color := 0; Inc(Lines[0].Current); @@ -642,7 +680,7 @@ begin end; // if end; -function TScreenEditSub.ParseInputEditText(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenEditSub.ParseInputEditText(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; var SDL_ModState: word; begin @@ -653,7 +691,16 @@ begin + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS}); if (PressedDown) then - begin // Key Down + begin + // check normal keys + if (IsPrintableChar(CharCode)) then + begin + Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text := + Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text + UCS4ToUTF8String(CharCode); + Exit; + end; + + // check special keys case PressedKey of SDLK_ESCAPE: @@ -665,15 +712,10 @@ begin // Exit Text Edit Mode TextEditMode := false; end; - SDLK_0..SDLK_9, SDLK_A..SDLK_Z, SDLK_SPACE, SDLK_MINUS, SDLK_EXCLAIM, SDLK_COMMA, SDLK_SLASH, SDLK_ASTERISK, SDLK_QUESTION, SDLK_QUOTE, SDLK_QUOTEDBL: - begin - Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text := - Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text + CharCode; - end; SDLK_BACKSPACE: begin - Delete(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text, - Length(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text), 1); + UTF8Delete(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text, + LengthUTF8(Lines[0].Line[Lines[0].Current].Note[CurrentNote].Text), 1); end; SDLK_RIGHT: begin @@ -758,9 +800,11 @@ var S: string; begin // temporary -{ for C := 0 to Lines[0].High do + { + for C := 0 to Lines[0].High do for N := 0 to Lines[0].Line[C].HighNut do - Lines[0].Line[C].Note[N].Text := AnsiLowerCase(Lines[0].Line[C].Note[N].Text);} + Lines[0].Line[C].Note[N].Text := UTF8LowerCase(Lines[0].Line[C].Note[N].Text); + } for C := 0 to Lines[0].High do begin @@ -1085,14 +1129,16 @@ var N: integer; NHigh: integer; begin -{ C := Lines[0].Current; + { + C := Lines[0].Current; for N := Lines[0].Line[C].HighNut downto 1 do begin Lines[0].Line[C].Note[N].Text := Lines[0].Line[C].Note[N-1].Text; end; // for - Lines[0].Line[C].Note[0].Text := '- ';} + Lines[0].Line[C].Note[0].Text := '- '; + } C := Lines[0].Current; NHigh := Lines[0].Line[C].HighNote; @@ -1233,21 +1279,24 @@ begin end; -procedure TScreenEditSub.onShow; +procedure TScreenEditSub.OnShow; +var + FileExt: IPath; begin inherited; - Log.LogStatus('Initializing', 'TEditScreen.onShow'); + Log.LogStatus('Initializing', 'TEditScreen.OnShow'); Lyric := TEditorLyrics.Create; ResetSingTemp; try - //Check if File is XML - if copy(CurrentSong.FileName,length(CurrentSong.FileName)-3,4) = '.xml' then - Error := not CurrentSong.LoadXMLSong() - else - Error := not CurrentSong.LoadSong(); + //Check if File is XML + FileExt := CurrentSong.FileName.GetExtension; + if FileExt.ToUTF8 = '.xml' then + Error := not CurrentSong.LoadXMLSong() + else + Error := not CurrentSong.LoadSong(); except Error := true; end; @@ -1269,12 +1318,12 @@ begin {$ENDIF} Text[TextTitle].Text := CurrentSong.Title; Text[TextArtist].Text := CurrentSong.Artist; - Text[TextMp3].Text := CurrentSong.Mp3; + Text[TextMp3].Text := CurrentSong.Mp3.ToUTF8; Lines[0].Current := 0; CurrentNote := 0; Lines[0].Line[0].Note[0].Color := 1; - AudioPlayback.Open(CurrentSong.Path + CurrentSong.Mp3); + AudioPlayback.Open(CurrentSong.Path.Append(CurrentSong.Mp3)); //Set Down Music Volume for Better hearability of Midi Sounds //Music.SetVolume(0.4); @@ -1412,7 +1461,7 @@ begin Result := true; end; -procedure TScreenEditSub.onHide; +procedure TScreenEditSub.OnHide; begin {$IFDEF UseMIDIPort} MidiOut.Close; diff --git a/src/screens/UScreenLevel.pas b/src/screens/UScreenLevel.pas index b41a8535..4d7d8b5e 100644 --- a/src/screens/UScreenLevel.pas +++ b/src/screens/UScreenLevel.pas @@ -46,8 +46,8 @@ type TScreenLevel = class(TMenu) public constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure SetAnimationProgress(Progress: real); override; end; @@ -58,16 +58,17 @@ uses UMain, UIni, USong, - UTexture; + UTexture, + UUnicodeUtils; -function TScreenLevel.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenLevel.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -119,7 +120,7 @@ begin Interaction := 0; end; -procedure TScreenLevel.onShow; +procedure TScreenLevel.OnShow; begin inherited; diff --git a/src/screens/UScreenLoading.pas b/src/screens/UScreenLoading.pas index ea639ba3..e368f181 100644 --- a/src/screens/UScreenLoading.pas +++ b/src/screens/UScreenLoading.pas @@ -43,10 +43,11 @@ uses type TScreenLoading = class(TMenu) public - Fadeout: boolean; + Fadeout: boolean; + constructor Create; override; - procedure onShow; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; + procedure OnShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; end; implementation @@ -55,7 +56,7 @@ uses UGraphic, UTime; -function TScreenLoading.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenLoading.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; end; @@ -69,7 +70,7 @@ begin Fadeout := false; end; -procedure TScreenLoading.onShow; +procedure TScreenLoading.OnShow; begin inherited; end; diff --git a/src/screens/UScreenMain.pas b/src/screens/UScreenMain.pas index a4e6009f..7237eb80 100644 --- a/src/screens/UScreenMain.pas +++ b/src/screens/UScreenMain.pas @@ -49,9 +49,9 @@ type TextDescriptionLong: integer; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: widechar; + function ParseInput(PressedKey: Cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; - procedure onShow; override; + procedure OnShow; override; procedure SetInteraction(Num: integer); override; procedure SetAnimationProgress(Progress: real); override; end; @@ -69,9 +69,10 @@ uses UParty, UDLLManager, UScreenCredits, - USkins; + USkins, + UUnicodeUtils; -function TScreenMain.ParseInput(PressedKey: cardinal; CharCode: widechar; +function TScreenMain.ParseInput(PressedKey: Cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; var SDL_ModState: word; @@ -84,22 +85,19 @@ begin if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': - begin + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; end; - 'C': - begin + Ord('C'): begin if (SDL_ModState = KMOD_LALT) then begin FadeTo(@ScreenCredits, SoundLib.Start); Exit; end; end; - 'M': - begin + Ord('M'): begin if (Ini.Players >= 1) and (Length(DLLMan.Plugins) >= 1) then begin FadeTo(@ScreenPartyOptions, SoundLib.Start); @@ -107,14 +105,12 @@ begin end; end; - 'S': - begin + Ord('S'): begin FadeTo(@ScreenStatMain, SoundLib.Start); Exit; end; - 'E': - begin + Ord('E'): begin FadeTo(@ScreenEdit, SoundLib.Start); Exit; end; @@ -172,7 +168,11 @@ begin //Editor if Interaction = 3 then begin + {$IFDEF UseMIDIPort} FadeTo(@ScreenEdit, SoundLib.Start); + {$ELSE} + ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_EDITOR')); + {$ENDIF} end; //Options @@ -232,7 +232,7 @@ begin Interaction := 0; end; -procedure TScreenMain.onShow; +procedure TScreenMain.OnShow; begin inherited; diff --git a/src/screens/UScreenName.pas b/src/screens/UScreenName.pas index d13db170..42af50d7 100644 --- a/src/screens/UScreenName.pas +++ b/src/screens/UScreenName.pas @@ -47,8 +47,8 @@ type public Goto_SingScreen: boolean; //If true then next Screen in SingScreen constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure SetAnimationProgress(Progress: real); override; end; @@ -59,9 +59,11 @@ uses UGraphic, UIni, UNote, - UTexture; + UTexture, + UUnicodeUtils; -function TScreenName.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; + +function TScreenName.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; var I: integer; SDL_ModState: word; @@ -74,10 +76,10 @@ begin + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT); // check normal keys - if (IsAlphaNumericChar(CharCode) or - {(CharCode in [' ','-','_','!',',','<','/','*','?','''','"']))} IsPunctuationChar(CharCode)) then + if (IsPrintableChar(CharCode)) then begin - Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode; + Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + + UCS4ToUTF8String(CharCode); Exit; end; @@ -195,7 +197,7 @@ begin SDLK_BACKSPACE: begin - Button[Interaction].Text[0].DeleteLastL; + Button[Interaction].Text[0].DeleteLastLetter(); end; SDLK_ESCAPE : @@ -248,7 +250,7 @@ begin Interaction := 0; end; -procedure TScreenName.onShow; +procedure TScreenName.OnShow; var I: integer; begin diff --git a/src/screens/UScreenOpen.pas b/src/screens/UScreenOpen.pas index a854e81b..70b883c4 100644 --- a/src/screens/UScreenOpen.pas +++ b/src/screens/UScreenOpen.pas @@ -34,10 +34,13 @@ interface {$I switches.inc} uses + Math, + SysUtils, + gl, + SDL, + UPath, UMenu, UMusic, - SDL, - SysUtils, UFiles, UTime, USongs, @@ -46,26 +49,31 @@ uses UTexture, UMenuText, ULyrics, - Math, - gl, UThemes; type TScreenOpen = class(TMenu) private - TextF: array[0..1] of integer; - TextN: integer; - public - Tex_Background: TTexture; - FadeOut: boolean; - Path: string; - BackScreen: pointer; + //fTextF: array[0..1] of integer; + fTextN: integer; // text-box ID of filename + fFilename: IPath; + fBackScreen: PMenu; + procedure AddBox(X, Y, W, H: real); + public constructor Create; override; - procedure onShow; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; -// function Draw: boolean; override; -// procedure Finish; + procedure OnShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + + {** + * Set by the caller to provide a default filename. + * Set to the selected filename after calling this screen or to PATH_NONE + * if the screen was aborted. + * TODO: maybe pass this value with a callback OnValueChanged() + *} + property Filename: IPath READ fFilename WRITE fFilename; + {** The screen that is shown after this screen is closed (set by the caller) *} + property BackScreen: PMenu READ fBackScreen WRITE fBackScreen; end; implementation @@ -75,45 +83,41 @@ uses UDraw, UMain, UScreenEditConvert, - USkins; + USkins, + UUnicodeUtils; -function TScreenOpen.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenOpen.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then // Key Down begin // check normal keys - case CharCode of - '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '.', ':', '\': - begin - if Interaction = 0 then - begin - Text[TextN].Text := Text[TextN].Text + CharCode; - end; - end; + if (IsPrintableChar(CharCode)) then + begin + if (Interaction = 0) then + begin + Text[fTextN].Text := Text[fTextN].Text + UCS4ToUTF8String(CharCode); + Exit; + end; end; // check special keys case PressedKey of - SDLK_Q: - begin - Result := false; - end; - 8: // del + SDLK_BACKSPACE: // del begin if Interaction = 0 then begin - Text[TextN].DeleteLastL; + Text[fTextN].DeleteLastLetter; end; end; SDLK_ESCAPE: begin //Empty Filename and go to last Screen - ConversionFileName := ''; + fFileName := PATH_NONE; AudioPlayback.PlaySound(SoundLib.Back); - FadeTo(BackScreen); + FadeTo(fBackScreen); end; SDLK_RETURN: @@ -121,16 +125,16 @@ begin if (Interaction = 2) then begin //Update Filename and go to last Screen - ConversionFileName := Text[TextN].Text; + fFileName := Path(Text[fTextN].Text); AudioPlayback.PlaySound(SoundLib.Back); - FadeTo(BackScreen); + FadeTo(fBackScreen); end else if (Interaction = 1) then begin //Empty Filename and go to last Screen - ConversionFileName := ''; + fFileName := PATH_NONE; AudioPlayback.PlaySound(SoundLib.Back); - FadeTo(BackScreen); + FadeTo(fBackScreen); end; end; @@ -165,21 +169,25 @@ constructor TScreenOpen.Create; begin inherited Create; + fFilename := PATH_NONE; + // line -{ AddStatic(20, 10, 80, 30, 0, 0, 0, 'MainBar', 'JPG', TEXTURE_TYPE_COLORIZED); + { + AddStatic(20, 10, 80, 30, 0, 0, 0, 'MainBar', 'JPG', TEXTURE_TYPE_COLORIZED); AddText(35, 17, 1, 18, 1, 1, 1, 'line'); - TextSentence := AddText(120, 14, 1, 24, 0, 0, 0, '0 / 0');} + TextSentence := AddText(120, 14, 1, 24, 0, 0, 0, '0 / 0'); + } // file list -// AddBox(400, 100, 350, 450); + //AddBox(400, 100, 350, 450); -// TextF[0] := AddText(430, 155, 0, 24, 0, 0, 0, 'a'); -// TextF[1] := AddText(430, 180, 0, 24, 0, 0, 0, 'a'); + //TextF[0] := AddText(430, 155, 0, 24, 0, 0, 0, 'a'); + //TextF[1] := AddText(430, 180, 0, 24, 0, 0, 0, 'a'); // file name AddBox(20, 540, 500, 40); - TextN := AddText(50, 548, 0, 24, 0, 0, 0, ConversionFileName); - AddInteraction(iText, TextN); + fTextN := AddText(50, 548, 0, 24, 0, 0, 0, fFileName.ToUTF8); + AddInteraction(iText, fTextN); // buttons {AddButton(540, 540, 100, 40, Skin.SkinPath + Skin.ButtonF); @@ -196,11 +204,12 @@ begin end; -procedure TScreenOpen.onShow; +procedure TScreenOpen.OnShow; begin inherited; Interaction := 0; + Text[fTextN].Text := fFilename.ToUTF8(); end; (* diff --git a/src/screens/UScreenOptions.pas b/src/screens/UScreenOptions.pas index a6486075..3a046400 100644 --- a/src/screens/UScreenOptions.pas +++ b/src/screens/UScreenOptions.pas @@ -34,9 +34,9 @@ interface {$I switches.inc} uses - UMenu, SDL, SysUtils, + UMenu, UDisplay, UMusic, UFiles, @@ -48,8 +48,8 @@ type public TextDescription: integer; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure InteractNext; override; procedure InteractPrev; override; procedure InteractNextRow; override; @@ -60,16 +60,17 @@ type implementation uses - UGraphic; + UGraphic, + UUnicodeUtils; -function TScreenOptions.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenOptions.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -189,7 +190,7 @@ begin Interaction := 0; end; -procedure TScreenOptions.onShow; +procedure TScreenOptions.OnShow; begin inherited; end; diff --git a/src/screens/UScreenOptionsAdvanced.pas b/src/screens/UScreenOptionsAdvanced.pas index 0fb8153c..7116ad40 100644 --- a/src/screens/UScreenOptionsAdvanced.pas +++ b/src/screens/UScreenOptionsAdvanced.pas @@ -34,8 +34,8 @@ interface {$I switches.inc} uses - UMenu, SDL, + UMenu, UDisplay, UMusic, UFiles, @@ -46,24 +46,25 @@ type TScreenOptionsAdvanced = class(TMenu) public constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; end; implementation uses UGraphic, + UUnicodeUtils, SysUtils; -function TScreenOptionsAdvanced.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenOptionsAdvanced.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -160,7 +161,7 @@ begin Interaction := 0; end; -procedure TScreenOptionsAdvanced.onShow; +procedure TScreenOptionsAdvanced.OnShow; begin inherited; diff --git a/src/screens/UScreenOptionsGame.pas b/src/screens/UScreenOptionsGame.pas index 0c152c41..caeaad6e 100644 --- a/src/screens/UScreenOptionsGame.pas +++ b/src/screens/UScreenOptionsGame.pas @@ -35,40 +35,39 @@ interface uses SDL, + UMenu, UDisplay, + UMusic, UFiles, UIni, - UMenu, - UMusic, - USongs, - UThemes; + UThemes, + USongs; type TScreenOptionsGame = class(TMenu) public old_Tabs, old_Sorting: integer; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure RefreshSongs; end; implementation uses - SysUtils, - UGraphic; + UGraphic, + UUnicodeUtils, + SysUtils; -function TScreenOptionsGame.ParseInput(PressedKey: cardinal; - CharCode: WideChar; - PressedDown: boolean): boolean; +function TScreenOptionsGame.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if PressedDown then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -166,7 +165,7 @@ begin ScreenSong.Refresh; end; -procedure TScreenOptionsGame.onShow; +procedure TScreenOptionsGame.OnShow; begin inherited; diff --git a/src/screens/UScreenOptionsGraphics.pas b/src/screens/UScreenOptionsGraphics.pas index ba1465b2..8ca13f09 100644 --- a/src/screens/UScreenOptionsGraphics.pas +++ b/src/screens/UScreenOptionsGraphics.pas @@ -46,8 +46,8 @@ type TScreenOptionsGraphics = class(TMenu) public constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; end; implementation @@ -55,17 +55,17 @@ implementation uses UGraphic, UMain, - SysUtils, - TypInfo; + UUnicodeUtils, + SysUtils; -function TScreenOptionsGraphics.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenOptionsGraphics.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -162,7 +162,7 @@ begin end; -procedure TScreenOptionsGraphics.onShow; +procedure TScreenOptionsGraphics.OnShow; begin inherited; diff --git a/src/screens/UScreenOptionsLyrics.pas b/src/screens/UScreenOptionsLyrics.pas index 035b0089..0ef4e2a6 100644 --- a/src/screens/UScreenOptionsLyrics.pas +++ b/src/screens/UScreenOptionsLyrics.pas @@ -46,24 +46,25 @@ type TScreenOptionsLyrics = class(TMenu) public constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; end; implementation uses UGraphic, + UUnicodeUtils, SysUtils; -function TScreenOptionsLyrics.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenOptionsLyrics.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -137,7 +138,7 @@ begin end; -procedure TScreenOptionsLyrics.onShow; +procedure TScreenOptionsLyrics.OnShow; begin inherited; diff --git a/src/screens/UScreenOptionsRecord.pas b/src/screens/UScreenOptionsRecord.pas index 7eb2ced7..828c20f6 100644 --- a/src/screens/UScreenOptionsRecord.pas +++ b/src/screens/UScreenOptionsRecord.pas @@ -61,8 +61,8 @@ type PreviewDeviceIndex: integer; // string arrays for select-slide options - InputSourceNames: array of string; - InputDeviceNames: array of string; + InputSourceNames: array of UTF8String; + InputDeviceNames: array of UTF8String; // dynamic generated themes for channel select-sliders SelectSlideChannelTheme: array of TThemeSelectSlide; @@ -95,9 +95,9 @@ type public constructor Create; override; function Draw: boolean; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; - procedure onHide; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; + procedure OnHide; override; end; const @@ -126,33 +126,34 @@ uses UFiles, UDisplay, UIni, + UUnicodeUtils, ULog; -function TScreenOptionsRecord.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenOptionsRecord.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; end; - '+': + Ord('+'): begin // FIXME: add a nice volume-slider instead // or at least provide visualization and acceleration if the user holds the key pressed. ChangeVolume(0.02); end; - '-': + Ord('-'): begin // FIXME: add a nice volume-slider instead // or at least provide visualization and acceleration if the user holds the key pressed. ChangeVolume(-0.02); end; - 'T': + Ord('T'): begin if ((SDL_GetModState() and KMOD_SHIFT) <> 0) then Ini.ThresholdIndex := (Ini.ThresholdIndex + Length(IThresholdVals) - 1) mod Length(IThresholdVals) @@ -418,7 +419,7 @@ begin NextVolumePollTime := 0; end; -procedure TScreenOptionsRecord.onShow; +procedure TScreenOptionsRecord.OnShow; var ChannelIndex: integer; begin @@ -436,7 +437,7 @@ begin StartPreview(); end; -procedure TScreenOptionsRecord.onHide; +procedure TScreenOptionsRecord.OnHide; var ChannelIndex: integer; begin diff --git a/src/screens/UScreenOptionsSound.pas b/src/screens/UScreenOptionsSound.pas index aa87ceb4..7556dceb 100644 --- a/src/screens/UScreenOptionsSound.pas +++ b/src/screens/UScreenOptionsSound.pas @@ -34,8 +34,8 @@ interface {$I switches.inc} uses - UMenu, SDL, + UMenu, UDisplay, UMusic, UFiles, @@ -46,26 +46,27 @@ type TScreenOptionsSound = class(TMenu) public constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: widechar; + function ParseInput(PressedKey: Cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; - procedure onShow; override; + procedure OnShow; override; end; implementation uses UGraphic, + UUnicodeUtils, SysUtils; function TScreenOptionsSound.ParseInput(PressedKey: cardinal; - CharCode: widechar; PressedDown: boolean): boolean; + CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -177,7 +178,7 @@ begin Interaction := 0; end; -procedure TScreenOptionsSound.onShow; +procedure TScreenOptionsSound.OnShow; begin inherited; Interaction := 0; diff --git a/src/screens/UScreenOptionsThemes.pas b/src/screens/UScreenOptionsThemes.pas index 1e7407f1..dca581a2 100644 --- a/src/screens/UScreenOptionsThemes.pas +++ b/src/screens/UScreenOptionsThemes.pas @@ -49,8 +49,8 @@ type public SkinSelect: integer; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure InteractInc; override; procedure InteractDec; override; end; @@ -61,17 +61,18 @@ uses SysUtils, UGraphic, UMain, - UPath, + UPathUtils, + UUnicodeUtils, USkins; -function TScreenOptionsThemes.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenOptionsThemes.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -135,7 +136,7 @@ begin if (SelInteraction = 0) then begin Skin.OnThemeChange; - UpdateSelectSlideOptions (Theme.OptionsThemes.SelectSkin, SkinSelect, ISkin, Ini.SkinNo); + UpdateSelectSlideOptions(Theme.OptionsThemes.SelectSkin, SkinSelect, ISkin, Ini.SkinNo); end; ReloadTheme(); @@ -178,7 +179,7 @@ begin AddButtonText(14, 20, Theme.Options.Description[7]); end; -procedure TScreenOptionsThemes.onShow; +procedure TScreenOptionsThemes.OnShow; begin inherited; @@ -187,7 +188,7 @@ end; procedure TScreenOptionsThemes.ReloadTheme; begin - Theme.LoadTheme(ThemePath + ITheme[Ini.Theme] + '.ini', Ini.Color); + Theme.LoadTheme(ThemePath.Append(ITheme[Ini.Theme] + '.ini'), Ini.Color); ScreenOptionsThemes := TScreenOptionsThemes.create(); ScreenOptionsThemes.onshow; diff --git a/src/screens/UScreenPartyNewRound.pas b/src/screens/UScreenPartyNewRound.pas index 03a72fa9..c4295502 100644 --- a/src/screens/UScreenPartyNewRound.pas +++ b/src/screens/UScreenPartyNewRound.pas @@ -34,12 +34,12 @@ interface {$I switches.inc} uses - UMenu, SDL, + SysUtils, + UMenu, UDisplay, UMusic, UFiles, - SysUtils, UThemes; type @@ -99,8 +99,8 @@ type constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure SetAnimationProgress(Progress: real); override; end; @@ -115,16 +115,17 @@ uses UDLLManager, ULanguage, USong, - ULog; + ULog, + UUnicodeUtils; -function TScreenPartyNewRound.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenPartyNewRound.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -215,12 +216,12 @@ begin LoadFromTheme(Theme.PartyNewRound); end; -procedure TScreenPartyNewRound.onShow; +procedure TScreenPartyNewRound.OnShow; var I: integer; - function GetTeamPlayers(const Num: byte): string; + function GetTeamPlayers(const Num: byte): UTF8String; var - Players: array of string; + Players: array of UTF8String; J: byte; begin if (Num-1 >= PartySession.Teams.NumTeams) then @@ -229,7 +230,7 @@ var //Create Players array SetLength(Players, PartySession.Teams.TeamInfo[Num-1].NumPlayers); for J := 0 to PartySession.Teams.TeamInfo[Num-1].NumPlayers-1 do - Players[J] := string(PartySession.Teams.TeamInfo[Num-1].PlayerInfo[J].Name); + Players[J] := UTF8String(PartySession.Teams.TeamInfo[Num-1].PlayerInfo[J].Name); //Implode and Return Result := Language.Implode(Players); @@ -364,7 +365,7 @@ begin if (PartySession.Teams.NumTeams >= 1) then begin Text[TextScoreTeam1].Text := InttoStr(PartySession.Teams.TeamInfo[0].Score); - Text[TextNameTeam1].Text := string(PartySession.Teams.TeamInfo[0].Name); + Text[TextNameTeam1].Text := UTF8String(PartySession.Teams.TeamInfo[0].Name); Text[TextTeam1Players].Text := GetTeamPlayers(1); Text[TextScoreTeam1].Visible := true; @@ -385,7 +386,7 @@ begin if (PartySession.Teams.NumTeams >= 2) then begin Text[TextScoreTeam2].Text := InttoStr(PartySession.Teams.TeamInfo[1].Score); - Text[TextNameTeam2].Text := string(PartySession.Teams.TeamInfo[1].Name); + Text[TextNameTeam2].Text := UTF8String(PartySession.Teams.TeamInfo[1].Name); Text[TextTeam2Players].Text := GetTeamPlayers(2); Text[TextScoreTeam2].Visible := true; @@ -406,7 +407,7 @@ begin if (PartySession.Teams.NumTeams >= 3) then begin Text[TextScoreTeam3].Text := InttoStr(PartySession.Teams.TeamInfo[2].Score); - Text[TextNameTeam3].Text := string(PartySession.Teams.TeamInfo[2].Name); + Text[TextNameTeam3].Text := UTF8String(PartySession.Teams.TeamInfo[2].Name); Text[TextTeam3Players].Text := GetTeamPlayers(3); Text[TextScoreTeam3].Visible := true; diff --git a/src/screens/UScreenPartyOptions.pas b/src/screens/UScreenPartyOptions.pas index 5f7f1d9e..2deffda6 100644 --- a/src/screens/UScreenPartyOptions.pas +++ b/src/screens/UScreenPartyOptions.pas @@ -61,20 +61,20 @@ type NumPlayer1, NumPlayer2, NumPlayer3: integer; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure SetAnimationProgress(Progress: real); override; procedure SetPlaylist2; end; var - IPlaylist: array[0..2] of string; - IPlaylist2: array of string; + IPlaylist: array[0..2] of UTF8String; + IPlaylist2: array of UTF8String; const - ITeams: array[0..1] of string = ('2', '3'); - IPlayers: array[0..3] of string = ('1', '2', '3', '4'); - IRounds: array[0..5] of string = ('2', '3', '4', '5', '6', '7'); + ITeams: array[0..1] of UTF8String = ('2', '3'); + IPlayers: array[0..3] of UTF8String = ('1', '2', '3', '4'); + IRounds: array[0..5] of UTF8String = ('2', '3', '4', '5', '6', '7'); implementation @@ -88,9 +88,10 @@ uses USong, UDLLManager, UPlaylist, - USongs; + USongs, + UUnicodeUtils; -function TScreenPartyOptions.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenPartyOptions.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; var I, J: integer; OnlyMultiPlayer: boolean; @@ -99,8 +100,8 @@ begin if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -239,14 +240,14 @@ begin //Load Screen From Theme LoadFromTheme(Theme.PartyOptions); - SelectLevel := AddSelectSlide (Theme.PartyOptions.SelectLevel, Ini.Difficulty, Theme.ILevel); - SelectPlayList := AddSelectSlide (Theme.PartyOptions.SelectPlayList, PlayList, IPlaylist); - SelectPlayList2 := AddSelectSlide (Theme.PartyOptions.SelectPlayList2, PlayList2, IPlaylist2); - SelectRounds := AddSelectSlide (Theme.PartyOptions.SelectRounds, Rounds, IRounds); - SelectTeams := AddSelectSlide (Theme.PartyOptions.SelectTeams, NumTeams, ITeams); - SelectPlayers1 := AddSelectSlide (Theme.PartyOptions.SelectPlayers1, NumPlayer1, IPlayers); - SelectPlayers2 := AddSelectSlide (Theme.PartyOptions.SelectPlayers2, NumPlayer2, IPlayers); - SelectPlayers3 := AddSelectSlide (Theme.PartyOptions.SelectPlayers3, NumPlayer3, IPlayers); + SelectLevel := AddSelectSlide(Theme.PartyOptions.SelectLevel, Ini.Difficulty, Theme.ILevel); + SelectPlayList := AddSelectSlide(Theme.PartyOptions.SelectPlayList, PlayList, IPlaylist); + SelectPlayList2 := AddSelectSlide(Theme.PartyOptions.SelectPlayList2, PlayList2, IPlaylist2); + SelectRounds := AddSelectSlide(Theme.PartyOptions.SelectRounds, Rounds, IRounds); + SelectTeams := AddSelectSlide(Theme.PartyOptions.SelectTeams, NumTeams, ITeams); + SelectPlayers1 := AddSelectSlide(Theme.PartyOptions.SelectPlayers1, NumPlayer1, IPlayers); + SelectPlayers2 := AddSelectSlide(Theme.PartyOptions.SelectPlayers2, NumPlayer2, IPlayers); + SelectPlayers3 := AddSelectSlide(Theme.PartyOptions.SelectPlayers3, NumPlayer3, IPlayers); Interaction := 0; @@ -301,7 +302,7 @@ begin UpdateSelectSlideOptions(Theme.PartyOptions.SelectPlayList2, 2, IPlaylist2, Playlist2); end; -procedure TScreenPartyOptions.onShow; +procedure TScreenPartyOptions.OnShow; begin inherited; diff --git a/src/screens/UScreenPartyPlayer.pas b/src/screens/UScreenPartyPlayer.pas index c2070fce..887d5202 100644 --- a/src/screens/UScreenPartyPlayer.pas +++ b/src/screens/UScreenPartyPlayer.pas @@ -64,8 +64,8 @@ type Player12Name: cardinal; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure SetAnimationProgress(Progress: real); override; end; @@ -76,9 +76,10 @@ uses UMain, UIni, UTexture, - UParty; + UParty, + UUnicodeUtils; -function TScreenPartyPlayer.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenPartyPlayer.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; var SDL_ModState: word; I, J: integer; @@ -107,9 +108,14 @@ begin begin // Key Down // check normal keys case CharCode of - '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"': + Ord('0')..Ord('9'), + Ord('a')..Ord('z'), + Ord('A')..Ord('Z'), + Ord(' '), Ord('-'), Ord('_'), Ord('!'), Ord(','), Ord('<'), Ord('/'), + Ord('*'), Ord('?'), Ord(''''), Ord('"'): begin - Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode; + Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + + UCS4ToUTF8String(CharCode); Exit; end; end; @@ -228,7 +234,7 @@ begin SDLK_BACKSPACE: begin - Button[Interaction].Text[0].DeleteLastL; + Button[Interaction].Text[0].DeleteLastLetter; end; SDLK_ESCAPE: @@ -294,7 +300,7 @@ begin Interaction := 0; end; -procedure TScreenPartyPlayer.onShow; +procedure TScreenPartyPlayer.OnShow; var I: integer; begin diff --git a/src/screens/UScreenPartyScore.pas b/src/screens/UScreenPartyScore.pas index 23cf666d..2de240b8 100644 --- a/src/screens/UScreenPartyScore.pas +++ b/src/screens/UScreenPartyScore.pas @@ -34,11 +34,11 @@ interface {$I switches.inc} uses - UMenu, SDL, + SysUtils, + UMenu, UDisplay, UMusic, - SysUtils, UThemes; type @@ -69,8 +69,8 @@ type MaxScore: word; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure SetAnimationProgress(Progress: real); override; end; @@ -83,16 +83,17 @@ uses UScreenSingModi, ULanguage, UTexture, - USkins; + USkins, + UUnicodeUtils; -function TScreenPartyScore.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenPartyScore.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -165,7 +166,9 @@ begin DecoColor[0].B := B; //Load Texture - Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.FirstTexture)), Theme.PartyScore.DecoTextures.FirstTyp, Color); + Tex := Texture.LoadTexture( + Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.FirstTexture), + Theme.PartyScore.DecoTextures.FirstTyp, Color); DecoTex[0] := Tex.TexNum; //Get Second Color @@ -176,7 +179,9 @@ begin DecoColor[1].B := B; //Load Second Texture - Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.SecondTexture)), Theme.PartyScore.DecoTextures.SecondTyp, Color); + Tex := Texture.LoadTexture( + Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.SecondTexture), + Theme.PartyScore.DecoTextures.SecondTyp, Color); DecoTex[1] := Tex.TexNum; //Get Third Color @@ -187,14 +192,16 @@ begin DecoColor[2].B := B; //Load Third Texture - Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.ThirdTexture)), Theme.PartyScore.DecoTextures.ThirdTyp, Color); + Tex := Texture.LoadTexture( + Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.ThirdTexture), + Theme.PartyScore.DecoTextures.ThirdTyp, Color); DecoTex[2] := Tex.TexNum; end; LoadFromTheme(Theme.PartyScore); end; -procedure TScreenPartyScore.onShow; +procedure TScreenPartyScore.OnShow; var I, J: integer; Placings: array [0..5] of byte; @@ -238,7 +245,7 @@ begin if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then begin Text[TextScoreTeam1].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[0].Score); - Text[TextNameTeam1].Text := string(ScreenSingModi.TeamInfo.Teaminfo[0].Name); + Text[TextNameTeam1].Text := UTF8String(ScreenSingModi.TeamInfo.Teaminfo[0].Name); //Set Deco Texture if Theme.PartyScore.DecoTextures.ChangeTextures then @@ -267,7 +274,7 @@ begin if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then begin Text[TextScoreTeam2].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[1].Score); - Text[TextNameTeam2].Text := string(ScreenSingModi.TeamInfo.Teaminfo[1].Name); + Text[TextNameTeam2].Text := UTF8String(ScreenSingModi.TeamInfo.Teaminfo[1].Name); //Set Deco Texture if Theme.PartyScore.DecoTextures.ChangeTextures then @@ -296,7 +303,7 @@ begin if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then begin Text[TextScoreTeam3].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[2].Score); - Text[TextNameTeam3].Text := string(ScreenSingModi.TeamInfo.Teaminfo[2].Name); + Text[TextNameTeam3].Text := UTF8String(ScreenSingModi.TeamInfo.Teaminfo[2].Name); //Set Deco Texture if Theme.PartyScore.DecoTextures.ChangeTextures then diff --git a/src/screens/UScreenPartyWin.pas b/src/screens/UScreenPartyWin.pas index 3c105c7d..afa5ce83 100644 --- a/src/screens/UScreenPartyWin.pas +++ b/src/screens/UScreenPartyWin.pas @@ -34,10 +34,11 @@ interface {$I switches.inc} uses + SDL, + SysUtils, UMenu, - SDL, UDisplay, + UDisplay, UMusic, - SysUtils, UThemes; type @@ -61,28 +62,29 @@ type TextWinner: cardinal; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure SetAnimationProgress(Progress: real); override; end; implementation -uses +uses UGraphic, UMain, UParty, UScreenSingModi, - ULanguage; + ULanguage, + UUnicodeUtils; -function TScreenPartyWin.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenPartyWin.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -135,7 +137,7 @@ begin LoadFromTheme(Theme.PartyWin); end; -procedure TScreenPartyWin.onShow; +procedure TScreenPartyWin.OnShow; var I: integer; Placing: TeamOrderArray; diff --git a/src/screens/UScreenPopup.pas b/src/screens/UScreenPopup.pas index 7e4671d6..fdf4a69c 100644 --- a/src/screens/UScreenPopup.pas +++ b/src/screens/UScreenPopup.pas @@ -34,42 +34,61 @@ interface {$I switches.inc} uses - UMenu, SDL, + SysUtils, + UMenu, UMusic, UFiles, - SysUtils, UThemes; type + TPopupCheckHandler = procedure(Value: boolean; Data: Pointer); + TScreenPopupCheck = class(TMenu) + private + fHandler: TPopupCheckHandler; + fHandlerData: Pointer; + public - Visible: boolean; //Whether the Menu should be Drawn + Visible: boolean; // whether the menu should be drawn constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; - procedure ShowPopup(msg: string); + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; + procedure ShowPopup(const Msg: UTF8String; Handler: TPopupCheckHandler; + HandlerData: Pointer; DefaultValue: boolean = false); function Draw: boolean; override; end; type - TScreenPopupError = class(TMenu) -{ private - CurMenu: byte; //Num of the cur. Shown Menu} + TScreenPopup = class(TMenu) + { + private + CurMenu: byte; //Num of the cur. Shown Menu + } public Visible: boolean; //Whether the Menu should be Drawn constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; - procedure onHide; override; - procedure ShowPopup(msg: string); + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; + procedure OnHide; override; + procedure ShowPopup(const Msg: UTF8String); function Draw: boolean; override; end; + TScreenPopupError = class(TScreenPopup) + public + constructor Create; + end; + + TScreenPopupInfo = class(TScreenPopup) + public + constructor Create; + end; + var -// ISelections: array of string; + //ISelections: array of string; SelectValue: integer; implementation @@ -82,70 +101,57 @@ uses ULanguage, UParty, UPlaylist, - UDisplay; + UDisplay, + UUnicodeUtils; -function TScreenPopupCheck.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +{ TScreenPopupCheck } + +function TScreenPopupCheck.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; +var + Value: boolean; begin Result := true; if (PressedDown) then begin // Key Down - // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': - begin - Result := false; - Exit; - end; - end; - // check special keys case PressedKey of SDLK_ESCAPE, SDLK_BACKSPACE : begin - Display.CheckOK := false; - Display.NextScreenWithCheck := NIL; + Value := false; Visible := false; Result := false; end; SDLK_RETURN: begin - case Interaction of - 0: begin - //Hack to Finish Singscreen correct on Exit with Q Shortcut - if (Display.NextScreenWithCheck = NIL) then - begin - if (Display.CurrentScreen = @ScreenSing) then - ScreenSing.Finish - else if (Display.CurrentScreen = @ScreenSingModi) then - ScreenSingModi.Finish; - end; - - Display.CheckOK := true; - end; - 1: begin - Display.CheckOK := false; - Display.NextScreenWithCheck := NIL; - end; - end; + Value := (Interaction = 0); Visible := false; Result := false; end; - SDLK_DOWN: InteractNext; - SDLK_UP: InteractPrev; - + SDLK_DOWN: InteractNext; + SDLK_UP: InteractPrev; + SDLK_RIGHT: InteractNext; - SDLK_LEFT: InteractPrev; + SDLK_LEFT: InteractPrev; end; end; + + if (not Result) then + begin + if (@fHandler <> nil) then + fHandler(Value, fHandlerData); + end; end; constructor TScreenPopupCheck.Create; begin inherited Create; + fHandler := nil; + fHandlerData := nil; + AddText(Theme.CheckPopup.TextCheck); LoadFromTheme(Theme.CheckPopup); @@ -163,18 +169,24 @@ end; function TScreenPopupCheck.Draw: boolean; begin - Draw:=inherited Draw; + Result := inherited Draw; end; -procedure TScreenPopupCheck.onShow; +procedure TScreenPopupCheck.OnShow; begin inherited; end; -procedure TScreenPopupCheck.ShowPopup(msg: string); +procedure TScreenPopupCheck.ShowPopup(const Msg: UTF8String; Handler: TPopupCheckHandler; + HandlerData: Pointer; DefaultValue: boolean); begin - Interaction := 0; //Reset Interaction + if (DefaultValue) then + Interaction := 0 + else + Interaction := 1; Visible := true; //Set Visible + fHandler := Handler; + fHandlerData := HandlerData; Text[0].Text := Language.Translate(msg); @@ -187,9 +199,9 @@ begin Background.OnShow end; -// error popup +{ TScreenPopup } -function TScreenPopupError.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenPopup.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then @@ -223,7 +235,7 @@ begin end; end; -constructor TScreenPopupError.Create; +constructor TScreenPopup.Create; begin inherited Create; @@ -238,22 +250,22 @@ begin Interaction := 0; end; -function TScreenPopupError.Draw: boolean; +function TScreenPopup.Draw: boolean; begin Draw := inherited Draw; end; -procedure TScreenPopupError.onShow; +procedure TScreenPopup.OnShow; begin inherited; end; -procedure TScreenPopupError.onHide; +procedure TScreenPopup.OnHide; begin end; -procedure TScreenPopupError.ShowPopup(msg: string); +procedure TScreenPopup.ShowPopup(const Msg: UTF8String); begin Interaction := 0; //Reset Interaction Visible := true; //Set Visible @@ -277,4 +289,20 @@ begin Button[0].Text[0].Text := 'OK'; end; +{ TScreenPopupError } + +constructor TScreenPopupError.Create; +begin + inherited; + Text[1].Text := Language.Translate('MSG_ERROR_TITLE'); +end; + +{ TScreenPopupInfo } + +constructor TScreenPopupInfo.Create; +begin + inherited; + Text[1].Text := Language.Translate('MSG_INFO_TITLE'); +end; + end. diff --git a/src/screens/UScreenScore.pas b/src/screens/UScreenScore.pas index a01c7691..ce1b11e5 100644 --- a/src/screens/UScreenScore.pas +++ b/src/screens/UScreenScore.pas @@ -128,10 +128,10 @@ type TextGolden_ActualValue: array[1..6] of integer; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; function ParseMouse(MouseButton: Integer; BtnDown: Boolean; X, Y: integer): boolean; override; - procedure onShow; override; - procedure onShowFinish; override; + procedure OnShow; override; + procedure OnShowFinish; override; function Draw: boolean; override; procedure FillPlayer(Item, P: integer); @@ -158,16 +158,18 @@ uses UIni, ULog, ULanguage, - UNote; + UNote, + UUnicodeUtils; -function TScreenScore.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; + +function TScreenScore.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -197,7 +199,7 @@ begin Result := True; if (MouseButton = SDL_BUTTON_LEFT) and BtnDown then begin //left-click anywhere sends return - ParseInput(SDLK_RETURN, #0, true); + ParseInput(SDLK_RETURN, 0, true); end; end; @@ -261,7 +263,7 @@ begin end; -procedure TScreenScore.onShow; +procedure TScreenScore.OnShow; var P: integer; // player I: integer; diff --git a/src/screens/UScreenSing.pas b/src/screens/UScreenSing.pas index 157f7e64..20805737 100644 --- a/src/screens/UScreenSing.pas +++ b/src/screens/UScreenSing.pas @@ -35,9 +35,9 @@ interface uses SysUtils, - gl, SDL, TextGL, + gl, UFiles, UGraphicClasses, UIni, @@ -49,6 +49,7 @@ uses USongs, UTexture, UThemes, + UPath, UTime; type @@ -101,11 +102,11 @@ type fCurrentVideoPlaybackEngine: IVideoPlayback; constructor Create; override; - procedure onShow; override; - procedure onShowFinish; override; - procedure onHide; override; + procedure OnShow; override; + procedure OnShowFinish; override; + procedure OnHide; override; - function ParseInput(PressedKey: cardinal; CharCode: widechar; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; function Draw: boolean; override; @@ -127,20 +128,21 @@ uses UNote, URecord, USong, - UDisplay; + UDisplay, + UUnicodeUtils; // method for input parsing. if false is returned, getnextwindow // should be checked to know the next window to load; -function TScreenSing.ParseInput(PressedKey: cardinal; CharCode: widechar; +function TScreenSing.ParseInput(PressedKey: Cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // key down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin // when not ask before exit then finish now if (Ini.AskbeforeDel <> 1) then @@ -152,7 +154,7 @@ begin Result := false; Exit; end; - 'V': // show visualization + Ord('V'): // show visualization begin fShowVisualization := not fShowVisualization; @@ -166,7 +168,7 @@ begin Exit; end; - 'P': + Ord('P'): begin Pause; Exit; @@ -216,6 +218,8 @@ end; // pause mod procedure TScreenSing.Pause; +var + VideoFile: IPath; begin if (not Paused) then // enable pause begin @@ -228,8 +232,8 @@ begin AudioPlayback.Pause; // pause video - if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + - CurrentSong.Video) then + VideoFile := CurrentSong.Path.Append(CurrentSong.Video); + if (CurrentSong.Video.IsSet) and VideoFile.Exists then fCurrentVideoPlaybackEngine.Pause; end @@ -241,8 +245,8 @@ begin AudioPlayback.Play; // video - if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + - CurrentSong.Video) then + VideoFile := CurrentSong.Path.Append(CurrentSong.Video); + if (CurrentSong.Video.IsSet) and VideoFile.Exists then fCurrentVideoPlaybackEngine.Pause; Paused := false; @@ -307,7 +311,7 @@ begin LyricsSync := TLyricsSyncSource.Create(); end; -procedure TScreenSing.onShow; +procedure TScreenSing.OnShow; var Index: integer; V1: boolean; @@ -317,12 +321,12 @@ var V2M: boolean; V3R: boolean; Color: TRGB; - + VideoFile, BgFile: IPath; success: boolean; begin inherited; - Log.LogStatus('Begin', 'onShow'); + Log.LogStatus('Begin', 'OnShow'); FadeOut := false; // reset video playback engine, to play video clip ... @@ -423,7 +427,7 @@ begin // FIXME: bad style, put the try-except into loadsong() and not here try // check if file is xml - if copy(CurrentSong.FileName, length(CurrentSong.FileName) - 3, 4) = '.xml' then + if CurrentSong.FileName.GetExtension.ToUTF8 = '.xml' then success := CurrentSong.LoadXMLSong() else success := CurrentSong.LoadSong(); @@ -467,9 +471,10 @@ begin *} VideoLoaded := false; fShowVisualization := false; - if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then + VideoFile := CurrentSong.Path.Append(CurrentSong.Video); + if (CurrentSong.Video.IsSet) and VideoFile.IsFile then begin - if (fCurrentVideoPlaybackEngine.Open(CurrentSong.Path + CurrentSong.Video)) then + if (fCurrentVideoPlaybackEngine.Open(VideoFile)) then begin fShowVisualization := false; fCurrentVideoPlaybackEngine := VideoPlayback; @@ -482,15 +487,17 @@ begin {* * set background to: picture *} - if (CurrentSong.Background <> '') and (VideoLoaded = false) + if (CurrentSong.Background.IsSet) and (VideoLoaded = false) and (TVisualizerOption(Ini.VisualizerOption) = voOff) then + begin + BgFile := CurrentSong.Path.Append(CurrentSong.Background); try - Tex_Background := Texture.LoadTexture(CurrentSong.Path + CurrentSong.Background); + Tex_Background := Texture.LoadTexture(BgFile); except - Log.LogError('Background could not be loaded: ' + CurrentSong.Path + - CurrentSong.Background); + Log.LogError('Background could not be loaded: ' + BgFile.ToNative); Tex_Background.TexNum := 0; end + end else begin Tex_Background.TexNum := 0; @@ -622,7 +629,7 @@ begin if Lines[0].Line[Index].TotalNotes = 0 then Inc(NumEmptySentences); - Log.LogStatus('End', 'onShow'); + Log.LogStatus('End', 'OnShow'); end; procedure TScreenSing.onShowFinish; @@ -640,7 +647,7 @@ begin CountSkipTimeSet; end; -procedure TScreenSing.onHide; +procedure TScreenSing.OnHide; begin // background texture if (Tex_Background.TexNum > 0) then diff --git a/src/screens/UScreenSingModi.pas b/src/screens/UScreenSingModi.pas index eeb06004..48d1e9a1 100644 --- a/src/screens/UScreenSingModi.pas +++ b/src/screens/UScreenSingModi.pas @@ -47,7 +47,7 @@ uses ULyrics, TextGL, gl, - + UPath, UThemes, UScreenSing, ModiSDK; @@ -62,16 +62,16 @@ type TeamInfo: TTeamInfo; constructor Create; override; - procedure onShow; override; + procedure OnShow; override; //procedure onShowFinish; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; function Draw: boolean; override; procedure Finish; override; end; type TCustomSoundEntry = record - Filename : string; + Filename : IPath; Stream : TAudioPlaybackStream; end; @@ -108,13 +108,13 @@ uses UGraphicClasses, ULanguage, UNote, - UPath, + UPathUtils, URecord, USkins; // Method for input parsing. If false is returned, GetNextWindow // should be checked to know the next window to load; -function TScreenSingModi.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenSingModi.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then @@ -176,7 +176,7 @@ begin end; end; -procedure TScreenSingModi.onShow; +procedure TScreenSingModi.OnShow; var I: integer; begin @@ -503,19 +503,20 @@ end; function LoadTex(const Name: PChar; Typ: TTextureType): TsmallTexture; var - Texname, EXT: string; + TexName: IPath; + Ext: UTF8String; Tex: TTexture; begin //Get texture Name TexName := Skin.GetTextureFileName(string(Name)); //Get File Typ - Ext := ExtractFileExt(TexName); - if (uppercase(Ext) = '.JPG') then + Ext := TexName.GetExtension().ToUTF8; + if (UpperCase(Ext) = '.JPG') then Ext := 'JPG' else Ext := 'BMP'; - Tex := Texture.LoadTexture(false, PChar(TexName), UTEXTURE.TTextureType(Typ), 0); + Tex := Texture.LoadTexture(false, TexName, UTexture.TTextureType(Typ), 0); Result.TexNum := Tex.TexNum; Result.W := Tex.W; @@ -544,20 +545,21 @@ function LoadSound(const Name: PChar): cardinal; var Stream: TAudioPlaybackStream; i: integer; - Filename: string; + Filename: IPath; + SoundFile: IPath; begin //Search for Sound in already loaded Sounds - Filename := UpperCase(SoundPath + Name); + SoundFile := SoundPath.Append(Name); for i := 0 to High(CustomSounds) do begin - if (UpperCase(CustomSounds[i].Filename) = Filename) then + if (SoundFile.Equals(CustomSounds[i].Filename, true)) then begin Result := i; Exit; end; end; - Stream := AudioPlayback.OpenSound(SoundPath + string(Name)); + Stream := AudioPlayback.OpenSound(SoundFile); if (Stream = nil) then begin Result := 0; diff --git a/src/screens/UScreenSong.pas b/src/screens/UScreenSong.pas index fa3c836e..5fa6de39 100644 --- a/src/screens/UScreenSong.pas +++ b/src/screens/UScreenSong.pas @@ -38,6 +38,7 @@ uses SDL, UCommon, UDisplay, + UPath, UFiles, UIni, ULanguage, @@ -118,19 +119,19 @@ type procedure SetScroll4; procedure SetScroll5; procedure SetScroll6; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; function ParseMouse(MouseButton: integer; BtnDown: boolean; X, Y: integer): boolean; override; function Draw: boolean; override; procedure GenerateThumbnails(); - procedure onShow; override; - procedure onHide; override; + procedure OnShow; override; + procedure OnHide; override; procedure SelectNext; procedure SelectPrev; procedure SkipTo(Target: cardinal); procedure FixSelected; //Show Wrong Song when Tabs on Fix procedure FixSelected2; //Show Wrong Song when Tabs on Fix procedure ShowCatTL(Cat: integer);// Show Cat in Top left - procedure ShowCatTLCustom(Caption: string);// Show Custom Text in Top left + procedure ShowCatTLCustom(Caption: UTF8String);// Show Custom Text in Top left procedure HideCatTL;// Show Cat in Tob left procedure Refresh; //Refresh Song Sorting procedure ChangeMusic; @@ -164,7 +165,8 @@ uses UParty, UPlaylist, UScreenSongMenu, - USkins; + USkins, + UUnicodeUtils; // ***** Public methods ****** // @@ -211,7 +213,7 @@ begin end; //Show Wrong Song when Tabs on Fix End -procedure TScreenSong.ShowCatTLCustom(Caption: string);// Show Custom Text in Top left +procedure TScreenSong.ShowCatTLCustom(Caption: UTF8String);// Show Custom Text in Top left begin Text[TextCat].Text := Caption; Text[TextCat].Visible := true; @@ -243,12 +245,13 @@ end; // Method for input parsing. If false is returned, GetNextWindow // should be checked to know the next window to load; -function TScreenSong.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenSong.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; var I: integer; I2: integer; SDL_ModState: word; - Letter: WideChar; + UpperLetter: UCS4Char; + TempStr: UTF8String; begin Result := true; @@ -273,9 +276,10 @@ begin //Jump to Artist/Titel if ((SDL_ModState and KMOD_LALT <> 0) and (Mode = smNormal)) then begin - if (WideCharUpperCase(CharCode)[1] in ([WideChar('A')..WideChar('Z'), WideChar('0') .. WideChar('9')]) ) then + UpperLetter := UCS4UpperCase(CharCode); + + if (UpperLetter in ([Ord('A')..Ord('Z'), Ord('0') .. Ord('9')]) ) then begin - Letter := WideCharUpperCase(CharCode)[1]; I2 := Length(CatSongs.Song); //Jump To Titel @@ -283,18 +287,21 @@ begin begin for I := 1 to High(CatSongs.Song) do begin - if (CatSongs.Song[(I + Interaction) mod I2].Visible) and - (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) and - (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Title)[1] = Letter) then + if (CatSongs.Song[(I + Interaction) mod I2].Visible) then begin - SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2)); + TempStr := CatSongs.Song[(I + Interaction) mod I2].Title; + if (Length(TempStr) > 0) and + (UCS4UpperCase(UTF8ToUCS4String(TempStr)[0]) = UpperLetter) then + begin + SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2)); - AudioPlayback.PlaySound(SoundLib.Change); + AudioPlayback.PlaySound(SoundLib.Change); - ChangeMusic; - SetScroll4; - //Break and Exit - Exit; + ChangeMusic; + SetScroll4; + //Break and Exit + Exit; + end; end; end; end @@ -303,19 +310,22 @@ begin begin for I := 1 to High(CatSongs.Song) do begin - if (CatSongs.Song[(I + Interaction) mod I2].Visible) and - (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) and - (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Artist)[1] = Letter) then + if (CatSongs.Song[(I + Interaction) mod I2].Visible) then begin - SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2)); + TempStr := CatSongs.Song[(I + Interaction) mod I2].Artist; + if (Length(TempStr) > 0) and + (UCS4UpperCase(UTF8ToUCS4String(TempStr)[0]) = UpperLetter) then + begin + SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2)); - AudioPlayback.PlaySound(SoundLib.Change); + AudioPlayback.PlaySound(SoundLib.Change); - ChangeMusic; - SetScroll4; + ChangeMusic; + SetScroll4; - //Break and Exit - Exit; + //Break and Exit + Exit; + end; end; end; end; @@ -325,14 +335,14 @@ begin end; // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; end; - 'M': //Show SongMenu + Ord('M'): //Show SongMenu begin if (Songs.SongList.Count > 0) then begin @@ -342,41 +352,41 @@ begin begin if CatSongs.CatNumShow = -3 then begin - ScreenSongMenu.onShow; + ScreenSongMenu.OnShow; ScreenSongMenu.MenuShow(SM_Playlist); end else begin - ScreenSongMenu.onShow; + ScreenSongMenu.OnShow; ScreenSongMenu.MenuShow(SM_Main); end; end else begin - ScreenSongMenu.onShow; + ScreenSongMenu.OnShow; ScreenSongMenu.MenuShow(SM_Playlist_Load); end; end //Party Mode -> Show Party Menu else begin - ScreenSongMenu.onShow; + ScreenSongMenu.OnShow; ScreenSongMenu.MenuShow(SM_Party_Main); end; end; Exit; end; - 'P': //Show Playlist Menu + Ord('P'): //Show Playlist Menu begin if (Songs.SongList.Count > 0) and (Mode = smNormal) then begin - ScreenSongMenu.onShow; + ScreenSongMenu.OnShow; ScreenSongMenu.MenuShow(SM_Playlist_Load); end; Exit; end; - 'J': //Show Jumpto Menu + Ord('J'): //Show Jumpto Menu begin if (Songs.SongList.Count > 0) and (Mode = smNormal) then begin @@ -385,13 +395,13 @@ begin Exit; end; - 'E': + Ord('E'): begin OpenEditor; Exit; end; - 'R': + Ord('R'): begin if (Songs.SongList.Count > 0) and (Mode = smNormal) then @@ -515,7 +525,7 @@ begin if (CatSongs.CatNumShow < -1) then begin //Atm: Set Empty Filter - CatSongs.SetFilter('', 0); + CatSongs.SetFilter('', fltAll); //Show Cat in Top Left Mod HideCatTL; @@ -744,18 +754,18 @@ begin if RightMbESC and (MouseButton = SDL_BUTTON_RIGHT) and BtnDown then //if RightMbESC is set, send ESC keypress - Result:=ParseInput(SDLK_ESCAPE, #0, true); + Result:=ParseInput(SDLK_ESCAPE, 0, true); //song scrolling with mousewheel if (MouseButton = SDL_BUTTON_WHEELDOWN) and BtnDown then - ParseInput(SDLK_RIGHT, #0, true); + ParseInput(SDLK_RIGHT, 0, true); if (MouseButton = SDL_BUTTON_WHEELUP) and BtnDown then - ParseInput(SDLK_LEFT, #0, true); + ParseInput(SDLK_LEFT, 0, true); //LMB anywhere starts if (MouseButton = SDL_BUTTON_LEFT) and BtnDown then - ParseInput(SDLK_RETURN, #0, true); + ParseInput(SDLK_RETURN, 0, true); end; constructor TScreenSong.Create; @@ -833,9 +843,9 @@ var I: integer; CoverButtonIndex: integer; CoverButton: TButton; - CoverName: string; CoverTexture: TTexture; Cover: TCover; + CoverFile: IPath; Song: TSong; begin if (Length(CatSongs.Song) <= 0) then @@ -850,7 +860,7 @@ begin CoverButton := nil; // create a clickable cover - CoverButtonIndex := AddButton(300 + I*250, 140, 200, 200, '', TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections); + CoverButtonIndex := AddButton(300 + I*250, 140, 200, 200, PATH_NONE, TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections); if (CoverButtonIndex > -1) then CoverButton := Button[CoverButtonIndex]; if (CoverButton = nil) then @@ -859,18 +869,16 @@ begin Song := CatSongs.Song[I]; // if cover-image is not found then show 'no cover' - if (not FileExists(Song.Path + Song.Cover)) then - Song.Cover := ''; - - if (Song.Cover = '') then - CoverName := Skin.GetTextureFileName('SongCover') - else - CoverName := Song.Path + Song.Cover; + CoverFile := Song.Path.Append(Song.Cover); + if (not CoverFile.IsFile()) then + Song.Cover := PATH_NONE; + if (Song.Cover.IsUnset) then + CoverFile := Skin.GetTextureFileName('SongCover'); // load cover and cache its texture - Cover := Covers.FindCover(CoverName); + Cover := Covers.FindCover(CoverFile); if (Cover = nil) then - Cover := Covers.AddCover(CoverName); + Cover := Covers.AddCover(CoverFile); // use the cached texture // TODO: this is a workaround until the new song-loading works. @@ -910,7 +918,7 @@ begin end; // Set visibility of video icon - Static[VideoIcon].Visible := (CatSongs.Song[Interaction].Video <> ''); + Static[VideoIcon].Visible := CatSongs.Song[Interaction].Video.IsSet; // Set texts Text[TextArtist].Text := CatSongs.Song[Interaction].Artist; @@ -1399,7 +1407,7 @@ begin end; end; -procedure TScreenSong.onShow; +procedure TScreenSong.OnShow; begin inherited; {** @@ -1456,14 +1464,14 @@ begin SetStatics; end; -procedure TScreenSong.onHide; +procedure TScreenSong.OnHide; begin // turn music volume to 100% AudioPlayback.SetVolume(1.0); // if preview is deactivated: load musicfile now if (IPreviewVolumeVals[Ini.PreviewVolume] = 0) then - AudioPlayback.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3); + AudioPlayback.Open(CatSongs.Song[Interaction].Path.Append(CatSongs.Song[Interaction].Mp3)); // if hide then stop music (for party mode popup on exit) if (Display.NextScreen <> @ScreenSing) and @@ -1642,7 +1650,7 @@ begin if not assigned(Song) then Exit; - if AudioPlayback.Open(Song.Path + Song.Mp3) then + if AudioPlayback.Open(Song.Path.Append(Song.Mp3)) then begin AudioPlayback.Position := AudioPlayback.Length / 4; // set preview volume diff --git a/src/screens/UScreenSongJumpto.pas b/src/screens/UScreenSongJumpto.pas index e55a6276..3a199576 100644 --- a/src/screens/UScreenSongJumpto.pas +++ b/src/screens/UScreenSongJumpto.pas @@ -34,42 +34,39 @@ interface {$I switches.inc} uses - UMenu, SDL, + SysUtils, + UMenu, UDisplay, UMusic, UFiles, - SysUtils, + USongs, UThemes; type TScreenSongJumpto = class(TMenu) private //For ChangeMusic - LastPlayed: integer; - VisibleBool: boolean; - public - VisSongs: integer; + fLastPlayed: integer; + fVisible: boolean; + fSelectType: TSongFilter; + fVisSongs: integer; - constructor Create; override; + procedure SetTextFound(Count: Cardinal); //Visible //Whether the Menu should be Drawn //Whether the Menu should be Drawn procedure SetVisible(Value: boolean); - property Visible: boolean read VisibleBool write SetVisible; + public + constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; function Draw: boolean; override; - procedure SetTextFound(const Count: cardinal); + property Visible: boolean read fVisible write SetVisible; end; -var - IType: array [0..2] of string; - SelectType: integer; - - implementation uses @@ -79,26 +76,24 @@ uses UTexture, ULanguage, UParty, - USongs, UScreenSong, - ULog; + ULog, + UUnicodeUtils; -function TScreenSongJumpto.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenSongJumpto.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case CharCode of - '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"', - '[', '{', ';', ':': - begin - if Interaction = 0 then - begin - Button[0].Text[0].Text := Button[0].Text[0].Text + CharCode; - SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType)); - end; - end; + if (IsAlphaNumericChar(CharCode) or + IsPunctuationChar(CharCode)) then + begin + if (Interaction = 0) then + begin + Button[0].Text[0].Text := Button[0].Text[0].Text + UCS4ToUTF8String(CharCode); + SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, fSelectType)); + end; end; // check special keys @@ -107,8 +102,8 @@ begin begin if (Interaction = 0) and (Length(Button[0].Text[0].Text) > 0) then begin - Button[0].Text[0].DeleteLastL; - SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType)); + Button[0].Text[0].DeleteLastLetter(); + SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, fSelectType)); end; end; @@ -117,18 +112,15 @@ begin begin Visible := false; AudioPlayback.PlaySound(SoundLib.Back); - if (VisSongs = 0) and (Length(Button[0].Text[0].Text) > 0) then + if (fVisSongs = 0) and (Length(Button[0].Text[0].Text) > 0) then begin ScreenSong.UnLoadDetailedCover; Button[0].Text[0].Text := ''; - CatSongs.SetFilter('', 0); + CatSongs.SetFilter('', fltAll); SetTextFound(0); end; end; - // Up and Down could be done at the same time, - // but I don't want to declare variables inside - // functions like this one, called so many times SDLK_DOWN: begin {SelectNext; @@ -146,7 +138,7 @@ begin Interaction := 1; InteractInc; if (Length(Button[0].Text[0].Text) > 0) then - SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType)); + SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, fSelectType)); Interaction := 0; end; SDLK_LEFT: @@ -154,7 +146,7 @@ begin Interaction := 1; InteractDec; if (Length(Button[0].Text[0].Text) > 0) then - SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType)); + SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, fSelectType)); Interaction := 0; end; end; @@ -162,8 +154,6 @@ begin end; constructor TScreenSongJumpto.Create; -//var -// I: integer; // Auto Removed, Unused Variable begin inherited Create; @@ -175,23 +165,23 @@ begin if (Length(Button[0].Text) = 0) then AddButtonText(14, 20, ''); - SelectType := 0; - AddSelectSlide(Theme.SongJumpto.SelectSlideType, SelectType, Theme.SongJumpto.IType); + fSelectType := fltAll; + AddSelectSlide(Theme.SongJumpto.SelectSlideType, PInteger(@fSelectType)^, Theme.SongJumpto.IType); Interaction := 0; - LastPlayed := 0; + fLastPlayed := 0; end; procedure TScreenSongJumpto.SetVisible(Value: boolean); begin -//If change from unvisible to Visible then OnShow - if (VisibleBool = false) and (Value = true) then +//If change from invisible to Visible then OnShow + if (fVisible = false) and (Value = true) then OnShow; - VisibleBool := Value; + fVisible := Value; end; -procedure TScreenSongJumpto.onShow; +procedure TScreenSongJumpto.OnShow; begin inherited; @@ -208,7 +198,7 @@ begin Interaction := 0; Button[0].Text[0].Selected := true; - LastPlayed := ScreenSong.Interaction; + fLastPlayed := ScreenSong.Interaction; end; function TScreenSongJumpto.Draw: boolean; @@ -216,7 +206,7 @@ begin Result := inherited Draw; end; -procedure TScreenSongJumpto.SetTextFound(const Count: cardinal); +procedure TScreenSongJumpto.SetTextFound(Count: cardinal); begin if (Count = 0) then begin @@ -235,7 +225,7 @@ begin end; //Set visSongs - VisSongs := Count; + fVisSongs := Count; //Fix SongSelection ScreenSong.Interaction := high(CatSongs.Song); @@ -243,9 +233,9 @@ begin ScreenSong.FixSelected; //Play Correct Music - if (ScreenSong.Interaction <> LastPlayed) then + if (ScreenSong.Interaction <> fLastPlayed) then begin - LastPlayed := ScreenSong.Interaction; + fLastPlayed := ScreenSong.Interaction; ScreenSong.ChangeMusic; end; diff --git a/src/screens/UScreenSongMenu.pas b/src/screens/UScreenSongMenu.pas index 0af94a8f..ec893c7a 100644 --- a/src/screens/UScreenSongMenu.pas +++ b/src/screens/UScreenSongMenu.pas @@ -50,8 +50,8 @@ type Visible: boolean; // whether the menu should be drawn constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; function Draw: boolean; override; procedure MenuShow(sMenu: byte); procedure HandleReturn; @@ -73,7 +73,7 @@ const SM_Party_Joker = 128 or 2; var - ISelections: array of string; + ISelections: array of UTF8String; SelectValue: integer; implementation @@ -86,9 +86,10 @@ uses ULanguage, UParty, UPlaylist, - USongs; + USongs, + UUnicodeUtils; -function TScreenSongMenu.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenSongMenu.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then @@ -96,27 +97,29 @@ begin if (CurMenu = SM_Playlist_New) and (Interaction=0) then begin // check normal keys - case WideCharUpperCase(CharCode)[1] of - '0'..'9', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"': - begin - Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode; - exit; - end; + if IsAlphaNumericChar(CharCode) or + (CharCode in [Ord(' '), Ord('-'), Ord('_'), Ord('!'), + Ord(','), Ord('<'), Ord('/'), Ord('*'), + Ord('?'), Ord(''''), Ord('"')]) then + begin + Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + + UCS4ToUTF8String(CharCode); + exit; end; // check special keys case PressedKey of SDLK_BACKSPACE: begin - Button[Interaction].Text[0].DeleteLastL; + Button[Interaction].Text[0].DeleteLastLetter; exit; end; end; end; // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -223,7 +226,7 @@ begin Result := inherited Draw; end; -procedure TScreenSongMenu.onShow; +procedure TScreenSongMenu.OnShow; begin inherited; end; @@ -405,9 +408,9 @@ begin Button[3].Visible := true; SelectsS[0].Visible := false; - Button[0].Text[0].Text := string(PartySession.Teams.Teaminfo[0].Name); - Button[1].Text[0].Text := string(PartySession.Teams.Teaminfo[1].Name); - Button[2].Text[0].Text := string(PartySession.Teams.Teaminfo[2].Name); + Button[0].Text[0].Text := UTF8String(PartySession.Teams.Teaminfo[0].Name); + Button[1].Text[0].Text := UTF8String(PartySession.Teams.Teaminfo[1].Name); + Button[2].Text[0].Text := UTF8String(PartySession.Teams.Teaminfo[2].Name); Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL'); // set right interaction diff --git a/src/screens/UScreenStatDetail.pas b/src/screens/UScreenStatDetail.pas index bbbb4a1b..249626b0 100644 --- a/src/screens/UScreenStatDetail.pas +++ b/src/screens/UScreenStatDetail.pas @@ -55,8 +55,8 @@ type TotPages: cardinal; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure SetAnimationProgress(Progress: real); override; procedure SetTitle; @@ -66,20 +66,21 @@ type implementation uses - UGraphic, - ULanguage, Math, Classes, - ULog; + UGraphic, + ULanguage, + ULog, + UUnicodeUtils; -function TScreenStatDetail.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenStatDetail.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -178,7 +179,7 @@ begin Typ := TStatType(0); end; -procedure TScreenStatDetail.onShow; +procedure TScreenStatDetail.OnShow; begin inherited; diff --git a/src/screens/UScreenStatMain.pas b/src/screens/UScreenStatMain.pas index 2fd91288..204f40cd 100644 --- a/src/screens/UScreenStatMain.pas +++ b/src/screens/UScreenStatMain.pas @@ -47,14 +47,14 @@ type private //Some Stat Value that don't need to be calculated 2 times SongsWithVid: cardinal; - function FormatOverviewIntro(FormatStr: string): string; - function FormatSongOverview(FormatStr: string): string; - function FormatPlayerOverview(FormatStr: string): string; + function FormatOverviewIntro(FormatStr: UTF8String): UTF8String; + function FormatSongOverview(FormatStr: UTF8String): UTF8String; + function FormatPlayerOverview(FormatStr: UTF8String): UTF8String; public TextOverview: integer; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; - procedure onShow; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; + procedure OnShow; override; procedure SetAnimationProgress(Progress: real); override; procedure SetOverview; @@ -70,21 +70,17 @@ uses ULanguage, UCommon, Classes, - {$IFDEF win32} - windows, - {$ELSE} - sysconst, - {$ENDIF} - ULog; - -function TScreenStatMain.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; + ULog, + UUnicodeUtils; + +function TScreenStatMain.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then begin // Key Down // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -170,11 +166,11 @@ begin //Set Songs with Vid SongsWithVid := 0; for I := 0 to Songs.SongList.Count -1 do - if (TSong(Songs.SongList[I]).Video <> '') then + if (TSong(Songs.SongList[I]).Video.IsSet) then Inc(SongsWithVid); end; -procedure TScreenStatMain.onShow; +procedure TScreenStatMain.OnShow; begin inherited; @@ -182,7 +178,7 @@ begin SetOverview; end; -function TScreenStatMain.FormatOverviewIntro(FormatStr: string): string; +function TScreenStatMain.FormatOverviewIntro(FormatStr: UTF8String): UTF8String; var Year, Month, Day: word; begin @@ -203,10 +199,10 @@ begin end; end; -function TScreenStatMain.FormatSongOverview(FormatStr: string): string; +function TScreenStatMain.FormatSongOverview(FormatStr: UTF8String): UTF8String; var CntSongs, CntSungSongs, CntVidSongs: integer; - MostPopSongArtist, MostPopSongTitle: string; + MostPopSongArtist, MostPopSongTitle: UTF8String; StatList: TList; MostSungSong: TStatResultMostSungSong; begin @@ -247,12 +243,12 @@ begin end; end; -function TScreenStatMain.FormatPlayerOverview(FormatStr: string): string; +function TScreenStatMain.FormatPlayerOverview(FormatStr: UTF8String): UTF8String; var CntPlayers: integer; BestScoreStat: TStatResultBestScores; BestSingerStat: TStatResultBestSingers; - BestPlayer, BestScorePlayer: string; + BestPlayer, BestScorePlayer: UTF8String; BestPlayerScore, BestScore: integer; SingerStats, ScoreStats: TList; begin @@ -307,7 +303,7 @@ end; procedure TScreenStatMain.SetOverview; var - Overview: string; + Overview: UTF8String; begin // Format overview Overview := FormatOverviewIntro(Language.Translate('STAT_OVERVIEW_INTRO')) + '\n \n' + diff --git a/src/screens/UScreenTop5.pas b/src/screens/UScreenTop5.pas index 1013a9b5..f9c86643 100644 --- a/src/screens/UScreenTop5.pas +++ b/src/screens/UScreenTop5.pas @@ -56,9 +56,9 @@ type Fadeout: boolean; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; function ParseMouse(MouseButton: integer; BtnDown: boolean; X, Y: integer): boolean; override; - procedure onShow; override; + procedure OnShow; override; function Draw: boolean; override; end; @@ -67,19 +67,19 @@ implementation uses UDataBase, UGraphic, + UMain, UIni, - UNote; + UNote, + UUnicodeUtils; -function TScreenTop5.ParseInput(PressedKey: cardinal; - CharCode: WideChar; - PressedDown: boolean): boolean; +function TScreenTop5.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if PressedDown then begin // check normal keys - case WideCharUpperCase(CharCode)[1] of - 'Q': + case UCS4UpperCase(CharCode) of + Ord('Q'): begin Result := false; Exit; @@ -113,7 +113,7 @@ begin Result := true; if (MouseButton = SDL_BUTTON_LEFT) and BtnDown then //left-click anywhere sends return - ParseInput(SDLK_RETURN, #0, true); + ParseInput(SDLK_RETURN, 0, true); end; constructor TScreenTop5.Create; @@ -137,7 +137,7 @@ begin end; -procedure TScreenTop5.onShow; +procedure TScreenTop5.OnShow; var I: integer; PMax: integer; diff --git a/src/screens/UScreenWelcome.pas b/src/screens/UScreenWelcome.pas index a00a84e2..4b463613 100644 --- a/src/screens/UScreenWelcome.pas +++ b/src/screens/UScreenWelcome.pas @@ -45,9 +45,9 @@ type Animation: real; Fadeout: boolean; constructor Create; override; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; override; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override; function Draw: boolean; override; - procedure onShow; override; + procedure OnShow; override; end; implementation @@ -58,7 +58,7 @@ uses USkins, UTexture; -function TScreenWelcome.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TScreenWelcome.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin Result := true; if (PressedDown) then @@ -91,7 +91,7 @@ begin Fadeout := false; end; -procedure TScreenWelcome.onShow; +procedure TScreenWelcome.OnShow; begin inherited; |