diff libcore/core/sys.c @ 121:789b23e01f52

misc: reorganize hierarchy, closes #2490
author David Demelier <markand@malikania.fr>
date Mon, 05 Oct 2020 13:25:06 +0200
parents src/core/sys.c@68ce8e02061a
children eb0a7ab71023
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libcore/core/sys.c	Mon Oct 05 13:25:06 2020 +0200
@@ -0,0 +1,181 @@
+/*
+ * sys.c -- system routines
+ *
+ * Copyright (c) 2020 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include <SDL.h>
+#include <SDL_image.h>
+#include <SDL_mixer.h>
+#include <SDL_ttf.h>
+
+#if !defined(_WIN32)            /* Assuming POSIX */
+#	include <sys/types.h>
+#	include <dirent.h>
+#endif
+
+#include "error.h"
+#include "error_p.h"
+#include "sys.h"
+
+#if defined(_WIN32)
+
+static void
+determine(char path[], size_t pathlen)
+{
+	char *base = SDL_GetBasePath();
+
+	/* On Windows, the data hierarchy is the same as the project. */
+	snprintf(path, pathlen, "%sassets", base);
+	SDL_free(base);
+}
+
+#else                           /* Assuming POSIX */
+
+static bool
+is_absolute(const char *path)
+{
+	assert(path);
+
+	return path[0] == '/';
+}
+
+static void
+determine(char path[], size_t pathlen)
+{
+	char localassets[PATH_MAX];
+	char *base = SDL_GetBasePath();
+	DIR *dp;
+
+	/* Try assets directory where executable lives. */
+	snprintf(localassets, sizeof (localassets), "%sassets", base);
+
+	if ((dp = opendir(localassets))) {
+		snprintf(path, pathlen, "%sassets", base);
+		closedir(dp);
+	} else {
+		/* We are not in the project source directory. */
+		if (is_absolute(SHAREDIR)) {
+			/* SHAREDIR is absolute */
+			snprintf(path, pathlen, "%s/molko", SHAREDIR);
+		} else if (is_absolute(BINDIR)) {
+			/* SHAREDIR is relative but BINDIR is absolute */
+			snprintf(path, pathlen, "%s/%s/molko", PREFIX, SHAREDIR);
+		} else {
+			/* SHAREDIR, BINDIR are both relative */
+			char *ptr = strstr(base, BINDIR);
+
+			if (ptr) {
+				*ptr = '\0';
+				snprintf(path, pathlen, "%s%s/molko", base, SHAREDIR);
+			} else {
+				/* Unable to determine. */
+				snprintf(path, pathlen, ".");
+			}
+		}
+	}
+
+	SDL_free(base);
+}
+
+#endif
+
+bool
+sys_init(void)
+{
+#if defined(__MINGW64__)
+	/* On MinGW buffering leads to painful debugging. */
+	setbuf(stderr, NULL);
+	setbuf(stdout, NULL);
+#endif
+
+	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
+		return error_sdl();
+	if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG)
+		return error_sdl();
+	if (TTF_Init() < 0)
+		return error_sdl();
+	if (Mix_Init(MIX_INIT_OGG) != MIX_INIT_OGG)
+		return error_sdl();
+	if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096) < 0)
+		return error_sdl();
+
+	return true;
+}
+
+const char *
+sys_datadir(void)
+{
+	static char path[PATH_MAX];
+
+	if (path[0] == '\0')
+		determine(path, sizeof (path));
+
+	return path;
+}
+
+const char *
+sys_datapath(const char *fmt, ...)
+{
+	const char *ret;
+	va_list ap;
+
+	va_start(ap, fmt);
+	ret = sys_datapathv(fmt, ap);
+	va_end(ap);
+
+	return ret;
+}
+
+const char *
+sys_datapathv(const char *fmt, va_list ap)
+{
+	static char path[PATH_MAX];
+	char filename[FILENAME_MAX];
+
+	vsnprintf(filename, sizeof (filename), fmt, ap);
+	snprintf(path, sizeof (path), "%s/%s", sys_datadir(), filename);
+
+	return path;
+}
+
+const char *
+sys_savepath(unsigned int idx)
+{
+	static char path[PATH_MAX];
+	char *pref;
+
+	if ((pref = SDL_GetPrefPath("malikania", "molko"))) {
+		snprintf(path, sizeof (path), "%ssave-%u", pref, idx);
+		SDL_free(pref);
+	} else
+		snprintf(path, sizeof (path), "save-%u", idx);
+
+	return path;
+}
+
+void
+sys_finish(void)
+{
+	Mix_Quit();
+	TTF_Quit();
+	IMG_Quit();
+	SDL_Quit();
+}