Ejemplo n.º 1
0
/**
 * Sort selected range of items (on indices @ <begin, begin+num_items-1>)
 * @param el list to be sorted
 * @param compare function for evaluation of the quicksort
 * @param begin start of sorting
 * @param num_items count of items to be sorted
 */
void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items)
{
	if (num_items < 2) return;
	assert(begin < el->Length());
	assert(begin + num_items <= el->Length());
	QSortT(el->Get(begin), num_items, compare);
}
Ejemplo n.º 2
0
/**
 * Save the highscores in a network game when it has ended
 * @return Position of the local company in the highscore list.
 */
int8 SaveHighScoreValueNetwork()
{
	const Company *c;
	const Company *cl[MAX_COMPANIES];
	uint count = 0;
	int8 company = -1;

	/* Sort all active companies with the highest score first */
	FOR_ALL_COMPANIES(c) cl[count++] = c;

	QSortT(cl, count, &HighScoreSorter);

	{
		uint i;

		memset(_highscore_table[SP_MULTIPLAYER], 0, sizeof(_highscore_table[SP_MULTIPLAYER]));

		/* Copy over Top5 companies */
		for (i = 0; i < lengthof(_highscore_table[SP_MULTIPLAYER]) && i < count; i++) {
			HighScore *hs = &_highscore_table[SP_MULTIPLAYER][i];

			SetDParam(0, cl[i]->index);
			SetDParam(1, cl[i]->index);
			GetString(hs->company, STR_HIGHSCORE_NAME, lastof(hs->company)); // get manager/company name string
			hs->score = cl[i]->old_economy[0].performance_history;
			hs->title = EndGameGetPerformanceTitleFromValue(hs->score);

			/* get the ranking of the local company */
			if (cl[i]->index == _local_company) company = i;
		}
	}

	/* Add top5 companies to highscore table */
	return company;
}
Ejemplo n.º 3
0
static void MakeSortedSaveGameList()
{
    uint sort_start = 0;
    uint sort_end = 0;

    /* Directories are always above the files (FIOS_TYPE_DIR)
     * Drives (A:\ (windows only) are always under the files (FIOS_TYPE_DRIVE)
     * Only sort savegames/scenarios, not directories
     */
    for (const FiosItem *item = _fios_items.Begin(); item != _fios_items.End(); item++) {
        switch (item->type) {
        case FIOS_TYPE_DIR:
            sort_start++;
            break;
        case FIOS_TYPE_PARENT:
            sort_start++;
            break;
        case FIOS_TYPE_DRIVE:
            sort_end++;
            break;
        default:
            break;
        }
    }

    uint s_amount = _fios_items.Length() - sort_start - sort_end;
    QSortT(_fios_items.Get(sort_start), s_amount, CompareFiosItems);
}
Ejemplo n.º 4
0
/**
 * Sort all items using quick sort and given 'CompareItems' function
 * @param el list to be sorted
 * @param compare function for evaluation of the quicksort
 */
void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare)
{
	uint size = el->Length();
	/* out-of-bounds access at the next line for size == 0 (even with operator[] at some systems)
	 * generally, do not sort if there are less than 2 items */
	if (size < 2) return;
	QSortT(el->Begin(), size, compare);
}
Ejemplo n.º 5
0
/**
 * Really perform the scan for all NewGRFs.
 * @param callback The callback to call after the scanning is complete.
 */
void DoScanNewGRFFiles(void *callback)
{
	_modal_progress_work_mutex->BeginCritical();

	ClearGRFConfigList(&_all_grfs);
	TarScanner::DoScan(TarScanner::NEWGRF);

	DEBUG(grf, 1, "Scanning for NewGRFs");
	uint num = GRFFileScanner::DoScan();

	DEBUG(grf, 1, "Scan complete, found %d files", num);
	if (num != 0 && _all_grfs != NULL) {
		/* Sort the linked list using quicksort.
		 * For that we first have to make an array, then sort and
		 * then remake the linked list. */
		GRFConfig **to_sort = MallocT<GRFConfig*>(num);

		uint i = 0;
		for (GRFConfig *p = _all_grfs; p != NULL; p = p->next, i++) {
			to_sort[i] = p;
		}
		/* Number of files is not necessarily right */
		num = i;

		QSortT(to_sort, num, &GRFSorter);

		for (i = 1; i < num; i++) {
			to_sort[i - 1]->next = to_sort[i];
		}
		to_sort[num - 1]->next = NULL;
		_all_grfs = to_sort[0];

		free(to_sort);

#ifdef ENABLE_NETWORK
		NetworkAfterNewGRFScan();
#endif
	}

	_modal_progress_work_mutex->EndCritical();
	_modal_progress_paint_mutex->BeginCritical();

	/* Yes... these are the NewGRF windows */
	InvalidateWindowClassesData(WC_SAVELOAD, 0, true);
	InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE, GOID_NEWGRF_RESCANNED, true);
	if (callback != NULL) ((NewGRFScanCallback*)callback)->OnNewGRFsScanned();

	DeleteWindowByClass(WC_MODAL_PROGRESS);
	SetModalProgress(false);
	MarkWholeScreenDirty();
	_modal_progress_paint_mutex->EndCritical();
}
Ejemplo n.º 6
0
/**
 * Set the start date of the timetable.
 * @param tile Not used.
 * @param flags Operation to perform.
 * @param p2 Various bitstuffed elements
 * - p2 = (bit 0-19) - Vehicle ID.
 * - p2 = (bit 20)   - Set to 1 to set timetable start for all vehicles sharing this order
 * @param p2 The timetable start date.
 * @param text Not used.
 * @return The error or cost of the operation.
 */
CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
    bool timetable_all = HasBit(p1, 20);
    Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20));
    if (v == NULL || !v->IsPrimaryVehicle() || v->orders.list == NULL) return CMD_ERROR;

    CommandCost ret = CheckOwnership(v->owner);
    if (ret.Failed()) return ret;

    /* Don't let a timetable start more than 15 years into the future or 1 year in the past. */
    Date start_date = (Date)p2;
    if (start_date < 0 || start_date > MAX_DAY) return CMD_ERROR;
    if (start_date - _date > 15 * DAYS_IN_LEAP_YEAR) return CMD_ERROR;
    if (_date - start_date > DAYS_IN_LEAP_YEAR) return CMD_ERROR;
    if (timetable_all && !v->orders.list->IsCompleteTimetable()) return CMD_ERROR;

    if (flags & DC_EXEC) {
        SmallVector<Vehicle *, 8> vehs;

        if (timetable_all) {
            for (Vehicle *w = v->orders.list->GetFirstSharedVehicle(); w != NULL; w = w->NextShared()) {
                *vehs.Append() = w;
            }
        } else {
            *vehs.Append() = v;
        }

        int total_duration = v->orders.list->GetTimetableTotalDuration();
        int num_vehs = vehs.Length();

        if (num_vehs >= 2) {
            QSortT(vehs.Begin(), vehs.Length(), &VehicleTimetableSorter);
        }

        int base = vehs.FindIndex(v);

        for (Vehicle **viter = vehs.Begin(); viter != vehs.End(); viter++) {
            int idx = (viter - vehs.Begin()) - base;
            Vehicle *w = *viter;

            w->lateness_counter = 0;
            ClrBit(w->vehicle_flags, VF_TIMETABLE_STARTED);
            /* Do multiplication, then division to reduce rounding errors. */
            w->timetable_start = start_date + idx * total_duration / num_vehs / DAY_TICKS;
            SetWindowDirty(WC_VEHICLE_TIMETABLE, w->index);
        }

    }

    return CommandCost();
}
Ejemplo n.º 7
0
/** Initialize the list of sorted cargo specifications. */
void InitializeSortedCargoSpecs()
{
	_sorted_cargo_specs_size = 0;
	const CargoSpec *cargo;
	/* Add each cargo spec to the list. */
	FOR_ALL_CARGOSPECS(cargo) {
		_sorted_cargo_specs[_sorted_cargo_specs_size] = cargo;
		_sorted_cargo_specs_size++;
	}

	/* Sort cargo specifications by cargo class and name. */
	QSortT(_sorted_cargo_specs, _sorted_cargo_specs_size, &CargoSpecClassSorter);

	_sorted_standard_cargo_specs_size = 0;
	FOR_ALL_SORTED_CARGOSPECS(cargo) {
		if (cargo->classes & CC_SPECIAL) break;
		_sorted_standard_cargo_specs_size++;
	}
}
/** Scan for all NewGRFs. */
void ScanNewGRFFiles()
{
	ClearGRFConfigList(&_all_grfs);

	TarScanner::DoScan();

	DEBUG(grf, 1, "Scanning for NewGRFs");
	uint num = GRFFileScanner::DoScan();

	DEBUG(grf, 1, "Scan complete, found %d files", num);
	if (num == 0 || _all_grfs == NULL) return;

	/* Sort the linked list using quicksort.
	 * For that we first have to make an array, then sort and
	 * then remake the linked list. */
	GRFConfig **to_sort = MallocT<GRFConfig*>(num);

	uint i = 0;
	for (GRFConfig *p = _all_grfs; p != NULL; p = p->next, i++) {
		to_sort[i] = p;
	}
	/* Number of files is not necessarily right */
	num = i;

	QSortT(to_sort, num, &GRFSorter);

	for (i = 1; i < num; i++) {
		to_sort[i - 1]->next = to_sort[i];
	}
	to_sort[num - 1]->next = NULL;
	_all_grfs = to_sort[0];

	free(to_sort);

#ifdef ENABLE_NETWORK
	NetworkAfterNewGRFScan();
#endif
}
	FORCEINLINE void SortByKey()
	{
		QSortT(this->Begin(), this->items, KeySorter);
	}
Ejemplo n.º 10
0
	inline void SortByKey()
	{
		QSortT(this->Begin(), this->items, KeySorter);
	}
Ejemplo n.º 11
0
/**
 * Try to add a fios item set with the given filename.
 * @param filename        the full path to the file to read
 * @param basepath_length amount of characters to chop of before to get a relative filename
 * @return true if the file is added.
 */
bool FiosFileScanner::AddFile(const char *filename, size_t basepath_length, const char *tar_filename)
{
	const char *ext = strrchr(filename, '.');
	if (ext == NULL) return false;

	char fios_title[64];
	fios_title[0] = '\0'; // reset the title;

	FiosType type = this->callback_proc(this->mode, filename, ext, fios_title, lastof(fios_title));
	if (type == FIOS_TYPE_INVALID) return false;

	for (const FiosItem *fios = _fios_items.Begin(); fios != _fios_items.End(); fios++) {
		if (strcmp(fios->name, filename) == 0) return false;
	}

	FiosItem *fios = _fios_items.Append();
#ifdef WIN32
	struct _stat sb;
	if (_tstat(OTTD2FS(filename), &sb) == 0) {
#else
	struct stat sb;
	if (stat(filename, &sb) == 0) {
#endif
		fios->mtime = sb.st_mtime;
	} else {
		fios->mtime = 0;
	}

	fios->type = type;
	strecpy(fios->name, filename, lastof(fios->name));

	/* If the file doesn't have a title, use its filename */
	const char *t = fios_title;
	if (StrEmpty(fios_title)) {
		t = strrchr(filename, PATHSEPCHAR);
		t = (t == NULL) ? filename : (t + 1);
	}
	strecpy(fios->title, t, lastof(fios->title));
	str_validate(fios->title, lastof(fios->title));

	return true;
}


/**
 * Fill the list of the files in a directory, according to some arbitrary rule.
 *  @param mode The mode we are in. Some modes don't allow 'parent'.
 *  @param callback_proc The function that is called where you need to do the filtering.
 *  @param subdir The directory from where to start (global) searching.
 */
static void FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_proc *callback_proc, Subdirectory subdir)
{
	struct stat sb;
	struct dirent *dirent;
	DIR *dir;
	FiosItem *fios;
	int sort_start;
	char d_name[sizeof(fios->name)];

	_fios_items.Clear();

	/* A parent directory link exists if we are not in the root directory */
	if (!FiosIsRoot(_fios_path)) {
		fios = _fios_items.Append();
		fios->type = FIOS_TYPE_PARENT;
		fios->mtime = 0;
		strecpy(fios->name, "..", lastof(fios->name));
		strecpy(fios->title, ".. (Parent directory)", lastof(fios->title));
	}

	/* Show subdirectories */
	if ((dir = ttd_opendir(_fios_path)) != NULL) {
		while ((dirent = readdir(dir)) != NULL) {
			strecpy(d_name, FS2OTTD(dirent->d_name), lastof(d_name));

			/* found file must be directory, but not '.' or '..' */
			if (FiosIsValidFile(_fios_path, dirent, &sb) && S_ISDIR(sb.st_mode) &&
					(!FiosIsHiddenFile(dirent) || strncasecmp(d_name, PERSONAL_DIR, strlen(d_name)) == 0) &&
					strcmp(d_name, ".") != 0 && strcmp(d_name, "..") != 0) {
				fios = _fios_items.Append();
				fios->type = FIOS_TYPE_DIR;
				fios->mtime = 0;
				strecpy(fios->name, d_name, lastof(fios->name));
				snprintf(fios->title, lengthof(fios->title), "%s" PATHSEP " (Directory)", d_name);
				str_validate(fios->title, lastof(fios->title));
			}
		}
		closedir(dir);
	}

	/* Sort the subdirs always by name, ascending, remember user-sorting order */
	{
		SortingBits order = _savegame_sort_order;
		_savegame_sort_order = SORT_BY_NAME | SORT_ASCENDING;
		QSortT(_fios_items.Begin(), _fios_items.Length(), CompareFiosItems);
		_savegame_sort_order = order;
	}

	/* This is where to start sorting for the filenames */
	sort_start = _fios_items.Length();

	/* Show files */
	FiosFileScanner scanner(mode, callback_proc);
	if (subdir == NO_DIRECTORY) {
		scanner.Scan(NULL, _fios_path, false);
	} else {
		scanner.Scan(NULL, subdir, true, true);
	}

	QSortT(_fios_items.Get(sort_start), _fios_items.Length() - sort_start, CompareFiosItems);

	/* Show drives */
	FiosGetDrives();

	_fios_items.Compact();
}

/**
 * Get the title of a file, which (if exists) is stored in a file named
 * the same as the data file but with '.title' added to it.
 * @param file filename to get the title for
 * @param title the title buffer to fill
 * @param last the last element in the title buffer
 * @param subdir the sub directory to search in
 */
static void GetFileTitle(const char *file, char *title, const char *last, Subdirectory subdir)
{
	char buf[MAX_PATH];
	strecpy(buf, file, lastof(buf));
	strecat(buf, ".title", lastof(buf));

	FILE *f = FioFOpenFile(buf, "r", subdir);
	if (f == NULL) return;

	size_t read = fread(title, 1, last - title, f);
	assert(title + read <= last);
	title[read] = '\0';
	str_validate(title, last);
	FioFCloseFile(f);
}