// File: dds_defs.h
// DX9 .DDS file header definitions.
#ifndef CRNLIB_DDS_DEFS_H
#define CRNLIB_DDS_DEFS_H

#include "crnlib.h"

#define CRNLIB_PIXEL_FMT_FOURCC(a, b, c, d) ((a) | ((b) << 8U) | ((c) << 16U) | ((d) << 24U))

namespace crnlib {
enum pixel_format {
  PIXEL_FMT_INVALID = 0,

  PIXEL_FMT_DXT1 = CRNLIB_PIXEL_FMT_FOURCC('D', 'X', 'T', '1'),
  PIXEL_FMT_DXT2 = CRNLIB_PIXEL_FMT_FOURCC('D', 'X', 'T', '2'),
  PIXEL_FMT_DXT3 = CRNLIB_PIXEL_FMT_FOURCC('D', 'X', 'T', '3'),
  PIXEL_FMT_DXT4 = CRNLIB_PIXEL_FMT_FOURCC('D', 'X', 'T', '4'),
  PIXEL_FMT_DXT5 = CRNLIB_PIXEL_FMT_FOURCC('D', 'X', 'T', '5'),
  PIXEL_FMT_3DC = CRNLIB_PIXEL_FMT_FOURCC('A', 'T', 'I', '2'),    // DXN_YX
  PIXEL_FMT_DXN = CRNLIB_PIXEL_FMT_FOURCC('A', '2', 'X', 'Y'),    // DXN_XY
  PIXEL_FMT_DXT5A = CRNLIB_PIXEL_FMT_FOURCC('A', 'T', 'I', '1'),  // ATI1N, https://www.vgamuseum.info/images/doc/ati/radeon_x1/radeon_x1x00_programming_guide.pdf

  // Non-standard, crnlib-specific pixel formats (some of these are supported by ATI's Compressonator)
  PIXEL_FMT_DXT5_CCxY = CRNLIB_PIXEL_FMT_FOURCC('C', 'C', 'x', 'Y'),
  PIXEL_FMT_DXT5_xGxR = CRNLIB_PIXEL_FMT_FOURCC('x', 'G', 'x', 'R'),
  PIXEL_FMT_DXT5_xGBR = CRNLIB_PIXEL_FMT_FOURCC('x', 'G', 'B', 'R'),
  PIXEL_FMT_DXT5_AGBR = CRNLIB_PIXEL_FMT_FOURCC('A', 'G', 'B', 'R'),

  PIXEL_FMT_DXT1A = CRNLIB_PIXEL_FMT_FOURCC('D', 'X', '1', 'A'),
  PIXEL_FMT_ETC1 = CRNLIB_PIXEL_FMT_FOURCC('E', 'T', 'C', '1'),
  PIXEL_FMT_ETC2 = CRNLIB_PIXEL_FMT_FOURCC('E', 'T', 'C', '2'),
  PIXEL_FMT_ETC2A = CRNLIB_PIXEL_FMT_FOURCC('E', 'T', '2', 'A'),
  PIXEL_FMT_ETC1S = CRNLIB_PIXEL_FMT_FOURCC('E', 'T', '1', 'S'),
  PIXEL_FMT_ETC2AS = CRNLIB_PIXEL_FMT_FOURCC('E', '2', 'A', 'S'),

  PIXEL_FMT_R8G8B8 = CRNLIB_PIXEL_FMT_FOURCC('R', 'G', 'B', 'x'),
  PIXEL_FMT_L8 = CRNLIB_PIXEL_FMT_FOURCC('L', 'x', 'x', 'x'),
  PIXEL_FMT_A8 = CRNLIB_PIXEL_FMT_FOURCC('x', 'x', 'x', 'A'),
  PIXEL_FMT_A8L8 = CRNLIB_PIXEL_FMT_FOURCC('L', 'x', 'x', 'A'),
  PIXEL_FMT_A8R8G8B8 = CRNLIB_PIXEL_FMT_FOURCC('R', 'G', 'B', 'A')
};

const crn_uint32 cDDSMaxImageDimensions = 8192U;

// Total size of header is sizeof(uint32)+cDDSSizeofDDSurfaceDesc2;
const crn_uint32 cDDSSizeofDDSurfaceDesc2 = 124;

// "DDS "
const crn_uint32 cDDSFileSignature = 0x20534444;

struct DDCOLORKEY {
  crn_uint32 dwUnused0;
  crn_uint32 dwUnused1;
};

struct DDPIXELFORMAT {
  crn_uint32 dwSize;
  crn_uint32 dwFlags;
  crn_uint32 dwFourCC;
  crn_uint32 dwRGBBitCount;  // ATI compressonator and crnlib will place a FOURCC code here for swizzled/cooked DXTn formats
  crn_uint32 dwRBitMask;
  crn_uint32 dwGBitMask;
  crn_uint32 dwBBitMask;
  crn_uint32 dwRGBAlphaBitMask;
};

struct DDSCAPS2 {
  crn_uint32 dwCaps;
  crn_uint32 dwCaps2;
  crn_uint32 dwCaps3;
  crn_uint32 dwCaps4;
};

struct DDSURFACEDESC2 {
  crn_uint32 dwSize;
  crn_uint32 dwFlags;
  crn_uint32 dwHeight;
  crn_uint32 dwWidth;
  union {
    crn_int32 lPitch;
    crn_uint32 dwLinearSize;
  };
  crn_uint32 dwBackBufferCount;
  crn_uint32 dwMipMapCount;
  crn_uint32 dwAlphaBitDepth;
  crn_uint32 dwUnused0;
  crn_uint32 lpSurface;
  DDCOLORKEY unused0;
  DDCOLORKEY unused1;
  DDCOLORKEY unused2;
  DDCOLORKEY unused3;
  DDPIXELFORMAT ddpfPixelFormat;
  DDSCAPS2 ddsCaps;
  crn_uint32 dwUnused1;
};

const crn_uint32 DDSD_CAPS = 0x00000001;
const crn_uint32 DDSD_HEIGHT = 0x00000002;
const crn_uint32 DDSD_WIDTH = 0x00000004;
const crn_uint32 DDSD_PITCH = 0x00000008;

const crn_uint32 DDSD_BACKBUFFERCOUNT = 0x00000020;
const crn_uint32 DDSD_ZBUFFERBITDEPTH = 0x00000040;
const crn_uint32 DDSD_ALPHABITDEPTH = 0x00000080;

const crn_uint32 DDSD_LPSURFACE = 0x00000800;

const crn_uint32 DDSD_PIXELFORMAT = 0x00001000;
const crn_uint32 DDSD_CKDESTOVERLAY = 0x00002000;
const crn_uint32 DDSD_CKDESTBLT = 0x00004000;
const crn_uint32 DDSD_CKSRCOVERLAY = 0x00008000;

const crn_uint32 DDSD_CKSRCBLT = 0x00010000;
const crn_uint32 DDSD_MIPMAPCOUNT = 0x00020000;
const crn_uint32 DDSD_REFRESHRATE = 0x00040000;
const crn_uint32 DDSD_LINEARSIZE = 0x00080000;

const crn_uint32 DDSD_TEXTURESTAGE = 0x00100000;
const crn_uint32 DDSD_FVF = 0x00200000;
const crn_uint32 DDSD_SRCVBHANDLE = 0x00400000;
const crn_uint32 DDSD_DEPTH = 0x00800000;

const crn_uint32 DDSD_ALL = 0x00fff9ee;

const crn_uint32 DDPF_ALPHAPIXELS = 0x00000001;
const crn_uint32 DDPF_ALPHA = 0x00000002;
const crn_uint32 DDPF_FOURCC = 0x00000004;
const crn_uint32 DDPF_PALETTEINDEXED8 = 0x00000020;
const crn_uint32 DDPF_RGB = 0x00000040;
const crn_uint32 DDPF_LUMINANCE = 0x00020000;

const crn_uint32 DDSCAPS_COMPLEX = 0x00000008;
const crn_uint32 DDSCAPS_TEXTURE = 0x00001000;
const crn_uint32 DDSCAPS_MIPMAP = 0x00400000;

const crn_uint32 DDSCAPS2_CUBEMAP = 0x00000200;
const crn_uint32 DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400;
const crn_uint32 DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800;

const crn_uint32 DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000;
const crn_uint32 DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000;
const crn_uint32 DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000;
const crn_uint32 DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000;

const crn_uint32 DDSCAPS2_VOLUME = 0x00200000;

}  // namespace crnlib

#endif  // CRNLIB_DDS_DEFS_H
