Ejemplo n.º 1
0
/**
 * Resizes the pool so 'index' can be addressed
 * @param index index we will allocate later
 * @pre index >= this->size
 * @pre index < Tmax_size
 */
DEFINE_POOL_METHOD(inline void)::ResizeFor(size_t index)
{
	assert(index >= this->size);
	assert(index < Tmax_size);

	size_t new_size = ::min(Tmax_size, Align(index + 1, Tgrowth_step));

	this->data = ReallocT(this->data, new_size);
	MemSetT(this->data + this->size, 0, new_size - this->size);

	this->size = new_size;
}
Ejemplo n.º 2
0
/**
 * Begin a paste process.
 * @param flags Flags for the command.
 * @param params What, where and how to paste.
 */
static void InitializePasting(DoCommandFlag flags, const CopyPasteParams &params)
{
	assert(_current_pasting == NULL);
	_current_pasting = new PastingState;

	_current_pasting->dc_flags    = flags | DC_PASTE;
	_current_pasting->overal_cost = 0;
	_current_pasting->had_success = false;
	_current_pasting->err_summary = STR_ERROR_CAN_T_PASTE_HERE;
	_current_pasting->err_message = STR_ERROR_NOTHING_TO_DO;
	MemSetT(_current_pasting->err_params, 0, lengthof(_current_pasting->err_params));
	_current_pasting->err_tile    = INVALID_TILE;
	_current_pasting->last_result = CommandCost(STR_ERROR_NOTHING_TO_DO);
}
Ejemplo n.º 3
0
/**
 * Save a custom playlist to settings after modification.
 * @param pl Playlist to store back
 */
void MusicSystem::SaveCustomPlaylist(PlaylistChoices pl)
{
	byte *settings_pl;
	if (pl == PLCH_CUSTOM1) {
		settings_pl = _settings_client.music.custom_1;
	} else if (pl == PLCH_CUSTOM2) {
		settings_pl = _settings_client.music.custom_2;
	} else {
		return;
	}

	size_t num = 0;
	MemSetT(settings_pl, 0, NUM_SONGS_PLAYLIST);

	for (Playlist::const_iterator song = this->standard_playlists[pl].begin(); song != this->standard_playlists[pl].end(); ++song) {
		/* Music set indices in the settings playlist are 1-based, 0 means unused slot */
		settings_pl[num++] = (byte)song->set_index + 1;
	}
}
Ejemplo n.º 4
0
/**
 * Makes given index valid
 * @param size size of item
 * @param index index of item
 * @pre index < this->size
 * @pre this->Get(index) == NULL
 */
DEFINE_POOL_METHOD(inline void *)::AllocateItem(size_t size, size_t index)
{
	assert(this->data[index] == NULL);

	this->first_unused = ::max(this->first_unused, index + 1);
	this->items++;

	Titem *item;
	if (Tcache && this->alloc_cache != NULL) {
		assert(sizeof(Titem) == size);
		item = (Titem *)this->alloc_cache;
		this->alloc_cache = this->alloc_cache->next;
		if (Tzero) MemSetT(item, 0);
	} else if (Tzero) {
		item = (Titem *)CallocT<byte>(size);
	} else {
		item = (Titem *)MallocT<byte>(size);
	}
	this->data[index] = item;
	item->index = (uint)index;
	return item;
}
Ejemplo n.º 5
0
void DisplaySplashImage()
{
    FILE *f = FioFOpenFile(SPLASH_IMAGE_FILE);
    if (f == NULL) return;

    png_byte header[8];
    fread(header, sizeof(png_byte), 8, f);
    if (png_sig_cmp(header, 0, 8) != 0) {
        fclose(f);
        return;
    }

    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, png_my_error, png_my_warning);

    if (png_ptr == NULL) {
        fclose(f);
        return;
    }

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
        png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
        fclose(f);
        return;
    }

    png_infop end_info = png_create_info_struct(png_ptr);
    if (end_info == NULL) {
        png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
        fclose(f);
        return;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        fclose(f);
        return;
    }

    png_init_io(png_ptr, f);
    png_set_sig_bytes(png_ptr, 8);

    png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

    uint width      = png_get_image_width(png_ptr, info_ptr);
    uint height     = png_get_image_height(png_ptr, info_ptr);
    uint bit_depth  = png_get_bit_depth(png_ptr, info_ptr);
    uint color_type = png_get_color_type(png_ptr, info_ptr);

    if (color_type != PNG_COLOR_TYPE_PALETTE || bit_depth != 8) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        fclose(f);
        return;
    }

    if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        fclose(f);
        return;
    }

    png_colorp palette;
    int num_palette;
    png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);

    png_bytep *row_pointers = png_get_rows(png_ptr, info_ptr);

    if (width > (uint) _screen.width) width = _screen.width;
    if (height > (uint) _screen.height) height = _screen.height;

    uint xoff = (_screen.width - width) / 2;
    uint yoff = (_screen.height - height) / 2;

    switch (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth()) {
    case 8: {
        uint8 *dst_ptr = (uint8 *)_screen.dst_ptr;
        /* Initialize buffer */
        MemSetT(dst_ptr, 0xff, _screen.pitch * _screen.height);

        for (uint y = 0; y < height; y++) {
            uint8 *src = row_pointers[y];
            uint8 *dst = dst_ptr + (yoff + y) * _screen.pitch + xoff;

            memcpy(dst, src, width);
        }

        for (int i = 0; i < num_palette; i++) {
            _cur_palette[i].a = i == 0 ? 0 : 0xff;
            _cur_palette[i].r = palette[i].red;
            _cur_palette[i].g = palette[i].green;
            _cur_palette[i].b = palette[i].blue;
        }

        _cur_palette[0xff].a = 0xff;
        _cur_palette[0xff].r = 0;
        _cur_palette[0xff].g = 0;
        _cur_palette[0xff].b = 0;

        _pal_first_dirty = 0;
        _pal_count_dirty = 256;
        break;
    }
    case 32: {
        uint32 *dst_ptr = (uint32 *)_screen.dst_ptr;
        /* Initialize buffer */
        MemSetT(dst_ptr, 0, _screen.pitch * _screen.height);

        for (uint y = 0; y < height; y++) {
            uint8 *src = row_pointers[y];
            uint32 *dst = dst_ptr + (yoff + y) * _screen.pitch + xoff;

            for (uint x = 0; x < width; x++) {
                dst[x] = palette[src[x]].blue | (palette[src[x]].green << 8) | (palette[src[x]].red << 16) | 0xff000000;
            }
        }
        break;
    }
    }

    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    fclose(f);
    return;
}
Ejemplo n.º 6
0
/**
 * Save the Ini file's data to the disk.
 * @param filename the file to save to.
 * @return true if saving succeeded.
 */
bool IniFile::SaveToDisk(const char *filename)
{
	/*
	 * First write the configuration to a (temporary) file and then rename
	 * that file. This to prevent that when OpenTTD crashes during the save
	 * you end up with a truncated configuration file.
	 */
	char file_new[MAX_PATH];

	strecpy(file_new, filename, lastof(file_new));
	strecat(file_new, ".new", lastof(file_new));
	FILE *f = fopen(file_new, "w");
	if (f == NULL) return false;

	for (const IniGroup *group = this->group; group != NULL; group = group->next) {
		if (group->comment) fputs(group->comment, f);
		fprintf(f, "[%s]\n", group->name);
		for (const IniItem *item = group->item; item != NULL; item = item->next) {
			if (item->comment != NULL) fputs(item->comment, f);

			/* protect item->name with quotes if needed */
			if (strchr(item->name, ' ') != NULL ||
					item->name[0] == '[') {
				fprintf(f, "\"%s\"", item->name);
			} else {
				fprintf(f, "%s", item->name);
			}

			fprintf(f, " = %s\n", item->value == NULL ? "" : item->value);
		}
	}
	if (this->comment) fputs(this->comment, f);

/*
 * POSIX (and friends) do not guarantee that when a file is closed it is
 * flushed to the disk. So we manually flush it do disk if we have the
 * APIs to do so. We only need to flush the data as the metadata itself
 * (modification date etc.) is not important to us; only the real data is.
 */
#ifdef WITH_FDATASYNC
	int ret = fdatasync(fileno(f));
	fclose(f);
	if (ret != 0) return false;
#else
	fclose(f);
#endif

#if defined(WIN32) || defined(WIN64)
	/* _tcsncpy = strcpy is TCHAR is char, but isn't when TCHAR is wchar. */
	#undef strncpy
	/* Allocate space for one more \0 character. */
	TCHAR tfilename[MAX_PATH + 1], tfile_new[MAX_PATH + 1];
	_tcsncpy(tfilename, OTTD2FS(filename), MAX_PATH);
	_tcsncpy(tfile_new, OTTD2FS(file_new), MAX_PATH);
	/* SHFileOperation wants a double '\0' terminated string. */
	tfilename[MAX_PATH - 1] = '\0';
	tfile_new[MAX_PATH - 1] = '\0';
	tfilename[_tcslen(tfilename) + 1] = '\0';
	tfile_new[_tcslen(tfile_new) + 1] = '\0';

	/* Rename file without any user confirmation. */
	SHFILEOPSTRUCT shfopt;
	MemSetT(&shfopt, 0);
	shfopt.wFunc  = FO_MOVE;
	shfopt.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI | FOF_SILENT;
	shfopt.pFrom  = tfile_new;
	shfopt.pTo    = tfilename;
	SHFileOperation(&shfopt);
#else
	if (rename(file_new, filename) < 0) {
		DEBUG(misc, 0, "Renaming %s to %s failed; configuration not saved", file_new, filename);
	}
#endif

	return true;
}
Ejemplo n.º 7
0
/**
 * Additional map variety is provided by applying different curve maps
 * to different parts of the map. A randomized low resolution grid contains
 * which curve map to use on each part of the make. This filtered non-linearly
 * to smooth out transitions between curves, so each tile could have between
 * 100% of one map applied or 25% of four maps.
 *
 * The curve maps define different land styles, i.e. lakes, low-lands, hills
 * and mountain ranges, although these are dependent on the landscape style
 * chosen as well.
 *
 * The level parameter dictates the resolution of the grid. A low resolution
 * grid will result in larger continuous areas of a land style, a higher
 * resolution grid splits the style into smaller areas.
 * @param level Rough indication of the size of the grid sections to style. Small level means large grid sections.
 */
static void HeightMapCurves(uint level)
{
	height_t mh = TGPGetMaxHeight() - I2H(1); // height levels above sea level only

	/** Basically scale height X to height Y. Everything in between is interpolated. */
	struct control_point_t {
		height_t x; ///< The height to scale from.
		height_t y; ///< The height to scale to.
	};
	/* Scaled curve maps; value is in height_ts. */
#define F(fraction) ((height_t)(fraction * mh))
	const control_point_t curve_map_1[] = { { F(0.0), F(0.0) },                       { F(0.8), F(0.13) },                       { F(1.0), F(0.4)  } };
	const control_point_t curve_map_2[] = { { F(0.0), F(0.0) }, { F(0.53), F(0.13) }, { F(0.8), F(0.27) },                       { F(1.0), F(0.6)  } };
	const control_point_t curve_map_3[] = { { F(0.0), F(0.0) }, { F(0.53), F(0.27) }, { F(0.8), F(0.57) },                       { F(1.0), F(0.8)  } };
	const control_point_t curve_map_4[] = { { F(0.0), F(0.0) }, { F(0.4),  F(0.3)  }, { F(0.7), F(0.8)  }, { F(0.92), F(0.99) }, { F(1.0), F(0.99) } };
#undef F

	/** Helper structure to index the different curve maps. */
	struct control_point_list_t {
		size_t length;               ///< The length of the curve map.
		const control_point_t *list; ///< The actual curve map.
	};
	const control_point_list_t curve_maps[] = {
		{ lengthof(curve_map_1), curve_map_1 },
		{ lengthof(curve_map_2), curve_map_2 },
		{ lengthof(curve_map_3), curve_map_3 },
		{ lengthof(curve_map_4), curve_map_4 },
	};

	height_t ht[lengthof(curve_maps)];
	MemSetT(ht, 0, lengthof(ht));

	/* Set up a grid to choose curve maps based on location; attempt to get a somewhat square grid */
	float factor = sqrt((float)_height_map.size_x / (float)_height_map.size_y);
	uint sx = Clamp((int)(((1 << level) * factor) + 0.5), 1, 128);
	uint sy = Clamp((int)(((1 << level) / factor) + 0.5), 1, 128);
	byte *c = AllocaM(byte, sx * sy);

	for (uint i = 0; i < sx * sy; i++) {
		c[i] = Random() % lengthof(curve_maps);
	}

	/* Apply curves */
	for (int x = 0; x < _height_map.size_x; x++) {

		/* Get our X grid positions and bi-linear ratio */
		float fx = (float)(sx * x) / _height_map.size_x + 1.0f;
		uint x1 = (uint)fx;
		uint x2 = x1;
		float xr = 2.0f * (fx - x1) - 1.0f;
		xr = sin(xr * M_PI_2);
		xr = sin(xr * M_PI_2);
		xr = 0.5f * (xr + 1.0f);
		float xri = 1.0f - xr;

		if (x1 > 0) {
			x1--;
			if (x2 >= sx) x2--;
		}

		for (int y = 0; y < _height_map.size_y; y++) {

			/* Get our Y grid position and bi-linear ratio */
			float fy = (float)(sy * y) / _height_map.size_y + 1.0f;
			uint y1 = (uint)fy;
			uint y2 = y1;
			float yr = 2.0f * (fy - y1) - 1.0f;
			yr = sin(yr * M_PI_2);
			yr = sin(yr * M_PI_2);
			yr = 0.5f * (yr + 1.0f);
			float yri = 1.0f - yr;

			if (y1 > 0) {
				y1--;
				if (y2 >= sy) y2--;
			}

			uint corner_a = c[x1 + sx * y1];
			uint corner_b = c[x1 + sx * y2];
			uint corner_c = c[x2 + sx * y1];
			uint corner_d = c[x2 + sx * y2];

			/* Bitmask of which curve maps are chosen, so that we do not bother
			 * calculating a curve which won't be used. */
			uint corner_bits = 0;
			corner_bits |= 1 << corner_a;
			corner_bits |= 1 << corner_b;
			corner_bits |= 1 << corner_c;
			corner_bits |= 1 << corner_d;

			height_t *h = &_height_map.height(x, y);

			/* Do not touch sea level */
			if (*h < I2H(1)) continue;

			/* Only scale above sea level */
			*h -= I2H(1);

			/* Apply all curve maps that are used on this tile. */
			for (uint t = 0; t < lengthof(curve_maps); t++) {
				if (!HasBit(corner_bits, t)) continue;

				bool found = false;
				const control_point_t *cm = curve_maps[t].list;
				for (uint i = 0; i < curve_maps[t].length - 1; i++) {
					const control_point_t &p1 = cm[i];
					const control_point_t &p2 = cm[i + 1];

					if (*h >= p1.x && *h < p2.x) {
						ht[t] = p1.y + (*h - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
						found = true;
						break;
					}
				}
				assert(found);
			}

			/* Apply interpolation of curve map results. */
			*h = (height_t)((ht[corner_a] * yri + ht[corner_b] * yr) * xri + (ht[corner_c] * yri + ht[corner_d] * yr) * xr);

			/* Readd sea level */
			*h += I2H(1);
		}
	}
}
Ejemplo n.º 8
0
static void HeightMapCurves(uint level)
{
	height_t ht[lengthof(_curve_maps)];
	MemSetT(ht, 0, lengthof(ht));

	/* Set up a grid to choose curve maps based on location */
	uint sx = Clamp(1 << level, 2, 32);
	uint sy = Clamp(1 << level, 2, 32);
	byte *c = AllocaM(byte, sx * sy);

	for (uint i = 0; i < sx * sy; i++) {
		c[i] = Random() % lengthof(_curve_maps);
	}

	/* Apply curves */
	for (uint x = 0; x < _height_map.size_x; x++) {

		/* Get our X grid positions and bi-linear ratio */
		float fx = (float)(sx * x) / _height_map.size_x + 0.5f;
		uint x1 = (uint)fx;
		uint x2 = x1;
		float xr = 2.0f * (fx - x1) - 1.0f;
		xr = sin(xr * M_PI_2);
		xr = sin(xr * M_PI_2);
		xr = 0.5f * (xr + 1.0f);
		float xri = 1.0f - xr;

		if (x1 > 0) {
			x1--;
			if (x2 >= sx) x2--;
		}

		for (uint y = 0; y < _height_map.size_y; y++) {

			/* Get our Y grid position and bi-linear ratio */
			float fy = (float)(sy * y) / _height_map.size_y + 0.5f;
			uint y1 = (uint)fy;
			uint y2 = y1;
			float yr = 2.0f * (fy - y1) - 1.0f;
			yr = sin(yr * M_PI_2);
			yr = sin(yr * M_PI_2);
			yr = 0.5f * (yr + 1.0f);
			float yri = 1.0f - yr;

			if (y1 > 0) {
				y1--;
				if (y2 >= sy) y2--;
			}

			uint corner_a = c[x1 + sx * y1];
			uint corner_b = c[x1 + sx * y2];
			uint corner_c = c[x2 + sx * y1];
			uint corner_d = c[x2 + sx * y2];

			/* Bitmask of which curve maps are chosen, so that we do not bother
			 * calculating a curve which won't be used. */
			uint corner_bits = 0;
			corner_bits |= 1 << corner_a;
			corner_bits |= 1 << corner_b;
			corner_bits |= 1 << corner_c;
			corner_bits |= 1 << corner_d;

			height_t *h = &_height_map.height(x, y);

			/* Apply all curve maps that are used on this tile. */
			for (uint t = 0; t < lengthof(_curve_maps); t++) {
				if (!HasBit(corner_bits, t)) continue;

				const control_point_t *cm = _curve_maps[t].list;
				for (uint i = 0; i < _curve_maps[t].length - 1; i++) {
					const control_point_t &p1 = cm[i];
					const control_point_t &p2 = cm[i + 1];

					if (*h >= p1.x && *h < p2.x) {
						ht[t] = p1.y + (*h - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
						break;
					}
				}
			}

			/* Apply interpolation of curve map results. */
			*h = (height_t)((ht[corner_a] * yri + ht[corner_b] * yr) * xri + (ht[corner_c] * yri + ht[corner_d] * yr) * xr);
		}
	}
}
/* Allocate a new Sound */
SoundEntry *AllocateSound()
{
	SoundEntry *sound = _sounds.Append();
	MemSetT(sound, 0);
	return sound;
}