Easy config files: Dictionary to Ini files and vice versa

Started by eri0o, Sun 13/09/2020 17:45:48

Previous topic - Next topic

eri0o

Not sure if this already exists... Did it for myself because I needed a quick way to config something independently of save games. It's an extension of AGS Dictionaries so they can serialize and deserialize to ini files and strings.

dicttoini.ash
Code: ags
// DictToIni Module Header 
// Version 0.0.1 - needs testing!
// Note: currently spaces aren't trimmed

/// Creates a new ini-like string representing the dictionary.
import String ToIniString(this Dictionary*);

/// Overwrites the dictionary with the key value pairs in the ini-like string.
import void FromIniString(this Dictionary*, String ini_string);

/// Creates an ini file on the player's save directory, from current dictionary key value pairs.
import void ToIniFile(this Dictionary*, String filename);

/// Reads an ini file on the player's save directory and replaces current dictionary with file's key value pairs.
import void FromIniFile(this Dictionary*, String filename);


dicttoini.asc
Code: ags
// DictToIni Module Script

#region STRING_EXTENSIONS
// ---- START OF STRING EXTENSIONS ---------------------------------------------

int CountToken(this String*, String token)
{
  int count = 0, cur = 0, next = 0;
  String sub = this.Copy();

  while(sub.Length > 0)
  {
    if(sub.IndexOf(token)==-1) return count;
    sub = sub.Substring(sub.IndexOf(token)+token.Length, sub.Length);
    count++;
  }
  return count;
}

String[] Split(this String*, String token)
{
  int i = 0, cur = 0, count;
  count = this.CountToken(token);
  if(count<=0)
  {
    String r[] = new String[1];
    r[0] = null;
    return r;
  }

  String r[] = new String[count+2];
  String sub = this.Copy();

  while(i < count)
  {
    cur = sub.IndexOf(token);
    if(cur==-1) cur=sub.Length;
    r[i] = sub.Substring(0, cur);
    sub = sub.Substring(sub.IndexOf(token)+token.Length, sub.Length);
    i++;
  }

  r[i] = sub.Substring(0, sub.Length);
  i++;
  r[i] = null;
  return  r;
}
// ---- END OF STRING EXTENSIONS -----------------------------------------------
#endregion //STRING_EXTENSIONS

String ToIniString(this Dictionary*)
{
  String ini_string = "";
  int keycount;
  String keys[];
  
  keys = this.GetKeysAsArray();
  keycount = this.ItemCount;
  
  for(int i=0; i<keycount; i++)
  {
    String value = this.Get(keys[i]);
    ini_string = ini_string.Append(String.Format("%s=%s\n", keys[i], value));
  }
  
  return ini_string;
}

void FromIniString(this Dictionary*, String ini_string)
{
  this.Clear();
  if(String.IsNullOrEmpty(ini_string)) return;
  
  int linecount = ini_string.CountToken("\n");
  String lines[] = ini_string.Split("\n");
  
  for(int i=0; i<linecount; i++)
  {
    if(lines[i].IndexOf("=") <= -1) continue;
   
    String kv[] = lines[i].Split("=");
    if(String.IsNullOrEmpty(kv[0]) || String.IsNullOrEmpty(kv[1])) continue;

    this.Set(kv[0], kv[1]);
  }
}

void ToIniFile(this Dictionary*, String filename)
{
  if(this.ItemCount == 0) return;
  
  String filepath = "$SAVEGAMEDIR$/";
  filepath = filepath.Append(filename);
  File* file = File.Open(filepath, eFileWrite);
  
  String ini_string = this.ToIniString();
    
  file.WriteRawLine(ini_string);

  file.Close();
}

void FromIniFile(this Dictionary*, String filename)
{
  this.Clear();  
  if(String.IsNullOrEmpty(filename)) return;

  String filepath = "$SAVEGAMEDIR$/";
  filepath = filepath.Append(filename);
  File* file = File.Open(filepath, eFileRead);
  
  for(String line = ""; !file.EOF; line = file.ReadRawLineBack())
  {
    if(String.IsNullOrEmpty(line)) continue;
    if(line .IndexOf("=") <= -1) continue;
    
    String kv[] = line.Split("=");
    if(String.IsNullOrEmpty(kv[0]) || String.IsNullOrEmpty(kv[1])) continue;
    
    this.Set(kv[0], kv[1]);
  }
  
  file.Close();  
}


I am attaching below a demo game where you can save and restore the config on the Sierra Menu. It will create a file game_config.ini in your game's save directory with the contents below (numbers depends on your slider).
Code: ini
speech_mode=1
speed=40
gamma_value=100
voice_volume=255
audio_volume=28


Demo: dicttoini.zip

Relevant change from the Sierra Template menu, is on GlobalScript.asc:

Code: ags

function btnSaveConfig_OnClick(GUIControl *control, MouseButton button)
{
  Dictionary* dict = Dictionary.Create(eNonSorted, eCaseSensitive);
  dict.Set("audio_volume", String.Format("%d",sldAudio.Value));
  dict.Set("voice_volume", String.Format("%d",sldVoice.Value));
  dict.Set("gamma_value", String.Format("%d",sldGamma.Value));
  dict.Set("speed", String.Format("%d",sldSpeed.Value));
  dict.Set("speech_mode", String.Format("%d",Speech.VoiceMode));
  dict.ToIniFile("game_config.ini");
}

function btnLoadConfig_OnClick(GUIControl *control, MouseButton button)
{
  Dictionary* dict = Dictionary.Create(eNonSorted);

  dict.FromIniFile("game_config.ini");
  if(dict.Contains("audio_volume"))
  {
    String key = dict.Get("audio_volume");
    sldAudio.Value = key.AsInt;
    System.Volume = sldAudio.Value;
  }
  if(dict.Contains("voice_volume"))
  {
    String key = dict.Get("voice_volume");
    sldVoice.Value = key.AsInt;
    SetSpeechVolume(sldVoice.Value);
  }
  if(dict.Contains("gamma_value"))
  {
    String key = dict.Get("gamma_value");
    sldGamma.Value = key.AsInt;
    System.Gamma = sldGamma.Value;
  }
  if(dict.Contains("speed"))
  {
    String key = dict.Get("speed");
    sldSpeed.Value = key.AsInt;
    SetGameSpeed(sldSpeed.Value);
  }
  if(dict.Contains("speech_mode"))
  {
    String key = dict.Get("speech_mode");
    Speech.VoiceMode = key.AsInt;
    if (Speech.VoiceMode == eSpeechVoiceOnly) btnVoice.Text = "Voice only";
    else if (Speech.VoiceMode == eSpeechTextOnly) btnVoice.Text = "Text only";
    else btnVoice.Text = "Voice and Text";
  }
}


SMF spam blocked by CleanTalk