Ejemplo n.º 1
0
static void openrct2_copy_files_over(const utf8 *originalDirectory, const utf8 *newDirectory, const utf8 *extension)
{
	utf8 *ch, filter[MAX_PATH], oldPath[MAX_PATH], newPath[MAX_PATH];
	int fileEnumHandle;
	file_info fileInfo;

	if (!platform_ensure_directory_exists(newDirectory)) {
		log_error("Could not create directory %s.", newDirectory);
		return;
	}

	// Create filter path
	safe_strncpy(filter, originalDirectory, MAX_PATH);
	ch = strchr(filter, '*');
	if (ch != NULL)
		*ch = 0;
	strcat(filter, "*");
	strcat(filter, extension);

	fileEnumHandle = platform_enumerate_files_begin(filter);
	while (platform_enumerate_files_next(fileEnumHandle, &fileInfo)) {
		safe_strncpy(newPath, newDirectory, MAX_PATH);
		strcat(newPath, fileInfo.path);

		safe_strncpy(oldPath, originalDirectory, MAX_PATH);
		ch = strchr(oldPath, '*');
		if (ch != NULL)
			*ch = 0;
		strcat(oldPath, fileInfo.path);

		if (!platform_file_exists(newPath))
			platform_file_copy(oldPath, newPath, false);
	}
	platform_enumerate_files_end(fileEnumHandle);

	fileEnumHandle = platform_enumerate_directories_begin(originalDirectory);
	while (platform_enumerate_directories_next(fileEnumHandle, filter)) {
		safe_strncpy(newPath, newDirectory, MAX_PATH);
		strcat(newPath, filter);

		safe_strncpy(oldPath, originalDirectory, MAX_PATH);
		ch = strchr(oldPath, '*');
		if (ch != NULL)
			*ch = 0;
		strcat(oldPath, filter);

		if (!platform_ensure_directory_exists(newPath)) {
			log_error("Could not create directory %s.", newPath);
			return;
		}
		openrct2_copy_files_over(oldPath, newPath, extension);
	}
	platform_enumerate_directories_end(fileEnumHandle);
}
Ejemplo n.º 2
0
static void window_install_track_design(rct_window* w)
{
    utf8 destPath[MAX_PATH];

    platform_get_user_directory(destPath, "track", sizeof(destPath));
    if (!platform_ensure_directory_exists(destPath))
    {
        log_error("Unable to create directory '%s'", destPath);
        context_show_error(STR_CANT_SAVE_TRACK_DESIGN, STR_NONE);
        return;
    }

    safe_strcat_path(destPath, _trackName.c_str(), sizeof(destPath));
    path_append_extension(destPath, ".td6", sizeof(destPath));

    if (platform_file_exists(destPath))
    {
        log_info("%s already exists, prompting user for a different track design name", destPath);
        context_show_error(STR_UNABLE_TO_INSTALL_THIS_TRACK_DESIGN, STR_NONE);
        window_text_input_raw_open(
            w, WIDX_INSTALL, STR_SELECT_NEW_NAME_FOR_TRACK_DESIGN, STR_AN_EXISTING_TRACK_DESIGN_ALREADY_HAS_THIS_NAME,
            _trackName.c_str(), 255);
    }
    else
    {
        if (track_repository_install(_trackPath.c_str()))
        {
            window_close(w);
        }
        else
        {
            context_show_error(STR_CANT_SAVE_TRACK_DESIGN, STR_NONE);
        }
    }
}
Ejemplo n.º 3
0
static int screenshot_get_next_path(char *path, char *extension)
{
	char *screenshotPath = osinterface_get_orct2_homesubfolder("screenshot");
	if (!platform_ensure_directory_exists(screenshotPath)) {
		free(screenshotPath);

		fprintf(stderr, "Unable to save screenshots in OpenRCT2 screenshot directory.\n");
		return -1;
	}

	int i;
	for (i = 1; i < 1000; i++) {
		RCT2_GLOBAL(0x013CE952, uint16) = i;

		// Glue together path and filename
		sprintf(path, "%s%cSCR%d%s", screenshotPath, osinterface_get_path_separator(), i, extension);

		if (!platform_file_exists(path)) {
			return i;
		}
	}

	free(screenshotPath);
	return -1;
}
Ejemplo n.º 4
0
void title_sequence_create_preset(const char *name)
{
	if (filename_valid_characters(name) && !title_sequence_name_exists(name)) {
		int preset = gConfigTitleSequences.num_presets;
		gConfigTitleSequences.num_presets++;
		gConfigTitleSequences.presets = realloc(gConfigTitleSequences.presets, sizeof(title_sequence) * (size_t)gConfigTitleSequences.num_presets);
		safe_strncpy(gConfigTitleSequences.presets[preset].name, name, TITLE_SEQUENCE_NAME_SIZE);
		gConfigTitleSequences.presets[preset].path[0] = 0;

		gConfigTitleSequences.presets[preset].saves = malloc(0);
		gConfigTitleSequences.presets[preset].commands = malloc(0);
		gConfigTitleSequences.presets[preset].num_saves = 0;
		gConfigTitleSequences.presets[preset].num_commands = 0;

		// Create the folder
		utf8 path[MAX_PATH];
		platform_get_user_directory(path, "title sequences");
		strcat(path, gConfigTitleSequences.presets[preset].name);
		platform_file_delete(path);
		platform_ensure_directory_exists(path);

		title_sequence_save_preset_script(preset);
		gCurrentTitleSequence = preset;
	}
}
Ejemplo n.º 5
0
    IPlatformEnvironment * SetupEnvironment()
    {
        utf8 userPath[MAX_PATH];
        platform_resolve_openrct_data_path();
        platform_resolve_user_data_path();
        platform_get_user_directory(userPath, NULL, sizeof(userPath));
        if (!platform_ensure_directory_exists(userPath))
        {
            Console::Error::WriteLine("Could not create user directory (do you have write access to your documents folder?)");
            return nullptr;
        }
        openrct2_set_exe_path();

        config_set_defaults();
        if (!config_open_default())
        {
            if (!config_find_or_browse_install_directory())
            {
                gConfigGeneral.last_run_version = String::Duplicate(OPENRCT2_VERSION);
                config_save_default();
                utf8 path[MAX_PATH];
                config_get_default_path(path, sizeof(path));
                Console::Error::WriteLine("An RCT2 install directory must be specified! Please edit \"game_path\" in %s.", path);
                return nullptr;
            }
            config_save_default();
        }

        if (!rct2_init_directories())
        {
            return nullptr;
        }
        if (!rct2_startup_checks())
        {
            return nullptr;
        }

        utf8 path[260];
        std::string basePaths[4];
        basePaths[(size_t)DIRBASE::RCT1] = String::ToStd(gConfigGeneral.rct1_path);
        basePaths[(size_t)DIRBASE::RCT2] = String::ToStd(gConfigGeneral.rct2_path);
        platform_get_openrct_data_path(path, sizeof(path));
        basePaths[(size_t)DIRBASE::OPENRCT2] = std::string(path);
        platform_get_user_directory(path, nullptr, sizeof(path));
        basePaths[(size_t)DIRBASE::USER] = std::string(path);

        IPlatformEnvironment * env = CreatePlatformEnvironment(basePaths);
        return env;
    }
Ejemplo n.º 6
0
/**
 * Default directory fallback is:
 *   - (command line argument)
 *   - <platform dependent>
 */
void platform_resolve_user_data_path()
{

    if (gCustomUserDataPath[0] != 0) {
        if (!platform_ensure_directory_exists(gCustomUserDataPath)) {
            log_error("Failed to create directory \"%s\", make sure you have permissions.", gCustomUserDataPath);
            return;
        }
        char *path;
        if ((path = realpath(gCustomUserDataPath, NULL)) == NULL) {
            log_error("Could not resolve path \"%s\"", gCustomUserDataPath);
            return;
        }

        safe_strcpy(_userDataDirectoryPath, path, MAX_PATH);
        free(path);

        // Ensure path ends with separator
        path_end_with_separator(_userDataDirectoryPath, MAX_PATH);
        log_verbose("User data path resolved to: %s", _userDataDirectoryPath);
        if (!platform_directory_exists(_userDataDirectoryPath)) {
            log_error("Custom user data directory %s does not exist", _userDataDirectoryPath);
        }
        return;
    }

    char buffer[MAX_PATH];
    log_verbose("buffer = '%s'", buffer);

    const char *homedir = getpwuid(getuid())->pw_dir;
    platform_posix_sub_user_data_path(buffer, MAX_PATH, homedir);

    log_verbose("OpenRCT2 user data directory = '%s'", buffer);
    sint32 len = strnlen(buffer, MAX_PATH);
    wchar_t *w_buffer = regular_to_wchar(buffer);
    w_buffer[len] = '\0';
    utf8 *path = widechar_to_utf8(w_buffer);
    free(w_buffer);
    safe_strcpy(_userDataDirectoryPath, path, MAX_PATH);
    free(path);
    log_verbose("User data path resolved to: %s", _userDataDirectoryPath);
}
Ejemplo n.º 7
0
int cmdline_for_sprite(const char **argv, int argc)
{
	if (argc == 0)
		return -1;

	if (_strcmpi(argv[0], "details") == 0) {
		if (argc < 2) {
			fprintf(stderr, "usage: sprite details <spritefile> [idx]\n");
			return -1;
		} else if (argc == 2) {
			const char *spriteFilePath = argv[1];

			if (!sprite_file_open(spriteFilePath)) {
				fprintf(stderr, "Unable to open input sprite file.\n");
				return -1;
			}

			printf("sprites: %d\n", spriteFileHeader.num_entries);
			printf("data size: %d\n", spriteFileHeader.total_size);

			sprite_file_close();
			return 1;
		} else {
			const char *spriteFilePath = argv[1];
			int spriteIndex = atoi(argv[2]);

			if (!sprite_file_open(spriteFilePath)) {
				fprintf(stderr, "Unable to open input sprite file.\n");
				return -1;
			}

			if (spriteIndex < 0 || spriteIndex >= (int)spriteFileHeader.num_entries) {
				sprite_file_close();
				fprintf(stderr, "Sprite #%d does not exist in sprite file.\n", spriteIndex);
				return -1;
			}

			rct_g1_element *g1 = &spriteFileEntries[spriteIndex];
			printf("width: %d\n", g1->width);
			printf("height: %d\n", g1->height);
			printf("x offset: %d\n", g1->x_offset);
			printf("y offset: %d\n", g1->y_offset);
			printf("data offset: 0x%X\n", g1->offset);

			sprite_file_close();
			return 1;
		}
	} else if (_strcmpi(argv[0], "export") == 0) {
		if (argc < 4) {
			fprintf(stderr, "usage: sprite export <spritefile> <idx> <output>\n");
			return -1;
		}

		const char *spriteFilePath = argv[1];
		int spriteIndex = atoi(argv[2]);
		const char *outputPath = argv[3];

		if (!sprite_file_open(spriteFilePath)) {
			fprintf(stderr, "Unable to open input sprite file.\n");
			return -1;
		}

		if (spriteIndex < 0 || spriteIndex >= (int)spriteFileHeader.num_entries) {
			fprintf(stderr, "Sprite #%d does not exist in sprite file.\n", spriteIndex);
			return -1;
		}

		if (!sprite_file_export(spriteIndex, outputPath)) {
			fprintf(stderr, "Could not export\n");
			sprite_file_close();
			return -1;
		}

		sprite_file_close();
		return 1;
	} else if (_strcmpi(argv[0], "exportall") == 0) {
		if (argc < 3) {
			fprintf(stderr, "usage: sprite exportall <spritefile> <output directory>\n");
			return -1;
		}

		const char *spriteFilePath = argv[1];
		char outputPath[_MAX_PATH];

		if (!sprite_file_open(spriteFilePath)) {
			fprintf(stderr, "Unable to open input sprite file.\n");
			return -1;
		}

		if (!platform_ensure_directory_exists(argv[2])){
			fprintf(stderr, "Unable to create directory.\n");
			return -1;
		}


		int maxIndex = (int)spriteFileHeader.num_entries;
		int numbers = (int)floor(log(maxIndex));
		
		strncpy(outputPath, argv[2], _MAX_PATH);
		int pathLen = strlen(outputPath);

		if (pathLen >= _MAX_PATH - numbers - 5){
			fprintf(stderr, "Path too long.\n");
			return -1;
		}

		for (int x = 0; x < numbers; x++){
			outputPath[pathLen + x] = '0';
		}
		strncpy(outputPath + pathLen + numbers, ".png", _MAX_PATH);

		for (int spriteIndex = 0; spriteIndex < maxIndex; spriteIndex++){

			if (spriteIndex % 100 == 99){
				// Status indicator
				printf("\r%d / %d, %d%%", spriteIndex, maxIndex, spriteIndex / maxIndex);
			}

			// Add to the index at the end of the file name
			char *counter = outputPath + pathLen + numbers - 1;
			(*counter)++;
			while (*counter > '9'){
				*counter = '0';
				counter--;
				(*counter)++;
			}

			if (!sprite_file_export(spriteIndex, outputPath)) {
				fprintf(stderr, "Could not export\n");
				sprite_file_close();
				return -1;
			}
		}

		sprite_file_close();
		return 1;

	} else if (_strcmpi(argv[0], "create") == 0) {
		if (argc < 2) {
			fprintf(stderr, "usage: sprite create <spritefile>\n");
			return -1;
		}

		const char *spriteFilePath = argv[1];

		spriteFileHeader.num_entries = 0;
		spriteFileHeader.total_size = 0;
		sprite_file_save(spriteFilePath);

		sprite_file_close();
		return 1;
	} else if (_strcmpi(argv[0], "append") == 0) {
		if (argc < 3) {
			fprintf(stderr, "usage: sprite append <spritefile> <input>\n");
			return -1;
		}

		const char *spriteFilePath = argv[1];
		const char *imagePath = argv[2];

		rct_g1_element spriteElement;
		uint8 *buffer;
		int bufferLength;
		if (!sprite_file_import(imagePath, &spriteElement, &buffer, &bufferLength, sprite_mode))
			return -1;

		if (!sprite_file_open(spriteFilePath)) {
			fprintf(stderr, "Unable to open input sprite file.\n");
			return -1;
		}
		
		spriteFileHeader.num_entries++;
		spriteFileHeader.total_size += bufferLength;
		spriteFileEntries = realloc(spriteFileEntries, spriteFileHeader.num_entries * sizeof(rct_g1_element));

		sprite_entries_make_relative();
		spriteFileData = realloc(spriteFileData, spriteFileHeader.total_size);
		sprite_entries_make_absolute();

		spriteFileEntries[spriteFileHeader.num_entries - 1] = spriteElement;
		memcpy(spriteFileData + (spriteFileHeader.total_size - bufferLength), buffer, bufferLength);
		spriteFileEntries[spriteFileHeader.num_entries - 1].offset = spriteFileData + (spriteFileHeader.total_size - bufferLength);
		
		free(buffer);
		if (!sprite_file_save(spriteFilePath))
			return -1;

		return 1;
	} else if (_strcmpi(argv[0], "build") == 0) {
		if (argc < 3) {
			fprintf(stderr, "usage: sprite build <spritefile> <resourcedir> [silent]\n");
			return -1;
		}

		const char *spriteFilePath = argv[1];
		const char *resourcePath = argv[2];
		char imagePath[MAX_PATH];
		int resourceLength = strlen(resourcePath);

		bool silent = (argc >= 4 && strcmp(argv[3], "silent") == 0);
		bool fileExists = true;
		FILE *file;

		spriteFileHeader.num_entries = 0;
		spriteFileHeader.total_size = 0;
		sprite_file_save(spriteFilePath);

		fprintf(stderr, "Building: %s\n", spriteFilePath);
		int i = 0;
		do {
			// Create image path
			strcpy(imagePath, resourcePath);
			if (resourcePath[resourceLength - 1] == '/' || resourcePath[resourceLength - 1] == '\\')
				imagePath[resourceLength - 1] = 0;
			sprintf(imagePath, "%s%c%d.png", imagePath, platform_get_path_separator(), i);

			file = fopen(imagePath, "r");
			if (file != NULL) {
				fclose(file);
				rct_g1_element spriteElement;
				uint8 *buffer;
				int bufferLength;
				if (!sprite_file_import(imagePath, &spriteElement, &buffer, &bufferLength, sprite_mode)) {
					fprintf(stderr, "Could not import image file: %s\nCanceling\n", imagePath);
					return -1;
				}

				if (!sprite_file_open(spriteFilePath)) {
					fprintf(stderr, "Unable to open sprite file: %s\nCanceling\n", spriteFilePath);
					return -1;
				}

				spriteFileHeader.num_entries++;
				spriteFileHeader.total_size += bufferLength;
				spriteFileEntries = realloc(spriteFileEntries, spriteFileHeader.num_entries * sizeof(rct_g1_element));

				sprite_entries_make_relative();
				spriteFileData = realloc(spriteFileData, spriteFileHeader.total_size);
				sprite_entries_make_absolute();

				spriteFileEntries[spriteFileHeader.num_entries - 1] = spriteElement;
				memcpy(spriteFileData + (spriteFileHeader.total_size - bufferLength), buffer, bufferLength);
				spriteFileEntries[spriteFileHeader.num_entries - 1].offset = spriteFileData + (spriteFileHeader.total_size - bufferLength);

				free(buffer);

				if (!sprite_file_save(spriteFilePath)) {
					fprintf(stderr, "Could not save sprite file: %s\nCanceling\n", imagePath);
					return -1;
				}
				if (!silent)
					fprintf(stderr, "Added: %s\n", imagePath);
			}
			i++;
		} while (file != NULL);


		fprintf(stderr, "Finished\n", imagePath);
		return 1;
	} else {
		fprintf(stderr, "Unknown sprite command.");
		return 1;
	}
}
Ejemplo n.º 8
0
bool openrct2_initialise()
{
	utf8 userPath[MAX_PATH];

	platform_resolve_user_data_path();
	platform_get_user_directory(userPath, NULL);
	if (!platform_ensure_directory_exists(userPath)) {
		log_fatal("Could not create user directory (do you have write access to your documents folder?)");
		return false;
	}

	if (!openrct2_setup_rct2_segment()) {
		log_fatal("Unable to load RCT2 data sector");
		return false;
	}

	openrct2_set_exe_path();

	config_set_defaults();
	if (!config_open_default()) {
		if (!config_find_or_browse_install_directory()) {
			log_fatal("An RCT2 install directory must be specified!");
			return false;
		}
	}

	gOpenRCT2ShowChangelog = true;
	if (gConfigGeneral.last_run_version != NULL && (strcmp(gConfigGeneral.last_run_version, OPENRCT2_VERSION) == 0))
		gOpenRCT2ShowChangelog = false;
	gConfigGeneral.last_run_version = OPENRCT2_VERSION;
	config_save_default();

	// TODO add configuration option to allow multiple instances
	// if (!gOpenRCT2Headless && !platform_lock_single_instance()) {
	// 	log_fatal("OpenRCT2 is already running.");
	// 	return false;
	// }

	get_system_info();
	if (!gOpenRCT2Headless) {
		audio_init();
		audio_get_devices();
	}
	if (!language_open(gConfigGeneral.language))
	{
		log_fatal("Failed to open language, exiting.");
		return false;
	}
	http_init();

	themes_set_default();
	themes_load_presets();
	title_sequences_set_default();
	title_sequences_load_presets();

	openrct2_setup_rct2_hooks();

	if (!rct2_init())
		return false;

	chat_init();

	openrct2_copy_original_user_files_over();

	// TODO move to audio initialise function
	if (str_is_null_or_empty(gConfigSound.device)) {
		Mixer_Init(NULL);
		RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = 0;
	} else {
		Mixer_Init(gConfigSound.device);
		for (int i = 0; i < gAudioDeviceCount; i++) {
			if (strcmp(gAudioDevices[i].name, gConfigSound.device) == 0) {
				RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = i;
			}
		}
	}

	return true;
}
Ejemplo n.º 9
0
 bool EnsureThemeDirectoryExists()
 {
     utf8 path[MAX_PATH];
     GetThemePath(path, sizeof(path));
     return platform_ensure_directory_exists(path);
 }
Ejemplo n.º 10
0
rct_window *window_loadsave_open(int type, char *defaultName)
{
	gLoadSaveCallback = NULL;
	gLoadSaveTitleSequenceSave = false;
	char path[MAX_PATH], *ch;
	int includeNewItem;
	rct_window* w;
	_type = type;
	_defaultName[0] = '\0';

	if (!str_is_null_or_empty(defaultName)) {
		safe_strcpy(_defaultName, defaultName, sizeof(_defaultName));
	}

	w = window_bring_to_front_by_class(WC_LOADSAVE);
	if (w == NULL) {
		w = window_create_centred(WW, WH, &window_loadsave_events, WC_LOADSAVE, WF_STICK_TO_FRONT);
		w->widgets = window_loadsave_widgets;
		w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_UP) | (1 << WIDX_NEW) | (1 << WIDX_SORT_NAME) | (1 << WIDX_SORT_DATE) | (1 << WIDX_BROWSE);
		w->colours[0] = 7;
		w->colours[1] = 7;
		w->colours[2] = 7;
	}

	_loadsaveType = type;
	switch (type & 0x0F) {
	case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME):
		w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_LOAD_GAME;
		break;
	case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) :
		w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_SAVE_GAME;
		break;
	case (LOADSAVETYPE_LOAD | LOADSAVETYPE_LANDSCAPE) :
		w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_LOAD_LANDSCAPE;
		break;
	case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) :
		w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_SAVE_LANDSCAPE;
		break;
	case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) :
		w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_SAVE_SCENARIO;
		break;
	case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
		w->widgets[WIDX_TITLE].image = STR_FILE_DIALOG_TITLE_INSTALL_NEW_TRACK_DESIGN;
		break;
	default:
		log_error("Unsupported load / save type: %d", type & 0x0F);
		return NULL;
	}

	w->no_list_items = 0;
	w->selected_list_item = -1;

	includeNewItem = (type & 0x01) == LOADSAVETYPE_SAVE;
	switch (type & 0x0E) {
	case LOADSAVETYPE_GAME:
		platform_get_user_directory(path, "save");
		if (!platform_ensure_directory_exists(path)) {
			log_error("Unable to create save directory.");
			window_close(w);
			return NULL;
		}

		window_loadsave_populate_list(w, includeNewItem, path, ".sv6");
		break;
	case LOADSAVETYPE_LANDSCAPE:
		platform_get_user_directory(path, "landscape");
		if (!platform_ensure_directory_exists(path)) {
			log_error("Unable to create landscapes directory.");
			window_close(w);
			return NULL;
		}

		window_loadsave_populate_list(w, includeNewItem, path, ".sc6");
		break;
	case LOADSAVETYPE_SCENARIO:
		platform_get_user_directory(path, "scenario");
		if (!platform_ensure_directory_exists(path)) {
			log_error("Unable to create scenarios directory.");
			window_close(w);
			return NULL;
		}

		window_loadsave_populate_list(w, includeNewItem, path, ".sc6");
		break;
	case LOADSAVETYPE_TRACK:
		/*
		Uncomment when user tracks are separated

		platform_get_user_directory(path, "tracks");
		if (!platform_ensure_directory_exists(path)) {
		log_error("Unable to create tracks directory.");
		window_close(w);
		return NULL;
		}
		*/

		safe_strcpy(path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), MAX_PATH);
		ch = strchr(path, '*');
		if (ch != NULL)
			*ch = 0;

		window_loadsave_populate_list(w, includeNewItem, path, ".td?");
		break;
	}
	w->no_list_items = _listItemsCount;
	window_init_scroll_widgets(w);
	return w;
}
Ejemplo n.º 11
0
sint32 cmdline_for_sprite(const char **argv, sint32 argc)
{
    gOpenRCT2Headless = true;
    if (argc == 0)
        return -1;

    if (_strcmpi(argv[0], "details") == 0) {
        if (argc < 2) {
            fprintf(stdout, "usage: sprite details <spritefile> [idx]\n");
            return -1;
        } else if (argc == 2) {
            const char *spriteFilePath = argv[1];

            if (!sprite_file_open(spriteFilePath)) {
                fprintf(stderr, "Unable to open input sprite file.\n");
                return -1;
            }

            printf("sprites: %u\n", spriteFileHeader.num_entries);
            printf("data size: %u\n", spriteFileHeader.total_size);

            sprite_file_close();
            return 1;
        } else {
            const char *spriteFilePath = argv[1];
            sint32 spriteIndex = atoi(argv[2]);

            if (!sprite_file_open(spriteFilePath)) {
                fprintf(stderr, "Unable to open input sprite file.\n");
                return -1;
            }

            if (spriteIndex < 0 || spriteIndex >= (sint32)spriteFileHeader.num_entries) {
                sprite_file_close();
                fprintf(stderr, "Sprite #%d does not exist in sprite file.\n", spriteIndex);
                return -1;
            }

            rct_g1_element *g1 = &spriteFileEntries[spriteIndex];
            printf("width: %d\n", g1->width);
            printf("height: %d\n", g1->height);
            printf("x offset: %d\n", g1->x_offset);
            printf("y offset: %d\n", g1->y_offset);
            printf("data offset: %p\n", g1->offset);

            sprite_file_close();
            return 1;
        }
    } else if (_strcmpi(argv[0], "export") == 0) {
        if (argc < 4) {
            fprintf(stdout, "usage: sprite export <spritefile> <idx> <output>\n");
            return -1;
        }

        const char *spriteFilePath = argv[1];
        sint32 spriteIndex = atoi(argv[2]);
        const char *outputPath = argv[3];

        if (!sprite_file_open(spriteFilePath)) {
            fprintf(stderr, "Unable to open input sprite file.\n");
            return -1;
        }

        if (spriteIndex < 0 || spriteIndex >= (sint32)spriteFileHeader.num_entries) {
            fprintf(stderr, "Sprite #%d does not exist in sprite file.\n", spriteIndex);
            return -1;
        }

        if (!sprite_file_export(spriteIndex, outputPath)) {
            fprintf(stderr, "Could not export\n");
            sprite_file_close();
            return -1;
        }

        sprite_file_close();
        return 1;
    } else if (_strcmpi(argv[0], "exportall") == 0) {
        if (argc < 3) {
            fprintf(stdout, "usage: sprite exportall <spritefile> <output directory>\n");
            return -1;
        }

        const char *spriteFilePath = argv[1];
        char outputPath[MAX_PATH];

        if (!sprite_file_open(spriteFilePath)) {
            fprintf(stderr, "Unable to open input sprite file.\n");
            return -1;
        }

        safe_strcpy(outputPath, argv[2], MAX_PATH);
        path_end_with_separator(outputPath, MAX_PATH);

        if (!platform_ensure_directory_exists(outputPath)){
            fprintf(stderr, "Unable to create directory.\n");
            return -1;
        }

        sint32 maxIndex = (sint32)spriteFileHeader.num_entries;
        sint32 numbers = (sint32)floor(log(maxIndex));
        size_t pathLen = strlen(outputPath);

        if (pathLen >= (size_t)(MAX_PATH - numbers - 5)) {
            fprintf(stderr, "Path too long.\n");
            return -1;
        }

        for (sint32 x = 0; x < numbers; x++){
            outputPath[pathLen + x] = '0';
        }
        safe_strcpy(outputPath + pathLen + numbers, ".png", MAX_PATH - pathLen - numbers);

        for (sint32 spriteIndex = 0; spriteIndex < maxIndex; spriteIndex++){

            if (spriteIndex % 100 == 99){
                // Status indicator
                printf("\r%d / %d, %d%%", spriteIndex, maxIndex, spriteIndex / maxIndex);
            }

            // Add to the index at the end of the file name
            char *counter = outputPath + pathLen + numbers - 1;
            (*counter)++;
            while (*counter > '9'){
                *counter = '0';
                counter--;
                (*counter)++;
            }

            if (!sprite_file_export(spriteIndex, outputPath)) {
                fprintf(stderr, "Could not export\n");
                sprite_file_close();
                return -1;
            }
        }

        sprite_file_close();
        return 1;

    } else if (_strcmpi(argv[0], "create") == 0) {
        if (argc < 2) {
            fprintf(stderr, "usage: sprite create <spritefile>\n");
            return -1;
        }

        const char *spriteFilePath = argv[1];

        spriteFileHeader.num_entries = 0;
        spriteFileHeader.total_size = 0;
        sprite_file_save(spriteFilePath);

        sprite_file_close();
        return 1;
    } else if (_strcmpi(argv[0], "append") == 0) {
        if (argc != 3 && argc != 5) {
            fprintf(stderr, "usage: sprite append <spritefile> <input> [<x offset> <y offset>]\n");
            return -1;
        }


        const char *spriteFilePath = argv[1];
        const char *imagePath = argv[2];
        sint16 x_offset = 0;
        sint16 y_offset = 0;

        if (argc == 5)
        {
            char *endptr;

            x_offset = strtol(argv[3], &endptr, 0);
            if (*endptr != 0)
            {
                fprintf(stderr, "X offset must be an integer\n");
                return -1;
            }

            y_offset = strtol(argv[4], &endptr, 0);
            if (*endptr != 0)
            {
                fprintf(stderr, "Y offset must be an integer\n");
                return -1;
            }
        }

        rct_g1_element spriteElement;
        uint8 *buffer;

        sint32 bufferLength;
        if (!sprite_file_import(imagePath, x_offset, y_offset, &spriteElement, &buffer, &bufferLength, gSpriteMode))

            return -1;

        if (!sprite_file_open(spriteFilePath)) {
            fprintf(stderr, "Unable to open input sprite file.\n");
            return -1;
        }

        spriteFileHeader.num_entries++;
        spriteFileHeader.total_size += bufferLength;
        spriteFileEntries = realloc(spriteFileEntries, spriteFileHeader.num_entries * sizeof(rct_g1_element));

        sprite_entries_make_relative();
        spriteFileData = realloc(spriteFileData, spriteFileHeader.total_size);
        sprite_entries_make_absolute();

        spriteFileEntries[spriteFileHeader.num_entries - 1] = spriteElement;
        memcpy(spriteFileData + (spriteFileHeader.total_size - bufferLength), buffer, bufferLength);
        spriteFileEntries[spriteFileHeader.num_entries - 1].offset = spriteFileData + (spriteFileHeader.total_size - bufferLength);

        free(buffer);
        if (!sprite_file_save(spriteFilePath))
            return -1;

        return 1;
    } else if (_strcmpi(argv[0], "build") == 0) {
        if (argc < 3) {
            fprintf(stdout, "usage: sprite build <spritefile> <sprite description file> [silent]\n");
            return -1;
        }

        const char *spriteFilePath = argv[1];
        const char *spriteDescriptionPath = argv[2];
        char* directoryPath = path_get_directory(spriteDescriptionPath);

        json_error_t error;
        json_t* sprite_list=json_load_file(spriteDescriptionPath, JSON_REJECT_DUPLICATES, &error);

        if (sprite_list == NULL)
        {
            fprintf(stderr, "Error parsing sprite description file: %s at line %d column %d\n", error.text, error.line, error.column);
            return -1;
        }

        if (!json_is_array(sprite_list))
        {
            fprintf(stderr, "Error: expected array\n");
            json_decref(sprite_list);
            return -1;
        }

        bool silent = (argc >= 4 && strcmp(argv[3], "silent") == 0);

        spriteFileHeader.num_entries = 0;
        spriteFileHeader.total_size = 0;
        sprite_file_save(spriteFilePath);

        fprintf(stdout, "Building: %s\n", spriteFilePath);

        size_t i;
        json_t* sprite_description;

        json_array_foreach(sprite_list, i, sprite_description)
        {
            if(!json_is_object(sprite_description))
            {
                fprintf(stderr, "Error: expected object for sprite %lu\n", (unsigned long)i);
                json_decref(sprite_list);
                return -1;
            }

            json_t* path = json_object_get(sprite_description,"path");
            if(!path || !json_is_string(path))
            {
                fprintf(stderr, "Error: no path provided for sprite %lu\n", (unsigned long)i);
                json_decref(sprite_list);
                return -1;
            }
            // Get x and y offsets, if present
            json_t* x_offset = json_object_get(sprite_description, "x_offset");
            json_t* y_offset = json_object_get(sprite_description, "y_offset");


            // Resolve absolute sprite path
            char *imagePath = platform_get_absolute_path(json_string_value(path), directoryPath);

            rct_g1_element spriteElement;
            uint8 *buffer;
            int bufferLength;

            if (!sprite_file_import(imagePath, x_offset==NULL ? 0 : json_integer_value(x_offset), y_offset==NULL ? 0 : json_integer_value(y_offset), &spriteElement, &buffer, &bufferLength, gSpriteMode))
            {
                fprintf(stderr, "Could not import image file: %s\nCanceling\n", imagePath);
                json_decref(sprite_list);
                free(imagePath);
                return -1;
            }

            if (!sprite_file_open(spriteFilePath))
            {
                fprintf(stderr, "Unable to open sprite file: %s\nCanceling\n", spriteFilePath);
                json_decref(sprite_list);
                free(imagePath);
                return -1;
            }

            spriteFileHeader.num_entries++;
            spriteFileHeader.total_size += bufferLength;
            spriteFileEntries = realloc(spriteFileEntries, spriteFileHeader.num_entries * sizeof(rct_g1_element));

            sprite_entries_make_relative();
            spriteFileData = realloc(spriteFileData, spriteFileHeader.total_size);
            sprite_entries_make_absolute();

            spriteFileEntries[spriteFileHeader.num_entries - 1] = spriteElement;
            memcpy(spriteFileData + (spriteFileHeader.total_size - bufferLength), buffer, bufferLength);
            spriteFileEntries[spriteFileHeader.num_entries - 1].offset = spriteFileData + (spriteFileHeader.total_size - bufferLength);

            free(buffer);

            if (!sprite_file_save(spriteFilePath))
            {
                fprintf(stderr, "Could not save sprite file: %s\nCanceling\n", imagePath);
                json_decref(sprite_list);
                free(imagePath);
                return -1;
            }

            if (!silent)
                fprintf(stdout, "Added: %s\n", imagePath);

            free(imagePath);
            sprite_file_close();

        }

        json_decref(sprite_list);
        free(directoryPath);

        fprintf(stdout, "Finished\n");
        return 1;
    } else {
Ejemplo n.º 12
0
static exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator * enumerator)
{
    exitcode_t result = CommandLine::HandleCommandDefault();
    if (result != EXITCODE_CONTINUE)
    {
        return result;
    }

    // Get the path that was passed
    const utf8 * rawPath;
    if (!enumerator->TryPopString(&rawPath))
    {
        Console::Error::WriteLine("Expected a path.");
        return EXITCODE_FAIL;
    }

    utf8 path[MAX_PATH];
    Path::GetAbsolute(path, sizeof(path), rawPath);

    // Check if path exists
    Console::WriteLine("Checking path...");
    if (!platform_directory_exists(path))
    {
        Console::Error::WriteLine("The path '%s' does not exist", path);
        return EXITCODE_FAIL;
    }

    // Check if g1.dat exists (naive but good check)
    Console::WriteLine("Checking g1.dat...");

    utf8 pathG1Check[MAX_PATH];
    String::Set(pathG1Check, sizeof(pathG1Check), path);
    Path::Append(pathG1Check, sizeof(pathG1Check), "Data");
    Path::Append(pathG1Check, sizeof(pathG1Check), "g1.dat");
    if (!platform_file_exists(pathG1Check))
    {
        Console::Error::WriteLine("RCT2 path not valid.");
        Console::Error::WriteLine("Unable to find %s.", pathG1Check);
        return EXITCODE_FAIL;
    }

    // Check user path that will contain the config
    utf8 userPath[MAX_PATH];
    platform_resolve_user_data_path();
    platform_get_user_directory(userPath, NULL, sizeof(userPath));
    if (!platform_ensure_directory_exists(userPath)) {
        Console::Error::WriteLine("Unable to access or create directory '%s'.", userPath);
        return EXITCODE_FAIL;
    }

    // Update RCT2 path in config
    config_set_defaults();
    config_open_default();
    String::DiscardDuplicate(&gConfigGeneral.rct2_path, path);
    if (config_save_default())
    {
        Console::WriteFormat("Updating RCT2 path to '%s'.", path);
        Console::WriteLine();
        Console::WriteLine("Updated config.ini");
        return EXITCODE_OK;
    }
    else
    {
        Console::Error::WriteLine("Unable to update config.ini");
        return EXITCODE_FAIL;
    }
}
Ejemplo n.º 13
0
void title_sequence_duplicate_preset(int duplicate, const char *name)
{
	if (duplicate >= 0 && duplicate < gConfigTitleSequences.num_presets && filename_valid_characters(name) && !title_sequence_name_exists(name)) {
		int preset = gConfigTitleSequences.num_presets;
		gConfigTitleSequences.num_presets++;
		gConfigTitleSequences.presets = realloc(gConfigTitleSequences.presets, sizeof(title_sequence) * (size_t)gConfigTitleSequences.num_presets);
		safe_strncpy(gConfigTitleSequences.presets[preset].name, name, TITLE_SEQUENCE_NAME_SIZE);
		gConfigTitleSequences.presets[preset].path[0] = 0;

		size_t savesSize = sizeof(char[TITLE_SEQUENCE_MAX_SAVE_LENGTH]) * gConfigTitleSequences.presets[duplicate].num_saves;
		size_t commandsSize = sizeof(title_command) * gConfigTitleSequences.presets[duplicate].num_commands;
		gConfigTitleSequences.presets[preset].saves = malloc(savesSize);
		gConfigTitleSequences.presets[preset].commands = malloc(commandsSize);
		memcpy(gConfigTitleSequences.presets[preset].saves, gConfigTitleSequences.presets[duplicate].saves, savesSize);
		memcpy(gConfigTitleSequences.presets[preset].commands, gConfigTitleSequences.presets[duplicate].commands, commandsSize);
		gConfigTitleSequences.presets[preset].num_saves = gConfigTitleSequences.presets[duplicate].num_saves;
		gConfigTitleSequences.presets[preset].num_commands = gConfigTitleSequences.presets[duplicate].num_commands;

		bool loadmm = false;
		for (int i = 0; i < gConfigTitleSequences.presets[preset].num_commands; i++) {
			if (gConfigTitleSequences.presets[preset].commands[i].command == TITLE_SCRIPT_LOADMM) {
				loadmm = true;
				gConfigTitleSequences.presets[preset].commands[i].command = TITLE_SCRIPT_LOAD;
				gConfigTitleSequences.presets[preset].commands[i].saveIndex = gConfigTitleSequences.presets[duplicate].num_saves;
			}
		}

		// Create the folder
		utf8 path[MAX_PATH], srcPath[MAX_PATH];
		platform_get_user_directory(path, "title sequences");
		strcat(path, gConfigTitleSequences.presets[preset].name);
		platform_file_delete(path);
		platform_ensure_directory_exists(path);

		// Copy the saves
		char separator = platform_get_path_separator();
		for (int i = 0; i < gConfigTitleSequences.presets[preset].num_saves; i++) {
			if (gConfigTitleSequences.presets[duplicate].path[0]) {
				safe_strncpy(srcPath, gConfigTitleSequences.presets[duplicate].path, MAX_PATH);
				strcat(srcPath, gConfigTitleSequences.presets[duplicate].saves[i]);
			}
			else {
				platform_get_user_directory(srcPath, "title sequences");
				strcat(srcPath, gConfigTitleSequences.presets[duplicate].name);
				strncat(srcPath, &separator, 1);
				strcat(srcPath, gConfigTitleSequences.presets[duplicate].saves[i]);
			}
			platform_get_user_directory(path, "title sequences");
			strcat(path, gConfigTitleSequences.presets[preset].name);
			strncat(path, &separator, 1);
			strcat(path, gConfigTitleSequences.presets[preset].saves[i]);

			platform_file_copy(srcPath, path, false);
		}

		if (loadmm) {
			title_sequence_add_save(preset, get_file_path(PATH_ID_SIXFLAGS_MAGICMOUNTAIN), "Six Flags Magic Mountain.SC6");
		}

		title_sequence_save_preset_script(preset);
		gCurrentTitleSequence = preset;
	}
}