Move the configure and keyconfig data into subtrees of the resource map. As a side effect, default key configurations are read directly from the content directory.

THIS IS AN INCOMPATIBLE CHANGE TO THE CONFIG FILES. Update content as well as src when upgrading here. Old configurations will be lost but the upgrade should otherwise be automatic.

Bumped version to 0.6.5 to commemorate the incompatible change.


git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3108 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
mcmartin
2009-02-16 00:40:42 +00:00
parent f2e4a8e223
commit c4f404af0a
12 changed files with 312 additions and 495 deletions
+9 -34
View File
@@ -146,11 +146,10 @@ register_flight_controls (void)
static void
initKeyConfig (void)
{
uio_Stream *fp;
int i;
/* First, load in the menu keys */
res_LoadFilename (contentDir, "menu.key", NULL);
LoadResourceIndex (contentDir, "menu.key", "menu.");
for (i = 0; i < NUM_MENU_KEYS; i++)
{
if (!menu_res_names[i])
@@ -158,30 +157,15 @@ initKeyConfig (void)
register_menu_controls (i);
}
fp = res_OpenResFile (configDir, "flight.cfg", "rt");
if (!fp)
LoadResourceIndex (configDir, "flight.cfg", "keys.");
if (!res_HasKey ("keys.1.name"))
{
if (copyFile (contentDir, "uqm.key",
configDir, "flight.cfg") == -1)
{
log_add (log_Fatal, "Error: Could not copy default key config "
"to user config dir: %s.", strerror (errno));
exit (EXIT_FAILURE);
}
log_add (log_Info, "Copying default key config file to user "
"config dir.");
if ((fp = res_OpenResFile (configDir, "flight.cfg", "rt")) == NULL)
{
log_add (log_Fatal, "Error: Could not open flight.cfg");
exit (EXIT_FAILURE);
}
/* Either flight.cfg doesn't exist, or we're using an old version
of flight.cfg, and thus we wound up loading untyped values into
'keys.keys.1.name' and such. Load the defaults from the content
directory. */
LoadResourceIndex (contentDir, "uqm.key", "keys.");
}
res_LoadFile (fp, NULL);
// TODO RES070
// res_LoadFile (fp, "keys.");
res_CloseResFile (fp);
register_flight_controls ();
@@ -454,16 +438,7 @@ RebindInputState (int template, int control, int index)
void
SaveKeyConfiguration (uio_DirHandle *path, const char *fname)
{
uio_Stream *f;
f = res_OpenResFile (path, fname, "wb");
if (f)
{
res_SaveFile (f, "keys.", FALSE);
// TODO RES070
// res_SaveFile (f, "keys.", TRUE);
res_CloseResFile (f);
}
SaveResourceIndex (path, fname, "keys.", TRUE);
}
void
-8
View File
@@ -59,7 +59,6 @@ long LengthResFile (uio_Stream *fp);
BOOLEAN res_CloseResFile (uio_Stream *fp);
BOOLEAN DeleteResFile (uio_DirHandle *dir, const char *filename);
RESOURCE_INDEX InitResourceSystem ();
void UninitResourceSystem (void);
BOOLEAN InstallResTypeVectors (const char *res_type, ResourceLoadFun *loadFun, ResourceFreeFun *freeFun, ResourceStringFun *stringFun);
void *res_GetResource (RESOURCE res);
@@ -99,13 +98,6 @@ extern DIRENTRY_REF LoadDirEntryTable (uio_DirHandle *dirHandle,
#define GetDirEntryContents GetStringContents
/* Key-Value resources */
void res_ClearTables (void);
void res_LoadFilename (uio_DirHandle *path, const char *fname, const char *prefix);
void res_SaveFilename (uio_DirHandle *path, const char *fname, const char *root, BOOLEAN strip_root);
void res_LoadFile (uio_Stream *fname, const char *prefix);
void res_SaveFile (uio_Stream *fname, const char *root, BOOLEAN strip_root);
BOOLEAN res_HasKey (const char *key);
+2 -2
View File
@@ -1,2 +1,2 @@
uqm_CFILES="direct.c filecntl.c getres.c loadres.c mapres.c
propfile.c resdata.c resinit.c stringbank.c"
uqm_CFILES="direct.c filecntl.c getres.c loadres.c stringbank.c
propfile.c resinit.c"
-250
View File
@@ -1,250 +0,0 @@
/* mapres.c, Copyright (c) 2005 Michael C. Martin */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope thta it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Se the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "libs/reslib.h"
#include "libs/log.h"
#include "libs/uio/charhashtable.h"
#include "propfile.h"
#include "stringbank.h"
/* The CharHashTable owns its keys, but not its values. We will keep the
values in a StringBank. */
static CharHashTable_HashTable *map = NULL;
static stringbank *bank = NULL;
static void
check_map_init (void)
{
if (map == NULL) {
map = CharHashTable_newHashTable (NULL, NULL, NULL, NULL, 0, 0.85, 0.9);
}
if (bank == NULL) {
bank = StringBank_Create ();
}
}
void
res_ClearTables (void)
{
if (map != NULL) {
CharHashTable_deleteHashTable (map);
map = NULL;
}
if (bank != NULL) {
StringBank_Free (bank);
bank = NULL;
}
}
BOOLEAN
res_Remove (const char *key)
{
return CharHashTable_remove (map, key);
}
/* Type conversion routines. */
static const char *
bool2str (BOOLEAN b)
{
return b ? "yes" : "no";
}
static const char *
int2str (int i) {
char buf[20];
sprintf (buf, "%d", i);
return StringBank_AddOrFindString (bank, buf);
}
static int
str2int (const char *s) {
return atoi(s);
}
static BOOLEAN
str2bool (const char *s) {
if (!strcasecmp (s, "yes") ||
!strcasecmp (s, "true") ||
!strcasecmp (s, "1") )
return TRUE;
return FALSE;
}
BOOLEAN
res_IsBoolean (const char *key)
{
const char *d;
check_map_init ();
d = res_GetString (key);
if (!d) return 0;
return !strcasecmp (d, "yes") ||
!strcasecmp (d, "no") ||
!strcasecmp (d, "true") ||
!strcasecmp (d, "false") ||
!strcasecmp (d, "0") ||
!strcasecmp (d, "1") ||
!strcasecmp (d, "");
}
BOOLEAN
res_IsInteger (const char *key)
{
const char *d;
check_map_init ();
d = res_GetString (key);
while (*d) {
if (!isdigit (*d))
return 0;
d++;
}
return 1;
}
const char *
res_GetString (const char *key)
{
check_map_init ();
return CharHashTable_find (map, key);
}
void
res_PutString (const char *key, const char *value)
{
check_map_init ();
value = StringBank_AddOrFindString (bank, value);
if (!CharHashTable_add (map, key, (void *)value))
{
CharHashTable_remove (map, key);
CharHashTable_add (map, key, (void *)value);
}
}
int
res_GetInteger (const char *key)
{
check_map_init ();
return str2int (res_GetString (key));
}
void
res_PutInteger (const char *key, int value)
{
check_map_init ();
res_PutString (key, int2str(value));
}
BOOLEAN
res_GetBoolean (const char *key)
{
check_map_init ();
return str2bool (res_GetString (key));
}
void
res_PutBoolean (const char *key, BOOLEAN value)
{
check_map_init ();
res_PutString (key, bool2str(value));
}
BOOLEAN
res_HasKey (const char *key)
{
check_map_init ();
return (res_GetString (key) != NULL);
}
void
res_LoadFile (uio_Stream *s, const char *prefix)
{
check_map_init ();
if (!map)
{
return;
}
PropFile_from_file (s, res_PutString, prefix);
}
void
res_LoadFilename (uio_DirHandle *path, const char *fname, const char *prefix)
{
check_map_init ();
if (!map)
{
return;
}
PropFile_from_filename (path, fname, res_PutString, prefix);
}
void
res_SaveFile (uio_Stream *f, const char *prefix, BOOLEAN strip_root)
{
CharHashTable_Iterator *i;
int prefix_len = 0;
if (prefix)
prefix_len = strlen (prefix);
check_map_init ();
i = CharHashTable_getIterator (map);
while (!CharHashTable_iteratorDone (i))
{
const char *key = CharHashTable_iteratorKey (i);
const char *value = (const char *)CharHashTable_iteratorValue (i);
if (!prefix || !strncmp (prefix, key, prefix_len)) {
if (prefix && strip_root) {
WriteResFile (key+prefix_len, 1, strlen (key) - prefix_len, f);
} else {
WriteResFile (key, 1, strlen (key), f);
}
PutResFileChar(' ', f);
PutResFileChar('=', f);
PutResFileChar(' ', f);
WriteResFile (value, 1, strlen (value), f);
PutResFileNewline(f);
}
i = CharHashTable_iteratorNext (i);
}
CharHashTable_freeIterator (i);
}
void
res_SaveFilename (uio_DirHandle *path, const char *fname, const char *prefix, BOOLEAN strip_root)
{
uio_Stream *f;
check_map_init ();
f = res_OpenResFile (path, fname, "wb");
if (f) {
res_SaveFile (f, prefix, strip_root);
res_CloseResFile (f);
}
}
-34
View File
@@ -1,34 +0,0 @@
//Copyright Paul Reiche, Fred Ford. 1992-2002
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "resintrn.h"
static RESOURCE_INDEX curResourceIndex;
void
_set_current_index_header (RESOURCE_INDEX newResourceIndex)
{
curResourceIndex = newResourceIndex;
}
RESOURCE_INDEX
_get_current_index_header (void)
{
return curResourceIndex;
}
+142 -12
View File
@@ -23,6 +23,7 @@
#include "types.h"
#include "libs/log.h"
#include "libs/gfxlib.h"
#include "libs/reslib.h"
#include "libs/sndlib.h"
#include "libs/vidlib.h"
#include "coderes.h"
@@ -127,18 +128,7 @@ process_resource_desc (const char *key, const char *value)
{
if (!CharHashTable_add (map, key, newDesc))
{
ResourceDesc *oldDesc = (ResourceDesc *)CharHashTable_find (map, key);
if (oldDesc != NULL)
{
if (newDesc->resdata.ptr != NULL)
{
/* XXX: It might be nice to actually clean it up properly */
log_add (log_Warning, "LEAK WARNING: Replaced '%s' while it was live", key);
}
HFree (oldDesc->fname);
HFree (oldDesc);
}
CharHashTable_remove (map, key);
res_Remove (key);
CharHashTable_add (map, key, newDesc);
}
}
@@ -188,9 +178,20 @@ BooleanToString (RESOURCE_DATA *resdata, char *buf, unsigned int size)
snprintf (buf, size, "%s", resdata->num ? "true" : "false");
}
static RESOURCE_INDEX curResourceIndex;
void
_set_current_index_header (RESOURCE_INDEX newResourceIndex)
{
curResourceIndex = newResourceIndex;
}
RESOURCE_INDEX
InitResourceSystem (void)
{
if (curResourceIndex) {
return curResourceIndex;
}
RESOURCE_INDEX ndx = allocResourceIndex ();
_set_current_index_header (ndx);
@@ -208,6 +209,15 @@ InitResourceSystem (void)
return ndx;
}
RESOURCE_INDEX
_get_current_index_header (void)
{
if (!curResourceIndex) {
InitResourceSystem ();
}
return curResourceIndex;
}
void
LoadResourceIndex (uio_DirHandle *dir, const char *rmpfile, const char *prefix)
{
@@ -304,3 +314,123 @@ InstallResTypeVectors (const char *resType, ResourceLoadFun *loadFun,
map = _get_current_index_header ()->map;
return CharHashTable_add (map, key, result) != 0;
}
/* These replace the mapres.c calls and probably should be split out at some point. */
const char *
res_GetString (const char *key)
{
RESOURCE_INDEX idx = _get_current_index_header ();
ResourceDesc *desc = lookupResourceDesc (idx, key);
if (!desc || !desc->resdata.ptr || strcmp(desc->vtable->resType, "STRING"))
return NULL;
return (const char *)desc->resdata.ptr;
}
void
res_PutString (const char *key, const char *value)
{
RESOURCE_INDEX idx = _get_current_index_header ();
ResourceDesc *desc = lookupResourceDesc (idx, key);
int srclen, dstlen;
if (!desc || !desc->resdata.ptr || strcmp(desc->vtable->resType, "STRING"))
{
/* TODO: This is kind of roundabout. We can do better by refactoring newResourceDesc */
process_resource_desc(key, "STRING:undefined");
desc = lookupResourceDesc (idx, key);
}
srclen = strlen (value);
dstlen = strlen (desc->resdata.ptr);
if (srclen > dstlen) {
char *newValue = HMalloc(srclen + 1);
char *oldValue = desc->fname;
log_add(log_Warning, "Reallocating string space for '%s'", key);
strncpy (newValue, value, srclen + 1);
desc->resdata.ptr = newValue;
desc->fname = newValue;
HFree (oldValue);
} else {
strncpy (desc->resdata.ptr, value, srclen + 1);
}
}
int
res_GetInteger (const char *key)
{
RESOURCE_INDEX idx = _get_current_index_header ();
ResourceDesc *desc = lookupResourceDesc (idx, key);
if (!desc || strcmp(desc->vtable->resType, "INT32"))
{
// TODO: Better error handling
return 0;
}
return desc->resdata.num;
}
void
res_PutInteger (const char *key, int value)
{
RESOURCE_INDEX idx = _get_current_index_header ();
ResourceDesc *desc = lookupResourceDesc (idx, key);
if (!desc || strcmp(desc->vtable->resType, "INT32"))
{
/* TODO: This is kind of roundabout. We can do better by refactoring newResourceDesc */
process_resource_desc(key, "INT32:0");
desc = lookupResourceDesc (idx, key);
}
desc->resdata.num = value;
}
BOOLEAN
res_GetBoolean (const char *key)
{
RESOURCE_INDEX idx = _get_current_index_header ();
ResourceDesc *desc = lookupResourceDesc (idx, key);
if (!desc || strcmp(desc->vtable->resType, "BOOLEAN"))
{
// TODO: Better error handling
return FALSE;
}
return desc->resdata.num ? TRUE : FALSE;
}
void
res_PutBoolean (const char *key, BOOLEAN value)
{
RESOURCE_INDEX idx = _get_current_index_header ();
ResourceDesc *desc = lookupResourceDesc (idx, key);
if (!desc || strcmp(desc->vtable->resType, "BOOLEAN"))
{
/* TODO: This is kind of roundabout. We can do better by refactoring newResourceDesc */
process_resource_desc(key, "BOOLEAN:false");
desc = lookupResourceDesc (idx, key);
}
desc->resdata.num = value;
}
BOOLEAN
res_HasKey (const char *key)
{
RESOURCE_INDEX idx = _get_current_index_header ();
return (lookupResourceDesc(idx, key) != NULL);
}
BOOLEAN
res_Remove (const char *key)
{
CharHashTable_HashTable *map = _get_current_index_header ()->map;
ResourceDesc *oldDesc = (ResourceDesc *)CharHashTable_find (map, key);
if (oldDesc != NULL)
{
if (oldDesc->resdata.ptr != NULL)
{
log_add (log_Warning, "WARNING: Replacing '%s' while it is live", key);
if (oldDesc->vtable && oldDesc->vtable->freeFun)
{
oldDesc->vtable->freeFun(oldDesc->resdata.ptr);
}
}
HFree (oldDesc->fname);
HFree (oldDesc);
}
return CharHashTable_remove (map, key);
}
+2 -5
View File
@@ -328,6 +328,7 @@ do_editkeys (WIDGET *self, int event)
static void
change_template (WIDGET_CHOICE *self, int oldval)
{
(void) oldval;
populate_editkeys (self->selected);
}
@@ -517,8 +518,6 @@ OnTextEntryChange (TEXTENTRY_STATE *pTES)
static BOOLEAN
OnTextEntryFrame (TEXTENTRY_STATE *pTES)
{
WIDGET_TEXTENTRY *widget = (WIDGET_TEXTENTRY *) pTES->CbParam;
redraw_menu ();
SleepThreadUntil (pTES->NextTime);
@@ -1371,8 +1370,6 @@ SetGlobalOptions (GLOBALOPTS *opts)
res_PutString ("keys.5.name", input_templates[4].name);
res_PutString ("keys.6.name", input_templates[5].name);
res_SaveFilename (configDir, "uqm.cfg", "config.", FALSE);
// TODO RES070
// res_SaveFilename (configDir, "uqm.cfg", "config.", TRUE);
SaveResourceIndex (configDir, "uqm.cfg", "config.", TRUE);
SaveKeyConfiguration (configDir, "flight.cfg");
}
+28 -23
View File
@@ -103,6 +103,7 @@ static int parseIntOption (const char *str, int *result,
const char *optName);
static int parseFloatOption (const char *str, float *f,
const char *optName);
static void parseIntVolume (int intVol, float *vol);
static int parseVolume (const char *str, float *vol, const char *optName);
static int InvalidArgument (const char *supplied, const char *opt_name);
static int Check_PC_3DO_opt (const char *value, DWORD mask, const char *opt,
@@ -210,9 +211,7 @@ main (int argc, char *argv[])
PlayerControls[1] = CONTROL_TEMPLATE_JOY_1;
// Fill in the options struct based on uqm.cfg
res_LoadFilename (configDir, "uqm.cfg", NULL);
// TODO RES070
// res_LoadFilename (configDir, "uqm.cfg", "config.");
LoadResourceIndex (configDir, "uqm.cfg", "config.");
if (res_HasKey ("config.reswidth"))
{
@@ -381,18 +380,18 @@ main (int argc, char *argv[])
}
if (res_HasKey ("config.musicvol"))
{
parseVolume (res_GetString ("config.musicvol"),
&options.musicVolumeScale, "music volume");
parseIntVolume (res_GetInteger ("config.musicvol"),
&options.musicVolumeScale);
}
if (res_HasKey ("config.sfxvol"))
{
parseVolume (res_GetString ("config.sfxvol"),
&options.sfxVolumeScale, "SFX volume");
parseIntVolume (res_GetInteger ("config.sfxvol"),
&options.sfxVolumeScale);
}
if (res_HasKey ("config.speechvol"))
{
parseVolume (res_GetString ("config.speechvol"),
&options.speechVolumeScale, "speech volume");
parseIntVolume (res_GetInteger ("config.speechvol"),
&options.speechVolumeScale);
}
{ /* remove old control template names */
@@ -907,6 +906,25 @@ parseOptions (int argc, char *argv[], struct options_struct *options)
return EXIT_SUCCESS;
}
static void
parseIntVolume (int intVol, float *vol)
{
if (intVol < 0)
{
*vol = 0.0f;
return;
}
if (intVol > 100)
{
*vol = 1.0f;
return;
}
*vol = intVol / 100.0f;
return;
}
static int
parseVolume (const char *str, float *vol, const char *optName)
{
@@ -925,20 +943,7 @@ parseVolume (const char *str, float *vol, const char *optName)
"for '%s'.", optName);
return -1;
}
if (intVol < 0)
{
*vol = 0.0f;
return 0;
}
if (intVol > 100)
{
*vol = 1.0f;
return 0;
}
*vol = intVol / 100.0f;
parseIntVolume (intVol, vol);
return 0;
}
+2 -2
View File
@@ -21,8 +21,8 @@
#define UQM_MAJOR_VERSION_S "0"
#define UQM_MINOR_VERSION 6
#define UQM_MINOR_VERSION_S "6"
#define UQM_PATCH_VERSION 4
#define UQM_PATCH_VERSION_S "4"
#define UQM_PATCH_VERSION 5
#define UQM_PATCH_VERSION_S "5"
#define UQM_EXTRA_VERSION ""
/* The final version is interpreted as:
* printf ("%d.%d.%d%s", UQM_MAJOR_VERSION, UQM_MINOR_VERSION,