[BACK]Return to main.c CVS log [TXT][DIR] Up to [contributed] / brogue-ce / src / platform

File: [contributed] / brogue-ce / src / platform / main.c (download)

Revision 1.2, Thu May 27 20:44:14 2021 UTC (2 years, 11 months ago) by rubenllorente
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +29 -0 lines

Added pledge() and unveil() support

#include <math.h>
#include <limits.h>
#include "platform.h"
#if defined(__OpenBSD__)
#include <unistd.h> // For pledge() and unveil()
#endif


// Expanding a macro as a string constant requires two levels of macros
#define _str(x)  #x
#define STRINGIFY(x)  _str(x)

struct brogueConsole currentConsole;

char dataDirectory[BROGUE_FILENAME_MAX] = STRINGIFY(DATADIR);
boolean serverMode = false;
boolean hasGraphics = false;
boolean graphicsEnabled = false;
boolean isCsvFormat = false;

static void printCommandlineHelp() {
    printf("%s",
    "--help         -h          print this help message\n"
    "--version      -V          print the version (i.e., " BROGUE_VERSION_STRING ")\n"
    "--scores                   dump scores to output and exit immediately\n"
    "-n                         start a new game, skipping the menu\n"
    "-s seed                    start a new game with the specified numerical seed\n"
    "-o filename[.broguesave]   open a save file (extension optional)\n"
    "-v recording[.broguerec]   view a recording (extension optional)\n"
#ifdef BROGUE_WEB
    "--server-mode              run the game in web-brogue server mode\n"
#endif
#ifdef BROGUE_SDL
    "--size N                   starts the game at font size N (1 to 20)\n"
    "--graphics     -G          enable graphical tiles\n"
    "--full-screen  -F          enable full screen\n"
    "--no-gpu                   disable hardware-accelerated graphics and HiDPI\n"
#endif
#ifdef BROGUE_CURSES
    "--term         -t          run in ncurses-based terminal mode\n"
#endif
    "--stealth      -S          display stealth range\n"
    "--no-effects   -E          disable color effects\n"
    "--wizard       -W          run in wizard mode, invincible with powerful items\n"
    "[--csv] --print-seed-catalog [START NUM LEVELS]\n"
    "                           (optional csv format)\n"
    "                           prints a catalog of the first LEVELS levels of NUM\n"
    "                           seeds from seed START (defaults: 1 1000 5)\n"
    );
    return;
}

static void badArgument(const char *arg) {
    printf("Bad argument: %s\n\n", arg);
    printCommandlineHelp();
}

int main(int argc, char *argv[])
{

#if 0
#define TOD(x)  ((double) (x) / FP_FACTOR)
    fixpt y, x1 = 1, x2 = FP_FACTOR * 70 / 100;
    for (int i=0; i < 10; i++) {
        y = fp_pow(x2, x1); printf("%.5f ^ %i = %.5f  (%lli)\n", TOD(x2), x1, TOD(y), y);
        // y = fp_sqrt(x1); printf("sqrt(%.5f) = %.5f  (%lli)\n", TOD(x1), TOD(y), y);
        x1 += 1;
    }
    exit(0);
#endif

#ifdef BROGUE_SDL
    currentConsole = sdlConsole;
#elif BROGUE_WEB
    currentConsole = webConsole;
#elif BROGUE_CURSES
    currentConsole = cursesConsole;
#endif

    rogue.nextGame = NG_NOTHING;
    rogue.nextGamePath[0] = '\0';
    rogue.nextGameSeed = 0;
    rogue.wizard = false;
    rogue.displayAggroRangeMode = false;
    rogue.trueColorMode = false;

    boolean initialGraphics = false;

    int i;
    for (i = 1; i < argc; i++) {
#if defined(__OpenBSD__)
	if (strcmp(argv[i], "--box") == 0) {
	    if (i + 1 < argc) {
	        if ( unveil("/usr","r")==-1 ) {
		    perror("Unveil failure. Aborting.");
			exit (1);
		}
		if ( unveil(argv[i + 1],"rwc")==-1 ) {
        	    perror("Unveil failure. Aborting.");
        		exit(1);
		}
		if ( chdir(argv[i+1])==-1 ) {
			perror("Could not change directory.");
			exit(1);
		}
		if ( pledge("stdio rpath wpath cpath fattr flock "
       			"getpw id tty proc", NULL )==-1 ) {
        	    perror("Pledge failure. Aborting.");
        		exit (1);
		}
		i++;
		continue;
	    }
	}
#endif // OpenBSD
        if (strcmp(argv[i], "--scores") == 0) {
            // just dump the scores and quit!
            dumpScores();
            return 0;
        }

        if (strcmp(argv[i], "--seed") == 0 || strcmp(argv[i], "-s") == 0) {
            // pick a seed!
            if (i + 1 < argc) {
                unsigned int seed = atof(argv[i + 1]); // plenty of precision in a double, and simpler than any other option
                if (seed != 0) {
                    i++;
                    rogue.nextGameSeed = seed;
                    rogue.nextGame = NG_NEW_GAME_WITH_SEED;
                    continue;
                }
            }
        }

        if (strcmp(argv[i], "-n") == 0) {
            if (rogue.nextGameSeed == 0) {
                rogue.nextGame = NG_NEW_GAME;
            } else {
                rogue.nextGame = NG_NEW_GAME_WITH_SEED;
            }
            continue;
        }

        if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--open") == 0) {
            if (i + 1 < argc) {
                strncpy(rogue.nextGamePath, argv[i + 1], BROGUE_FILENAME_MAX);
                rogue.nextGamePath[BROGUE_FILENAME_MAX - 1] = '\0';
                rogue.nextGame = NG_OPEN_GAME;

                if (!endswith(rogue.nextGamePath, GAME_SUFFIX)) {
                    append(rogue.nextGamePath, GAME_SUFFIX, BROGUE_FILENAME_MAX);
                }

                i++;
                continue;
            }
        }

        if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--view") == 0) {
            if (i + 1 < argc) {
                strncpy(rogue.nextGamePath, argv[i + 1], BROGUE_FILENAME_MAX);
                rogue.nextGamePath[BROGUE_FILENAME_MAX - 1] = '\0';
                rogue.nextGame = NG_VIEW_RECORDING;

                if (!endswith(rogue.nextGamePath, RECORDING_SUFFIX)) {
                    append(rogue.nextGamePath, RECORDING_SUFFIX, BROGUE_FILENAME_MAX);
                }

                i++;
                continue;
            }
        }

        if (strcmp(argv[i], "--print-seed-catalog") == 0) {
            if (i + 3 < argc) {
                // Use convertions from types the next size up, because they're signed
                unsigned long startingSeed = atof(argv[i + 1]);
                unsigned long numberOfSeeds = atoll(argv[i + 2]);
                unsigned int numberOfLevels = atol(argv[i + 3]);

                if (startingSeed > 0 && numberOfLevels <= 40) {
                    printSeedCatalog(startingSeed, numberOfSeeds, numberOfLevels, isCsvFormat);
                    return 0;
                }
            } else {
                printSeedCatalog(1, 1000, 5, isCsvFormat);
                return 0;
            }
        }

        if (strcmp(argv[i], "-V") == 0 || strcmp(argv[i], "--version") == 0) {
            printf("%s\n", BROGUE_VERSION_STRING);
            return 0;
        }

        if (!(strcmp(argv[i], "-?") && strcmp(argv[i], "-h") && strcmp(argv[i], "--help"))) {
            printCommandlineHelp();
            return 0;
        }

        if (strcmp(argv[i], "-G") == 0 || strcmp(argv[i], "--graphics") == 0) {
            initialGraphics = true;  // we call setGraphicsEnabled later
            continue;
        }

        if (strcmp(argv[i], "--csv") == 0 ) {
            isCsvFormat = true;  // we call printSeedCatalog later
            continue;
        }

#ifdef BROGUE_SDL
        if (strcmp(argv[i], "--size") == 0) {
            if (i + 1 < argc) {
                int size = atoi(argv[i + 1]);
                if (size > 0 && size <= 20) {
                    windowWidth = round(pow(1.1, size) * 620.);
                    // Height set automatically
                };

                i++;
                continue;
            }
        }

        if (strcmp(argv[i], "-F") == 0 || strcmp(argv[i], "--full-screen") == 0) {
            fullScreen = true;
            continue;
        }

        if (strcmp(argv[i], "--no-gpu") == 0) {
            softwareRendering = true;
            continue;
        }
#endif

#ifdef BROGUE_CURSES
        if (strcmp(argv[i], "--term") == 0 || strcmp(argv[i], "-t") == 0) {
            currentConsole = cursesConsole;
            continue;
        }
#endif

#ifdef BROGUE_WEB
        if(strcmp(argv[i], "--server-mode") == 0) {
            currentConsole = webConsole;
            rogue.nextGame = NG_NEW_GAME;
            serverMode = true;
            continue;
        }
#endif

        if (strcmp(argv[i], "--stealth") == 0 || strcmp(argv[i], "-S") == 0) {
            rogue.displayAggroRangeMode = true;
            continue;
        }

        if (strcmp(argv[i], "--no-effects") == 0 || strcmp(argv[i], "-E") == 0) {
            rogue.trueColorMode = true;
            continue;
        }

        if (strcmp(argv[i], "--wizard") == 0 || strcmp(argv[i], "-W") == 0) {
            rogue.wizard = true;
            continue;
        }

        // maybe it ends with .broguesave or .broguerec, then?
        if (endswith(argv[i], GAME_SUFFIX)) {
            strncpy(rogue.nextGamePath, argv[i], BROGUE_FILENAME_MAX);
            rogue.nextGamePath[BROGUE_FILENAME_MAX - 1] = '\0';
            rogue.nextGame = NG_OPEN_GAME;
            continue;
        }

        if (endswith(argv[i], RECORDING_SUFFIX)) {
            strncpy(rogue.nextGamePath, argv[i], BROGUE_FILENAME_MAX);
            rogue.nextGamePath[BROGUE_FILENAME_MAX - 1] = '\0';
            rogue.nextGame = NG_VIEW_RECORDING;
            continue;
        }

        badArgument(argv[i]);
        return 1;
    }

    hasGraphics = (currentConsole.setGraphicsEnabled != NULL);
    // Now actually set graphics. We do this to ensure there is exactly one
    // call, whether true or false
    graphicsEnabled = setGraphicsEnabled(initialGraphics);

    loadKeymap();
    currentConsole.gameLoop();

    return 0;
}