static void setup_wav_header(snd_pcm_t *pcm, struct wav_fmt *fmt)
{
	fmt->fmt = TO_LE16(0x01);
	fmt->chan = TO_LE16(pcm->channels);
	fmt->rate = TO_LE32(pcm->rate);
	fmt->bwidth = pcm->frame_bits / 8;
	fmt->bps = fmt->bwidth * pcm->rate;
	fmt->bits = snd_pcm_format_width(pcm->format);
	fmt->bps = TO_LE32(fmt->bps);
	fmt->bwidth = TO_LE16(fmt->bwidth);
	fmt->bits = TO_LE16(fmt->bits);
}
Example #2
0
static void dumpResource(FILE *fp, int type, int index, const ResourceEntry *re) {
	fprintf(stdout, "Resource size %d flags 0x%x id 0x%x type 0x%x\n", re->size, re->flags, re->id, type);
	FILE *out;

	char name[32];
	snprintf(name, sizeof(name), "%s%d", resourceTypeName(type), index);

	const int pos = ftell(fp);
	fseek(fp, re->offset, SEEK_SET);

	uint8_t *buf = (uint8_t *)malloc(re->size);
	if (buf) {
		fread(buf, 1, re->size, fp);

		switch (type) {
		case kResTypeIcon:
			out = fopen(name, "wb");
			if (out) {
					// icons are stored with DIB header
				uint8_t header[BITMAPFILEHEADER_SIZE];

				header[0] = 'B'; header[1] = 'M';
				TO_LE32(header + 2, BITMAPFILEHEADER_SIZE + re->size);
				TO_LE16(header + 6, 0);
				TO_LE16(header + 8, 0);
				TO_LE32(header + 10, BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE + 16 * 4);

				fwrite(header, 1, sizeof(header), out);

				// Fixup dimensions to 32x32, the lower 32 rows contain garbage
				if (buf[0] == 40 && buf[4] == 32 && buf[8] == 64) {
					fprintf(stdout, "Fixing up dimensions to 32x32\n");
					buf[8] = 32;
				}

				fwrite(buf, 1, re->size, out);
				fclose(out);
			}
			break;
		case kResTypeData:
			out = fopen(name, "wb");
			if (out) {
				fwrite(buf, 1, re->size, out);
				fclose(out);
			}
			break;
		}
		free(buf);
	}
	fseek(fp, pos, SEEK_SET);
}
Example #3
0
DEF_UDP_RECEIVE_COMMAND(Client, PACKET_UDP_MASTER_RESPONSE_LIST)
{
	/* packet begins with the protocol version (uint8)
	 * then an uint16 which indicates how many
	 * ip:port pairs are in this packet, after that
	 * an uint32 (ip) and an uint16 (port) for each pair.
	 */

	ServerListType type = (ServerListType)(p->Recv_uint8() - 1);

	if (type < SLT_END) {
		for (int i = p->Recv_uint16(); i != 0 ; i--) {
			sockaddr_storage addr_storage;
			memset(&addr_storage, 0, sizeof(addr_storage));

			if (type == SLT_IPv4) {
				addr_storage.ss_family = AF_INET;
				((sockaddr_in*)&addr_storage)->sin_addr.s_addr = TO_LE32(p->Recv_uint32());
			} else {
				assert(type == SLT_IPv6);
				addr_storage.ss_family = AF_INET6;
				byte *addr = (byte*)&((sockaddr_in6*)&addr_storage)->sin6_addr;
				for (uint i = 0; i < sizeof(in6_addr); i++) *addr++ = p->Recv_uint8();
			}
			NetworkAddress addr(addr_storage, type == SLT_IPv4 ? sizeof(sockaddr_in) : sizeof(sockaddr_in6));
			addr.SetPort(p->Recv_uint16());

			/* Somehow we reached the end of the packet */
			if (this->HasClientQuit()) return;

			NetworkUDPQueryServer(addr);
		}
	}
}
/* fix up the length fields in WAV header */
static void fixup_wav_header(snd_pcm_t *pcm)
{
	snd_pcm_file_t *file = pcm->private_data;
	int len, ret;

	/* RIFF length */
	if (lseek(file->fd, 4, SEEK_SET) == 4) {
		len = (file->filelen + 0x24) > 0x7fffffff ?
			0x7fffffff : (int)(file->filelen + 0x24);
		len = TO_LE32(len);
		ret = write(file->fd, &len, 4);
		if (ret < 0)
			return;
	}
	/* data length */
	if (lseek(file->fd, 0x28, SEEK_SET) == 0x28) {
		len = file->filelen > 0x7fffffff ?
			0x7fffffff : (int)file->filelen;
		len = TO_LE32(len);
		ret = write(file->fd, &len, 4);
		if (ret < 0)
			return;
	}
}
Example #5
0
/**
 * Generic .BMP writer
 * @param name file name including extension
 * @param callb callback used for gathering rendered image
 * @param userdata parameters forwarded to \a callb
 * @param w width in pixels
 * @param h height in pixels
 * @param pixelformat bits per pixel
 * @param palette colour palette (for 8bpp mode)
 * @return was everything ok?
 * @see ScreenshotHandlerProc
 */
static bool MakeBMPImage(const char *name, ScreenshotCallback *callb, void *userdata, uint w, uint h, int pixelformat, const Colour *palette)
{
	uint bpp; // bytes per pixel
	switch (pixelformat) {
		case 8:  bpp = 1; break;
		/* 32bpp mode is saved as 24bpp BMP */
		case 32: bpp = 3; break;
		/* Only implemented for 8bit and 32bit images so far */
		default: return false;
	}

	FILE *f = fopen(name, "wb");
	if (f == NULL) return false;

	/* Each scanline must be aligned on a 32bit boundary */
	uint bytewidth = Align(w * bpp, 4); // bytes per line in file

	/* Size of palette. Only present for 8bpp mode */
	uint pal_size = pixelformat == 8 ? sizeof(RgbQuad) * 256 : 0;

	/* Setup the file header */
	BitmapFileHeader bfh;
	bfh.type = TO_LE16('MB');
	bfh.size = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size + bytewidth * h);
	bfh.reserved = 0;
	bfh.off_bits = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size);

	/* Setup the info header */
	BitmapInfoHeader bih;
	bih.size = TO_LE32(sizeof(BitmapInfoHeader));
	bih.width = TO_LE32(w);
	bih.height = TO_LE32(h);
	bih.planes = TO_LE16(1);
	bih.bitcount = TO_LE16(bpp * 8);
	bih.compression = 0;
	bih.sizeimage = 0;
	bih.xpels = 0;
	bih.ypels = 0;
	bih.clrused = 0;
	bih.clrimp = 0;

	/* Write file header and info header */
	if (fwrite(&bfh, sizeof(bfh), 1, f) != 1 || fwrite(&bih, sizeof(bih), 1, f) != 1) {
		fclose(f);
		return false;
	}

	if (pixelformat == 8) {
		/* Convert the palette to the windows format */
		RgbQuad rq[256];
		for (uint i = 0; i < 256; i++) {
			rq[i].red   = palette[i].r;
			rq[i].green = palette[i].g;
			rq[i].blue  = palette[i].b;
			rq[i].reserved = 0;
		}
		/* Write the palette */
		if (fwrite(rq, sizeof(rq), 1, f) != 1) {
			fclose(f);
			return false;
		}
	}

	/* Try to use 64k of memory, store between 16 and 128 lines */
	uint maxlines = Clamp(65536 / (w * pixelformat / 8), 16, 128); // number of lines per iteration

	uint8 *buff = MallocT<uint8>(maxlines * w * pixelformat / 8); // buffer which is rendered to
	uint8 *line = AllocaM(uint8, bytewidth); // one line, stored to file
	memset(line, 0, bytewidth);

	/* Start at the bottom, since bitmaps are stored bottom up */
	do {
		uint n = min(h, maxlines);
		h -= n;

		/* Render the pixels */
		callb(userdata, buff, h, w, n);

		/* Write each line */
		while (n-- != 0) {
			if (pixelformat == 8) {
				/* Move to 'line', leave last few pixels in line zeroed */
				memcpy(line, buff + n * w, w);
			} else {
				/* Convert from 'native' 32bpp to BMP-like 24bpp.
				 * Works for both big and little endian machines */
				Colour *src = ((Colour *)buff) + n * w;
				byte *dst = line;
				for (uint i = 0; i < w; i++) {
					dst[i * 3    ] = src[i].b;
					dst[i * 3 + 1] = src[i].g;
					dst[i * 3 + 2] = src[i].r;
				}
			}
			/* Write to file */
			if (fwrite(line, bytewidth, 1, f) != 1) {
				free(buff);
				fclose(f);
				return false;
			}
		}
	} while (h != 0);

	free(buff);
	fclose(f);

	return true;
}