示例#1
0
文件: audio.c 项目: Rodbourn/OpenRCT2
void audio_populate_devices()
{
    if (gAudioDevices != NULL)
        free(gAudioDevices);

    gAudioDeviceCount = SDL_GetNumAudioDevices(SDL_FALSE);
    if (gAudioDeviceCount <= 0)
        return;

    audio_device *systemAudioDevices = malloc(gAudioDeviceCount * sizeof(audio_device));
    for (int i = 0; i < gAudioDeviceCount; i++) {
        const char *utf8Name = SDL_GetAudioDeviceName(i, SDL_FALSE);
        if (utf8Name == NULL)
            utf8Name = language_get_string(5511);

        safe_strcpy(systemAudioDevices[i].name, utf8Name, AUDIO_DEVICE_NAME_SIZE);
    }
#ifndef __LINUX__
    gAudioDeviceCount++;
    gAudioDevices = malloc(gAudioDeviceCount * sizeof(audio_device));
    safe_strcpy(gAudioDevices[0].name, language_get_string(5510), AUDIO_DEVICE_NAME_SIZE);
    memcpy(&gAudioDevices[1], systemAudioDevices, (gAudioDeviceCount - 1) * sizeof(audio_device));
#else
    gAudioDevices = malloc(gAudioDeviceCount * sizeof(audio_device));
    memcpy(gAudioDevices, systemAudioDevices, gAudioDeviceCount * sizeof(audio_device));
#endif // __LINUX__

    free(systemAudioDevices);
}
示例#2
0
/**
 * Loads only the basic information from a scenario.
 *  rct2: 0x006761D6
 */
int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *info)
{
	SDL_RWops* rw;

	log_verbose("loading scenario details, %s", path);

	rw = SDL_RWFromFile(path, "rb");
	if (rw != NULL) {
		// Read first chunk
		sawyercoding_read_chunk(rw, (uint8*)header);
		if (header->type == S6_TYPE_SCENARIO) {
			// Read second chunk
			sawyercoding_read_chunk(rw, (uint8*)info);
			SDL_RWclose(rw);
			RCT2_GLOBAL(0x009AA00C, uint8) = 0;

			// Get filename
			utf8 filename[MAX_PATH];
			const char *temp_filename = path_get_filename(path);
			int len = strnlen(temp_filename, MAX_PATH);
			safe_strncpy(filename, temp_filename, MAX_PATH);
			if (len == MAX_PATH)
			{
				filename[MAX_PATH - 1] = '\0';
				log_warning("truncated string %s", filename);
			}
			path_remove_extension(filename);

			rct_string_id localisedStringIds[3];
			if (language_get_localised_scenario_strings(filename, localisedStringIds)) {
				if (localisedStringIds[0] != (rct_string_id)STR_NONE) {
					safe_strncpy(info->name, language_get_string(localisedStringIds[0]), 64);
				}
				if (localisedStringIds[2] != (rct_string_id)STR_NONE) {
					safe_strncpy(info->details, language_get_string(localisedStringIds[2]), 256);
				}
			} else {
				// Checks for a scenario string object (possibly for localisation)
				if ((info->entry.flags & 0xFF) != 255) {
					if (object_get_scenario_text(&info->entry)) {
						rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*);
						format_string(info->name, stex_entry->scenario_name, NULL);
						format_string(info->details, stex_entry->details, NULL);
						RCT2_GLOBAL(0x009AA00C, uint8) = stex_entry->var_06;
						object_free_scenario_text();
					}
				}
			}
示例#3
0
static void window_loadsave_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex)
{
	int i, y;
	rct_string_id stringId, templateStringId = 3165;
	char *templateString;

	gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width - 1, dpi->y + dpi->height - 1, ColourMapA[w->colours[1]].mid_light);

	templateString = (char*)language_get_string(templateStringId);
	for (i = 0; i < w->no_list_items; i++) {
		y = i * 10;
		if (y > dpi->y + dpi->height)
			break;

		if (y + 10 < dpi->y)
			continue;

		stringId = STR_BLACK_STRING;
		if (i == w->selected_list_item) {
			stringId = STR_WINDOW_COLOUR_2_STRING;
			gfx_fill_rect(dpi, 0, y, 800, y + 9, 0x2000031);
		}

		strcpy(templateString, _listItems[i].name);
		gfx_draw_string_left(dpi, stringId, &templateStringId, 0, 0, y - 1);
	}
}
示例#4
0
/**
 *
 *  rct2: 0x006CF8CD
 */
static void window_track_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex)
{
	rct_string_id stringId, stringId2;
	int i, x, y, colour;
	utf8 *trackDesignItem, *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, utf8);

	colour = ColourMapA[w->colours[0]].mid_light;
	colour = (colour << 24) | (colour << 16) | (colour << 8) | colour;
	gfx_clear(dpi, colour);

	i = 0;
	x = 0;
	y = 0;

	trackDesignItem = trackDesignList;
	if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) {
		if (*trackDesignItem == 0) {
			// No track designs
			gfx_draw_string_left(dpi, STR_NO_TRACK_DESIGNS_OF_THIS_TYPE, NULL, 0, x, y - 1);
			return;
		}
	} else {
		// Build custom track item
		if (i == w->track_list.var_482) {
			// Highlight
			gfx_fill_rect(dpi, x, y, w->width, y + 9, 0x2000000 | 49);
			stringId = 1193;
		} else {
			stringId = 1191;
		}

		stringId2 = STR_BUILD_CUSTOM_DESIGN;
		gfx_draw_string_left(dpi, stringId, &stringId2, 0, x, y - 1);
		y += 10;
		i++;
	}

	while (*trackDesignItem != 0) {
		if (y + 10 >= dpi->y && y < dpi->y + dpi->height) {
			if (i == w->track_list.var_482) {
				// Highlight
				gfx_fill_rect(dpi, x, y, w->width, y + 9, 0x2000000 | 49);
				stringId = 1193;
			} else {
				stringId = 1191;
			}

			// Draw track name
			window_track_list_format_name((char *)language_get_string(3165), trackDesignItem, 0, 1);
			stringId2 = 3165;
			gfx_draw_string_left(dpi, stringId, &stringId2, 0, x, y - 1);
		}
		y += 10;
		i++;
		trackDesignItem += 128;
	}
}
示例#5
0
std::string Object::GetOverrideString(uint8 index) const
{
    const char * identifier = GetIdentifier();
    rct_string_id stringId = language_get_object_override_string_id(identifier, index);

    const utf8 * result = nullptr;
    if (stringId != STR_NONE)
    {
        result = language_get_string(stringId);
    }
    return String::ToStd(result);
}
示例#6
0
void format_comma_separated_integer(char **dest, long long value)
{
	int digit, groupIndex;
	char *dst = *dest;
	char *finish;
	char tmp;
	const char *commaMark = language_get_string(5151);
	const char *ch;

	// Negative sign
	if (value < 0) {
		*dst++ = '-';
		value = -value;
	}

	*dest = dst;

	if (value == 0) {
		*dst++ = '0';
	} else {
		// Groups of three digits, right to left
		groupIndex = 0;
		while (value > 0) {
			// Append group separator
			if (groupIndex == 3) {
				groupIndex = 0;

				ch = commaMark;
				while (*ch != 0) {
					*dst++ = *ch++;
				}
			}

			digit = value % 10;
			value /= 10;

			*dst++ = '0' + digit;
			groupIndex++;
		}
	}
	finish = dst;

	// Reverse string
	dst--;
	while (*dest < dst) {
		tmp = **dest;
		**dest = *dst;
		*dst = tmp;
		(*dest)++;
		dst--;
	}
	*dest = finish;
}
示例#7
0
static void scenario_translate(scenario_index_entry *scenarioEntry, const rct_object_entry *stexObjectEntry)
{
    rct_string_id localisedStringIds[3];
    if (language_get_localised_scenario_strings(scenarioEntry->name, localisedStringIds)) {
        if (localisedStringIds[0] != STR_NONE) {
            safe_strcpy(scenarioEntry->name, language_get_string(localisedStringIds[0]), 64);
        }
        if (localisedStringIds[2] != STR_NONE) {
            safe_strcpy(scenarioEntry->details, language_get_string(localisedStringIds[2]), 256);
        }
    } else {
        // Checks for a scenario string object (possibly for localisation)
        if ((stexObjectEntry->flags & 0xFF) != 255) {
            if (object_get_scenario_text((rct_object_entry*)stexObjectEntry)) {
                rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*);
                format_string(scenarioEntry->name, stex_entry->scenario_name, NULL);
                format_string(scenarioEntry->details, stex_entry->details, NULL);
                object_free_scenario_text();
            }
        }
    }
示例#8
0
static void window_overwrite_prompt_paint(rct_window *w, rct_drawpixelinfo *dpi)
{
	window_draw_widgets(w, dpi);

	rct_string_id templateStringId = 3165;
	char *templateString;

	templateString = (char*)language_get_string(templateStringId);
	strcpy(templateString, _window_overwrite_prompt_name);

	int x = w->x + w->width / 2;
	int y = w->y + (w->height / 2) - 3;
	gfx_draw_string_centred_wrapped(dpi, &templateStringId, x, y, w->width - 4, 2708, 0);
}
示例#9
0
void format_string_part(utf8 **dest, rct_string_id format, char **args)
{
	if (format == STR_NONE) {
		**dest = 0;
	} else if (format < 0x8000) {
		// Language string
		format_string_part_from_raw(dest, language_get_string(format), args);
	} else if (format < 0x9000) {
		// Custom string
		format -= 0x8000;

		// Bits 10, 11 represent number of bytes to pop off arguments
		*args += (format & 0xC00) >> 9;
		format &= ~0xC00;

		strcpy(*dest, RCT2_ADDRESS(0x135A8F4 + (format * 32), char));
		*dest = strchr(*dest, 0) + 1;
	} else if (format < 0xE000) {
示例#10
0
static void window_tile_inspector_scrollpaint()
{
	int x = 15, y = 11 * (window_tile_inspector_item_count - 1), i = 0;
	rct_window *w;
	rct_drawpixelinfo *dpi;
	char buffer[256];

	window_paint_get_registers(w, dpi);

	if (window_tile_inspector_tile_x == -1)
		return;

	rct_map_element *element = map_get_first_element_at(window_tile_inspector_tile_x, window_tile_inspector_tile_y);

	do {

		int type = map_element_get_type(element);
		char *type_name;
		int base_height = element->base_height;
		int clearance_height = element->clearance_height;

		if ((i & 1) != 0)
			gfx_fill_rect(dpi, x - 15, y, x + WW - 20, y + 11, RCT2_GLOBAL(0x0141FC4A + (w->colours[1] * 8), uint8) | 0x1000000);

		switch (type) {
			case MAP_ELEMENT_TYPE_SURFACE:
				sprintf(
					buffer,
					"Surface (%s, %s)",
					language_get_string(STR_TILE_INSPECTOR_TERRAIN_START + map_element_get_terrain(element)),
					language_get_string(STR_TILE_INSPECTOR_TERRAIN_EDGE_START + map_element_get_terrain_edge(element))
				);
				type_name = buffer;
				break;
			case MAP_ELEMENT_TYPE_PATH:
			{
				// TODO: use these
				uint8 pathType, pathDirection;
				pathType = element->properties.path.type >> 2;
				pathDirection = element->properties.path.type & 3;
			}
			sprintf(
				buffer,
				"Path (%s)",
				"" // TODO: queue? has bins? has benches? e.t.c.
			);
			type_name = buffer;
			break;
			case MAP_ELEMENT_TYPE_TRACK:
				type_name = "Track"; // TODO: show type?
				break;
			case MAP_ELEMENT_TYPE_SCENERY:
				sprintf(
					buffer,
					"Scenery (%s)",
					language_get_string(g_smallSceneryEntries[element->properties.scenery.type]->name)
				);
				type_name = buffer;
				break;
			case MAP_ELEMENT_TYPE_ENTRANCE:
				sprintf(
					buffer,
					"Entrance (%s)",
					language_get_string(STR_TILE_INSPECTOR_ENTRANCE_START + element->properties.entrance.type)
					);
				type_name = buffer;
				break;
			case MAP_ELEMENT_TYPE_FENCE:
				sprintf(
					buffer,
					"Fence (%s)",
					language_get_string(g_wallSceneryEntries[element->properties.scenery.type]->name)
					);
				type_name = buffer;
				break;
			case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE:
				type_name = "Scenery multiple";
				break;
			case MAP_ELEMENT_TYPE_BANNER:
				sprintf(
					buffer,
					"Banner (%d)",
					element->properties.banner.index
				);
				type_name = buffer;
				break;
		}

		gfx_draw_string(dpi, type_name, 12, x, y);
		gfx_draw_string_left(dpi, 5182, &base_height, 12, x + 200, y);
		gfx_draw_string_left(dpi, 5182, &clearance_height, 12, x + 280, y);

		uint8 flags = element->flags;
		char j;

		buffer[8] = '\0';

		for (j = 7; j >= 0; j--, flags >>= 1) {
			buffer[j] = flags & 1 ? '1' : '0';
		}

		gfx_draw_string(dpi, buffer, 12, x + 390, y);

		y -= 11;
		i++;

	} while (!map_element_is_last_for_tile(element++));

}
示例#11
0
/**
 * 
 *  rct2: 0x006A8B40
 */
void object_list_load()
{
	HANDLE hFindFile;
	WIN32_FIND_DATAA findFileData;
	int totalFiles = 0, totalFileSize = 0, fileDateModifiedChecksum = 0;

	char pluginPath[MAX_PATH];
	get_plugin_path(pluginPath);

	// Enumerate through each object in the directory
	hFindFile = FindFirstFile(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), &findFileData);
	if (hFindFile != INVALID_HANDLE_VALUE) {
		do {
			totalFiles++;
			totalFileSize += findFileData.nFileSizeLow;
			fileDateModifiedChecksum ^=
				findFileData.ftLastWriteTime.dwLowDateTime ^
				findFileData.ftLastWriteTime.dwHighDateTime;
			fileDateModifiedChecksum = ror32(fileDateModifiedChecksum, 5);
		} while (FindNextFile(hFindFile, &findFileData));
		FindClose(hFindFile);
	}

	totalFiles = ror32(totalFiles, 24);
	totalFiles = (totalFiles & ~0xFF) | 1;
	totalFiles = rol32(totalFiles, 24);

	// Read plugin header
	rct_plugin_header pluginHeader;

	FILE *file = fopen(pluginPath, "rb");
	if (file != NULL) {
		if (fread(&pluginHeader, sizeof(pluginHeader), 1, file) == 1) {
			// Check if object repository has changed in anyway
			if (
				totalFiles == pluginHeader.total_files &&
				totalFileSize == pluginHeader.total_file_size &&
				fileDateModifiedChecksum == pluginHeader.date_modified_checksum
			) {
				// Dispose installed object list
				if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, sint32) != -1) {
					rct2_free(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*));
					RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, sint32) = -1;
				}

				// Read installed object list
				RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_malloc(pluginHeader.object_list_size);
				if (fread(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*), pluginHeader.object_list_size, 1, file) == 1) {
					RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) = pluginHeader.object_list_no_items;

					fclose(file);
					sub_6A9FC0();
					object_list_examine();
					return;
				}
			}
		}
		fclose(file);
	}

	// Reload object list
	RCT2_GLOBAL(0x00F42B94, uint32) = totalFiles;
	RCT2_GLOBAL(0x00F42B98, uint32) = totalFileSize;
	RCT2_GLOBAL(0x00F42B9C, uint32) = fileDateModifiedChecksum;
	//RCT2_CALLPROC_EBPSAFE(0x006A8D8F);

	int eax = 3161;
	if (RCT2_GLOBAL(0x9AA00D, uint8) != 0){
		eax = 3160;
		RCT2_GLOBAL(0x9AA00D, uint8) = 0;
	}
	// File count removed and replaced by variable
	// RCT2_GLOBAL(0xF42BA8, uint32) = 0;
	uint32 file_count = 0;

	// Progress bar related.
	RCT2_GLOBAL(0xF42BD8, uint8) = 0;

	sub_6A9FC0();

	// Dispose installed object list
	if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, sint32) != -1) {
		rct2_free(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*));
		RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, sint32) = -1;
	}

	RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) = 0;
	RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_malloc(4096);
	if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, int) == -1){
		RCT2_CALLPROC_X(0x006E3838, 0x343, 0xC5A, 0, 0, 0, 0, 0);
		return;
	}

	uint32 installed_buffer_size = 0x1000;
	uint32 current_item_offset = 0;

	hFindFile = FindFirstFile(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), &findFileData);
	if (hFindFile == INVALID_HANDLE_VALUE){
		//6a92ea This hasn't been implemented but there isn't much point.
		// It would make a empty object file if no files found.
		return;
	}

	for (uint8 first_time = 1; first_time || FindNextFile(hFindFile, &findFileData);){
		first_time = 0;

		RCT2_GLOBAL(0x9ABD98, HANDLE) = hFindFile;
		
		file_count++;
		// update progress bar. 
		eax = (file_count << 8) / ((RCT2_GLOBAL(0xF42B94, uint32) & 0xFFFFFF) + 1);



		if ((eax & 0xFF) != RCT2_GLOBAL(0xF42BD8, uint8)){
			RCT2_GLOBAL(0xF42BD8, uint8) = eax & 0xFF;
			// update progress bar
		}

		if ((installed_buffer_size - current_item_offset) <= 2842){
			installed_buffer_size += 0x1000;
			RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_realloc(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*), installed_buffer_size);
			if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, int) == -1){
				RCT2_CALLPROC_X(0x006E3838, 0x343, 0xC5A, 0, 0, 0, 0, 0);
				return;
			}
		}

		char path[260];
		subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), findFileData.cFileName);

		FILE *obj_file = fopen(path, "rb");
		if (obj_file == NULL){
			continue;
		}

		rct_object_entry* entry = RCT2_ADDRESS(0xF42B74, rct_object_entry);
		if (fread(entry, sizeof(rct_object_entry), 1, obj_file) != 1){
			fclose(obj_file);
			continue;
		}
		fclose(obj_file);

		RCT2_GLOBAL(0xF42BC4, uint32) = current_item_offset;

		uint8* installed_entry_pointer = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*) + current_item_offset;

		memcpy(installed_entry_pointer, entry, sizeof(rct_object_entry));
		installed_entry_pointer += sizeof(rct_object_entry);

		strcpy(installed_entry_pointer, findFileData.cFileName);
		while (*installed_entry_pointer++);

		*((sint32*)installed_entry_pointer) = -1;
		*(installed_entry_pointer + 4) = 0;
		*((sint32*)(installed_entry_pointer + 5)) = 0;
		*((uint16*)(installed_entry_pointer + 9)) = 0;
		*((uint32*)(installed_entry_pointer + 11)) = 0;

		RCT2_GLOBAL(0x9ADAF0, uint32) = 0xF26E;

		RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)++;

		// This is a variable used by object_load to decide if it should
		// use object_paint on the entry.
		RCT2_GLOBAL(0x9ADAFD, uint8) = 1;

		// Probably used by object paint.
		RCT2_GLOBAL(0x9ADAF4, uint32) = 0xF42BDB;

		int chunk_size;
		if (!object_load(-1, entry, &chunk_size)){
			RCT2_GLOBAL(0x9ADAF4, sint32) = -1;
			RCT2_GLOBAL(0x9ADAFD, uint8) = 0;
			RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)--;
			continue;
		}
		// See above note
		RCT2_GLOBAL(0x9ADAF4, sint32) = -1;
		RCT2_GLOBAL(0x9ADAFD, uint8) = 0;

		if ((entry->flags & 0xF0) == 0x80){
			RCT2_GLOBAL(0xF42B70, uint32)++;
			if (RCT2_GLOBAL(0xF42B70, uint32) > 772){
				RCT2_GLOBAL(0xF42B70, uint32)--;
				RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)--;
				continue;
			}
		}
		*((sint32*)installed_entry_pointer) = chunk_size;
		installed_entry_pointer += 4;

		uint8* chunk = RCT2_GLOBAL(RCT2_ADDRESS_CURR_OBJECT_CHUNK_POINTER, uint8*); // Loaded in object_load

		// When made of two parts i.e Wooden Roller Coaster (Dream Woodie Cars);
		if ((entry->flags & 0xF) == 0 && !(*((uint32*)(chunk + 8)) & 0x1000)){
			rct_string_id obj_string = chunk[12];
			if (obj_string == 0xFF){
				obj_string = chunk[13];
				if (obj_string == 0xFF){
					obj_string = chunk[14];
				}
			}

			obj_string += 2;
			format_string(installed_entry_pointer, obj_string, 0);
			strcat(installed_entry_pointer, "\t (");
			strcat(installed_entry_pointer, language_get_string(RCT2_GLOBAL(0xF42BBC, uint32)));
			strcat(installed_entry_pointer, ")");
			while (*installed_entry_pointer++);
		}
		else{
			strcpy(installed_entry_pointer, language_get_string(RCT2_GLOBAL(0xF42BBC, uint32)));
			while (*installed_entry_pointer++);
		}
		*((uint32*)installed_entry_pointer) = RCT2_GLOBAL(0x9ADAF0, uint32) - 0xF26E;
		installed_entry_pointer += 4;

		uint8* esi = RCT2_ADDRESS(0xF42BDB, uint8);
		int cl = *esi++;
		*installed_entry_pointer++ = cl;
		if (cl){
			memcpy(installed_entry_pointer, esi, cl*sizeof(rct_object_entry));
			installed_entry_pointer += cl*sizeof(rct_object_entry);
		}

		cl = *esi++;
		*installed_entry_pointer++ = cl;
		if (cl){
			memcpy(installed_entry_pointer, esi, cl*sizeof(rct_object_entry));
			installed_entry_pointer += cl*sizeof(rct_object_entry);
		}

		*((uint32*)installed_entry_pointer) = RCT2_GLOBAL(0xF433DD, uint32);
		installed_entry_pointer += 4;

		int size_of_object = installed_entry_pointer - RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*) - current_item_offset;

		object_unload(entry->flags & 0xF, (rct_object_entry_extended*)entry);

		// Return pointer to start of entry
		installed_entry_pointer -= size_of_object;

		uint8* copied_entry = RCT2_ADDRESS(0x140E9AC, uint8);

		size_of_object = object_copy(copied_entry, installed_entry_pointer);

		RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)--;
		copied_entry += sizeof(rct_object_entry);
		// Skip filename
		while (*copied_entry++);

		// Skip 
		copied_entry += 4;

		installed_entry_pointer = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*);

		for (uint32 i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); ++i){

			uint8* temp_installed_entry = installed_entry_pointer;
			temp_installed_entry += sizeof(rct_object_entry);

			// Skip filename
			while (*temp_installed_entry++);

			// Skip 
			temp_installed_entry += 4;

			if (strcmp(temp_installed_entry, copied_entry) <= 0)break;

			installed_entry_pointer = (uint8*)(object_get_next((rct_object_entry*)installed_entry_pointer));
		}

		// Difference to new location
		int no_bytes_to_move = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*) + current_item_offset - installed_entry_pointer;

		uint8* curr_location = installed_entry_pointer;
		uint8* move_location = installed_entry_pointer + size_of_object;

		if (no_bytes_to_move){
			memmove(move_location, curr_location, no_bytes_to_move);
		}

		copied_entry = RCT2_ADDRESS(0x140E9AC, uint8);
		memcpy(installed_entry_pointer, copied_entry, size_of_object);
		current_item_offset += size_of_object;
		RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)++;
	}
示例#12
0
void format_string_code(unsigned int format_code, char **dest, char **args)
{
	int value;

	switch (format_code) {
	case FORMAT_COMMA32:
		// Pop argument
		value = *((sint32*)*args);
		*args += 4;

		format_comma_separated_integer(dest, value);
		break;
	case FORMAT_INT32:
		// Pop argument
		value = *((sint32*)*args);
		*args += 4;

		format_integer(dest, value);
		break;
	case FORMAT_COMMA2DP32:
		// Pop argument
		value = *((sint32*)*args);
		*args += 4;

		format_comma_separated_fixed_2dp(dest, value);
		break;
		case FORMAT_COMMA1DP16:
		// Pop argument
		value = *((sint16*)*args);
		*args += 2;

		format_comma_separated_fixed_1dp(dest, value);
		break;
	case FORMAT_COMMA16:
		// Pop argument
		value = *((sint16*)*args);
		*args += 2;

		format_comma_separated_integer(dest, value);
		break;
	case FORMAT_UINT16:
		// Pop argument
		value = *((uint16*)*args);
		*args += 2;

		format_integer(dest, value);
		break;
	case FORMAT_CURRENCY2DP:
		// Pop argument
		value = *((sint32*)*args);
		*args += 4;

		format_currency_2dp(dest, value);
		break;
	case FORMAT_CURRENCY:
		// Pop argument
		value = *((sint32*)*args);
		*args += 4;

		format_currency(dest, value);
		break;
	case FORMAT_STRINGID:
	case FORMAT_STRINGID2:
		// Pop argument
		value = *((uint16*)*args);
		*args += 2;

		format_string_part(dest, value, args);
		(*dest)--;
		break;
	case FORMAT_STRING:
		// Pop argument
		value = *((uint32*)*args);
		*args += 4;

		if (value != 0) {
			strcpy(*dest, (char*)value);
			*dest += strlen(*dest);
		}
		break;
	case FORMAT_MONTHYEAR:
		// Pop argument
		value = *((uint16*)*args);
		*args += 2;

		format_date(dest, value);
		break;
	case FORMAT_MONTH:
		// Pop argument
		value = *((uint16*)*args);
		*args += 2;

		strcpy(*dest, language_get_string(STR_MONTH_MARCH + date_get_month(value)));
		*dest += strlen(*dest);
		break;
	case FORMAT_VELOCITY:
		// Pop argument
		value = *((sint16*)*args);
		*args += 2;

		format_velocity(dest, value);
		break;
	case FORMAT_POP16:
		*args += 2;
		break;
	case FORMAT_PUSH16:
		*args -= 2;
		break;
	case FORMAT_DURATION:
		// Pop argument
		value = *((uint16*)*args);
		*args += 2;

		format_duration(dest, value);
		break;
	case FORMAT_REALTIME:
		// Pop argument
		value = *((uint16*)*args);
		*args += 2;

		format_realtime(dest, value);
		break;
	case FORMAT_LENGTH:
		// Pop argument
		value = *((sint16*)*args);
		*args += 2;

		format_length(dest, value);
		break;
	case FORMAT_SPRITE:
		// Pop argument
		value = *((uint32*)*args);
		*args += 4;

		*(*dest)++ = 23;
		*((uint32*)(*dest)) = value;
		*dest += 4;
		break;
	}
}
示例#13
0
static void window_loadsave_mouseup(rct_window *w, int widgetIndex)
{
	int result = 0;
	char path[MAX_PATH], filter[MAX_PATH];

	switch (widgetIndex){
	case WIDX_CLOSE:
		window_close(w);
		break;
	case WIDX_UP:
	{
		char directory[MAX_PATH];
		int includeNewItem = (_type & 1) == LOADSAVETYPE_SAVE;
		
		safe_strcpy(directory, _parentDirectory, sizeof(directory));
		window_loadsave_populate_list(w, includeNewItem, directory, _extension);
		window_init_scroll_widgets(w);
		w->no_list_items = _listItemsCount;
		break;
	}
	case WIDX_NEW:
	{		
		rct_string_id templateStringId = 3165;
		char *templateString;
		
		templateString = (char *)language_get_string(templateStringId);
		strcpy(templateString, _defaultName);
		window_text_input_open(w, WIDX_NEW, STR_NONE, 2710, templateStringId, 0, 64);
		break;
	}
	case WIDX_BROWSE:
		safe_strcpy(path, _directory, MAX_PATH);
		if (_type & LOADSAVETYPE_SAVE) {
			strcat(path, _defaultName);
		}

		memset(filter, '\0', MAX_PATH);
		safe_strcpy(filter, "*", MAX_PATH);
		strncat(filter, _extension, MAX_PATH - strnlen(filter, MAX_PATH) - 1);

		file_dialog_desc desc;
		memset(&desc, 0, sizeof(desc));
		desc.initial_directory = _directory;
		if (_type & LOADSAVETYPE_SAVE) {
			desc.default_filename = path;
		}

		switch (_type) {
		case (LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME) :
			desc.type = FD_OPEN;
			desc.title = language_get_string(STR_FILE_DIALOG_TITLE_LOAD_GAME);
			desc.filters[0].name = language_get_string(STR_OPENRCT2_SAVED_GAME);
			desc.filters[0].pattern = "*.sv4;*.sv6";
			break;
		case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) :
			desc.type = FD_SAVE;
			desc.title = language_get_string(STR_FILE_DIALOG_TITLE_SAVE_GAME);
			desc.filters[0].name = language_get_string(STR_OPENRCT2_SAVED_GAME);
			desc.filters[0].pattern = "*.sv6";
			break;
		case (LOADSAVETYPE_LOAD | LOADSAVETYPE_LANDSCAPE) :
			desc.type = FD_OPEN;
			desc.title = language_get_string(STR_FILE_DIALOG_TITLE_LOAD_LANDSCAPE);
			desc.filters[0].name = language_get_string(STR_OPENRCT2_LANDSCAPE_FILE);
			desc.filters[0].pattern = "*.sc4;*.sv4;*.sc6;*.sv6";
			break;
		case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) :
			desc.type = FD_SAVE;
			desc.title = language_get_string(STR_FILE_DIALOG_TITLE_SAVE_LANDSCAPE);
			desc.filters[0].name = language_get_string(STR_OPENRCT2_LANDSCAPE_FILE);
			desc.filters[0].pattern = "*.sc6";
			break;
		case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) :
			desc.type = FD_SAVE;
			desc.title = language_get_string(STR_FILE_DIALOG_TITLE_SAVE_SCENARIO);
			desc.filters[0].name = language_get_string(STR_OPENRCT2_SCENARIO_FILE);
			desc.filters[0].pattern = "*.sc6";
			break;
		case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
			desc.type = FD_OPEN;
			desc.title = language_get_string(STR_FILE_DIALOG_TITLE_INSTALL_NEW_TRACK_DESIGN);
			desc.filters[0].name = language_get_string(STR_OPENRCT2_TRACK_DESIGN_FILE);
			desc.filters[0].pattern = "*.td4;*.td6";
			break;
		}

		result = platform_open_common_file_dialog(path, &desc);
		if (result) {
			window_loadsave_select(w, path);
		}
		break;
	case WIDX_SORT_NAME:
		if (gConfigGeneral.load_save_sort == SORT_NAME_ASCENDING){
			gConfigGeneral.load_save_sort = SORT_NAME_DESCENDING;
		} else {
			gConfigGeneral.load_save_sort = SORT_NAME_ASCENDING;
		}
		config_save_default();
		window_loadsave_sort_list(0, _listItemsCount - 1);
		window_invalidate(w);
		break;
	case WIDX_SORT_DATE:
		if (gConfigGeneral.load_save_sort == SORT_DATE_DESCENDING){
			gConfigGeneral.load_save_sort = SORT_DATE_ASCENDING;
		} else {
			gConfigGeneral.load_save_sort = SORT_DATE_DESCENDING;
		}
		config_save_default();
		window_loadsave_sort_list(0, _listItemsCount - 1);
		window_invalidate(w);
		break;
	}
}
/**
 * 
 *  rct2: 0x006AAB56
 */
static void window_editor_object_selection_paint()
{
	int i, x, y, width, numSelected, totalSelectable, type;
	rct_window *w;
	rct_drawpixelinfo *dpi;
	rct_widget *widget;
	rct_object_entry *highlightedEntry;
	rct_string_id stringId;
	uint8 *text, source;
	char *datName, *name, *stringBuffer;

	window_paint_get_registers(w, dpi);

	/*if (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS) {
		gfx_fill_rect_inset(dpi,
			w->x + w->widgets[WIDX_FILTER_RIDE_TAB_ALL].left - 1,
			w->y + w->widgets[WIDX_FILTER_RIDE_TAB_ALL].bottom,
			w->x + w->widgets[WIDX_FILTER_RIDE_TAB_STALL].right + 1,
			w->y + w->widgets[WIDX_FILTER_RIDE_TAB_ALL].bottom + 2,
			w->colours[1],
			0x10
			);
	}*/

	window_draw_widgets(w, dpi);

	// Draw tabs
	for (i = 0; i < WINDOW_OBJECT_SELECTION_PAGE_COUNT; i++) {
		widget = &w->widgets[WIDX_TAB_1 + i];
		if (widget->type == WWT_EMPTY)
			continue;

		x = w->x + widget->left;
		y = w->y + widget->top;
		gfx_draw_sprite(dpi, 5458 + i, x, y, 0);
	}

	const int ride_tabs[] = { 5458, 0x200015A1, 5542, 0x200015AA, 5557 + 5, 5551, 5530, 5327 };

	// Draw ride tabs
	if (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS) {
		for (i = 0; i < 7; i++) {
		widget = &w->widgets[WIDX_FILTER_RIDE_TAB_ALL + i];
			if (widget->type == WWT_EMPTY)
				continue;

			x = w->x + widget->left;
			y = w->y + widget->top;
			gfx_draw_sprite(dpi, ride_tabs[i] | (w->colours[1] << 19), x, y, 0);
		}

	}

	// Preview background
	widget = &w->widgets[WIDX_PREVIEW];
	gfx_fill_rect(
		dpi,
		w->x + widget->left + 1,
		w->y + widget->top + 1,
		w->x + widget->right - 1,
		w->y + widget->bottom - 1,
		RCT2_ADDRESS(0x0141FC44, uint8)[w->colours[1] * 8]
	);

	// Draw number of selected items
	if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER)) {
		x = w->x + 3;
		y = w->y + w->height - 13;

		numSelected = RCT2_ADDRESS(0x00F433F7, uint16)[w->selected_tab];
		totalSelectable = object_entry_group_counts[w->selected_tab];
		if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER)
			totalSelectable = 4;

		RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint16) = numSelected;
		RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint16) = totalSelectable;
		gfx_draw_string_left(dpi, 3164, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, 0, x, y);
	}

	rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*);

	/*gfx_fill_rect_inset(dpi,
		w->x + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].left,
		w->y + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].top,
		w->x + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].right,
		w->y + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].bottom,
		w->colours[1],
		0x30
		);

	RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32) = (uint32)&_filter_string;
	gfx_draw_string_left_clipped(
		dpi,
		1170,
		(void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS,
		w->colours[1],
		w->x + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].left + 1,
		w->y + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].top,
		w->x + window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].right
		);*/

	if (w->selected_list_item == -1 || stex_entry == NULL)
		return;

	highlightedEntry = (rct_object_entry*)w->var_494;
	type = highlightedEntry->flags & 0x0F;

	// Draw preview
	widget = &w->widgets[WIDX_PREVIEW];
	x = w->x + (widget->left + widget->right) / 2 + 1;
	y = w->y + (widget->top + widget->bottom) / 2 + 1;
	object_paint(type, 3, type, x, y, 0, (int)dpi, (int)stex_entry);

	// Draw name of object
	x = w->x + (widget->left + widget->right) / 2 + 1;
	y = w->y + widget->bottom + 3;
	width = w->width - w->widgets[WIDX_LIST].right - 6;

	// Skip object dat name
	text = (char*)(highlightedEntry + 1);
	datName = text;
	do {
		text++;
	} while (*(text - 1) != 0);
	text += 4;
	name = text;

	RCT2_GLOBAL(0x009BC677, uint8) = 14;

	stringId = 3165;
	stringBuffer = (char*)language_get_string(3165) + 1;
	if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) {
		// Skip name
		do {
			text++;
		} while (*(text - 1) != 0);
		text += 4;
		text += *text * 16 + 1;
		text += *text * 16 + 1;

		if (RCT2_GLOBAL(text, uint32) & 0x1000000) {
			strcpy(stringBuffer, name);
		} else {
			int eax = *text;
			if (*text == 0xFF) {
				eax = *(text + 1);
				if (*(text + 1) == 0xFF)
					eax = *(text + 2);
			}
			format_string(stringBuffer, eax + 2, NULL);
		}
	} else {
		strcpy(stringBuffer, name);
	}
	gfx_draw_string_centred_clipped(dpi, stringId, NULL, 0, x, y, width);
	
	// Draw description of object
	x = w->x + w->widgets[WIDX_LIST].right + 4;
	y += 15;
	object_paint(type, 259, type, x, y, (int)w, (int)dpi, (int)stex_entry);

	// Draw object source
	source = (highlightedEntry->flags & 0xF0) >> 4;
	switch (source) {
	case 8: stringId = 2741; break;
	case 1: stringId = 5262; break;
	case 2: stringId = 5263; break;
	default: stringId = 5264; break;
	}
	gfx_draw_string_right(dpi, stringId, NULL, 2, w->x + w->width - 5, w->y + w->height - 3 - 12 - 14);

	// 
	if (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS) {
		y = w->y + w->height - 3 - 12 - 14 - 14;

		rct_ride_type *rideType = (rct_ride_type*)stex_entry;
		for (int i = 0; i < 3; i++) {
			if (rideType->ride_type[i] == 255)
				continue;

			stringId = 2 + rideType->ride_type[i];
			gfx_draw_string_right(dpi, stringId, NULL, 2, w->x + w->width - 5, y);
			y -= 11;
		}
	}

	//stringId = highlightedEntry->checksum
	// gfx_draw_string_right(dpi, stringId, NULL, 2, w->x + w->width - 5, w->y + w->height - 3 - 12 - 14);

	// Draw object dat name
	stringId = 3165;
	strcpy(stringBuffer, datName);
	gfx_draw_string_right(dpi, stringId, NULL, 0, w->x + w->width - 5, w->y + w->height - 3 - 12);
}