Ability to define cartridge directory TIC-80 standalone uses #175
This commit is contained in:
		@@ -733,7 +733,7 @@ static bool loadProject(Console* console, const char* data, s32 size, tic_cartri
 | 
			
		||||
 | 
			
		||||
static bool hasExt(const char* name, const char* ext)
 | 
			
		||||
{
 | 
			
		||||
	return strstr(name, ext) == name + strlen(name) - strlen(ext);
 | 
			
		||||
	return strcmp(name + strlen(name) - strlen(ext), ext) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -2584,6 +2584,8 @@ static void cmdLoadCart(Console* console, const char* name)
 | 
			
		||||
			loadCart(console->tic, &embed.file, data, size, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		strcpy(console->romName, fsFilename(name));
 | 
			
		||||
 | 
			
		||||
		embed.yes = true;
 | 
			
		||||
 | 
			
		||||
		SDL_free(data);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										156
									
								
								src/fs.c
									
									
									
									
									
								
							
							
						
						
									
										156
									
								
								src/fs.c
									
									
									
									
									
								
							@@ -29,12 +29,11 @@
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#if !defined(__WINRT__) && !defined(__WINDOWS__)
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__WINRT__) || defined(__WINDOWS__)
 | 
			
		||||
#include <direct.h>
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__EMSCRIPTEN__)
 | 
			
		||||
@@ -540,18 +539,80 @@ static void makeDir(const char* name)
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool fsExistsFile(FileSystem* fs, const char* name)
 | 
			
		||||
const char* fsFilename(const char *path)
 | 
			
		||||
{
 | 
			
		||||
	const char* path = getFilePath(fs, name);
 | 
			
		||||
	FILE* file = tic_fopen(UTF8ToString(path), UTF8ToString("rb"));
 | 
			
		||||
	const char* full = fsFullname(path);
 | 
			
		||||
	const char* base = fsBasename(path);
 | 
			
		||||
 | 
			
		||||
	if(file)
 | 
			
		||||
	return base ? full + strlen(fsBasename(path)) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* fsFullname(const char *path)
 | 
			
		||||
{
 | 
			
		||||
	char* result = NULL;
 | 
			
		||||
 | 
			
		||||
#if defined(__WINDOWS__) || defined(__WINRT__)
 | 
			
		||||
	static wchar_t wpath[FILENAME_MAX];
 | 
			
		||||
	GetFullPathNameW(UTF8ToString(path), sizeof(wpath), wpath, NULL);
 | 
			
		||||
 | 
			
		||||
	result = StringToUTF8(wpath);
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* fsBasename(const char *path)
 | 
			
		||||
{
 | 
			
		||||
	char* result = NULL;
 | 
			
		||||
 | 
			
		||||
#if defined(__WINDOWS__) || defined(__WINRT__)
 | 
			
		||||
	{
 | 
			
		||||
		fclose(file);
 | 
			
		||||
		return true;
 | 
			
		||||
		char* full = (char*)fsFullname(path);
 | 
			
		||||
 | 
			
		||||
		struct tic_stat_struct s;
 | 
			
		||||
		if(tic_stat(UTF8ToString(full), &s) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			result = full;
 | 
			
		||||
 | 
			
		||||
			if(S_ISREG(s.st_mode))
 | 
			
		||||
			{
 | 
			
		||||
				const char* ptr = result + strlen(result);
 | 
			
		||||
 | 
			
		||||
				while(ptr >= result)
 | 
			
		||||
				{
 | 
			
		||||
					if(*ptr == '\\')
 | 
			
		||||
					{
 | 
			
		||||
						result[ptr-result] = '\0';
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					ptr--;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
	if(result && result[strlen(result)-1] != '\\')
 | 
			
		||||
		strcat(result, "\\");
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool fsExists(const char* name)
 | 
			
		||||
{
 | 
			
		||||
	struct tic_stat_struct s;
 | 
			
		||||
	return tic_stat(UTF8ToString(name), &s) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool fsExistsFile(FileSystem* fs, const char* name)
 | 
			
		||||
{
 | 
			
		||||
	return fsExists(getFilePath(fs, name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool fsSaveFile(FileSystem* fs, const char* name, const void* data, size_t size, bool overwrite)
 | 
			
		||||
@@ -714,55 +775,64 @@ void fsOpenWorkingFolder(FileSystem* fs)
 | 
			
		||||
	fsOpenSystemPath(fs, path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void createFileSystem(void(*callback)(FileSystem*))
 | 
			
		||||
void createFileSystem(const char* path, void(*callback)(FileSystem*))
 | 
			
		||||
{
 | 
			
		||||
	FileSystem* fs = (FileSystem*)SDL_malloc(sizeof(FileSystem));
 | 
			
		||||
	memset(fs, 0, sizeof(FileSystem));
 | 
			
		||||
 | 
			
		||||
	fs->net = createNet();
 | 
			
		||||
 | 
			
		||||
	if(path)
 | 
			
		||||
	{
 | 
			
		||||
		strcpy(fs->dir, path);
 | 
			
		||||
		callback(fs);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
#if defined(__EMSCRIPTEN__)
 | 
			
		||||
 | 
			
		||||
	strcpy(fs->dir, "/" TIC_PACKAGE "/" TIC_NAME "/");
 | 
			
		||||
		strcpy(fs->dir, "/" TIC_PACKAGE "/" TIC_NAME "/");
 | 
			
		||||
 | 
			
		||||
#elif defined(__ANDROID__)
 | 
			
		||||
 | 
			
		||||
	strcpy(fs->dir, SDL_AndroidGetExternalStoragePath());
 | 
			
		||||
	const char AppFolder[] = "/" TIC_NAME "/";
 | 
			
		||||
	strcat(fs->dir, AppFolder);
 | 
			
		||||
	mkdir(fs->dir, 0700);
 | 
			
		||||
		strcpy(fs->dir, SDL_AndroidGetExternalStoragePath());
 | 
			
		||||
		const char AppFolder[] = "/" TIC_NAME "/";
 | 
			
		||||
		strcat(fs->dir, AppFolder);
 | 
			
		||||
		mkdir(fs->dir, 0700);
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
	char* path = SDL_GetPrefPath(TIC_PACKAGE, TIC_NAME);
 | 
			
		||||
	strcpy(fs->dir, path);
 | 
			
		||||
	SDL_free(path);
 | 
			
		||||
		char* path = SDL_GetPrefPath(TIC_PACKAGE, TIC_NAME);
 | 
			
		||||
		strcpy(fs->dir, path);
 | 
			
		||||
		SDL_free(path);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	fs->net = createNet();
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
#if defined(__EMSCRIPTEN__)
 | 
			
		||||
	EM_ASM_
 | 
			
		||||
	(
 | 
			
		||||
		{
 | 
			
		||||
			var dir = "";
 | 
			
		||||
			Module.Pointer_stringify($0).split("/").forEach(function(val)
 | 
			
		||||
		EM_ASM_
 | 
			
		||||
		(
 | 
			
		||||
			{
 | 
			
		||||
				if(val.length)
 | 
			
		||||
				var dir = "";
 | 
			
		||||
				Module.Pointer_stringify($0).split("/").forEach(function(val)
 | 
			
		||||
				{
 | 
			
		||||
					dir += "/" + val;
 | 
			
		||||
					FS.mkdir(dir);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
			
 | 
			
		||||
			FS.mount(IDBFS, {}, dir);
 | 
			
		||||
			FS.syncfs(true, function(error)
 | 
			
		||||
			{
 | 
			
		||||
				if(error) console.log(error);
 | 
			
		||||
				else Runtime.dynCall('vi', $1, [$2]);
 | 
			
		||||
			});			
 | 
			
		||||
		}, fs->dir, callback, fs
 | 
			
		||||
	);
 | 
			
		||||
					if(val.length)
 | 
			
		||||
					{
 | 
			
		||||
						dir += "/" + val;
 | 
			
		||||
						FS.mkdir(dir);
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
				
 | 
			
		||||
				FS.mount(IDBFS, {}, dir);
 | 
			
		||||
				FS.syncfs(true, function(error)
 | 
			
		||||
				{
 | 
			
		||||
					if(error) console.log(error);
 | 
			
		||||
					else Runtime.dynCall('vi', $1, [$2]);
 | 
			
		||||
				});			
 | 
			
		||||
			}, fs->dir, callback, fs
 | 
			
		||||
		);
 | 
			
		||||
#else
 | 
			
		||||
	callback(fs);
 | 
			
		||||
		callback(fs);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								src/fs.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								src/fs.h
									
									
									
									
									
								
							@@ -47,7 +47,7 @@ typedef void(*OpenCallback)(const char* name, const void* buffer, size_t size, v
 | 
			
		||||
 | 
			
		||||
typedef struct FileSystem FileSystem;
 | 
			
		||||
 | 
			
		||||
void createFileSystem(void(*callback)(FileSystem*));
 | 
			
		||||
void createFileSystem(const char* path, void(*callback)(FileSystem*));
 | 
			
		||||
 | 
			
		||||
void fsEnumFiles(FileSystem* fs, ListCallback callback, void* data);
 | 
			
		||||
void fsAddFile(FileSystem* fs, AddCallback callback, void* data);
 | 
			
		||||
@@ -61,6 +61,10 @@ void* fsLoadRootFile(FileSystem* fs, const char* name, s32* size);
 | 
			
		||||
void fsMakeDir(FileSystem* fs, const char* name);
 | 
			
		||||
bool fsExistsFile(FileSystem* fs, const char* name);
 | 
			
		||||
 | 
			
		||||
const char* fsBasename(const char *path);
 | 
			
		||||
const char* fsFilename(const char *path);
 | 
			
		||||
const char* fsFullname(const char *path);
 | 
			
		||||
bool fsExists(const char* name);
 | 
			
		||||
void* fsReadFile(const char* path, s32* size);
 | 
			
		||||
bool fsWriteFile(const char* path, const void* data, s32 size);
 | 
			
		||||
bool fsCopyFile(const char* src, const char* dst);
 | 
			
		||||
 
 | 
			
		||||
@@ -2419,7 +2419,7 @@ static void onFSInitialized(FileSystem* fs)
 | 
			
		||||
void onEmscriptenWget(const char* file)
 | 
			
		||||
{
 | 
			
		||||
	studio.argv[1] = DEFAULT_CART;
 | 
			
		||||
	createFileSystem(onFSInitialized);
 | 
			
		||||
	createFileSystem(NULL, onFSInitialized);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void onEmscriptenWgetError(const char* error) {}
 | 
			
		||||
@@ -2446,12 +2446,14 @@ s32 main(s32 argc, char **argv)
 | 
			
		||||
	{
 | 
			
		||||
		emscripten_async_wget(studio.argv[1], DEFAULT_CART, onEmscriptenWget, onEmscriptenWgetError);
 | 
			
		||||
	}
 | 
			
		||||
	else createFileSystem(onFSInitialized);
 | 
			
		||||
	else createFileSystem(NULL, onFSInitialized);
 | 
			
		||||
 | 
			
		||||
	emscripten_set_main_loop(tick, TIC_FRAMERATE == 60 ? 0 : TIC_FRAMERATE, 1);
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
	createFileSystem(onFSInitialized);
 | 
			
		||||
	printf("filename %s\n", fsFilename("../TIC-80/config.tic"));
 | 
			
		||||
 | 
			
		||||
	createFileSystem(argc > 1 && fsExists(argv[1]) ? fsBasename(argv[1]) : NULL, onFSInitialized);
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		u64 nextTick = SDL_GetPerformanceCounter();
 | 
			
		||||
 
 | 
			
		||||
@@ -375,7 +375,7 @@ static void replace(char* src, const char* what, const char* with)
 | 
			
		||||
 | 
			
		||||
static bool hasExt(const char* name, const char* ext)
 | 
			
		||||
{
 | 
			
		||||
	return strstr(name, ext) == name + strlen(name) - strlen(ext);
 | 
			
		||||
	return strcmp(name + strlen(name) - strlen(ext), ext) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cutExt(char* name, const char* ext)
 | 
			
		||||
@@ -400,7 +400,7 @@ static bool addMenuItem(const char* name, const char* info, s32 id, void* ptr, b
 | 
			
		||||
		MenuItem* item = &data->items[data->count++];
 | 
			
		||||
 | 
			
		||||
		item->name = SDL_strdup(name);
 | 
			
		||||
 | 
			
		||||
		bool project = false;
 | 
			
		||||
		if(dir)
 | 
			
		||||
		{
 | 
			
		||||
			char folder[FILENAME_MAX];
 | 
			
		||||
@@ -417,7 +417,7 @@ static bool addMenuItem(const char* name, const char* info, s32 id, void* ptr, b
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				cutExt(item->label, ProjectExt);
 | 
			
		||||
				item->project = true;
 | 
			
		||||
				project = true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -429,6 +429,7 @@ static bool addMenuItem(const char* name, const char* info, s32 id, void* ptr, b
 | 
			
		||||
		item->id = id;
 | 
			
		||||
		item->dir = dir;
 | 
			
		||||
		item->cover = NULL;
 | 
			
		||||
		item->project = project;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return data->count < MAX_CARTS;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user