Configuration routines

Various parts of Allegro, such as the sound routines and the load_joystick_data() function, require some configuration information. This data is stored in text files as a collection of `variable=value' lines, along with comments that begin with a `#' character and continue to the end of the line. The configuration file may optionally be divided into sections, which begin with a `[sectionname]' line. Each section has a unique namespace, to prevent variable name conflicts, but any variables that aren't in a section are considered to belong to all the sections simultaneously.

Note that variable and section names cannot contain spaces.

By default the configuration data is read from a file called `allegro.cfg', which can be located either in the same directory as the program executable, or the directory pointed to by the ALLEGRO environment variable. Under Unix, it also checks for `~/allegro.cfg', `~/.allegrorc', `/etc/allegro.cfg', and `/etc/allegrorc', in that order; under BeOS only the last two are also checked. MacOS X also checks in the Contents/Resources directory of the application bundle, if any, before doing the checks above.

If you don't like this approach, you can specify any filename you like, or use a block of binary configuration data provided by your program (which could for example be loaded from a datafile). You can also extend the paths searched for allegro resources with set_allegro_resource_path().

You can store whatever custom information you like in the config file, along with the standard variables that are used by Allegro (see below). Allegro comes with a setup directory where you can find configuration programs. The standalone setup program is likely to be of interest to final users. It allows any user to create an `allegro.cfg' file without the need to touch a text editor and enter values by hand. It also provides a few basic tests like sound playing for sound card testing. You are welcome to include the setup program with your game, either as is or with modified graphics to fit better your game.


void set_config_file(const char *filename);

Sets the configuration file to be used by all subsequent config functions. If you don't call this function, Allegro will use the default `allegro.cfg' file, looking first in the same directory as your program and then in the directory pointed to by the ALLEGRO environment variable and the usual platform-specific paths for configuration files. For example it will look for `/etc/allegro.cfg' under Unix.

All pointers returned by previous calls to get_config_string() and other related functions are invalidated when you call this function! You can call this function before install_allegro() to change the configuration file, but after set_uformat() if you want to use a text encoding format other than the default.

See also: set_config_data, override_config_file, push_config_state, set_uformat, Standard config variables, set_config_string, get_config_string.
Examples using this: exconfig.
void set_config_data(const char *data, int length);

Specifies a block of data to be used by all subsequent config functions, which you have already loaded from disk (eg. as part of some more complicated format of your own, or in a grabber datafile). This routine makes a copy of the information, so you can safely free the data after calling it.
See also: set_config_file, override_config_data, push_config_state, Standard config variables, set_config_string, get_config_string.
void override_config_file(const char *filename);

Specifies a file containing config overrides. These settings will be used in addition to the parameters in the main config file, and where a variable is present in both files this version will take priority. This can be used by application programmers to override some of the config settings from their code, while still leaving the main config file free for the end user to customise. For example, you could specify a particular sample frequency and IBK instrument file, but the user could still use an `allegro.cfg' file to specify the port settings and irq numbers.

The override config file will not only take precedence when reading, but will also be used for storing values. When you are done with using the override config file, you can call override_config_file with a NULL parameter, so config data will be directly read from the current config file again.

Note: The override file is completely independent from the current configuration. You can e.g. call set_config_file, and the override file will still be active. Also the flush_config_file function will only affect the current config file (which can be changed with set_config_file), never the overriding one specified with this function. The modified override config is written back to disk whenever you call override_config_file.

Example:

      override_config_file("my.cfg");
      /* This will read from my.cfg, and if it doesn't find a
       * setting, will read from the current config file instead.
       */
      language = get_config_string("system", "language", NULL);
      /* This will always write to my.cfg, no matter if the
       * settings is already present or not.
       */
      set_config_string("system", "language", "RU");
      /* This forces the changed setting to be written back to
       * disk. Else it is written back at the next call to
       * override_config_file, or when Allegro shuts down.
       */
      override_config_file(NULL);

Note that this function and override_config_data() are mutually exclusive, i.e. calling one will cancel the effects of the other.

See also: override_config_data, set_config_file.
void override_config_data(const char *data, int length);

Version of override_config_file() which uses a block of data that has already been read into memory. The length of the block has to be specified in bytes. Example:
      /* Force German as system language, Spanish keyboard map. */
      const char *override_data = "[system]\n"
         "language=DE\n"
         "keyboard=ES";
      override_config_data(override_data, ustrsize(override_data));

Note that this function and override_config_file() are mutually exclusive, i.e. calling one will cancel the effects of the other.

See also: override_config_file, set_config_data.
void push_config_state();

Pushes the current configuration state (filename, variable values, etc). onto an internal stack, allowing you to select some other config source and later restore the current settings by calling pop_config_state(). This function is mostly intended for internal use by other library functions, for example when you specify a config filename to the save_joystick_data() function, it pushes the config state before switching to the file you specified.
See also: pop_config_state, set_config_file, save_joystick_data.
Examples using this: exconfig.
void pop_config_state();

Pops a configuration state previously stored by push_config_state(), replacing the current config source with it.
See also: push_config_state.
Examples using this: exconfig.
void flush_config_file();

Writes the current config file to disk if the contents have changed since it was loaded or since the latest call to the function.
See also: set_config_file, override_config_file, push_config_state.
void reload_config_texts(const char *new_language);

Reloads the translated strings returned by get_config_text(). This is useful to switch to another language in your program at runtime. If you want to modify the `[system]' language configuration variable yourself, or you have switched configuration files, you will want to pass NULL to just reload whatever language is currently selected. Or you can pass a string containing the two letter code of the language you desire to switch to, and the function will modify the language variable. After you call this function, the previously returned pointers of get_config_text() will be invalid. Example:
      ...
      /* The user selects French from a language choice menu. */
      reload_config_texts("FR");
See also: get_config_text, get_config_string, Standard config variables.
void hook_config_section(const char *section, int (*intgetter)(const char *name, int def), const char *(*stringgetter)(const char *name, const char *def), void (*stringsetter)(const char *name, const char *value));

Takes control of the specified config file section, so that your hook functions will be used to manipulate it instead of the normal disk file access. If both the getter and setter functions are NULL, a currently present hook will be unhooked. Hooked functions have the highest priority. If a section is hooked, the hook will always be called, so you can also hook a '#' section: even override_config_file() cannot override a hooked section. Example:
      int decode_encrypted_int(const char *name, int def)
      {
         ...
      }
      
      const char *decode_encrypted_string(const char *name, const char *def)
      {
         ...
      }
      
      void encode_plaintext_string(const char *name, const char *value)
      {
         ...
      }
      
      int main(int argc, char *argv[])
      {
         ...
         /* Make it harder for users to tinker with the high scores. */
         hook_config_section("high_scores", decode_encrypted_int,
            decode_encrypted_string, encode_plaintext_string);
         ...
      } END_OF_MAIN()
See also: config_is_hooked.
int config_is_hooked(const char *section);

Returns TRUE if the specified config section has been hooked. Example:
      if (config_is_hooked("high_scores")) {
         hook_config_section("high_scores, NULL, NULL, NULL);
      }
See also: hook_config_section.
const char *get_config_string(const char *section, const char *name, const char *def);

Retrieves a string variable from the current config file. The section name may be set to NULL to read variables from the root of the file, or used to control which set of parameters (eg. sound or joystick) you are interested in reading. Example:
      const char *lang = get_config_string("system", "language", "EN");

Return value: Returns a pointer to the constant string found in the configuration file. If the named variable cannot be found, or its entry in the config file is empty, the value of `def' is returned.

See also: set_config_file, set_config_string, get_config_argv, get_config_float, get_config_hex, get_config_int, get_config_id, get_config_text.
Examples using this: exconfig.
int get_config_int(const char *section, const char *name, int def);

Reads an integer variable from the current config file. See the comments about get_config_string().
See also: set_config_file, set_config_int, get_config_string, get_config_argv, get_config_float, get_config_hex, get_config_id.
Examples using this: exconfig.
int get_config_hex(const char *section, const char *name, int def);

Reads an integer variable from the current config file, in hexadecimal format. See the comments about get_config_string().
See also: set_config_file, set_config_hex, get_config_string, get_config_argv, get_config_float, get_config_int, get_config_id.
float get_config_float(const char *section, const char *name, float def);

Reads a floating point variable from the current config file. See the comments about get_config_string().
See also: set_config_file, set_config_float, get_config_string, get_config_argv, get_config_hex, get_config_int, get_config_id.
int get_config_id(const char *section, const char *name, int def);

Reads a 4-letter driver ID variable from the current config file. See the comments about get_config_string().
See also: set_config_file, set_config_id, get_config_string, get_config_argv, get_config_float, get_config_hex, get_config_int.
char **get_config_argv(const char *section, const char *name, int *argc);

Reads a token list (words separated by spaces) from the current config file. The token list is stored in a temporary buffer that will be clobbered by the next call to get_config_argv(), so the data should not be expected to persist.

Return value: Returns an argv style argument list and sets `argc' to the number of retrieved tokens. If the variable is not present, returns NULL and sets argc to zero.

See also: set_config_file, get_config_string, get_config_float, get_config_hex, get_config_int, get_config_id.
Examples using this: exconfig.
const char *get_config_text(const char *msg);

This function is primarily intended for use by internal library code, but it may perhaps be helpful to application programmers as well. It uses the `language.dat' or `XXtext.cfg' files (where XX is a language code) to look up a translated version of the parameter in the currently selected language.

This is basically the same thing as calling get_config_string() with `[language]' as the section, `msg' as the variable name, and `msg' as the default value, but it contains some special code to handle Unicode format conversions. The `msg' parameter is always given in ASCII format, but the returned string will be converted into the current text encoding, with memory being allocated as required, so you can assume that this pointer will persist without having to manually allocate storage space for each string.

Note that if you are planning on distributing your game on the Unix platform there is a special issue with how to deal with the `language.dat' file. Read section "Files shared by Allegro" of the chapter "Unix specifics" to learn more about this.

Return value: Returns a suitable translation if one can be found or a copy of the parameter if nothing else is available.

See also: get_config_string, reload_config_texts, Standard config variables.
void set_config_string(const char *section, const char *name, const char *val);

Writes a string variable to the current config file, replacing any existing value it may have, or removes the variable if `val' is NULL. The section name may be set to NULL to write the variable to the root of the file, or used to control which section the variable is inserted into. The altered file will be cached in memory, and not actually written to disk until you call allegro_exit(). Note that you can only write to files in this way, so the function will have no effect if the current config source was specified with set_config_data() rather than set_config_file().

As a special case, variable or section names that begin with a '#' character are treated specially and will not be read from or written to the disk. Addon packages can use this to store version info or other status information into the config module, from where it can be read with the get_config_string() function.

See also: set_config_file, get_config_string, set_config_float, set_config_hex, set_config_int, set_config_id.
void set_config_int(const char *section, const char *name, int val);

Writes an integer variable to the current config file. See the comments about set_config_string().
See also: set_config_file, get_config_int, set_config_string, set_config_float, set_config_hex, set_config_id.
void set_config_hex(const char *section, const char *name, int val);

Writes an integer variable to the current config file, in hexadecimal format. See the comments about set_config_string().
See also: set_config_file, get_config_hex, set_config_string, set_config_float, set_config_int, set_config_id.
void set_config_float(const char *section, const char *name, float val);

Writes a floating point variable to the current config file. See the comments about set_config_string().
See also: set_config_file, get_config_float, set_config_string, set_config_hex, set_config_int, set_config_id.
void set_config_id(const char *section, const char *name, int val);

Writes a 4-letter driver ID variable to the current config file. See the comments about set_config_string().
See also: set_config_file, get_config_id, set_config_string, set_config_float, set_config_hex, set_config_int.
int list_config_entries(const char *section, const char ***names);

This function can be used to get a list of all entries in the given config section. The names parameter is a pointer to an array of strings. If it points to a NULL pointer, the list will be allocated, else it will be re-allocated. You should free the list again with free_config_entries if you don't need it anymore, or you can pass it again to list_config_entries and the memory will be re-used. See the following example for how you can use it, it will print out the complete contents of the current configuration:
   int i, n;
   char const **sections = NULL;
   char const **entries = NULL;

   /* List all entries not in any section. */
   n = list_config_entries(NULL, &entries);
   for (i = 0; i < n; i++)
      printf(" %s=\"%s\"\n", entries[i], get_config_string(
             NULL, entries[i], "-"));

   /* List all sections (and entries in them). */
   n = list_config_sections(&sections);
   /* loop through all section names */
   for (i = 0; i < n; i++)
   {
      int j, m;
      printf("%s\n", sections[i]);
      m = list_config_entries(sections[i], &entries);
      /* loop through all entries in the section */
      for (j = 0; j < m; j++)
      {
          printf(" %s=\"%s\"\n", entries[j], get_config_string(
             sections[i], entries[j], "-"));
      }
   }
   /* It is enough to free the arrays once at the end. */
   free_config_entries(&sections);
   free_config_entries(&entries);

Return value: Returns the number of valid strings in the names array.

See also: set_config_file, get_config_string, list_config_sections, free_config_entries.
int list_config_sections(const char ***names);

The names parameter is a pointer to an array of strings. If it points to a NULL pointer, the list will be allocated, else it will be re-allocated. After the function returns, it will contain the names of all sections in the current configuration. Use free_config_entries to free the allocated memory again. See list_config_entries for more information and an example how to use it.

Return value: Returns the number of valid strings in the names array.

See also: list_config_entries, set_config_file, get_config_string, free_config_entries.
int free_config_entries(const char ***names);

Once you are done with the string arrays filled in by list_config_entries and list_config_sections, you can free them again with this function. The passed array pointer will be set to NULL, and you directly can pass the same pointer again to list_config_entries or list_config_sections later - but you also could pass them again without freeing first, since the memory is re-allocated when the pointer is not NULL.

See list_config_entries for an example of how to use it.

See also: list_config_entries, list_config_sections.

Standard config variables

Allegro uses these standard variables from the configuration file:

See also: set_config_file, set_config_string, get_config_string.

Back to contents