Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add piano mode (F6) #820

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions game/config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,7 @@ Effect=0
T1=1
T2=2
T3=3

[KeyBindings]
PianoKeysLow=92,97,122,115,120,100,99,118,103,98,104,110,109,107,44,108,46,59,47
PianoKeysHigh=49,113,50,119,51,101,114,53,116,54,121,117,56,105,57,111,48,112,91,61,93
1 change: 1 addition & 0 deletions game/languages/English.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2108,6 +2108,7 @@ CTRL_SHIFT_4 = Paste LYRICS+NOTES over each of the next 4 lines
CTRL_SHIFT_ALT_4 = Paste LYRICS+NOTES+LINE-END 4 times
CTRL_SHIFT_5 = Paste LYRICS+NOTES over each of the next 5 lines
CTRL_SHIFT_ALT_5 = Paste LYRICS+NOTES+LINE-END 5 times
F6 = Toggle Piano edit mode
;-------------------------------------------------------;
; ID_070: UScreenOptions ;
;-------------------------------------------------------;
Expand Down
20 changes: 20 additions & 0 deletions src/base/UCommon.pas
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,15 @@ interface
function SplitString(const Str: string; MaxCount: integer = 0; Separators: TSysCharSet = SepWhitespace; RemoveEmpty: boolean = true): TStringDynArray;

function StringInArray(const Value: string; Strings: array of string): Boolean;
function SplitStringToIntArray(const S: string): TArray<Cardinal>;

function StringDeleteFromArray(var InArray: TIntegerDynArray; const InIndex: integer): Boolean; overload;
function StringDeleteFromArray(var InStrings: TStringDynArray; const InIndex: integer): Boolean; overload;
function StringDeleteFromArray(var InStrings: TUTF8StringDynArray; const InIndex: integer): Boolean; overload;

type
TPianoKeyArray = array of Cardinal;

type
TRGB = record
R: single;
Expand Down Expand Up @@ -134,6 +138,22 @@ implementation
UMain,
UUnicodeUtils;

function SplitStringToIntArray(const S: string): TArray<Cardinal>;
var
StrList: TStringList;
I: Integer;
begin
StrList := TStringList.Create;
try
StrList.CommaText := S;
SetLength(Result, StrList.Count);
for I := 0 to StrList.Count - 1 do
Result[I] := StrToInt(StrList[I]);
finally
StrList.Free;
end;
end;

function StringInArray(const Value: string; Strings: array of string): Boolean;
var I: Integer;
begin
Expand Down
30 changes: 30 additions & 0 deletions src/base/UIni.pas
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ TIni = class
IniSection: string; IniProperty: string; Default: integer; CaseInsensitive: boolean = false): integer; overload;
function ReadArrayIndex(const SearchArray: array of UTF8String; IniFile: TCustomIniFile;
IniSection: string; IniProperty: string; Default: integer; DefaultValue: UTF8String; CaseInsensitive: boolean = false): integer; overload;
function InitializePianoKeyArray(const Values: array of Cardinal): TPianoKeyArray;

procedure LoadInputDeviceCfg(IniFile: TMemIniFile);
procedure SaveInputDeviceCfg(IniFile: TIniFile);
Expand Down Expand Up @@ -268,6 +269,8 @@ TIni = class
JukeboxNextLineOtherOColorG: integer;
JukeboxNextLineOtherOColorB: integer;

PianoKeysLow: TPianoKeyArray;
PianoKeysHigh: TPianoKeyArray;

// default encoding for texts (lyrics, song-name, ...)
DefaultEncoding: TEncoding;
Expand Down Expand Up @@ -1378,13 +1381,26 @@ procedure TIni.LoadScreenModes(IniFile: TCustomIniFile);
Depth := ReadArrayIndex(IDepth, IniFile, 'Graphics', 'Depth', IGNORE_INDEX, '32 bit');
end;

function TIni.InitializePianoKeyArray(const Values: array of Cardinal): TPianoKeyArray;
var
i: Integer;
begin
SetLength(Result, Length(Values));
for i := Low(Values) to High(Values) do
Result[i] := Values[i];
end;

procedure TIni.Load();
var
IniFile: TMemIniFile;
I: integer;
IShowWebScore: array of UTF8String;
HexColor: string;
Col: TRGB;
KeysLow: string;
KeysHigh: string;
ReadPianoKeysLow: TPianoKeyArray;
ReadPianoKeysHigh: TPianoKeyArray;
begin
LoadFontFamilyNames;
ILyricsFont := FontFamilyNames;
Expand Down Expand Up @@ -1715,6 +1731,20 @@ procedure TIni.Load();
Ini.JukeboxNextLineOtherOColorB := Round(Col.B);
end;

KeysLow := IniFile.ReadString('KeyBindings', 'PianoKeysLow', '');
KeysHigh := IniFile.ReadString('KeyBindings', 'PianoKeysHigh', '');
PianoKeysLow := InitializePianoKeyArray([60, 97, 121, 115, 120, 100, 99, 118, 103, 98, 104, 110, 109, 107, 44, 108, 46, 246, 45]);
PianoKeysHigh := InitializePianoKeyArray([49, 113, 50, 119, 51, 101, 114, 53, 116, 54, 122, 117, 56, 105, 57, 111, 48, 112, 252, 96, 43]);
ReadPianoKeysLow := SplitStringToIntArray(KeysLow);
ReadPianoKeysHigh := SplitStringToIntArray(KeysHigh);
Log.LogWarn('Got ' + IntToStr(Length(ReadPianoKeysLow)) + ' Low keys', 'ScreenEditSub');
Log.LogWarn('Got ' + IntToStr(Length(ReadPianoKeysHigh)) + ' high keys', 'ScreenEditSub');

if Length(ReadPianoKeysLow) = 19 then
PianoKeysLow := ReadPianoKeysLow;
if Length(ReadPianoKeysHigh) = 21 then
PianoKeysHigh := ReadPianoKeysHigh;

LoadPaths(IniFile);

TranslateOptionValues;
Expand Down
119 changes: 112 additions & 7 deletions src/screens/UScreenEditSub.pas
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ TScreenEditSub = class(TMenu)
P1EditMode: boolean;
P2EditMode: boolean;
BPMEditMode: boolean;
PianoEditMode: boolean;

PianoKeysLow: TPianoKeyArray;
PianoKeysHigh: TPianoKeyArray;

// to interactive divide note
LastClickTime: Integer;
Expand Down Expand Up @@ -389,6 +393,7 @@ TScreenEditSub = class(TMenu)
function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override;
function ParseInputEditText(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean;
function ParseInputEditBPM(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean;
function ParseInputEditPiano(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean;
function ParseMouse(MouseButton: Integer; BtnDown: boolean; X, Y: Integer): boolean; override;
function Draw: boolean; override;
procedure OnHide; override;
Expand Down Expand Up @@ -472,6 +477,24 @@ function TScreenEditSub.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; Pre
begin
Result := true;

SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});

if PianoEditMode then
begin
Result := ParseInputEditPiano(PressedKey, CharCode, PressedDown);
if (Result = true) then
begin
SDL_ModState := KMOD_LSHIFT or KMOD_LCTRL;
PressedKey := SDLK_SPACE;
end;
if (PressedKey = SDLK_RETURN) then
begin
PressedKey := SDLK_P;
end;
Result := true;
end;

if TextEditMode or
TitleEditMode or
ArtistEditMode or
Expand All @@ -489,12 +512,9 @@ function TScreenEditSub.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; Pre
begin
Result := ParseInputEditBPM(PressedKey, CharCode, PressedDown)
end
else
else
begin

SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});

if (PressedDown) then // Key Down
begin
// check normal keys
Expand Down Expand Up @@ -1423,7 +1443,7 @@ function TScreenEditSub.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; Pre
ShowInteractiveBackground;
end;

SDLK_SLASH, SDLK_HASH:
SDLK_SLASH, SDLK_HASH, SDLK_KP_DIVIDE:
begin
CopyToUndo;
if SDL_ModState = 0 then
Expand Down Expand Up @@ -1484,6 +1504,12 @@ function TScreenEditSub.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; Pre
StartTextInput;
end;

SDLK_F6:
begin
// Enter Piano Edit Mode
PianoEditMode := true;
end;

SDLK_SPACE:
begin
if (SDL_ModState = 0) or (SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL) then
Expand Down Expand Up @@ -2146,7 +2172,7 @@ function TScreenEditSub.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; Pre
end;

end; // case
end;
end;
end; // if
end;

Expand Down Expand Up @@ -2416,7 +2442,7 @@ function TScreenEditSub.ParseInputEditText(PressedKey: cardinal; CharCode: UCS4C
end;
end;
end;
SDLK_SLASH:
SDLK_SLASH, SDLK_KP_DIVIDE:
begin
CopyToUndo;
if SDL_ModState = KMOD_LCTRL then
Expand Down Expand Up @@ -2543,6 +2569,80 @@ function TScreenEditSub.ParseInputEditBPM(PressedKey: cardinal; CharCode: UCS4Ch
end; //if (PressedDown)
end;

function TScreenEditSub.ParseInputEditPiano(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean;
var
SDL_ModState: word;
Shift: Integer;
NewNote: Integer;
i: Integer;
begin
// used when in Piano Edit Mode
Result := true;
NewNote := -1000;
SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});

Shift := 0;
if SDL_ModState = KMOD_LSHIFT then
begin
Shift := 12;
end;


if PressedDown then
begin
// check special keys
case PressedKey of
SDLK_ESCAPE, SDLK_F6:
begin
PianoEditMode := false;
end;
end;
if PianoEditMode = true then
begin
for i := Low(PianoKeysLow) to High(PianoKeysLow) do
begin
if PressedKey = PianoKeysLow[i] then
begin
NewNote := i - 7 + Shift; // Adjusted index to match existing logic
Break;
end;
end;
if NewNote = -1000 then // If not found in PianoKeysLow, check PianoKeysHigh
begin
for i := Low(PianoKeysHigh) to High(PianoKeysHigh) do
begin
if PressedKey = PianoKeysHigh[i] then
begin
NewNote := i + 6 + Shift; // Adjusted index to match existing logic
Break;
end;
end;
end;

if NewNote <> -1000 then
begin
Tracks[CurrentTrack].Lines[Tracks[CurrentTrack].CurrentLine].Notes[CurrentNote[CurrentTrack]].Tone := NewNote;
// Play Midi
PlaySentenceMidi := false;
PlayVideo := false;
midinotefound := false;
PlayOne := true;
PlayOneMidi := true;
StopVideoPreview();
{$IFDEF UseMIDIPort} MidiTime := USTime.GetTime;
MidiStart := GetTimeFromBeat(Tracks[CurrentTrack].Lines[Tracks[CurrentTrack].CurrentLine].Notes[CurrentNote[CurrentTrack]].StartBeat);
MidiStop := GetTimeFromBeat(
Tracks[CurrentTrack].Lines[Tracks[CurrentTrack].CurrentLine].Notes[CurrentNote[CurrentTrack]].StartBeat +
Tracks[CurrentTrack].Lines[Tracks[CurrentTrack].CurrentLine].Notes[CurrentNote[CurrentTrack]].Duration); {$ENDIF}
LastClick := -100;
end
else
Result := False;
end; //if (PianoEditMode)
end; //if (PressedDown)
end;

function TScreenEditSub.ParseMouse(MouseButton: Integer; BtnDown: boolean; X, Y: Integer): boolean;
var
nBut: Integer;
Expand Down Expand Up @@ -4589,6 +4689,11 @@ constructor TScreenEditSub.Create;

// in notes place -> for move notes by mouse
//NotesBackgroundId := AddSelectSlide(Theme.EditSub.NotesBackground, i, Empty);

// Initialize Piano Keys to default values
PianoKeysLow := Ini.PianoKeysLow;
PianoKeysHigh := Ini.PianoKeysHigh;

end;

procedure TScreenEditSub.OnShow;
Expand Down