Пример #1
0
/**
 * 
 *  rct2: 0x006A93CD
 */
static void object_list_examine()
{
	int i;
	rct_object_entry *object;

	object = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*);
	for (i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, sint32); i++) {
		if (object->flags & 0xF0)
			RCT2_GLOBAL(0x00F42BDA, uint8) |= 1;

		object = object_get_next(object);
	}
}
Пример #2
0
STATUS test_init(void)
{
	OBJECT *obj;
	output_verbose("initializing objects...");
	for (obj=object_get_first(); obj!=NULL; obj=object_get_next(obj))
	{
		if (object_init(obj)==FAILED)
		{
			output_error("object %s initialization failed", object_name(obj));
			return FAILED;
		}
	}
	return SUCCESS;
}
Пример #3
0
/**
 * Takes the y coordinate of the clicked on scroll list
 * and converts this into an object selection.
 * Returns the position in the list.
 * Object_selection_flags, installed_entry also populated
 *
 * rct2: 0x006AA703
 */
static int get_object_from_object_selection(uint8 object_type, int y, uint8 *object_selection_flags, rct_object_entry **installed_entry)
{
	rct_object_filters *filter;
	*installed_entry = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*);
	uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*);
	uint8 source;
	int object_count = 0;
	for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){
		filter = get_object_filter(RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) - i);
		source = ((*installed_entry)->flags & 0xF0) >> 4;
		if (((*installed_entry)->flags & 0xF) == object_type && filter_source(*installed_entry) && filter_string(*installed_entry) && filter_chunks(*installed_entry, filter)){
			if (!(*selection_flags & 0x20)){
				y -= 12;
				*object_selection_flags = *selection_flags;
				if (y < 0)return object_count;
				object_count++;
			}
		}

		*installed_entry = object_get_next(*installed_entry);
		selection_flags++;
	}
	return -1;
}
Пример #4
0
/** sanitize

	Sanitizes a gridlabd model by clear names and position from object headers

    @returns 0 on success, -2 on error
 **/
extern "C" int sanitize(int argc, char *argv[])
{
	OBJECT *obj;
	FILE *fp;
	double delta_latitude, delta_longitude;

	// lat/lon change
	if ( strcmp(global_sanitizeoffset,"")==0 )
	{
		delta_latitude = random_uniform(NULL,-5,+5);
		delta_longitude = random_uniform(NULL,-180,+180);
	}
	else if ( global_sanitizeoffset=="destroy" )
		delta_latitude = delta_longitude = QNAN;
	else if ( sscanf(global_sanitizeoffset.get_string(),"%lf%*[,/]%lf",&delta_latitude,&delta_longitude)!=2 )
	{
		output_error("sanitize_offset lat/lon '%s' is not valid", global_sanitizeoffset.get_string());
		return -2;
	}

	// sanitize object names
	for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) )
	{
		if ( obj->name!=NULL && (global_sanitizeoptions&SO_NAMES)==SO_NAMES )
			sanitize_name(obj);
		if ( isfinite(obj->latitude) && (global_sanitizeoptions&SO_GEOCOORDS)==SO_GEOCOORDS )
		{
			obj->latitude += delta_latitude;
			if ( obj->latitude<-90 ) obj->latitude = -90;
			if ( obj->latitude>+90 ) obj->latitude = +90;
		}
		if ( isfinite(obj->longitude) && (global_sanitizeoptions&SO_GEOCOORDS)==SO_GEOCOORDS )
			obj->longitude = fmod(obj->longitude+delta_longitude,360);
	}

	// dump object name index
	if ( strcmp(global_sanitizeindex,".xml")==0 )
	{
		strcpy(global_sanitizeindex,global_modelname);
		char *ext = strrchr(global_sanitizeindex,'.');
		if ( ext && strcmp(ext,".glm")==0 ) strcpy(ext,"-index.xml");
		else strcat(global_sanitizeindex,"-index.xml");
	}
	else if ( strcmp(global_sanitizeindex,".txt")==0 )
	{
		strcpy(global_sanitizeindex,global_modelname);
		char *ext = strrchr(global_sanitizeindex,'.');
		if ( ext && strcmp(ext,".glm")==0 ) strcpy(ext,"-index.txt");
		else strcat(global_sanitizeindex,"-index.txt");
	}
	else if ( global_sanitizeindex[0]=='.' )
	{
		output_error("sanitization index file spec '%s' is not recognized", global_sanitizeindex.get_string());
		return -2;
	}
	if ( strcmp(global_sanitizeindex,"")!=0 )
	{
		char *ext = strrchr(global_sanitizeindex,'.');
		bool use_xml = (ext && strcmp(ext,".xml")==0) ;
		fp = fopen(global_sanitizeindex,"w");
		if ( fp )
		{
			SAFENAME *item;
			if ( use_xml )
			{
				fprintf(fp,"<data>\n");
				fprintf(fp,"\t<modelname>%s</modelname>\n",global_modelname);
				fprintf(fp,"\t<geographic_offsets>\n");
				fprintf(fp,"\t\t<latitude>%.6f</latitude>\n",delta_latitude);
				fprintf(fp,"\t\t<longitude>%.6f</longitude>\n",delta_longitude);
				fprintf(fp,"\t</geographic_offsets>\n");
				fprintf(fp,"\t<safename_list>\n");
				for ( item=safename_list ; item!=NULL ; item=item->next )
					fprintf(fp,"\t\t<name>\n\t\t\t<safe>%s</safe>\n\t\t\t<unsafe>%s</unsafe>\n\t\t</name>\n", item->name, item->old);
				fprintf(fp,"\t</safename_list>\n");
				fprintf(fp,"</data>\n");
			}
			else
			{
				fprintf(fp,"modelname\t= %s\n", global_modelname);
				fprintf(fp,"\n[POSITIONS]\n");
				fprintf(fp,"latitude\t= %.6f\n",delta_latitude);
				fprintf(fp,"longitude\t= %.6f\n",delta_longitude);
				fprintf(fp,"\n[NAMES]\n");
				for ( item=safename_list ; item!=NULL ; item=item->next )
					fprintf(fp,"%s\t= %s\n", item->name, item->old);
			}
			fclose(fp);
		}
	}

	return 0;
}
Пример #5
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)++;
	}
Пример #6
0
/* initialize modules */
int link_initall(void)
{
	output_debug("link_initall(): link startup in progress...");
	glxlink *mod;
	for ( mod=glxlink::get_first() ; mod!=NULL ; mod=mod->get_next() )
	{
		LINKLIST *item;

		output_debug("link_initall(): setting up %s link", mod->get_target());

		// set default global list (if needed)
		if ( mod->get_globals()==NULL )
		{
			GLOBALVAR *var = NULL;
			while ( (var=global_getnext(var))!=NULL )
			{
				if ( var->prop!=NULL && var->prop->name!=NULL )
				{
					LINKLIST *item = mod->add_global(var->prop->name);
					if ( item!=NULL )
						item->data = (void*)var;
					else
						output_error("link_initall(): unable to link %s", var->prop->name);
				}
				else
					output_warning("link_initall(): a variable property definition is null"); 
			}
		}
		else 
		{
			// link global variables
			for ( item=mod->get_globals() ; item!=NULL ; item=mod->get_next(item) )
			{
				if ( strcmp(item->name,"")==0 ) continue;
				item->data = (void*)global_find(item->name);
				if ( item->data==NULL )
					output_error("link_initall(target='%s'): global '%s' is not found", mod->get_target(), item->name);
			}
		}

		// link objects
		if ( mod->get_objects()==NULL )
		{
			// set default object list
			OBJECT *obj = NULL;
			for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) )
			{
				// add named objects
				LINKLIST *item = NULL;
				if ( obj->name!=NULL )
					item = mod->add_object(obj->name);
				else
				{
					char id[256];
					sprintf(id,"%s:%d",obj->oclass->name,obj->id);
					item = mod->add_object(id);
				}
				item->data = (void*)obj;
			}
		}
		else
		{
			LINKLIST *item;

			// link global variables
			for ( item=mod->get_objects() ; item!=NULL ; item=mod->get_next(item) )
			{
				if ( strcmp(item->name,"")==0 ) continue;
				OBJECT *obj = NULL;
				item->data = (void*)object_find_name(item->name);
				if ( item->data==NULL)
					output_error("link_initall(target='%s'): object '%s' is not found", mod->get_target(), item->name);
			}
		}

		// link exports
		for ( item=mod->get_exports() ; item!=NULL ; item=mod->get_next(item) )
		{
			char objname[64], propname[64], varname[64];
			if ( sscanf(item->name,"%[^.].%s %s",objname,propname,varname)==3 )
			{
				OBJECTPROPERTY *objprop = (OBJECTPROPERTY*)malloc(sizeof(OBJECTPROPERTY));
				objprop->obj = object_find_name(objname);
				if ( objprop->obj )
				{
					objprop->prop = class_find_property(objprop->obj->oclass,propname);
					if ( objprop->prop==NULL )
						output_error("link_initall(target='%s'): export '%s' property not found", mod->get_target(), item->name);
					else
					{
						item->data = objprop;
						strcpy(item->name,varname);
					}
				}
				else
					output_error("link_initall(target='%s'): export '%s' object not found", mod->get_target(), item->name);
			}
			else
				output_error("link_initall(target='%s'): '%s' is not a valid export specification", mod->get_target(), item->name);
		}

		// link imports
		for ( item=mod->get_imports() ; item!=NULL ; item=mod->get_next(item) )
		{
			char objname[64], propname[64], varname[64];
			if ( sscanf(item->name,"%[^.].%s %s",objname,propname,varname)==3 )
			{
				OBJECTPROPERTY *objprop = (OBJECTPROPERTY*)malloc(sizeof(OBJECTPROPERTY));
				objprop->obj = object_find_name(objname);
				if ( objprop->obj )
				{
					objprop->prop = class_find_property(objprop->obj->oclass,propname);
					if ( objprop->prop==NULL )
						output_error("link_initall(target='%s'): import '%s' property not found", mod->get_target(), item->name);
					else
					{
						item->data = objprop;
						strcpy(item->name,varname);
					}
				}
				else
					output_error("link_initall(target='%s'): import '%s' object not found", mod->get_target(), item->name);
			}
			else
				output_error("link_initall(target='%s'): '%s' is not a valid import specification", mod->get_target(), item->name);
		}

		// initialize link module
		if ( !mod->do_init() )
		{
			output_error("link_initall(): link startup failed");
			link_termall();
			return 0;
		}
	}
	output_debug("link_initall(): link startup done ok");
	atexit((void(*)(void))link_termall);
	return 1;
}
Пример #7
0
/** Initialize the delta mode code

	This call must be completed before the first call to any delta mode code.
	If the call fails, no delta mode code can be executed.  Failure does not
	affect whether event mode code can run.

	@return SUCCESS or FAILED
 **/
STATUS delta_init(void)
{
	OBJECT *obj, **pObj;
	char temp_name_buff[64];
	unsigned int n, toprank = 0;
	OBJECT ***ranklist;
	int *rankcount;
	MODULE *module;
	clock_t t = clock();

	/* count qualified modules */
	for ( module=module_get_first() ; module!=NULL ; module=module_get_next(module) )
	{
		if ( 0 != module->deltadesired ){
			// this could probably be counted in module_init()...
			delta_modulecount++;
			if (profile.module_list[0]!=0)
				strcat(profile.module_list,",");
			strcat(profile.module_list,module->name);
		}
	}

	/* if none, stop here */
	if ( delta_modulecount==0 ){
		goto Success;
	}

	/* allocate memory for qualified module list */
	delta_modulelist = (MODULE**)malloc(sizeof(MODULE**)*delta_modulecount);
	if(0 == delta_modulelist){
		output_error("unable to allocate memory for deltamode module list");
		/* TROUBLESHOOT
		  Deltamode operation requires more memory than is available.
		  Try freeing up memory by making more heap available or making the model smaller. 
		 */
		return FAILED;
	}
	/* build qualified module list */
	delta_modulecount = 0;
	global_deltamode_updateorder[0]='\0';
	for ( module=module_get_first() ; module!=NULL ; module=module_get_next(module) )
	{
		if ( 0 != module->deltadesired )
		{
			if ( delta_modulecount>0 )
				strcat(global_deltamode_updateorder,",");
			strcat(global_deltamode_updateorder,module->name);
			delta_modulelist[delta_modulecount++] = module;
		}
	}

	/* count qualified objects */
	for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) )
	{
		if ( obj->flags&OF_DELTAMODE )
		{
			if ( !obj->oclass->update )
				output_debug("object '%s' requested deltamode updates but the class '%s' does not export the update function", object_name(obj, temp_name_buff, 63), obj->oclass->name);
			delta_objectcount++;
			if ( obj->rank > toprank ){
				toprank = obj->rank;
			}
		}
	}

	/* if none, stop here */
	if ( delta_objectcount==0 ){
		goto Success;
	}

	/* allocate final object list */
	delta_objectlist = (OBJECT**)malloc(sizeof(OBJECT*)*delta_objectcount);
	if ( delta_objectlist==NULL)
	{
		output_error("unable to allocate memory for deltamode object list");
		/* TROUBLESHOOT
		  Deltamode operation requires more memory than is available.
		  Try freeing up memory by making more heap available or making the model smaller. 
		 */
		return FAILED;
	}

	/* allocate rank lists */
	ranklist = (OBJECT***)malloc(sizeof(OBJECT**)*(toprank+1));
	if ( 0 == ranklist ){
		output_error("unable to allocate memory for deltamode ranklist");
		/* TROUBLESHOOT
		  Deltamode operation requires more memory than is available.
		  Try freeing up memory by making more heap available or making the model smaller. 
		 */
		return FAILED;
	}
	memset(ranklist,0,sizeof(OBJECT**)*(toprank+1));

	/* allocate rank counts */
	rankcount = (int*)malloc(sizeof(int)*(toprank+1));
	if ( 0 == rankcount ){
		output_error("unable to allocate memory for deltamode rankcount");
		/* TROUBLESHOOT
		  Deltamode operation requires more memory than is available.
		  Try freeing up memory by making more heap available or making the model smaller. 
		 */
		return FAILED;
	}
	memset(rankcount,0,sizeof(int)*(toprank+1));

	/* count qualified objects in each rank */
	for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) )
	{
		if ( obj->flags&OF_DELTAMODE ){
			rankcount[obj->rank]++;
		}
	}

	/* allocate rank lists */
	for ( n=0 ; n<=toprank ; n++)
	{
		if ( rankcount[n]>0 )
		{
			ranklist[n] = (OBJECT**)malloc(sizeof(OBJECT*)*rankcount[n]);
			if ( !ranklist[n] ){
				output_error("unable to allocate memory for deltamode rankcount %i", n);
				/* TROUBLESHOOT
				  Deltamode operation requires more memory than is available.
				  Try freeing up memory by making more heap available or making the model smaller. 
				 */
				return FAILED;
			}
			rankcount[n] = 0; /* clear for index recount */
		}
		else
			ranklist[n] = NULL;
	}

	/* assign qualified objects to rank lists */
	for ( obj=object_get_first() ; obj!=NULL ; obj=object_get_next(obj) )
	{
		if ( obj->flags&OF_DELTAMODE ){
			ranklist[obj->rank][rankcount[obj->rank]++] = obj;
		}
	}

	/* build final object list */
	pObj = delta_objectlist;
	for ( n=0 ; n<=toprank ; n++)
	{
		int m;
		for ( m=0 ; m<rankcount[n] ; m++ ){
			*pObj++ = ranklist[n][m];
		}
		if ( ranklist[n]!=NULL ){
			free(ranklist[n]);
			ranklist[n] = NULL;
		}
	}

	/* release memory */
	free(rankcount);
	rankcount = NULL;
	free(ranklist);
	ranklist = NULL;
Success:
	profile.t_init += clock() - t;
	return SUCCESS;
}
Пример #8
0
/**
 * 
 *  rct2: 0x006AADA3
 */
static void window_editor_object_selection_scrollpaint()
{
	int x, y, i, colour, colour2, numObjects, type;
	short scrollIndex;
	rct_object_entry *entry;
	rct_object_filters *filter;
	rct_window *w;
	rct_drawpixelinfo *dpi;
	uint8 *itemFlags;
	uint8 source;

	window_scrollpaint_get_registers(w, dpi, scrollIndex);

	colour = RCT2_ADDRESS(0x0141FC48, uint8)[w->colours[1] * 8];
	colour = (colour << 24) | (colour << 16) | (colour << 8) | colour;
	gfx_clear(dpi, colour);

	numObjects = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, sint32);
	entry = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*);
	itemFlags = RCT2_GLOBAL(0x009ADAEC, uint8*);
	y = 0;
	for (i = 0; i < numObjects; i++) {
		filter = get_object_filter(i);
		type = entry->flags & 0x0F;
		source = (entry->flags & 0xF0) >> 4;
		if (type == w->selected_tab && !(*itemFlags & 0x20) && filter_source(entry) && filter_string(entry) && filter_chunks(entry, filter)) {
			if (y + 12 >= dpi->y && y <= dpi->y + dpi->height) {
				// Draw checkbox
				if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) && !(*itemFlags & 0x20))
					gfx_fill_rect_inset(dpi, 2, y, 11, y + 10, w->colours[1], 0xE0);

				// Highlight background
				colour = 142;
				if (entry == (rct_object_entry*)w->var_494 && !(*itemFlags & 0x20)) {
					gfx_fill_rect(dpi, 0, y, w->width, y + 11, 0x2000031);
					colour = 14;
				}

				// Draw checkmark
				if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) && (*itemFlags & 1)) {
					x = 2;
					RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = colour == 14 ? -2 : -1;
					colour2 = w->colours[1] & 0x7F;
					if (*itemFlags & 0x1C)
						colour2 |= 0x40;

					gfx_draw_string(dpi, (char*)0x009DED72, colour2, x, y);
				}

				// Draw text
				char *buffer = (char*)0x0141ED68;
				*buffer = colour;
				strcpy(buffer + 1, object_get_name(entry));
				if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) {
					while (*buffer != 0 && *buffer != 9)
						buffer++;

					*buffer = 0;
				}

				if (*itemFlags & 0x20) {
					colour = w->colours[1] & 0x7F;
					RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = -1;
				} else {
					colour = 0;
					RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = 224;
				}
				x = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER ? 0 : 15;
				gfx_draw_string(dpi, (char*)0x0141ED68, colour, x, y);
			}
			y += 12;
		}

		entry = object_get_next(entry);
		itemFlags++;
	}
}