share/text.o \
share/sync.o \
share/tilt.o \
+ share/common.o \
ball/hud.o \
ball/mode.o \
ball/game.o \
#include "config.h"
#include "binary.h"
#include "text.h"
+#include "common.h"
/*---------------------------------------------------------------------------*/
d->time, d->goal, d->score, d->balls, d->times);
}
-static time_t make_time_from_utc(struct tm *tm)
-{
- struct tm local, *utc;
- time_t t;
-
- t = mktime(tm);
-
- local = *localtime(&t);
- utc = gmtime(&t);
-
- local.tm_year += local.tm_year - utc->tm_year;
- local.tm_mon += local.tm_mon - utc->tm_mon ;
- local.tm_mday += local.tm_mday - utc->tm_mday;
- local.tm_hour += local.tm_hour - utc->tm_hour;
- local.tm_min += local.tm_min - utc->tm_min ;
- local.tm_sec += local.tm_sec - utc->tm_sec ;
-
- return mktime(&local);
-}
-
static int demo_header_read(FILE *fp, struct demo *d)
{
int magic;
return 0;
}
-static char *bname(const char *name, const char *suffix)
-{
- static char buf[MAXSTR];
-
- char *base;
- size_t l;
-
- /* Remove the directory delimiter */
-
- base = strrchr(name, '/');
-#ifdef _WIN32
- if (!base)
- base = strrchr(name, '\\');
- else
- {
- char *tmp;
- if ((tmp = strrchr(base, '\\')))
- base = tmp;
- }
-#endif
- strncpy(buf, base ? base + 1 : name, MAXSTR);
-
- /* Remove the extension */
-
- l = strlen(buf) - strlen(suffix);
- if ((l > 1) && (strcmp(buf + l, suffix) == 0))
- buf[l] = '\0';
-
- return buf;
-}
-
static void demo_header_write(FILE *fp, struct demo *d)
{
int magic = MAGIC;
if (demo_header_read(fp, d))
{
strncpy(d->filename, config_user(filename), MAXSTR);
- strncpy(d->name, bname(text_from_locale(d->filename), REPLAY_EXT),
+ strncpy(d->name,
+ base_name(text_from_locale(d->filename), REPLAY_EXT),
PATHMAX);
d->name[PATHMAX - 1] = '\0';
return (0 <= i && i < count) ? &demos[i] : NULL;
}
-const char *date_to_str(time_t i)
-{
- static char str[MAXSTR];
- const char *fmt;
-
- /* TRANSLATORS: here is the format of the date shown at the
- replay selection screen (and possibly elsewhere). The default
- format is necessarily locale-independent. See strftime(3) for
- details on the format.
- */
-
- fmt = /* xgettext:no-c-format */ L_("%Y-%m-%d %H:%M:%S");
- strftime(str, MAXSTR, fmt, localtime(&i));
- return text_from_locale(str);
-}
-
/*---------------------------------------------------------------------------*/
int demo_exists(const char *name)
{
- FILE *fp;
char buf[MAXSTR];
strcpy(buf, config_user(name));
strcat(buf, REPLAY_EXT);
- if ((fp = fopen(buf, "r")))
- {
- fclose(fp);
- return 1;
- }
- return 0;
+
+ return file_exists(buf);
}
void demo_unique(char *name)
strcpy(dst, config_user(name));
strcat(dst, REPLAY_EXT);
-#ifdef _WIN32
- if (demo_exists(name))
- remove(dst);
-#endif
- rename(src, dst);
+ file_rename(src, dst);
}
}
if (demo_fp && demo_header_read(demo_fp, &demo_replay))
{
strncpy(demo_replay.filename, name, MAXSTR);
- strncpy(demo_replay.name, bname(text_from_locale(demo_replay.filename),
- REPLAY_EXT), PATHMAX);
+ strncpy(demo_replay.name,
+ base_name(text_from_locale(demo_replay.filename), REPLAY_EXT),
+ PATHMAX);
if (!demo_load_level(&demo_replay, &demo_level_replay))
return 0;
#include "text.h"
#include "set.h"
#include "game.h"
+#include "common.h"
/*---------------------------------------------------------------------------*/
+static int set_state = 0;
+
static int set;
static int count;
}
}
-static char *strip_eol(char *str)
-{
- char *c = str + strlen(str) - 1;
-
- while (c >= str && (*c == '\n' || *c =='\r'))
- *c-- = '\0';
-
- return str;
-}
-
static int set_load(struct set *s, const char *filename)
{
FILE *fin;
char buf[MAXSTR];
- int res;
+
+ char *scores;
fin = fopen(config_data(filename), "r");
strcpy(s->file, filename);
- if ((res = fgets(buf, MAXSTR, fin) != NULL))
- strcpy(s->name, strip_eol(buf));
- if (res && (res = fgets(buf, MAXSTR, fin) != NULL))
- strcpy(s->desc, strip_eol(buf));
- if (res && (res = fgets(buf, MAXSTR, fin) != NULL))
- strcpy(s->id, strip_eol(buf));
- if (res && (res = fgets(buf, MAXSTR, fin) != NULL))
- strcpy(s->shot, strip_eol(buf));
- if (res && (res = fgets(buf, MAXSTR, fin) != NULL))
- sscanf(buf, "%d %d %d %d %d %d",
- &s->time_score.timer[0],
- &s->time_score.timer[1],
- &s->time_score.timer[2],
- &s->coin_score.coins[0],
- &s->coin_score.coins[1],
- &s->coin_score.coins[2]);
-
- strcpy(s->user_scores, "neverballhs-");
- strcat(s->user_scores, s->id);
-
- /* Count levels. */
-
- s->count = 0;
-
- while (s->count < MAXLVL && (fscanf(fin, "%s", buf) == 1))
- s->count++;
+ if (read_line(&s->name, fin) &&
+ read_line(&s->desc, fin) &&
+ read_line(&s->id, fin) &&
+ read_line(&s->shot, fin) &&
+ read_line(&scores, fin))
+ {
+ sscanf(scores, "%d %d %d %d %d %d",
+ &s->time_score.timer[0],
+ &s->time_score.timer[1],
+ &s->time_score.timer[2],
+ &s->coin_score.coins[0],
+ &s->coin_score.coins[1],
+ &s->coin_score.coins[2]);
+
+ free(scores);
+
+ strcpy(s->user_scores, "neverballhs-");
+ strcat(s->user_scores, s->id);
+
+ /* Count levels. */
+
+ s->count = 0;
+
+ while (s->count < MAXLVL && fscanf(fin, "%s", buf) == 1)
+ s->count++;
+
+ fclose(fin);
+
+ return 1;
+ }
+
+ free(s->name);
+ free(s->desc);
+ free(s->id);
+ free(s->shot);
fclose(fin);
- return 1;
+ return 0;
}
/*---------------------------------------------------------------------------*/
FILE *fin;
char name[MAXSTR];
+ if (set_state)
+ set_free();
+
set = 0;
count = 0;
if ((fin = fopen(config_data(SET_FILE), "r")))
{
while (count < MAXSET && fgets(name, MAXSTR, fin))
- if (set_load(&set_v[count], strip_eol(name)))
+ if (set_load(&set_v[count], strip_newline(name)))
count++;
fclose(fin);
+
+ set_state = 1;
}
return count;
}
+void set_free(void)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ free(set_v[i].name);
+ free(set_v[i].desc);
+ free(set_v[i].id);
+ free(set_v[i].shot);
+ }
+
+ set_state = 0;
+}
+
/*---------------------------------------------------------------------------*/
int set_exists(int i)
level_v[i].is_locked = 0;
}
-
/*---------------------------------------------------------------------------*/
{
char file[PATHMAX];
- char id[MAXSTR]; /* Internal set identifier */
- char name[MAXSTR]; /* Set name */
- char desc[MAXSTR]; /* Set description */
- char shot[MAXSTR]; /* Set screen-shot */
+ char *id; /* Internal set identifier */
+ char *name; /* Set name */
+ char *desc; /* Set description */
+ char *shot; /* Set screen-shot */
char user_scores[PATHMAX]; /* User high-score file */
/*---------------------------------------------------------------------------*/
-int set_init();
-int set_exists(int);
+int set_init(void);
+void set_free(void);
+
+int set_exists(int);
const struct set *get_set(int);
#include "config.h"
#include "st_shared.h"
#include "util.h"
+#include "common.h"
#include "st_demo.h"
#include "st_title.h"
switch (i)
{
case GUI_BACK:
+ set_free();
return goto_state(&st_title);
break;
--- /dev/null
+/*
+ * Copyright (C) 2007 Neverball contributors
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#include "common.h"
+
+#define MAXSTR 256
+
+/*---------------------------------------------------------------------------*/
+
+int read_line(char **dst, FILE *fin)
+{
+ char buffer[MAXSTR] = "";
+ int buffer_size = 0;
+
+ char *store = NULL;
+ char *store_new = NULL;
+ int store_size = 0;
+
+ int seen_newline = 0;
+
+ while (!seen_newline)
+ {
+ if (fgets(buffer, sizeof (buffer), fin) == NULL)
+ {
+ if (store_size > 0)
+ break;
+ else
+ {
+ *dst = NULL;
+ return 0;
+ }
+ }
+
+ buffer_size = strlen(buffer) + 1;
+
+ /* Erase trailing newline. */
+
+ if (buffer[buffer_size - 2] == '\n')
+ {
+ seen_newline = 1;
+ buffer[buffer_size - 2] = '\0';
+ buffer_size--;
+ }
+
+ /* Allocate or reallocate space for the buffer. */
+
+ if ((store_new = realloc(store, store_size + buffer_size)))
+ {
+ /* Avoid passing garbage to string functions. */
+
+ if (store == NULL)
+ store_new[0] = '\0';
+
+ store = store_new;
+ store_size += buffer_size;
+
+ store_new = NULL;
+ }
+ else
+ {
+ fprintf(stderr, "Failed to allocate memory.\n");
+
+ free(store);
+ *dst = NULL;
+ return 0;
+ }
+
+ strncat(store, buffer, buffer_size);
+ }
+
+ *dst = store;
+
+ return 1;
+}
+
+char *strip_newline(char *str)
+{
+ char *c = str + strlen(str) - 1;
+
+ while (c >= str && (*c == '\n' || *c =='\r'))
+ *c-- = '\0';
+
+ return str;
+}
+
+time_t make_time_from_utc(struct tm *tm)
+{
+ struct tm local, *utc;
+ time_t t;
+
+ t = mktime(tm);
+
+ local = *localtime(&t);
+ utc = gmtime(&t);
+
+ local.tm_year += local.tm_year - utc->tm_year;
+ local.tm_mon += local.tm_mon - utc->tm_mon ;
+ local.tm_mday += local.tm_mday - utc->tm_mday;
+ local.tm_hour += local.tm_hour - utc->tm_hour;
+ local.tm_min += local.tm_min - utc->tm_min ;
+ local.tm_sec += local.tm_sec - utc->tm_sec ;
+
+ return mktime(&local);
+}
+
+const char *date_to_str(time_t i)
+{
+ static char str[sizeof ("YYYY-mm-dd HH:MM:SS")];
+ strftime(str, sizeof (str), "%Y-%m-%d %H:%M:%S", localtime(&i));
+ return str;
+}
+
+int file_exists(const char *name)
+{
+ FILE *fp;
+
+ if ((fp = fopen(name, "r")))
+ {
+ fclose(fp);
+ return 1;
+ }
+ return 0;
+}
+
+int file_rename(const char *src, const char *dst)
+{
+#ifdef _WIN32
+ if (file_exists(dst))
+ remove(dst);
+#endif
+ return rename(src, dst);
+}
+
+char *base_name(const char *name, const char *suffix)
+{
+ static char buf[MAXSTR];
+
+ char *base;
+ size_t l;
+
+ /* Remove the directory delimiter. */
+
+ base = strrchr(name, '/');
+#ifdef _WIN32
+ if (!base)
+ base = strrchr(name, '\\');
+ else
+ {
+ char *tmp;
+ if ((tmp = strrchr(base, '\\')))
+ base = tmp;
+ }
+#endif
+ strncpy(buf, base ? base + 1 : name, MAXSTR);
+
+ /* Remove the extension. */
+
+ l = strlen(buf) - strlen(suffix);
+ if ((l > 1) && (strcmp(buf + l, suffix) == 0))
+ buf[l] = '\0';
+
+ return buf;
+}
+
+/*---------------------------------------------------------------------------*/
--- /dev/null
+/*
+ * Copyright (C) 2007 Neverball contributors
+ *
+ * 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
+ */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <time.h>
+
+int read_line(char **, FILE *);
+char *strip_newline(char *);
+
+time_t make_time_from_utc(struct tm *);
+const char *date_to_str(time_t);
+
+int file_exists(const char *);
+int file_rename(const char *, const char *);
+
+char *base_name(const char *name, const char *suffix);
+
+#endif