<commit_before>unit KM_ResKeys;
{$I KaM_Remake.inc}
interface
uses
  {$IFDEF MSWindows} Windows, {$ENDIF}
  {$IFDEF Unix} LCLType, {$ENDIF}
  {$IFDEF FPC} lconvencoding, LazUTF8, {$ENDIF}
  Classes, SysUtils, StrUtils, KromUtils, Math,
  KM_Defaults, KM_CommonClasses, KM_CommonTypes, KM_FileIO, KM_ResTexts;

const
  // Load key IDs from this include file
  KEYMAP_COUNT = 45;
  {$I KM_KeyIDs.inc}

  DEF_KEYS: array [0..KEYMAP_COUNT-1] of Byte = (
    37,  39,  38,  40, 112, 113, 114, 115,  72,  83,
    76,  70,  88, 187, 189, 190, 188, 116, 117, 118,
    119, 66,  80,  84,  34,  33,   8,  49,  50,  51,
    52,  53,  54,  55,  56,  57,  48,  32,  46,  13,
    27,  77,  86,  68,  67
  );

  KEY_FUNC_TX: array [0..KEYMAP_COUNT-1] of Word = (
    TX_KEY_FUNC_SCROLL_LEFT,   TX_KEY_FUNC_SCROLL_RIGHT, TX_KEY_FUNC_SCROLL_UP, TX_KEY_FUNC_SCROLL_DOWN, TX_KEY_FUNC_MENU_BUILD,
    TX_KEY_FUNC_MENU_RATIO,    TX_KEY_FUNC_MENU_STATS,   TX_KEY_FUNC_MENU_MAIN, TX_KEY_FUNC_HALT,        TX_KEY_FUNC_SPLIT,
    TX_KEY_FUNC_LINKUP, TX_KEY_FUNC_FOOD, TX_KEY_FUNC_STORM, TX_KEY_FUNC_FORM_INCREASE, TX_KEY_FUNC_FORM_DECREASE,
    TX_KEY_FUNC_TURN_CW, TX_KEY_FUNC_TURN_CCW, TX_KEY_FUNC_GAME_SPEED_1, TX_KEY_FUNC_GAME_SPEED_2, TX_KEY_FUNC_GAME_SPEED_3,
    TX_KEY_FUNC_GAME_SPEED_4, TX_KEY_FUNC_BEACON, TX_KEY_FUNC_PAUSE, TX_KEY_FUNC_SHOW_TEAMS, TX_KEY_FUNC_ZOOM_IN,
    TX_KEY_FUNC_ZOOM_OUT, TX_KEY_FUNC_ZOOM_RESET, TX_KEY_FUNC_SELECT_1, TX_KEY_FUNC_SELECT_2, TX_KEY_FUNC_SELECT_3,
    TX_KEY_FUNC_SELECT_4, TX_KEY_FUNC_SELECT_5, TX_KEY_FUNC_SELECT_6, TX_KEY_FUNC_SELECT_7, TX_KEY_FUNC_SELECT_8,
    TX_KEY_FUNC_SELECT_9, TX_KEY_FUNC_SELECT_10, TX_KEY_FUNC_CENTER_ALERT, TX_KEY_FUNC_DELETE_MSG, TX_KEY_FUNC_SHOW_GAME_CHAT,
    TX_KEY_FUNC_CLOSE_MENU, TX_KEY_FUNC_DBG_MAP, TX_KEY_FUNC_DBG_VICTORY, TX_KEY_FUNC_DBG_DEFEAT, TX_KEY_FUNC_DBG_SCOUT
  );

type
  TKMKeyLibrary = class
  private
    fCount: Integer;
    fKeys: array [0..KEYMAP_COUNT-1] of Integer;
    fKeymapPath: string;
    function GetKeys(aIndex: Word): Integer;
    procedure SetKeys(aIndex: Word; aValue: Integer);
  public
    constructor Create;
    property Count: Integer read fCount;
    function GetKeyName(aKey: Word): string;
    function GetKeyNameById(aId: Word): string;
    function GetFunctionNameById(aId: Integer): string;
    property Keys[aIndex: Word]: Integer read GetKeys write SetKeys; default;
    procedure LoadKeymapFile;
    procedure ResetKeymap;
    procedure SaveKeymap;
  end;


var
  // All games Keys accessible from everywhere
  gResKeys: TKMKeyLibrary;


implementation


{ TKMKeyLibrary }
constructor TKMKeyLibrary.Create;
begin
  inherited;

  fCount := KEYMAP_COUNT;
  fKeymapPath := (ExeDir + 'keys.keymap');

  LoadKeymapFile;
end;


// Each line in .keymap file has an index and a text. Lines without index are skipped
procedure TKMKeyLibrary.LoadKeymapFile;
var
  I: Integer;
  SL: TStringList;
  delim1, delim2: Integer;
  keyId, keyVal: Integer;
begin
  if not FileExists(fKeymapPath) then
  begin
    ResetKeymap;
    Exit;
  end;

  SL := TStringList.Create;
  {$IFDEF WDC} SL.LoadFromFile(fKeymapPath); {$ENDIF}
  //In FPC TStringList can't cope with BOM (or UnicodeStrings at all really)
  {$IFDEF FPC} SL.Text := ReadTextU(aFile, 1252); {$ENDIF}

  // Parse text
  for I := 0 to SL.Count - 1 do
  begin
    delim1 := Pos(':', SL[I]);
    delim2 := Pos('//', SL[I]);
    if (delim1 = 0) or (delim2 = 0) or (delim1 > delim2) then Continue;

    keyId := StrToIntDef(Copy(SL[I], 0, delim1 - 1), -1);
    keyVal := StrToIntDef(Copy(SL[I], delim1 + 1, delim2 - delim1 - 1), -1);

    if not InRange(keyId, 0, fCount - 1) or (keyVal = -1) then Continue;

    fKeys[keyId] := keyVal;
  end;
end;


function TKMKeyLibrary.GetKeys(aIndex: Word): Integer;
begin
  Result := fKeys[aIndex];
end;


procedure TKMKeyLibrary.SetKeys(aIndex: Word; aValue: Integer);
begin
  fKeys[aIndex] := aValue;
end;


procedure TKMKeyLibrary.SaveKeymap;
var
  Keystring: string;
  KeyStringList: TStringList;
  I: Integer;
begin
  KeyStringList := TStringList.Create;
  {$IFDEF WDC}KeyStringList.DefaultEncoding := TEncoding.UTF8;{$ENDIF}

  for I := 0 to fCount - 1 do
  begin
    Keystring := IntToStr(I) + ':'+ IntToStr(fKeys[I]) + '// ' + GetFunctionNameById(I);
    KeyStringList.Add(Keystring);
  end;

  KeyStringList.SaveToFile(fKeymapPath{$IFDEF WDC}, TEncoding.UTF8{$ENDIF});
  KeyStringList.Free;
end;


procedure TKMKeyLibrary.ResetKeymap;
var
  I: Integer;
begin
  for I := 0 to fCount - 1 do
    fKeys[I] := DEF_KEYS[I];
end;


// Here we define the action name values
function TKMKeyLibrary.GetFunctionNameById(aId: Integer): string;
begin

  case aId of
    0..KEYMAP_COUNT - 1: Result := gResTexts[KEY_FUNC_TX[aId]];

    // Higher value to separate bindable keys from special keys
    100: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_EXTRA];
    101: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_TERAIN_EDIT];
    102: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_VILLAGE_PLAN];
    103: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_VISUAL_SCRIPT];
    104: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_GLOBAL_SCRIPT];
    105: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_MENU_MAIN];
    106: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_1];
    107: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_2];
    108: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_3];
    109: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_4];
    110: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_5];
    111: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_6];
    112: Result := gResTexts[TX_KEY_FUNC_UNASSIGNABLE];
    113: Result := gResTexts[TX_KEY_FUNC_UNASSIGNABLE];
  else
    Result := gResTexts[TX_KEY_FUNC_UNKNOWN] + ' ' + IntToStr(aId) + '! ~~~';
  end;<commit_msg>Cleanup<commit_after>unit KM_ResKeys;
{$I KaM_Remake.inc}
interface
uses
  Classes, SysUtils, StrUtils, KromUtils, Math,
  KM_Defaults, KM_CommonClasses, KM_CommonTypes, KM_FileIO, KM_ResTexts;

const
  // Load key IDs from this include file
  KEYMAP_COUNT = 45;
  {$I KM_KeyIDs.inc}

  DEF_KEYS: array [0..KEYMAP_COUNT-1] of Byte = (
    37,  39,  38,  40, 112, 113, 114, 115,  72,  83,
    76,  70,  88, 187, 189, 190, 188, 116, 117, 118,
    119, 66,  80,  84,  34,  33,   8,  49,  50,  51,
    52,  53,  54,  55,  56,  57,  48,  32,  46,  13,
    27,  77,  86,  68,  67
  );

  KEY_FUNC_TX: array [0..KEYMAP_COUNT-1] of Word = (
    TX_KEY_FUNC_SCROLL_LEFT, TX_KEY_FUNC_SCROLL_RIGHT, TX_KEY_FUNC_SCROLL_UP, TX_KEY_FUNC_SCROLL_DOWN, TX_KEY_FUNC_MENU_BUILD,
    TX_KEY_FUNC_MENU_RATIO, TX_KEY_FUNC_MENU_STATS, TX_KEY_FUNC_MENU_MAIN, TX_KEY_FUNC_HALT, TX_KEY_FUNC_SPLIT,
    TX_KEY_FUNC_LINKUP, TX_KEY_FUNC_FOOD, TX_KEY_FUNC_STORM, TX_KEY_FUNC_FORM_INCREASE, TX_KEY_FUNC_FORM_DECREASE,
    TX_KEY_FUNC_TURN_CW, TX_KEY_FUNC_TURN_CCW, TX_KEY_FUNC_GAME_SPEED_1, TX_KEY_FUNC_GAME_SPEED_2, TX_KEY_FUNC_GAME_SPEED_3,
    TX_KEY_FUNC_GAME_SPEED_4, TX_KEY_FUNC_BEACON, TX_KEY_FUNC_PAUSE, TX_KEY_FUNC_SHOW_TEAMS, TX_KEY_FUNC_ZOOM_IN,
    TX_KEY_FUNC_ZOOM_OUT, TX_KEY_FUNC_ZOOM_RESET, TX_KEY_FUNC_SELECT_1, TX_KEY_FUNC_SELECT_2, TX_KEY_FUNC_SELECT_3,
    TX_KEY_FUNC_SELECT_4, TX_KEY_FUNC_SELECT_5, TX_KEY_FUNC_SELECT_6, TX_KEY_FUNC_SELECT_7, TX_KEY_FUNC_SELECT_8,
    TX_KEY_FUNC_SELECT_9, TX_KEY_FUNC_SELECT_10, TX_KEY_FUNC_CENTER_ALERT, TX_KEY_FUNC_DELETE_MSG, TX_KEY_FUNC_SHOW_GAME_CHAT,
    TX_KEY_FUNC_CLOSE_MENU, TX_KEY_FUNC_DBG_MAP, TX_KEY_FUNC_DBG_VICTORY, TX_KEY_FUNC_DBG_DEFEAT, TX_KEY_FUNC_DBG_SCOUT
  );

type
  TKMKeyLibrary = class
  private
    fCount: Integer;
    fKeys: array [0..KEYMAP_COUNT-1] of Integer;
    fKeymapPath: string;
    function GetKeys(aIndex: Word): Integer;
    procedure SetKeys(aIndex: Word; aValue: Integer);
  public
    constructor Create;
    property Count: Integer read fCount;
    function GetKeyName(aKey: Word): string;
    function GetKeyNameById(aId: Word): string;
    function GetFunctionNameById(aId: Integer): string;
    property Keys[aIndex: Word]: Integer read GetKeys write SetKeys; default;
    procedure LoadKeymapFile;
    procedure ResetKeymap;
    procedure SaveKeymap;
  end;


var
  // All games Keys accessible from everywhere
  gResKeys: TKMKeyLibrary;


implementation


{ TKMKeyLibrary }
constructor TKMKeyLibrary.Create;
begin
  inherited;

  fCount := KEYMAP_COUNT;
  fKeymapPath := (ExeDir + 'keys.keymap');

  LoadKeymapFile;
end;


// Each line in .keymap file has an index and a text. Lines without index are skipped
procedure TKMKeyLibrary.LoadKeymapFile;
var
  I: Integer;
  SL: TStringList;
  delim1, delim2: Integer;
  keyId, keyVal: Integer;
begin
  if not FileExists(fKeymapPath) then
  begin
    ResetKeymap;
    Exit;
  end;

  SL := TStringList.Create;
  {$IFDEF WDC} SL.LoadFromFile(fKeymapPath); {$ENDIF}
  //In FPC TStringList can't cope with BOM (or UnicodeStrings at all really)
  {$IFDEF FPC} SL.Text := ReadTextU(aFile, 1252); {$ENDIF}

  // Parse text
  for I := 0 to SL.Count - 1 do
  begin
    delim1 := Pos(':', SL[I]);
    delim2 := Pos('//', SL[I]);
    if (delim1 = 0) or (delim2 = 0) or (delim1 > delim2) then Continue;

    keyId := StrToIntDef(Copy(SL[I], 0, delim1 - 1), -1);
    keyVal := StrToIntDef(Copy(SL[I], delim1 + 1, delim2 - delim1 - 1), -1);

    if not InRange(keyId, 0, fCount - 1) or (keyVal = -1) then Continue;

    fKeys[keyId] := keyVal;
  end;
end;


function TKMKeyLibrary.GetKeys(aIndex: Word): Integer;
begin
  Result := fKeys[aIndex];
end;


procedure TKMKeyLibrary.SetKeys(aIndex: Word; aValue: Integer);
begin
  fKeys[aIndex] := aValue;
end;


procedure TKMKeyLibrary.SaveKeymap;
var
  Keystring: string;
  KeyStringList: TStringList;
  I: Integer;
begin
  KeyStringList := TStringList.Create;
  {$IFDEF WDC}KeyStringList.DefaultEncoding := TEncoding.UTF8;{$ENDIF}

  for I := 0 to fCount - 1 do
  begin
    Keystring := IntToStr(I) + ':'+ IntToStr(fKeys[I]) + '// ' + GetFunctionNameById(I);
    KeyStringList.Add(Keystring);
  end;

  KeyStringList.SaveToFile(fKeymapPath{$IFDEF WDC}, TEncoding.UTF8{$ENDIF});
  KeyStringList.Free;
end;


procedure TKMKeyLibrary.ResetKeymap;
var
  I: Integer;
begin
  for I := 0 to fCount - 1 do
    fKeys[I] := DEF_KEYS[I];
end;


// Here we define the action name values
function TKMKeyLibrary.GetFunctionNameById(aId: Integer): string;
begin
  case aId of
    0..KEYMAP_COUNT - 1: Result := gResTexts[KEY_FUNC_TX[aId]];

    // Higher value to separate bindable keys from special keys
    100: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_EXTRA];
    101: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_TERAIN_EDIT];
    102: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_VILLAGE_PLAN];
    103: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_VISUAL_SCRIPT];
    104: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_GLOBAL_SCRIPT];
    105: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_MENU_MAIN];
    106: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_1];
    107: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_2];
    108: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_3];
    109: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_4];
    110: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_5];
    111: Result := gResTexts[TX_KEY_FUNC_MAPEDIT_SUBMENU_6];
    112: Result := gResTexts[TX_KEY_FUNC_UNASSIGNABLE];
    113: Result := gResTexts[TX_KEY_FUNC_UNASSIGNABLE];
  else
    Result := gResTexts[TX_KEY_FUNC_UNKNOWN] + ' ' + IntToStr(aId) + '! ~~~';
  end;
{'fraction_non_alphanumeric': 0.10425870295105143, 'fraction_numerical': 0.03702067503092419, 'mean_word_length': 4.573116691285081, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3912569', 'n_tokens_mistral': 4991, 'n_tokens_neox': 4547, 'n_words': 948}