Setup Menu changes now persist across runs
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1916 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
Changes towards version 0.5:
|
Changes towards version 0.5:
|
||||||
|
- Options selected in the Setup Menu now persist across runs -Michael
|
||||||
|
- Added a simple implementation of key-value pair "resource" files
|
||||||
|
for organizing simple data such as configuration options -Michael
|
||||||
- Added a 'fullscreen' setup menu option - Alex
|
- Added a 'fullscreen' setup menu option - Alex
|
||||||
- Fixed a bug that prevented Slylandro Probes from ever showing up
|
- Fixed a bug that prevented Slylandro Probes from ever showing up
|
||||||
in interplanetary exploration (found by SvdB, bug #768)
|
in interplanetary exploration (found by SvdB, bug #768)
|
||||||
|
|||||||
@@ -480,6 +480,14 @@ SOURCE=..\sc2code\libs\memory\w_memlib.c
|
|||||||
# PROP Default_Filter ""
|
# PROP Default_Filter ""
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\sc2code\libs\resource\alist.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\sc2code\libs\resource\alist.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\sc2code\libs\resource\direct.c
|
SOURCE=..\sc2code\libs\resource\direct.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -500,6 +508,10 @@ SOURCE=..\sc2code\libs\resource\loadres.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\sc2code\libs\resource\mapres.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\sc2code\libs\resource\resdata.c
|
SOURCE=..\sc2code\libs\resource\resdata.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -510,6 +522,14 @@ SOURCE=..\sc2code\libs\resource\resinit.c
|
|||||||
|
|
||||||
SOURCE=..\sc2code\libs\resource\resintrn.h
|
SOURCE=..\sc2code\libs\resource\resintrn.h
|
||||||
# End Source File
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\sc2code\libs\resource\stringbank.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\sc2code\libs\resource\stringbank.h
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "sound"
|
# Begin Group "sound"
|
||||||
|
|
||||||
|
|||||||
@@ -120,5 +120,27 @@ extern DIRENTRY_REF LoadDirEntryTable (uio_DirHandle *dirHandle,
|
|||||||
#define GetDirEntryAddress GetStringAddress
|
#define GetDirEntryAddress GetStringAddress
|
||||||
#define GetDirEntryContents GetStringContents
|
#define GetDirEntryContents GetStringContents
|
||||||
|
|
||||||
|
/* Key-Value resources */
|
||||||
|
void res_ClearTables (void);
|
||||||
|
|
||||||
|
void res_LoadFilename (uio_DirHandle *path, const char *fname);
|
||||||
|
void res_SaveFilename (uio_DirHandle *path, const char *fname, const char *root);
|
||||||
|
|
||||||
|
void res_LoadFile (uio_Stream *fname);
|
||||||
|
void res_SaveFile (uio_Stream *fname, const char *root);
|
||||||
|
|
||||||
|
BOOLEAN res_HasKey (const char *key);
|
||||||
|
|
||||||
|
const char *res_GetString (const char *key);
|
||||||
|
void res_PutString (const char *key, const char *value);
|
||||||
|
|
||||||
|
BOOLEAN res_IsInteger (const char *key);
|
||||||
|
int res_GetInteger (const char *key);
|
||||||
|
void res_PutInteger (const char *key, int value);
|
||||||
|
|
||||||
|
BOOLEAN res_IsBoolean (const char *key);
|
||||||
|
BOOLEAN res_GetBoolean (const char *key);
|
||||||
|
void res_PutBoolean (const char *key, BOOLEAN value);
|
||||||
|
|
||||||
#endif /* _RESLIB_H */
|
#endif /* _RESLIB_H */
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
uqm_CFILES="direct.c filecntl.c getres.c loadres.c resdata.c resinit.c"
|
uqm_CFILES="alist.c direct.c filecntl.c getres.c loadres.c mapres.c
|
||||||
|
resdata.c resinit.c stringbank.c"
|
||||||
|
|||||||
@@ -0,0 +1,232 @@
|
|||||||
|
/* alist.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 "alist.h"
|
||||||
|
#include "stringbank.h"
|
||||||
|
|
||||||
|
alist_entry *
|
||||||
|
AlistEntry_New (const char *key, const char *value)
|
||||||
|
{
|
||||||
|
alist_entry *e;
|
||||||
|
e = malloc (sizeof(alist_entry));
|
||||||
|
e->key = key;
|
||||||
|
e->value = value;
|
||||||
|
e->next = NULL;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AlistEntry_Free (alist_entry *e)
|
||||||
|
{
|
||||||
|
if (e == NULL)
|
||||||
|
return;
|
||||||
|
AlistEntry_Free (e->next);
|
||||||
|
free (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
alist *
|
||||||
|
Alist_New (void)
|
||||||
|
{
|
||||||
|
alist *result = malloc (sizeof(alist));
|
||||||
|
result->first = NULL;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Alist_Free (alist *m) {
|
||||||
|
if (m == NULL) return;
|
||||||
|
AlistEntry_Free (m->first);
|
||||||
|
free (m);
|
||||||
|
}
|
||||||
|
|
||||||
|
alist_entry *
|
||||||
|
Alist_GetEntry (alist *m, const char *key)
|
||||||
|
{
|
||||||
|
alist_entry *x = m->first;
|
||||||
|
while (x != NULL) {
|
||||||
|
if (!strcmp (x->key, key))
|
||||||
|
return x;
|
||||||
|
x = x->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
Alist_GetString (alist *m, const char *key)
|
||||||
|
{
|
||||||
|
alist_entry *x = Alist_GetEntry (m, key);
|
||||||
|
return x ? x->value : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Alist_PutString (alist *m, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
alist_entry *e = Alist_GetEntry (m, key);
|
||||||
|
if (e == NULL) {
|
||||||
|
e = AlistEntry_New(key, value);
|
||||||
|
e->next = m->first;
|
||||||
|
m->first = e;
|
||||||
|
} else {
|
||||||
|
e->value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Alist_PutAll (alist *dst, alist *src)
|
||||||
|
{
|
||||||
|
alist_entry *e = src->first;
|
||||||
|
while (e) {
|
||||||
|
Alist_PutString (dst, e->key, e->value);
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alist *
|
||||||
|
Alist_New_FromFile (uio_Stream *f)
|
||||||
|
{
|
||||||
|
long flen;
|
||||||
|
alist *m;
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
flen = LengthResFile (f);
|
||||||
|
|
||||||
|
data = malloc (flen + 1);
|
||||||
|
if (!data) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadResFile (data, 1, flen, f);
|
||||||
|
data[flen] = '\0';
|
||||||
|
|
||||||
|
m = Alist_New_FromString (data);
|
||||||
|
free (data);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
alist *
|
||||||
|
Alist_New_FromFilename (uio_DirHandle *path, const char *fname)
|
||||||
|
{
|
||||||
|
alist *result;
|
||||||
|
uio_Stream *f = res_OpenResFile (path, fname, "rt");
|
||||||
|
if (!f) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
result = Alist_New_FromFile (f);
|
||||||
|
res_CloseResFile(f);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
alist *
|
||||||
|
Alist_New_FromString (char *d)
|
||||||
|
{
|
||||||
|
alist *m = Alist_New ();
|
||||||
|
int len, i;
|
||||||
|
if (!m) return NULL;
|
||||||
|
|
||||||
|
len = strlen(d);
|
||||||
|
i = 0;
|
||||||
|
while (i < len) {
|
||||||
|
int key_start, key_end, value_start, value_end;
|
||||||
|
/* Starting a line: search for non-whitespace */
|
||||||
|
while ((i < len) && isspace (d[i])) i++;
|
||||||
|
if (i >= len) break; /* Done parsing! */
|
||||||
|
/* If it was a comment, skip to end of comment/file */
|
||||||
|
if (d[i] == '#') {
|
||||||
|
while ((i < len) && (d[i] != '\n')) i++;
|
||||||
|
if (i >= len) break;
|
||||||
|
continue; /* Back to keyword search */
|
||||||
|
}
|
||||||
|
key_start = i;
|
||||||
|
/* Find the = on this line */
|
||||||
|
while ((i < len) && (d[i] != '=') &&
|
||||||
|
(d[i] != '\n') && (d[i] != '#')) i++;
|
||||||
|
if (i >= len) { /* Bare key at EOF */
|
||||||
|
fprintf (stderr, "Warning: Bare keyword at EOF");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Comments here mean incomplete line too */
|
||||||
|
if (d[i] != '=') {
|
||||||
|
fprintf (stderr, "Warning: Key without value");
|
||||||
|
while ((i < len) && (d[i] != '\n')) i++;
|
||||||
|
if (i >= len) break;
|
||||||
|
continue; /* Back to keyword search */
|
||||||
|
}
|
||||||
|
/* Key ends at first whitespace before = , or at key_start*/
|
||||||
|
key_end = i;
|
||||||
|
while ((key_end > key_start) && isspace (d[key_end-1]))
|
||||||
|
key_end--;
|
||||||
|
|
||||||
|
/* Consume the = */
|
||||||
|
i++;
|
||||||
|
/* Value starts at first non-whitespace after = on line... */
|
||||||
|
while ((i < len) && (d[i] != '#') && (d[i] != '\n') &&
|
||||||
|
isspace (d[i]))
|
||||||
|
i++;
|
||||||
|
value_start = i;
|
||||||
|
/* Until first non-whitespace before terminator */
|
||||||
|
while ((i < len) && (d[i] != '#') && (d[i] != '\n'))
|
||||||
|
i++;
|
||||||
|
value_end = i;
|
||||||
|
while ((value_end > value_start) && isspace (d[value_end-1]))
|
||||||
|
value_end--;
|
||||||
|
/* Skip past EOL or EOF */
|
||||||
|
while ((i < len) && (d[i] != '\n'))
|
||||||
|
i++;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
/* We now have start and end values for key and value.
|
||||||
|
We terminate the strings for both by writing \0s, then
|
||||||
|
make a new map entry. */
|
||||||
|
d[key_end] = '\0';
|
||||||
|
d[value_end] = '\0';
|
||||||
|
Alist_PutString (m, StringBank_AddOrFindString(d+key_start),
|
||||||
|
StringBank_AddOrFindString(d+value_start));
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Alist_Dump (alist *m, uio_Stream *s, const char *prefix)
|
||||||
|
{
|
||||||
|
alist_entry *e = m->first;
|
||||||
|
int prefix_len = 0;
|
||||||
|
if (prefix)
|
||||||
|
prefix_len = strlen (prefix);
|
||||||
|
while (e) {
|
||||||
|
if (!prefix || !strncmp (prefix, e->key, prefix_len)) {
|
||||||
|
char *i = e->key;
|
||||||
|
while (*i) {
|
||||||
|
PutResFileChar (*i++, s);
|
||||||
|
}
|
||||||
|
PutResFileChar(' ', s);
|
||||||
|
PutResFileChar('=', s);
|
||||||
|
PutResFileChar(' ', s);
|
||||||
|
i = e->value;
|
||||||
|
while (*i) {
|
||||||
|
PutResFileChar (*i++, s);
|
||||||
|
}
|
||||||
|
PutResFileChar ('\n', s);
|
||||||
|
}
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/* alist.h, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ALIST_H_
|
||||||
|
#define _ALIST_H_
|
||||||
|
|
||||||
|
#include "libs/uio.h"
|
||||||
|
|
||||||
|
/* Associative List types. */
|
||||||
|
|
||||||
|
typedef struct _alist_entry {
|
||||||
|
const char *key, *value;
|
||||||
|
struct _alist_entry *next;
|
||||||
|
} alist_entry;
|
||||||
|
|
||||||
|
typedef struct _alist_map {
|
||||||
|
alist_entry *first;
|
||||||
|
} alist;
|
||||||
|
|
||||||
|
/* ***** alist_entry operations ***** */
|
||||||
|
|
||||||
|
/* Constructor and destructor */
|
||||||
|
alist_entry *AlistEntry_New (const char *key, const char *value);
|
||||||
|
void AlistEntry_Free (alist_entry *e);
|
||||||
|
|
||||||
|
/* ***** alist operations ***** */
|
||||||
|
|
||||||
|
/* Standard constructor and destructor */
|
||||||
|
alist *Alist_New (void);
|
||||||
|
void Alist_Free (alist *m);
|
||||||
|
|
||||||
|
/* Specialized constructors: Parse an alist out of a stream, file, or
|
||||||
|
string. It expects a bunch of key=value statements, one per
|
||||||
|
line. */
|
||||||
|
alist *Alist_New_FromFile (uio_Stream *f);
|
||||||
|
alist *Alist_New_FromFilename (uio_DirHandle *path, const char *fname);
|
||||||
|
alist *Alist_New_FromString (char *d);
|
||||||
|
|
||||||
|
/* Getting and Setting operations */
|
||||||
|
alist_entry *Alist_GetEntry (alist *m, const char *key);
|
||||||
|
const char *Alist_GetString (alist *m, const char *key);
|
||||||
|
void Alist_PutString (alist *m, const char *key, const char *value);
|
||||||
|
void Alist_PutAll (alist *dest, alist *src);
|
||||||
|
|
||||||
|
/* Dump the alist to the specified stream in a form that could be
|
||||||
|
read later by the Alist_New_From* routines. Dump only keys
|
||||||
|
that begin with the prefix; NULL means all keys. */
|
||||||
|
void Alist_Dump (alist *m, uio_Stream *s, const char *prefix);
|
||||||
|
|
||||||
|
#endif /* _ALIST_H_ */
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
/* mapres.h, 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 "alist.h"
|
||||||
|
#include "stringbank.h"
|
||||||
|
|
||||||
|
static alist *map = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_map_init (void)
|
||||||
|
{
|
||||||
|
if (map == NULL) {
|
||||||
|
map = Alist_New ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
res_ClearTables (void)
|
||||||
|
{
|
||||||
|
if (map != NULL) {
|
||||||
|
Alist_Free (map);
|
||||||
|
map = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
str2int (const char *s) {
|
||||||
|
return atoi(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOLEAN
|
||||||
|
str2bool (const char *s) {
|
||||||
|
if (!stricmp (s, "yes") ||
|
||||||
|
!stricmp (s, "true") ||
|
||||||
|
!stricmp (s, "1") )
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
res_LoadFile (uio_Stream *s)
|
||||||
|
{
|
||||||
|
alist *d;
|
||||||
|
check_map_init ();
|
||||||
|
|
||||||
|
d = Alist_New_FromFile (s);
|
||||||
|
if (d) {
|
||||||
|
Alist_PutAll (map, d);
|
||||||
|
Alist_Free (d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
res_LoadFilename (uio_DirHandle *path, const char *fname)
|
||||||
|
{
|
||||||
|
alist *d;
|
||||||
|
check_map_init ();
|
||||||
|
|
||||||
|
d = Alist_New_FromFilename (path, fname);
|
||||||
|
if (d) {
|
||||||
|
Alist_PutAll (map, d);
|
||||||
|
Alist_Free (d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
res_SaveFile (uio_Stream *f, const char *root)
|
||||||
|
{
|
||||||
|
check_map_init ();
|
||||||
|
Alist_Dump (map, f, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
res_SaveFilename (uio_DirHandle *path, const char *fname, const char *root)
|
||||||
|
{
|
||||||
|
uio_Stream *f;
|
||||||
|
|
||||||
|
check_map_init ();
|
||||||
|
f = res_OpenResFile (path, fname, "wt");
|
||||||
|
if (f) {
|
||||||
|
res_SaveFile (f, root);
|
||||||
|
res_CloseResFile (f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
res_IsBoolean (const char *key)
|
||||||
|
{
|
||||||
|
const char *d;
|
||||||
|
check_map_init ();
|
||||||
|
|
||||||
|
d = res_GetString (key);
|
||||||
|
if (!d) return 0;
|
||||||
|
|
||||||
|
return !stricmp (d, "yes") ||
|
||||||
|
!stricmp (d, "no") ||
|
||||||
|
!stricmp (d, "true") ||
|
||||||
|
!stricmp (d, "false") ||
|
||||||
|
!stricmp (d, "0") ||
|
||||||
|
!stricmp (d, "1") ||
|
||||||
|
!stricmp (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 Alist_GetString (map, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
res_PutString (const char *key, const char *value)
|
||||||
|
{
|
||||||
|
check_map_init ();
|
||||||
|
Alist_PutString (map, key, 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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
/* stringbank.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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "stringbank.h"
|
||||||
|
|
||||||
|
#define CHUNK_SIZE (1024 - sizeof (void *) - sizeof (int))
|
||||||
|
|
||||||
|
typedef struct _stringbank_chunk {
|
||||||
|
char data[CHUNK_SIZE];
|
||||||
|
int len;
|
||||||
|
struct _stringbank_chunk *next;
|
||||||
|
} chunk;
|
||||||
|
|
||||||
|
static chunk *bank = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_chunk (void)
|
||||||
|
{
|
||||||
|
chunk *n = malloc (sizeof (chunk));
|
||||||
|
n->len = 0;
|
||||||
|
n->next = bank;
|
||||||
|
bank = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
StringBank_AddString (const char *str)
|
||||||
|
{
|
||||||
|
int len = strlen (str);
|
||||||
|
chunk *x = bank;
|
||||||
|
if (len > CHUNK_SIZE)
|
||||||
|
return NULL;
|
||||||
|
while (x) {
|
||||||
|
int remaining = CHUNK_SIZE - x->len;
|
||||||
|
if (len < remaining) {
|
||||||
|
char *result = x->data + x->len;
|
||||||
|
strcpy (result, str);
|
||||||
|
x->len += len + 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
x = x->next;
|
||||||
|
}
|
||||||
|
/* No room in any currently existing chunk */
|
||||||
|
add_chunk ();
|
||||||
|
strcpy (bank->data, str);
|
||||||
|
bank->len += len + 1;
|
||||||
|
return bank->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
StringBank_AddOrFindString (const char *str)
|
||||||
|
{
|
||||||
|
int len = strlen (str);
|
||||||
|
chunk *x = bank;
|
||||||
|
if (len > CHUNK_SIZE)
|
||||||
|
return NULL;
|
||||||
|
while (x) {
|
||||||
|
int i = 0;
|
||||||
|
while (i < x->len) {
|
||||||
|
if (!strcmp (x->data + i, str))
|
||||||
|
return x->data + i;
|
||||||
|
while (x->data[i]) i++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
x = x->next;
|
||||||
|
}
|
||||||
|
/* We didn't find it, so add it */
|
||||||
|
return StringBank_AddString (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
void
|
||||||
|
StringBank_Dump (FILE *s)
|
||||||
|
{
|
||||||
|
chunk *x = bank;
|
||||||
|
while (x) {
|
||||||
|
int i = 0;
|
||||||
|
while (i < x->len) {
|
||||||
|
fprintf (s, "\"%s\"\n", x->data + i);
|
||||||
|
while (x->data[i]) i++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
x = x->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/* stringbank.h, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _STRINGBANK_H_
|
||||||
|
#define _STRINGBANK_H_
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Put str into the string bank. */
|
||||||
|
const char *StringBank_AddString (const char *str);
|
||||||
|
|
||||||
|
/* Put str into the string bank if it's not already there. Much slower. */
|
||||||
|
const char *StringBank_AddOrFindString (const char *str);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* Print out a list of the contents of the string bank to the named stream. */
|
||||||
|
void StringBank_Dump (FILE *s);
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
#endif /* _STRINGBANK_H_ */
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "libs/graphics/gfx_common.h"
|
#include "libs/graphics/gfx_common.h"
|
||||||
#include "libs/graphics/widgets.h"
|
#include "libs/graphics/widgets.h"
|
||||||
#include "libs/graphics/tfb_draw.h"
|
#include "libs/graphics/tfb_draw.h"
|
||||||
|
#include "libs/reslib.h"
|
||||||
|
|
||||||
#define MENU_BKG "lbm/setupmenu.ani"
|
#define MENU_BKG "lbm/setupmenu.ani"
|
||||||
|
|
||||||
@@ -333,9 +334,9 @@ static WIDGET_MENU_SCREEN graphics_menu = {
|
|||||||
"Graphics Options",
|
"Graphics Options",
|
||||||
{ {0, 0}, NULL },
|
{ {0, 0}, NULL },
|
||||||
#ifdef HAVE_OPENGL
|
#ifdef HAVE_OPENGL
|
||||||
6, graphics_widgets,
|
7, graphics_widgets,
|
||||||
#else
|
#else
|
||||||
5, graphics_widgets,
|
6, graphics_widgets,
|
||||||
#endif
|
#endif
|
||||||
0 };
|
0 };
|
||||||
|
|
||||||
@@ -759,21 +760,32 @@ SetGlobalOptions (GLOBALOPTS *opts)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res_PutInteger ("config.reswidth", NewWidth);
|
||||||
|
res_PutInteger ("config.resheight", NewHeight);
|
||||||
|
res_PutInteger ("config.bpp", NewDepth);
|
||||||
|
res_PutBoolean ("config.alwaysgl", opts->driver == OPTVAL_ALWAYS_GL);
|
||||||
|
|
||||||
|
|
||||||
switch (opts->scaler) {
|
switch (opts->scaler) {
|
||||||
case OPTVAL_BILINEAR_SCALE:
|
case OPTVAL_BILINEAR_SCALE:
|
||||||
NewGfxFlags |= TFB_GFXFLAGS_SCALE_BILINEAR;
|
NewGfxFlags |= TFB_GFXFLAGS_SCALE_BILINEAR;
|
||||||
|
res_PutString ("config.scaler", "bilinear");
|
||||||
break;
|
break;
|
||||||
case OPTVAL_BIADAPT_SCALE:
|
case OPTVAL_BIADAPT_SCALE:
|
||||||
NewGfxFlags |= TFB_GFXFLAGS_SCALE_BIADAPT;
|
NewGfxFlags |= TFB_GFXFLAGS_SCALE_BIADAPT;
|
||||||
|
res_PutString ("config.scaler", "biadapt");
|
||||||
break;
|
break;
|
||||||
case OPTVAL_BIADV_SCALE:
|
case OPTVAL_BIADV_SCALE:
|
||||||
NewGfxFlags |= TFB_GFXFLAGS_SCALE_BIADAPTADV;
|
NewGfxFlags |= TFB_GFXFLAGS_SCALE_BIADAPTADV;
|
||||||
|
res_PutString ("config.scaler", "biadv");
|
||||||
break;
|
break;
|
||||||
case OPTVAL_TRISCAN_SCALE:
|
case OPTVAL_TRISCAN_SCALE:
|
||||||
NewGfxFlags |= TFB_GFXFLAGS_SCALE_TRISCAN;
|
NewGfxFlags |= TFB_GFXFLAGS_SCALE_TRISCAN;
|
||||||
|
res_PutString ("config.scaler", "triscan");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* OPTVAL_NO_SCALE has no equivalent in gfxflags. */
|
/* OPTVAL_NO_SCALE has no equivalent in gfxflags. */
|
||||||
|
res_PutString ("config.scaler", "no");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (opts->scanlines) {
|
if (opts->scanlines) {
|
||||||
@@ -786,6 +798,10 @@ SetGlobalOptions (GLOBALOPTS *opts)
|
|||||||
else
|
else
|
||||||
NewGfxFlags &= ~TFB_GFXFLAGS_FULLSCREEN;
|
NewGfxFlags &= ~TFB_GFXFLAGS_FULLSCREEN;
|
||||||
|
|
||||||
|
res_PutBoolean ("config.scanlines", opts->scanlines);
|
||||||
|
res_PutBoolean ("config.fullscreen", opts->fullscreen);
|
||||||
|
|
||||||
|
|
||||||
if ((NewWidth != ScreenWidthActual) ||
|
if ((NewWidth != ScreenWidthActual) ||
|
||||||
(NewHeight != ScreenHeightActual) ||
|
(NewHeight != ScreenHeightActual) ||
|
||||||
(NewDepth != ScreenColorDepth) ||
|
(NewDepth != ScreenColorDepth) ||
|
||||||
@@ -803,4 +819,11 @@ SetGlobalOptions (GLOBALOPTS *opts)
|
|||||||
optWhichCoarseScan = (opts->cscan == OPTVAL_3DO) ? OPT_3DO : OPT_PC;
|
optWhichCoarseScan = (opts->cscan == OPTVAL_3DO) ? OPT_3DO : OPT_PC;
|
||||||
optSmoothScroll = (opts->scroll == OPTVAL_3DO) ? OPT_3DO : OPT_PC;
|
optSmoothScroll = (opts->scroll == OPTVAL_3DO) ? OPT_3DO : OPT_PC;
|
||||||
|
|
||||||
|
res_PutBoolean ("config.subtitles", opts->subtitles == OPTVAL_ENABLED);
|
||||||
|
res_PutBoolean ("config.textmenu", opts->menu == OPTVAL_PC);
|
||||||
|
res_PutBoolean ("config.textgradients", opts->text == OPTVAL_PC);
|
||||||
|
res_PutBoolean ("config.iconicscan", opts->cscan == OPTVAL_3DO);
|
||||||
|
res_PutBoolean ("config.smoothscroll", opts->scroll == OPTVAL_3DO);
|
||||||
|
|
||||||
|
res_SaveFilename (configDir, "uqm.cfg", "config.");
|
||||||
}
|
}
|
||||||
|
|||||||
+71
-7
@@ -175,6 +175,69 @@ main (int argc, char *argv[])
|
|||||||
TFB_PreInit ();
|
TFB_PreInit ();
|
||||||
mem_init ();
|
mem_init ();
|
||||||
InitThreadSystem ();
|
InitThreadSystem ();
|
||||||
|
initIO ();
|
||||||
|
prepareConfigDir (options.configDir);
|
||||||
|
|
||||||
|
// Fill in the options struct based on uqm.cfg
|
||||||
|
res_LoadFilename (configDir, "uqm.cfg");
|
||||||
|
if (res_HasKey ("config.reswidth"))
|
||||||
|
{
|
||||||
|
options.width = res_GetInteger ("config.reswidth");
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.resheight"))
|
||||||
|
{
|
||||||
|
options.height = res_GetInteger ("config.resheight");
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.bpp"))
|
||||||
|
{
|
||||||
|
options.bpp = res_GetInteger ("config.bpp");
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.alwaysgl"))
|
||||||
|
{
|
||||||
|
options.gfxDriver = res_GetBoolean ("config.alwaysgl") ?
|
||||||
|
TFB_GFXDRIVER_SDL_OPENGL : TFB_GFXDRIVER_SDL_PURE;
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.scaler"))
|
||||||
|
{
|
||||||
|
const char *optarg = res_GetString ("config.scaler");
|
||||||
|
|
||||||
|
if (!strcmp (optarg, "bilinear"))
|
||||||
|
options.gfxFlags |= TFB_GFXFLAGS_SCALE_BILINEAR;
|
||||||
|
else if (!strcmp (optarg, "biadapt"))
|
||||||
|
options.gfxFlags |= TFB_GFXFLAGS_SCALE_BIADAPT;
|
||||||
|
else if (!strcmp (optarg, "biadv"))
|
||||||
|
options.gfxFlags |= TFB_GFXFLAGS_SCALE_BIADAPTADV;
|
||||||
|
else if (!strcmp (optarg, "triscan"))
|
||||||
|
options.gfxFlags |= TFB_GFXFLAGS_SCALE_TRISCAN;
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.scanlines") && res_GetBoolean ("config.scanlines"))
|
||||||
|
{
|
||||||
|
options.gfxFlags |= TFB_GFXFLAGS_SCANLINES;
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.fullscreen") && res_GetBoolean ("config.fullscreen"))
|
||||||
|
{
|
||||||
|
options.gfxFlags |= TFB_GFXFLAGS_FULLSCREEN;
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.subtitles"))
|
||||||
|
{
|
||||||
|
options.subTitles = res_GetBoolean ("config.subtitles");
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.textmenu"))
|
||||||
|
{
|
||||||
|
options.whichMenu = res_GetBoolean ("config.textmenu") ? OPT_PC : OPT_3DO;
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.textgradients"))
|
||||||
|
{
|
||||||
|
options.whichFonts = res_GetBoolean ("config.textgradients") ? OPT_PC : OPT_3DO;
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.iconicscan"))
|
||||||
|
{
|
||||||
|
options.whichCoarseScan = res_GetBoolean ("config.iconicscan") ? OPT_3DO : OPT_PC;
|
||||||
|
}
|
||||||
|
if (res_HasKey ("config.smoothscroll"))
|
||||||
|
{
|
||||||
|
options.smoothScroll = res_GetBoolean ("config.smoothscroll") ? OPT_3DO : OPT_PC;
|
||||||
|
}
|
||||||
|
|
||||||
optionsResult = parseOptions(argc, argv, &options);
|
optionsResult = parseOptions(argc, argv, &options);
|
||||||
if (optionsResult != 0)
|
if (optionsResult != 0)
|
||||||
@@ -206,10 +269,8 @@ main (int argc, char *argv[])
|
|||||||
sfxVolumeScale = options.sfxVolumeScale;
|
sfxVolumeScale = options.sfxVolumeScale;
|
||||||
speechVolumeScale = options.speechVolumeScale;
|
speechVolumeScale = options.speechVolumeScale;
|
||||||
|
|
||||||
initIO ();
|
|
||||||
prepareContentDir (options.contentDir, options.addons);
|
prepareContentDir (options.contentDir, options.addons);
|
||||||
HFree ((void *) options.addons);
|
HFree ((void *) options.addons);
|
||||||
prepareConfigDir (options.configDir);
|
|
||||||
prepareMeleeDir ();
|
prepareMeleeDir ();
|
||||||
prepareSaveDir ();
|
prepareSaveDir ();
|
||||||
initTempDir ();
|
initTempDir ();
|
||||||
@@ -316,6 +377,11 @@ preParseOptions(int argc, char *argv[], struct options_struct *options)
|
|||||||
options->logFile = optarg;
|
options->logFile = optarg;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'C':
|
||||||
|
{
|
||||||
|
options->configDir = optarg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case '?':
|
case '?':
|
||||||
case 'h':
|
case 'h':
|
||||||
options->runMode = runMode_usage;
|
options->runMode = runMode_usage;
|
||||||
@@ -353,9 +419,6 @@ parseOptions(int argc, char *argv[], struct options_struct *options)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'C':
|
|
||||||
options->configDir = optarg;
|
|
||||||
break;
|
|
||||||
case 'r':
|
case 'r':
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
@@ -501,8 +564,9 @@ parseOptions(int argc, char *argv[], struct options_struct *options)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'l':
|
case 'l':
|
||||||
// -l is a no-op on the second pass..
|
case 'C':
|
||||||
break;
|
// -l and -C are no-ops on the second pass.
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
if (Check_PC_3DO_opt (optarg, OPT_PC | OPT_3DO,
|
if (Check_PC_3DO_opt (optarg, OPT_PC | OPT_3DO,
|
||||||
|
|||||||
Reference in New Issue
Block a user