about summary refs log tree commit diff
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/client/ec_client.c24
-rw-r--r--src/engine/e_engine.c106
-rw-r--r--src/engine/e_engine.h2
-rw-r--r--src/engine/e_map.c2
-rw-r--r--src/engine/server/es_server.c20
5 files changed, 127 insertions, 27 deletions
diff --git a/src/engine/client/ec_client.c b/src/engine/client/ec_client.c
index 1ae1d51a..1a6a24f1 100644
--- a/src/engine/client/ec_client.c
+++ b/src/engine/client/ec_client.c
@@ -550,7 +550,7 @@ void client_disconnect()
 
 static int client_load_data()
 {
-	debug_font = gfx_load_texture("data/debug_font.png", IMG_AUTO, TEXLOAD_NORESAMPLE);
+	debug_font = gfx_load_texture("debug_font.png", IMG_AUTO, TEXLOAD_NORESAMPLE);
 	return 1;
 }
 
@@ -698,7 +698,7 @@ static const char *client_load_map_search(const char *mapname, int wanted_crc)
 	client_set_state(CLIENTSTATE_LOADING);
 	
 	/* try the normal maps folder */
-	str_format(buf, sizeof(buf), "data/maps/%s.map", mapname);
+	str_format(buf, sizeof(buf), "maps/%s.map", mapname);
 	error = client_load_map(buf, wanted_crc);
 	if(!error)
 		return error;
@@ -1601,18 +1601,6 @@ void client_save_line(const char *line)
 
 int main(int argc, char **argv)
 {
-#if defined(CONF_PLATFORM_MACOSX)
-	char buffer[512];
-	unsigned pos = strrchr(argv[0], '/') - argv[0];
-
-	if(pos >= 512)
-		return -1;
-
-	strncpy(buffer, argv[0], 511);
-	buffer[pos] = 0;
-	chdir(buffer);
-#endif
-
 	/* init the engine */
 	dbg_msg("client", "starting...");
 	engine_init("Teeworlds");
@@ -1624,6 +1612,14 @@ int main(int argc, char **argv)
 	/* parse the command line arguments */
 	engine_parse_arguments(argc, argv);
 	
+	/* change into data-dir */
+	if (!engine_chdir_datadir(argv[0]))
+	{
+		dbg_msg("client", "fatal error: data-dir cannot be found");
+		gui_messagebox("Error", "The data-dir cannot be found.");
+		return -1;
+	}
+	
 	/* run the client*/
 	client_run();
 	
diff --git a/src/engine/e_engine.c b/src/engine/e_engine.c
index 45eecfe3..3afd9ff9 100644
--- a/src/engine/e_engine.c
+++ b/src/engine/e_engine.c
@@ -13,6 +13,9 @@
 #include <engine/e_network.h>
 #include "e_linereader.h"
 
+/* compiled-in data-dir path */
+#define DATA_DIR "data"
+
 static JOBPOOL hostlookuppool;
 
 static void con_dbg_dumpmem(void *result, void *user_data)
@@ -22,6 +25,7 @@ static void con_dbg_dumpmem(void *result, void *user_data)
 
 
 static char application_save_path[512] = {0};
+char *datadir_override;
 
 const char *engine_savepath(const char *filename, char *buffer, int max)
 {
@@ -89,6 +93,11 @@ void engine_parse_arguments(int argc, char **argv)
 			abs = 1;
 			i++;
 		}
+		else if(argv[i][0] == '-' && argv[i][1] == 'd' && argv[i][2] == 0 && argc - i > 1)
+		{
+			datadir_override = argv[i+1];
+			i++;
+		}
 	}
 
 	if(abs)
@@ -405,3 +414,100 @@ void engine_hostlookup(HOSTLOOKUP *lookup, const char *hostname)
 	jobs_add(&hostlookuppool, &lookup->job, hostlookup_thread, lookup);
 }
 
+int engine_chdir_datadir(char *argv0)
+{
+#if defined(CONF_FAMILY_UNIX)
+	static const char *sdirs[] = {
+		"/usr/share/teeworlds",
+		"/usr/local/share/teeworlds"
+	};
+	static const int sdirs_count = sizeof(sdirs) / sizeof(sdirs[0]);
+#endif
+
+	int found = 0;
+	char data_dir[1024*2];
+	
+	/* 1) use provided data-dir override */
+	if (datadir_override)
+	{
+		if (fs_is_dir(datadir_override))
+		{
+			str_copy(data_dir, datadir_override, sizeof(data_dir));
+			dbg_msg("engine/datadir", "using override '%s'", data_dir);
+			found = 1;
+		}
+		else
+		{
+			dbg_msg("engine/datadir",
+				"specified data-dir '%s' does not exist",
+				datadir_override);
+			return 0;
+		}
+	}
+	
+#if defined(CONF_FAMILY_UNIX)
+	/* 2) use data-dir in PWD if present */
+	if (!found && fs_is_dir("data"))
+	{
+		strcpy(data_dir, "data");
+		found = 1;
+	}
+	
+	/* 3) use compiled-in data-dir if present */
+	if (!found && fs_is_dir(DATA_DIR))
+	{
+		strcpy(data_dir, DATA_DIR);
+		found = 1;
+	}
+	
+	/* 4) check for usable path in argv[0] */
+	if (!found)
+	{
+		unsigned int pos = strrchr(argv0, '/') - argv0;
+		
+		if (pos < sizeof(data_dir))
+		{
+			char basedir[sizeof(data_dir)];
+			strncpy(basedir, argv0, pos);
+			basedir[pos] = '\0';
+			str_format(data_dir, sizeof(data_dir),
+				"%s/data", basedir);
+			
+			if (fs_is_dir(data_dir))
+				found = 1;
+		}
+	}
+
+	/* 5) check for all default locations */
+	if (!found)
+	{
+		int i;
+		for (i = 0; i < sdirs_count; i++)
+		{
+			if (fs_is_dir(sdirs[i]))
+			{
+				strcpy(data_dir, sdirs[i]);
+				found = 1;
+				break;
+			}
+		}
+	}
+#elif defined(CONF_FAMILY_WINDOWS)
+	/* FIXME: any alternative directories to search? %PROGRAM_FILES%/.../ */
+	if (!found && fs_is_dir("data"))
+	{
+		strcpy(data_dir, "data");
+		found = 1;
+	}
+#endif
+	
+	if (found)
+	{
+		dbg_msg("engine/datadir", "using '%s'", data_dir);
+		
+		/* change working directory to data-dir */
+		fs_chdir(data_dir);
+	}
+	
+	return found;
+}
diff --git a/src/engine/e_engine.h b/src/engine/e_engine.h
index dfe2f6f5..5db7a4dd 100644
--- a/src/engine/e_engine.h
+++ b/src/engine/e_engine.h
@@ -10,6 +10,8 @@ int engine_config_write_start();
 void engine_config_write_line(const char *line);
 void engine_config_write_stop();
 
+int engine_chdir_datadir(char *argv0);
+
 int engine_stress(float probability);
 
 typedef struct HOSTLOOKUP
diff --git a/src/engine/e_map.c b/src/engine/e_map.c
index c33868d7..a2048310 100644
--- a/src/engine/e_map.c
+++ b/src/engine/e_map.c
@@ -53,7 +53,7 @@ int map_is_loaded()
 int map_load(const char *mapname)
 {
 	char buf[512];
-	str_format(buf, sizeof(buf), "data/maps/%s.map", mapname);
+	str_format(buf, sizeof(buf), "maps/%s.map", mapname);
 	map = datafile_load(buf);
 	return map != 0;
 }
diff --git a/src/engine/server/es_server.c b/src/engine/server/es_server.c
index 6cdf835f..58866e09 100644
--- a/src/engine/server/es_server.c
+++ b/src/engine/server/es_server.c
@@ -882,7 +882,7 @@ static int server_load_map(const char *mapname)
 {
 	DATAFILE *df;
 	char buf[512];
-	str_format(buf, sizeof(buf), "data/maps/%s.map", mapname);
+	str_format(buf, sizeof(buf), "maps/%s.map", mapname);
 	df = datafile_load(buf);
 	if(!df)
 		return 0;
@@ -1145,17 +1145,6 @@ static void server_register_commands()
 
 int main(int argc, char **argv)
 {
-#if defined(CONF_PLATFORM_MACOSX)
-	char buffer[512];
-	unsigned pos = strrchr(argv[0], '/') - argv[0];
-
-	if(pos >= 512)
-		return -1;
-
-	strncpy(buffer, argv[0], 511);
-	buffer[pos] = 0;
-	chdir(buffer);
-#endif
 #if defined(CONF_FAMILY_WINDOWS)
 	int i;
 	for(i = 1; i < argc; i++)
@@ -1181,6 +1170,13 @@ int main(int argc, char **argv)
 	/* parse the command line arguments */
 	engine_parse_arguments(argc, argv);
 	
+	/* change into data-dir */
+	if (!engine_chdir_datadir(argv[0]))
+	{
+		dbg_msg("server", "fatal error: data-dir cannot be found");
+		return -1;
+	}
+	
 	/* run the server */
 	server_run();
 	return 0;