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:
|
||||
- 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
|
||||
- Fixed a bug that prevented Slylandro Probes from ever showing up
|
||||
in interplanetary exploration (found by SvdB, bug #768)
|
||||
|
||||
@@ -480,6 +480,14 @@ SOURCE=..\sc2code\libs\memory\w_memlib.c
|
||||
# PROP Default_Filter ""
|
||||
# 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
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -500,6 +508,10 @@ SOURCE=..\sc2code\libs\resource\loadres.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\resource\mapres.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\resource\resdata.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -510,6 +522,14 @@ SOURCE=..\sc2code\libs\resource\resinit.c
|
||||
|
||||
SOURCE=..\sc2code\libs\resource\resintrn.h
|
||||
# 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
|
||||
# Begin Group "sound"
|
||||
|
||||
|
||||
@@ -120,5 +120,27 @@ extern DIRENTRY_REF LoadDirEntryTable (uio_DirHandle *dirHandle,
|
||||
#define GetDirEntryAddress GetStringAddress
|
||||
#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 */
|
||||
|
||||
|
||||
@@ -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/widgets.h"
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
#include "libs/reslib.h"
|
||||
|
||||
#define MENU_BKG "lbm/setupmenu.ani"
|
||||
|
||||
@@ -333,9 +334,9 @@ static WIDGET_MENU_SCREEN graphics_menu = {
|
||||
"Graphics Options",
|
||||
{ {0, 0}, NULL },
|
||||
#ifdef HAVE_OPENGL
|
||||
6, graphics_widgets,
|
||||
7, graphics_widgets,
|
||||
#else
|
||||
5, graphics_widgets,
|
||||
6, graphics_widgets,
|
||||
#endif
|
||||
0 };
|
||||
|
||||
@@ -759,21 +760,32 @@ SetGlobalOptions (GLOBALOPTS *opts)
|
||||
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) {
|
||||
case OPTVAL_BILINEAR_SCALE:
|
||||
NewGfxFlags |= TFB_GFXFLAGS_SCALE_BILINEAR;
|
||||
res_PutString ("config.scaler", "bilinear");
|
||||
break;
|
||||
case OPTVAL_BIADAPT_SCALE:
|
||||
NewGfxFlags |= TFB_GFXFLAGS_SCALE_BIADAPT;
|
||||
res_PutString ("config.scaler", "biadapt");
|
||||
break;
|
||||
case OPTVAL_BIADV_SCALE:
|
||||
NewGfxFlags |= TFB_GFXFLAGS_SCALE_BIADAPTADV;
|
||||
res_PutString ("config.scaler", "biadv");
|
||||
break;
|
||||
case OPTVAL_TRISCAN_SCALE:
|
||||
NewGfxFlags |= TFB_GFXFLAGS_SCALE_TRISCAN;
|
||||
res_PutString ("config.scaler", "triscan");
|
||||
break;
|
||||
default:
|
||||
/* OPTVAL_NO_SCALE has no equivalent in gfxflags. */
|
||||
res_PutString ("config.scaler", "no");
|
||||
break;
|
||||
}
|
||||
if (opts->scanlines) {
|
||||
@@ -786,6 +798,10 @@ SetGlobalOptions (GLOBALOPTS *opts)
|
||||
else
|
||||
NewGfxFlags &= ~TFB_GFXFLAGS_FULLSCREEN;
|
||||
|
||||
res_PutBoolean ("config.scanlines", opts->scanlines);
|
||||
res_PutBoolean ("config.fullscreen", opts->fullscreen);
|
||||
|
||||
|
||||
if ((NewWidth != ScreenWidthActual) ||
|
||||
(NewHeight != ScreenHeightActual) ||
|
||||
(NewDepth != ScreenColorDepth) ||
|
||||
@@ -803,4 +819,11 @@ SetGlobalOptions (GLOBALOPTS *opts)
|
||||
optWhichCoarseScan = (opts->cscan == 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.");
|
||||
}
|
||||
|
||||
+70
-6
@@ -175,6 +175,69 @@ main (int argc, char *argv[])
|
||||
TFB_PreInit ();
|
||||
mem_init ();
|
||||
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);
|
||||
if (optionsResult != 0)
|
||||
@@ -206,10 +269,8 @@ main (int argc, char *argv[])
|
||||
sfxVolumeScale = options.sfxVolumeScale;
|
||||
speechVolumeScale = options.speechVolumeScale;
|
||||
|
||||
initIO ();
|
||||
prepareContentDir (options.contentDir, options.addons);
|
||||
HFree ((void *) options.addons);
|
||||
prepareConfigDir (options.configDir);
|
||||
prepareMeleeDir ();
|
||||
prepareSaveDir ();
|
||||
initTempDir ();
|
||||
@@ -316,6 +377,11 @@ preParseOptions(int argc, char *argv[], struct options_struct *options)
|
||||
options->logFile = optarg;
|
||||
break;
|
||||
}
|
||||
case 'C':
|
||||
{
|
||||
options->configDir = optarg;
|
||||
break;
|
||||
}
|
||||
case '?':
|
||||
case 'h':
|
||||
options->runMode = runMode_usage;
|
||||
@@ -353,9 +419,6 @@ parseOptions(int argc, char *argv[], struct options_struct *options)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'C':
|
||||
options->configDir = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
{
|
||||
int width, height;
|
||||
@@ -501,7 +564,8 @@ parseOptions(int argc, char *argv[], struct options_struct *options)
|
||||
break;
|
||||
}
|
||||
case 'l':
|
||||
// -l is a no-op on the second pass..
|
||||
case 'C':
|
||||
// -l and -C are no-ops on the second pass.
|
||||
break;
|
||||
case 'i':
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user