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); }
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); }
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; } }
/** * 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; }