code duplication
[netris.git] / util.c
diff --git a/util.c b/util.c
index 98248ed64e3ab11d625e6fa514325e2ae9c63146..92a890859a7bb5f701afa30a3614c04f2f0a9bed 100644 (file)
--- a/util.c
+++ b/util.c
@@ -15,8 +15,6 @@
  * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: util.c,v 1.27 1996/02/09 08:22:23 mhw Exp $
  */
 
 #include "netris.h"
 #include <sys/time.h>
 #include <netdb.h>
 #include <errno.h>
+#include <setjmp.h>
 
-static MyEventType AlarmGenFunc(EventGenRec *gen, MyEvent *event);
+#include "util.h"
 
-static EventGenRec alarmGen =
-               { &alarmGen, 0, FT_read, -1, AlarmGenFunc, EM_alarm };
+static MyEventType AlarmGenFunc(EventGenRec *gen, MyEvent *event);
+static EventGenRec alarmGen = {
+       &alarmGen, 0, FT_read, -1, AlarmGenFunc, EM_alarm
+};
 static EventGenRec *nextGen = &alarmGen;
 
-static myRandSeed = 1;
+static int myRandSeed = 1;
 
-static struct timeval baseTimeval;
+static long baseTimeval;
 
-ExtFunc void InitUtil(void)
-{
-       if (initSeed)
-               SRandom(initSeed);
-       else
-               SRandom(time(0));
-       signal(SIGINT, CatchInt);
-       ResetBaseTime();
-}
 
-ExtFunc void ResetBaseTime(void)
-{
-       gettimeofday(&baseTimeval, NULL);
-}
-
-ExtFunc void AtExit(void (*handler)(void))
+void AtExit(void (*handler)(void))
 {
 #ifdef HAS_ON_EXIT
        on_exit((void *)handler, NULL);
@@ -63,99 +50,58 @@ ExtFunc void AtExit(void (*handler)(void))
 #endif
 }
 
-ExtFunc void Usage(void)
-{
-       fprintf(stderr,
-         "Netris version %s (C) 1994,1995,1996  Mark H. Weaver <mhw@netris.org>\n"
-         "Usage: netris <options>\n"
-         "  -h         Print usage information\n"
-         "  -w         Wait for connection\n"
-         "  -c <host>  Initiate connection\n"
-         "  -p <port>  Set port number (default is %d)\n"
-         "  -k <keys>  Remap keys.  The argument is a prefix of the string\n"
-         "               containing the keys in order: left, rotate, right, drop,\n"
-         "               down-faster, toggle-spying, pause, faster, redraw.\n"
-         "               \"^\" prefixes controls.  (default is \"%s\")\n"
-         "  -i <sec>   Set the step-down interval, in seconds\n"
-         "  -r <robot> Execute <robot> (a command) as a robot controlling\n"
-         "               the game instead of the keyboard\n"
-         "  -F         Use fair robot interface\n"
-         "  -s <seed>  Start with given random seed\n"
-         "  -D         Drops go into drop mode\n"
-         "               This means that sliding off a cliff after a drop causes\n"
-         "               another drop automatically\n"
-         "  -S         Disable standout mode (inverse/bold) for slow terminals\n"
-         "  -H         Show distribution and warranty information\n"
-         "  -R         Show rules\n",
-         version_string, DEFAULT_PORT, DEFAULT_KEYS);
-}
+///////////// HELP MESSAGES /////////////
 
-ExtFunc void DistInfo(void)
+void Header(void)
 {
        fprintf(stderr,
-         "Netris version %s (C) 1994,1995,1996  Mark H. Weaver <mhw@netris.org>\n"
-         "\n"
-         "This program is free software; you can redistribute it and/or modify\n"
-         "it under the terms of the GNU General Public License as published by\n"
-         "the Free Software Foundation; either version 2 of the License, or\n"
-         "(at your option) any later version.\n"
-         "\n"
-         "This program is distributed in the hope that it will be useful,\n"
-         "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-         "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
-         "GNU General Public License for more details.\n"
-         "\n"
-         "You should have received a copy of the GNU General Public License\n"
-         "along with this program; if not, write to the Free Software\n"
-         "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n",
-         version_string);
+               "NETRIS %s\t(c) 1994-1996,1999 Mark H. Weaver <mhw@netris.org>\n"
+               "          \t(c) 2002 Shiar <shiar@shiar.org>\n\n",
+               version_string
+       );
 }
 
-ExtFunc void Rules(void)
+void DistInfo(void)
 {
        fprintf(stderr,
-         "Netris version %s rules\n"
-         "\n"
-         "Two player mode\n"
-         "---------------\n"
-         "It's just like normal T*tris except that when you clear more than\n"
-         "one row with a single piece, the other player's board is moved up\n"
-         "and junk rows are added to the bottom.  If you clear 2, 3 or 4\n"
-         "rows, 1, 2 or 4 junk rows are added to your opponent's board,\n"
-         "respectively.  The junk rows have exactly one empty column.\n"
-         "For each group of junk rows given, the empty columns will line\n"
-         "up.  This is intentional.\n"
-         "\n"
-         "The longest surviving player wins the game.\n"
-         "\n"
-         "One player mode\n"
-         "---------------\n"
-         "This mode is currently very boring, because there's no scoring\n"
-         "and it never gets any faster.  This will be rectified at some point.\n"
-         "I'm not very motivated to do it right now because I'm sick of one\n"
-         "player T*tris.  For now, use the \"f\" key (by default) to make the\n"
-         "game go faster.  Speedups cannot be reversed for the remainder of\n"
-         "the game.\n",
-         version_string);
+               "This program is free software; you can redistribute it and/or modify\n"
+               "it under the terms of the GNU General Public License as published by\n"
+               "the Free Software Foundation; either version 2 of the License, or\n"
+               "(at your option) any later version.\n"
+               "\n"
+               "This program is distributed in the hope that it will be useful,\n"
+               "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+               "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+               "GNU General Public License for more details.\n"
+               "\n"
+               "You should have received a copy of the GNU General Public License\n"
+               "along with this program; if not, write to the Free Software\n"
+               "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n"
+               "\n"
+       );
 }
 
+///////////// RANDOM /////////////
+
 /*
  * My really crappy random number generator follows
  * Should be more than sufficient for our purposes though
  */
-ExtFunc void SRandom(int seed)
+void SRandom(int seed)
 {
-       initSeed = seed;
+       Game.seed = seed;
        myRandSeed = seed % 31751 + 1;
 }
 
-ExtFunc int Random(int min, int max1)
-{
+int Random(int min, int max1)
+{ //return a random value
        myRandSeed = (myRandSeed * 31751 + 15437) % 32767;
        return myRandSeed % (max1 - min) + min;
 }
 
-ExtFunc int MyRead(int fd, void *data, int len)
+///////////// I/O /////////////
+
+int MyRead(int fd, void *data, int len)
 {
        int result, left;
 
@@ -172,7 +118,7 @@ ExtFunc int MyRead(int fd, void *data, int len)
        return len;
 }
 
-ExtFunc int MyWrite(int fd, void *data, int len)
+int MyWrite(int fd, void *data, int len)
 {
        int result, left;
 
@@ -189,7 +135,27 @@ ExtFunc int MyWrite(int fd, void *data, int len)
        return len;
 }
 
-ExtFunc void NormalizeTime(struct timeval *tv)
+///////////// CONFIG /////////////
+
+void WriteConf(void)
+{
+       FILE *file_out;
+
+       file_out = fopen(CONFIG_FILE, "w");
+       if (file_out == NULL) {
+               perror("Error writing config file");
+               exit(1);
+       }
+
+       fprintf(file_out, "### NETRIS %s Config file ###\n\n", version_string);
+
+       fclose(file_out);
+       fprintf(stderr, "Wrote new game configuration to %s\n", CONFIG_FILE);
+}
+
+///////////// TIME /////////////
+
+void NormalizeTime(struct timeval *tv)
 {
        tv->tv_sec += tv->tv_usec / 1000000;
        tv->tv_usec %= 1000000;
@@ -199,12 +165,7 @@ ExtFunc void NormalizeTime(struct timeval *tv)
        }
 }
 
-ExtFunc void CatchInt(int sig)
-{
-       exit(0);
-}
-
-ExtFunc void CatchAlarm(int sig)
+void CatchAlarm(int sig)
 {
        alarmGen.ready = 1;
        signal(SIGALRM, CatchAlarm);
@@ -215,25 +176,43 @@ static MyEventType AlarmGenFunc(EventGenRec *gen, MyEvent *event)
        return E_alarm;
 }
 
-ExtFunc long CurTimeval(void)
+void SetTimeval(struct timeval *tv, long usec)
+{
+       tv->tv_sec = usec / 1000000;
+       tv->tv_usec = usec % 1000000;
+}
+
+long GetTimeval(struct timeval *tv)
+{
+       return tv->tv_sec * 1000000 + tv->tv_usec;
+}
+
+long AbsTimeval(void)
 {
        struct timeval tv;
 
        gettimeofday(&tv, NULL);
-       tv.tv_sec -= baseTimeval.tv_sec;
-       tv.tv_usec -= baseTimeval.tv_usec;
        return GetTimeval(&tv);
 }
 
-ExtFunc void SetTimeval(struct timeval *tv, long usec)
-{
-       tv->tv_sec = usec / 1000000;
-       tv->tv_usec = usec % 1000000;
+void ResetBaseTime(void)
+{ //Reset the timer
+       baseTimeval = AbsTimeval();
+}
+
+void PauseTime(void)
+{ //Pause the timer
+       baseTimeval -= AbsTimeval();
 }
 
-ExtFunc long GetTimeval(struct timeval *tv)
+void ResumeTime(void)
+{ //Unpause timer
+       baseTimeval += AbsTimeval();
+}
+
+long CurTimeval(void)
 {
-       return tv->tv_sec * 1000000 + tv->tv_usec;
+       return AbsTimeval() - baseTimeval;
 }
 
 static long SetITimer1(long interval, long value)
@@ -248,7 +227,7 @@ static long SetITimer1(long interval, long value)
        return GetTimeval(&old.it_value);
 }
 
-ExtFunc long SetITimer(long interval, long value)
+long SetITimer(long interval, long value)
 {
        long old;
 
@@ -258,19 +237,21 @@ ExtFunc long SetITimer(long interval, long value)
        return old;
 }
 
-ExtFunc volatile void die(char *msg)
+///////////// ... /////////////
+
+volatile void die(char *msg)
 {
        perror(msg);
        exit(1);
 }
 
-ExtFunc volatile void fatal(char *msg)
+volatile void fatal(char *msg)
 {
        fprintf(stderr, "%s\n", msg);
        exit(1);
 }
 
-ExtFunc void BlockSignals(MySigSet *saved, ...)
+void BlockSignals(MySigSet *saved, ...)
 {
        MySigSet set;
        va_list args;
@@ -297,7 +278,7 @@ ExtFunc void BlockSignals(MySigSet *saved, ...)
        va_end(args);
 }
 
-ExtFunc void RestoreSignals(MySigSet *saved, MySigSet *set)
+void RestoreSignals(MySigSet *saved, MySigSet *set)
 {
 #ifdef HAS_SIGPROCMASK
        sigprocmask(SIG_SETMASK, set, saved);
@@ -309,31 +290,34 @@ ExtFunc void RestoreSignals(MySigSet *saved, MySigSet *set)
 #endif
 }
 
-ExtFunc void AddEventGen(EventGenRec *gen)
+///////////// EVENTS /////////////
+
+void AddEventGen(EventGenRec *gen)
 {
        assert(gen->next == NULL);
        gen->next = nextGen->next;
        nextGen->next = gen;
 }
 
-ExtFunc void RemoveEventGen(EventGenRec *gen)
+void RemoveEventGen(EventGenRec *gen)
 {
-       assert(gen->next != NULL);
-       while (nextGen->next != gen)
-               nextGen = nextGen->next;
-       nextGen->next = gen->next;
-       gen->next = NULL;
+       // assert(gen->next != NULL);   /* Be more forgiving, for SIGINTs */
+       if (gen->next) {
+               while (nextGen->next != gen)
+                       nextGen = nextGen->next;
+               nextGen->next = gen->next;
+               gen->next = NULL;
+       }
 }
 
-ExtFunc MyEventType WaitMyEvent(MyEvent *event, int mask)
-{
+MyEventType WaitMyEvent(MyEvent *event, int mask)
+{ //poll
        int i, retry = 0;
        fd_set fds[FT_len];
        EventGenRec *gen;
        int result, anyReady, anySet;
        struct timeval tv;
 
-       /* XXX In certain circumstances, this routine does polling */
        for (;;) {
                for (i = 0; i < FT_len; ++i)
                        FD_ZERO(&fds[i]);
@@ -354,7 +338,7 @@ ExtFunc MyEventType WaitMyEvent(MyEvent *event, int mask)
                        tv.tv_sec = 0;
                        tv.tv_usec = (retry && !anyReady) ? 500000 : 0;
                        result = select(FD_SETSIZE, &fds[FT_read], &fds[FT_write],
-                                       &fds[FT_except], anyReady ? &tv : NULL);
+                                       &fds[FT_except], anyReady ? &tv : NULL);
                }
                else {
                        if (retry && !anyReady)
@@ -363,9 +347,10 @@ ExtFunc MyEventType WaitMyEvent(MyEvent *event, int mask)
                }
                gen = nextGen;
                do {
-                       if ((gen->mask & mask)
-                                       && (gen->ready || (result > 0 && gen->fd >= 0
-                                               && FD_ISSET(gen->fd, &fds[gen->fdType])))) {
+                       if ((gen->mask & mask) && (gen->ready || (
+                               result > 0 && gen->fd >= 0
+                               && FD_ISSET(gen->fd, &fds[gen->fdType])
+                       ))) {
                                gen->ready = 0;
                                event->type = gen->func(gen, event);
                                if (event->type != E_none) {
@@ -379,7 +364,3 @@ ExtFunc MyEventType WaitMyEvent(MyEvent *event, int mask)
        }
 }
 
-/*
- * vi: ts=4 ai
- * vim: noai si
- */