mirror of
https://gitlab.com/skmp/dca3-game.git
synced 2025-01-17 13:28:22 +01:00
116 lines
3.8 KiB
C
116 lines
3.8 KiB
C
#pragma once
|
|
|
|
#include <math.h>
|
|
#include <stdbool.h>
|
|
#include "nvmath.h"
|
|
#include "pixel.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define PVR_MAX_TEXTURE_WIDTH 1024
|
|
#define PVR_MAX_TEXTURE_HEIGHT 1024
|
|
#define PVR_MAX_MIPMAPS (11)
|
|
|
|
#define CHANNEL_CNT_ARGB 4
|
|
#define VECTOR_W 2
|
|
#define VECTOR_H 2
|
|
#define VECTOR_AREA (VECTOR_W * VECTOR_H)
|
|
#define VECTOR_SIZE (CHANNEL_CNT_ARGB * VECTOR_AREA)
|
|
|
|
#define PVR_CODEBOOK_ENTRY_SIZE_BYTES (8)
|
|
#define PVR_CODEBOOK_SIZE_BYTES (2048)
|
|
#define PVR_FULL_CODEBOOK (256)
|
|
|
|
typedef enum {
|
|
PT_SIZE_8,
|
|
PT_SIZE_16,
|
|
PT_SIZE_32,
|
|
PT_SIZE_64,
|
|
PT_SIZE_128,
|
|
PT_SIZE_256,
|
|
PT_SIZE_512,
|
|
PT_SIZE_1024,
|
|
} ptTextureSize;
|
|
|
|
typedef enum {
|
|
//The values for following seven formats match up with the values used by the hardware
|
|
PT_ARGB1555,
|
|
PT_RGB565,
|
|
PT_ARGB4444,
|
|
PT_YUV,
|
|
PT_NORMAL,
|
|
PT_PALETTE_4B,
|
|
PT_PALETTE_8B,
|
|
|
|
//This is not a real PVR pixel format. It's a stand in for a YUV texture that is twiddled,
|
|
//which is not encoded the same way as other twiddled formats.
|
|
//It exists so that ConvertFromFormatToBGRA8888 can know that a texture is twiddled.
|
|
PT_YUV_TWID = PT_YUV + 8,
|
|
|
|
//Don't get this confused with ptePixelFormat
|
|
} ptPixelFormat;
|
|
#define PT_PIXEL_OFFSET PT_PALETTE_8B
|
|
|
|
//Returns the number of pixels in a codebook entry for a compressed texture of a given format
|
|
unsigned VectorArea(ptPixelFormat format);
|
|
|
|
size_t TotalMipSize(ptPixelFormat format, int vq, int level);
|
|
size_t UncompressedMipSize(unsigned w, unsigned h, ptPixelFormat format);
|
|
size_t MipMapOffset(ptPixelFormat format, int vq, int level);
|
|
size_t CalcTextureSize(int u, int v, ptPixelFormat format, int mipmap, int vq, int codebook_size_bytes);
|
|
void MakeTwiddled32(void *pix, int w, int h);
|
|
void MakeTwiddled16(void *pix, int w, int h);
|
|
void MakeTwiddled8(void *pix, int w, int h);
|
|
void MakeDetwiddled8(void *pix, int w, int h);
|
|
void MakeDetwiddled32(void *pix, int w, int h);
|
|
void DecompressVQ(const uint8_t *indicies, int index_cnt, const void *codebook, int cb_offset, void *dst, int auto_small_vq, int codebook_size);
|
|
unsigned MipLevels(int size);
|
|
bool IsValidStrideWidth(unsigned size);
|
|
float BytesPerPixel(ptPixelFormat format);
|
|
void ConvertFromFormatToBGRA8888(const void *src, int pixel_format, pxlABGR8888 *pal, unsigned w, unsigned h, pxlABGR8888 *dst);
|
|
void ptConvertToTargetFormat(const pxlABGR8888 *src, unsigned w, unsigned h, pxlABGR8888 *pal, size_t palsize, void *dst, ptPixelFormat pixel_format);
|
|
const char * ptGetPixelFormatString(unsigned format);
|
|
|
|
static inline unsigned ConvToYUV(pxlABGR8888 l, pxlABGR8888 r) {
|
|
const float avgR = (l.r + r.r) / 2;
|
|
const float avgG = (l.g + r.g) / 2;
|
|
const float avgB = (l.b + r.b) / 2;
|
|
|
|
//compute each pixel's Y
|
|
int Y0 = CLAMP(0, (int)(0.299 * l.r + 0.587 * l.g + 0.114 * l.b), 255);
|
|
int Y1 = CLAMP(0, (int)(0.299 * r.r + 0.587 * r.g + 0.114 * r.b), 255);
|
|
|
|
int U = CLAMP(0, (int)(-0.169 * avgR - 0.331 * avgG + 0.4990 * avgB + 128), 255);
|
|
int V = CLAMP(0, (int)( 0.499 * avgR - 0.418 * avgG - 0.0813 * avgB + 128), 255);
|
|
|
|
unsigned yuv1 = ((uint8_t)Y0) << 8 | (uint8_t)U;
|
|
unsigned yuv2 = ((uint8_t)Y1) << 8 | (uint8_t)V;
|
|
|
|
return (yuv1 << 16) | yuv2;
|
|
}
|
|
|
|
//Writes two pixels, to dst[0] and dst[1]
|
|
static inline void ConvFromYUV(unsigned yuv1, unsigned yuv2, pxlABGR8888 *dst) {
|
|
const int Y0 = (yuv1 & 0xFF00) >> 8;
|
|
const int Y1 = (yuv2 & 0xFF00) >> 8;
|
|
const int U = (int)(yuv1 & 0xFF) - 128;
|
|
const int V = (int)(yuv2 & 0xFF) - 128;
|
|
int r, g, b;
|
|
|
|
r = CLAMP(0, (int)(Y0 + 1.375 * V), 255);
|
|
g = CLAMP(0, (int)(Y0 - 0.34375 * U - 0.6875 * V), 255);
|
|
b = CLAMP(0, (int)(Y0 + 1.71875 * U), 255);
|
|
dst[0] = pxlSetABGR8888(pxlU8toF(r), pxlU8toF(g), pxlU8toF(b), 1);
|
|
|
|
r = CLAMP(0, (int)(Y1 + 1.375 * V), 255);
|
|
g = CLAMP(0, (int)(Y1 - 0.34375 * U - 0.6875 * V), 255);
|
|
b = CLAMP(0, (int)(Y1 + 1.71875 * U), 255);
|
|
dst[1] = pxlSetABGR8888(pxlU8toF(r), pxlU8toF(g), pxlU8toF(b), 1);
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|