void WavWriter::Close()
{
    // calculate the total file length
    u32 len = ftell(m_file) - 8;
    fseek(m_file, 4, SEEK_SET);
    u8 data[4];
    utilPutDword(data, len);
    fwrite(data, 1, 4, m_file);
    // write out the size of the data section
    fseek(m_file, m_posSize, SEEK_SET);
    utilPutDword(data, m_len);
    fwrite(data, 1, 4, m_file);
    fclose(m_file);
    m_file = NULL;
}
void WavWriter::SetFormat(const WAVEFORMATEX* format)
{
    if (m_file == NULL)
        return;
    // write fmt header
    u8 data[4] = { 'f', 'm', 't', ' ' };
    fwrite(data, 1, 4, m_file);
    u32 value = sizeof(WAVEFORMATEX);
    utilPutDword(data, value);
    fwrite(data, 1, 4, m_file);
    fwrite(format, 1, sizeof(WAVEFORMATEX), m_file);
    // start data header
    u8 data2[4] = { 'd', 'a', 't', 'a' };
    fwrite(data2, 1, 4, m_file);

    m_posSize = ftell(m_file);
    // write 0 for data chunk size. Filled out during Close()
    utilPutDword(data, 0);
    fwrite(data, 1, 4, m_file);
}
bool PaletteViewControl::saveMSPAL(const char *name)
{
  FILE *f = fopen(name, "wb");

  if(!f)
    return false;

  u8 data[4] = { 'R', 'I', 'F', 'F' };

  fwrite(data, 1, 4, f);
  utilPutDword(data, 256 * 4 + 16);
  fwrite(data, 1, 4, f);
  u8 data3[4] = { 'P', 'A', 'L', ' ' };
  fwrite(data3, 1, 4, f);
  u8 data4[4] = { 'd', 'a', 't', 'a' };
  fwrite(data4, 1, 4, f);
  utilPutDword(data, 256*4+4);
  fwrite(data, 1, 4, f);
  utilPutWord(&data[0], 0x0300);
  utilPutWord(&data[2], 256); // causes problems if not 16 or 256
  fwrite(data, 1, 4, f);
  
  for(int i = 0; i < colors; i++) {
    u16 c = palette[i];
    int r = (c & 0x1f) << 3;
    int g = (c & 0x3e0) >> 2;
    int b = (c & 0x7c00) >> 7;

    u8 data7[4] = { r, g, b, 0 };
    fwrite(data7, 1, 4, f);
  }
  if(colors < 256) {
    for(int i = colors; i < 256; i++) {
      u8 data7[4] = { 0, 0, 0, 0 };
      fwrite(data7, 1, 4, f);
    }
  }
  fclose(f);

  return true;
}
bool WavWriter::Open(const char* name)
{
    if (m_file)
        Close();
    m_file = fopen(name, "wb");

    if (!m_file)
        return false;
    // RIFF header
    u8 data[4] = { 'R', 'I', 'F', 'F' };
    fwrite(data, 1, 4, m_file);
    utilPutDword(data, 0);
    // write 0 for now. Will get filled during close
    fwrite(data, 1, 4, m_file);
    // write WAVE header
    u8 data2[4] = { 'W', 'A', 'V', 'E' };
    fwrite(data2, 1, 4, m_file);
    return true;
}
void GBMapView::saveBMP(const char *name)
{
  u8 writeBuffer[1024 * 3];

  FILE *fp = fopen(name,"wb");

  if(!fp) {
    systemMessage(MSG_ERROR_CREATING_FILE, "Error creating file %s", name);
    return;
  }

  struct {
    u8 ident[2];
    u8 filesize[4];
    u8 reserved[4];
    u8 dataoffset[4];
    u8 headersize[4];
    u8 width[4];
    u8 height[4];
    u8 planes[2];
    u8 bitsperpixel[2];
    u8 compression[4];
    u8 datasize[4];
    u8 hres[4];
    u8 vres[4];
    u8 colors[4];
    u8 importantcolors[4];
    u8 pad[2];
  } bmpheader;
  memset(&bmpheader, 0, sizeof(bmpheader));

  bmpheader.ident[0] = 'B';
  bmpheader.ident[1] = 'M';

  u32 fsz = sizeof(bmpheader) + w*h*3;
  utilPutDword(bmpheader.filesize, fsz);
  utilPutDword(bmpheader.dataoffset, 0x38);
  utilPutDword(bmpheader.headersize, 0x28);
  utilPutDword(bmpheader.width, w);
  utilPutDword(bmpheader.height, h);
  utilPutDword(bmpheader.planes, 1);
  utilPutDword(bmpheader.bitsperpixel, 24);
  utilPutDword(bmpheader.datasize, 3*w*h);

  fwrite(&bmpheader, 1, sizeof(bmpheader), fp);

  u8 *b = writeBuffer;

  int sizeX = w;
  int sizeY = h;

  u8 *pixU8 = (u8 *)data+3*w*(h-1);
  for(int y = 0; y < sizeY; y++) {
    for(int x = 0; x < sizeX; x++) {
      *b++ = *pixU8++; // B
      *b++ = *pixU8++; // G
      *b++ = *pixU8++; // R
    }
    pixU8 -= 2*3*w;
    fwrite(writeBuffer, 1, 3*w, fp);

    b = writeBuffer;
  }

  fclose(fp);
}