Merge pull request #607 from UnknownShadow200/BitmapColRewrite

Bitmap col rewrite
This commit is contained in:
UnknownShadow200 2019-10-10 10:49:48 +11:00 committed by GitHub
commit 5513d49b85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 245 additions and 216 deletions

View File

@ -54,7 +54,6 @@ void Bitmap_Scale(Bitmap* dst, Bitmap* src, int srcX, int srcY, int srcWidth, in
*#########################################################################################################################*/ *#########################################################################################################################*/
#define PNG_SIG_SIZE 8 #define PNG_SIG_SIZE 8
#define PNG_IHDR_SIZE 13 #define PNG_IHDR_SIZE 13
#define PNG_RGB_MASK 0xFFFFFFUL
#define PNG_PALETTE 256 #define PNG_PALETTE 256
#define PNG_FourCC(a, b, c, d) (((cc_uint32)a << 24) | ((cc_uint32)b << 16) | ((cc_uint32)c << 8) | (cc_uint32)d) #define PNG_FourCC(a, b, c, d) (((cc_uint32)a << 24) | ((cc_uint32)b << 16) | ((cc_uint32)c << 8) | (cc_uint32)d)
@ -127,7 +126,7 @@ static void Png_Reconstruct(cc_uint8 type, cc_uint8 bytesPerPixel, cc_uint8* lin
} }
} }
#define Bitmap_Set(dst, r,g,b,a) dst.B = b; dst.G = g; dst.R = r; dst.A = a; #define Bitmap_Set(dst, r,g,b,a) dst = BitmapCol_Make(r, g, b, a);
#define PNG_Do_Grayscale(dstI, src, scale) rgb = (src) * scale; Bitmap_Set(dst[dstI], rgb, rgb, rgb, 255); #define PNG_Do_Grayscale(dstI, src, scale) rgb = (src) * scale; Bitmap_Set(dst[dstI], rgb, rgb, rgb, 255);
#define PNG_Do_Grayscale_8(dstI, srcI) rgb = src[srcI]; Bitmap_Set(dst[dstI], rgb, rgb, rgb, 255); #define PNG_Do_Grayscale_8(dstI, srcI) rgb = src[srcI]; Bitmap_Set(dst[dstI], rgb, rgb, rgb, 255);
@ -307,14 +306,15 @@ static Png_RowExpander Png_GetExpander(cc_uint8 col, cc_uint8 bitsPerSample) {
return NULL; return NULL;
} }
static void Png_ComputeTransparency(Bitmap* bmp, BitmapCol col) { /* Sets alpha to 0 for any pixels in the bitmap whose RGB is same as col */
cc_uint32 trnsRGB = col.B | (col.G << 8) | (col.R << 16); /* TODO: Remove this!! */ static void ComputeTransparency(Bitmap* bmp, BitmapCol col) {
BitmapCol trnsRGB = col & BITMAPCOL_RGB_MASK;
int x, y, width = bmp->Width, height = bmp->Height; int x, y, width = bmp->Width, height = bmp->Height;
for (y = 0; y < height; y++) { for (y = 0; y < height; y++) {
cc_uint32* row = Bitmap_RawRow(bmp, y); BitmapCol* row = Bitmap_GetRow(bmp, y);
for (x = 0; x < width; x++) { for (x = 0; x < width; x++) {
cc_uint32 rgb = row[x] & PNG_RGB_MASK; BitmapCol rgb = row[x] & BITMAPCOL_RGB_MASK;
row[x] = (rgb == trnsRGB) ? trnsRGB : row[x]; row[x] = (rgb == trnsRGB) ? trnsRGB : row[x];
} }
} }
@ -337,8 +337,7 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
cc_uint32 scanlineSize, scanlineBytes; cc_uint32 scanlineSize, scanlineBytes;
/* palette data */ /* palette data */
BitmapCol black = BITMAPCOL_CONST(0, 0, 0, 255); BitmapCol trnsCol;
BitmapCol transparentCol;
BitmapCol palette[PNG_PALETTE]; BitmapCol palette[PNG_PALETTE];
cc_uint32 i; cc_uint32 i;
@ -360,8 +359,8 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
if (res) return res; if (res) return res;
if (!Png_Detect(tmp, PNG_SIG_SIZE)) return PNG_ERR_INVALID_SIG; if (!Png_Detect(tmp, PNG_SIG_SIZE)) return PNG_ERR_INVALID_SIG;
transparentCol = black; trnsCol = BITMAPCOL_BLACK;
for (i = 0; i < PNG_PALETTE; i++) { palette[i] = black; } for (i = 0; i < PNG_PALETTE; i++) { palette[i] = BITMAPCOL_BLACK; }
Inflate_MakeStream(&compStream, &inflate, stream); Inflate_MakeStream(&compStream, &inflate, stream);
ZLibHeader_Init(&zlibHeader); ZLibHeader_Init(&zlibHeader);
@ -411,9 +410,10 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
if (res) return res; if (res) return res;
for (i = 0; i < dataSize; i += 3) { for (i = 0; i < dataSize; i += 3) {
palette[i / 3].R = tmp[i]; palette[i / 3] &= BITMAPCOL_A_MASK; /* set RGB to 0 */
palette[i / 3].G = tmp[i + 1]; palette[i / 3] |= tmp[i ] << BITMAPCOL_R_SHIFT;
palette[i / 3].B = tmp[i + 2]; palette[i / 3] |= tmp[i + 1] << BITMAPCOL_G_SHIFT;
palette[i / 3] |= tmp[i + 2] << BITMAPCOL_B_SHIFT;
} }
} break; } break;
@ -424,8 +424,7 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
if (res) return res; if (res) return res;
/* RGB is 16 bits big endian, ignore least significant 8 bits */ /* RGB is 16 bits big endian, ignore least significant 8 bits */
transparentCol.R = tmp[0]; transparentCol.G = tmp[0]; trnsCol = BitmapCol_Make(tmp[0], tmp[0], tmp[0], 0);
transparentCol.B = tmp[0]; transparentCol.A = 0;
} else if (col == PNG_COL_INDEXED) { } else if (col == PNG_COL_INDEXED) {
if (dataSize > PNG_PALETTE) return PNG_ERR_TRANS_COUNT; if (dataSize > PNG_PALETTE) return PNG_ERR_TRANS_COUNT;
res = Stream_Read(stream, tmp, dataSize); res = Stream_Read(stream, tmp, dataSize);
@ -433,7 +432,8 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
/* set alpha component of palette */ /* set alpha component of palette */
for (i = 0; i < dataSize; i++) { for (i = 0; i < dataSize; i++) {
palette[i].A = tmp[i]; palette[i] &= BITMAPCOL_RGB_MASK; /* set A to 0 */
palette[i] |= tmp[i] << PACKEDCOL_A_SHIFT;
} }
} else if (col == PNG_COL_RGB) { } else if (col == PNG_COL_RGB) {
if (dataSize != 6) return PNG_ERR_TRANS_COUNT; if (dataSize != 6) return PNG_ERR_TRANS_COUNT;
@ -441,8 +441,7 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
if (res) return res; if (res) return res;
/* R,G,B is 16 bits big endian, ignore least significant 8 bits */ /* R,G,B is 16 bits big endian, ignore least significant 8 bits */
transparentCol.R = tmp[0]; transparentCol.G = tmp[2]; trnsCol = BitmapCol_Make(tmp[0], tmp[2], tmp[4], 0);
transparentCol.B = tmp[4]; transparentCol.A = 0;
} else { } else {
return PNG_ERR_TRANS_INVALID; return PNG_ERR_TRANS_INVALID;
} }
@ -499,7 +498,7 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
case PNG_FourCC('I','E','N','D'): { case PNG_FourCC('I','E','N','D'): {
if (dataSize) return PNG_ERR_INVALID_END_SIZE; if (dataSize) return PNG_ERR_INVALID_END_SIZE;
if (!transparentCol.A) Png_ComputeTransparency(bmp, transparentCol); if (!BitmapCol_A(trnsCol)) ComputeTransparency(bmp, trnsCol);
return bmp->Scan0 ? 0 : PNG_ERR_NO_DATA; return bmp->Scan0 ? 0 : PNG_ERR_NO_DATA;
} break; } break;
@ -565,14 +564,19 @@ static void Png_Filter(cc_uint8 filter, const cc_uint8* cur, const cc_uint8* pri
static void Png_MakeRow(const BitmapCol* src, cc_uint8* dst, int lineLen, bool alpha) { static void Png_MakeRow(const BitmapCol* src, cc_uint8* dst, int lineLen, bool alpha) {
cc_uint8* end = dst + lineLen; cc_uint8* end = dst + lineLen;
BitmapCol col; /* if we use *src, register gets reloaded each time */
if (alpha) { if (alpha) {
for (; dst < end; src++, dst += 4) { for (; dst < end; src++, dst += 4) {
dst[0] = src->R; dst[1] = src->G; dst[2] = src->B; dst[3] = src->A; col = *src;
dst[0] = BitmapCol_R(col); dst[1] = BitmapCol_G(col);
dst[2] = BitmapCol_B(col); dst[3] = BitmapCol_A(col);
} }
} else { } else {
for (; dst < end; src++, dst += 3) { for (; dst < end; src++, dst += 3) {
dst[0] = src->R; dst[1] = src->G; dst[2] = src->B; col = *src;
dst[0] = BitmapCol_R(col); dst[1] = BitmapCol_G(col);
dst[2] = BitmapCol_B(col);
} }
} }
} }

View File

@ -6,37 +6,52 @@
*/ */
struct Stream; struct Stream;
/* Represents an ARGB colour, suitable for native graphics API texture pixels. */ /* Represents a packed 32 bit RGBA colour, suitable for native graphics API texture pixels. */
typedef union BitmapCol_ { typedef cc_uint32 BitmapCol;
#if defined CC_BUILD_WEB || defined CC_BUILD_ANDROID #if defined CC_BUILD_WEB || defined CC_BUILD_ANDROID
struct { cc_uint8 R, G, B, A; }; #define BITMAPCOL_R_SHIFT 0
#define BITMAPCOL_G_SHIFT 8
#define BITMAPCOL_B_SHIFT 16
#define BITMAPCOL_A_SHIFT 24
#elif defined CC_BIG_ENDIAN
#define BITMAPCOL_A_SHIFT 0
#define BITMAPCOL_R_SHIFT 8
#define BITMAPCOL_G_SHIFT 16
#define BITMAPCOL_B_SHIFT 24
#else #else
struct { cc_uint8 B, G, R, A; }; #define BITMAPCOL_B_SHIFT 0
#define BITMAPCOL_G_SHIFT 8
#define BITMAPCOL_R_SHIFT 16
#define BITMAPCOL_A_SHIFT 24
#endif #endif
cc_uint32 _raw;
} BitmapCol;
/* Whether components of two colours are all equal. */ #define BITMAPCOL_R_MASK (0xFFU << BITMAPCOL_R_SHIFT)
#define BitmapCol_Equals(a,b) ((a)._raw == (b)._raw) #define BITMAPCOL_G_MASK (0xFFU << BITMAPCOL_G_SHIFT)
#define PackedCol_ARGB(r, g, b, a) (((cc_uint32)(r) << 16) | ((cc_uint32)(g) << 8) | ((cc_uint32)(b)) | ((cc_uint32)(a) << 24)) #define BITMAPCOL_B_MASK (0xFFU << BITMAPCOL_B_SHIFT)
#define BITMAPCOL_A_MASK (0xFFU << BITMAPCOL_A_SHIFT)
#define BitmapCol_R(col) ((cc_uint8)(col >> BITMAPCOL_R_SHIFT))
#define BitmapCol_G(col) ((cc_uint8)(col >> BITMAPCOL_G_SHIFT))
#define BitmapCol_B(col) ((cc_uint8)(col >> BITMAPCOL_B_SHIFT))
#define BitmapCol_A(col) ((cc_uint8)(col >> BITMAPCOL_A_SHIFT))
#define BitmapCol_R_Bits(col) ((cc_uint8)(col) << BITMAPCOL_R_SHIFT)
#define BitmapCol_G_Bits(col) ((cc_uint8)(col) << BITMAPCOL_G_SHIFT)
#define BitmapCol_B_Bits(col) ((cc_uint8)(col) << BITMAPCOL_B_SHIFT)
#define BitmapCol_A_Bits(col) ((cc_uint8)(col) << BITMAPCOL_A_SHIFT)
#define BitmapCol_Make(r, g, b, a) (BitmapCol_R_Bits(r) | BitmapCol_G_Bits(g) | BitmapCol_B_Bits(b) | BitmapCol_A_Bits(a))
#define BITMAPCOL_RGB_MASK (BITMAPCOL_R_MASK | BITMAPCOL_G_MASK | BITMAPCOL_B_MASK)
#define BITMAPCOL_BLACK BitmapCol_Make( 0, 0, 0, 255)
#define BITMAPCOL_WHITE BitmapCol_Make(255, 255, 255, 255)
/* A 2D array of BitmapCol pixels */ /* A 2D array of BitmapCol pixels */
typedef struct Bitmap_ { cc_uint8* Scan0; int Width, Height; } Bitmap; typedef struct Bitmap_ { cc_uint8* Scan0; int Width, Height; } Bitmap;
#define PNG_MAX_DIMS 0x8000 #define PNG_MAX_DIMS 0x8000
#if defined CC_BUILD_WEB || defined CC_BUILD_ANDROID
#define BITMAPCOL_CONST(r, g, b, a) { r, g, b, a }
#else
#define BITMAPCOL_CONST(r, g, b, a) { b, g, r, a }
#endif
/* Returns number of bytes a bitmap consumes. */ /* Returns number of bytes a bitmap consumes. */
#define Bitmap_DataSize(width, height) ((cc_uint32)(width) * (cc_uint32)(height) * 4) #define Bitmap_DataSize(width, height) ((cc_uint32)(width) * (cc_uint32)(height) * 4)
/* Gets the yth row of a bitmap as raw cc_uint32* pointer. */
/* NOTE: You SHOULD not rely on the order of the 4 bytes in the pointer. */
/* Different platforms may have different endian, or different component order. */
#define Bitmap_RawRow(bmp, y) ((cc_uint32*)(bmp)->Scan0 + (y) * (bmp)->Width)
/* Gets the yth row of the given bitmap. */ /* Gets the yth row of the given bitmap. */
#define Bitmap_GetRow(bmp, y) ((BitmapCol*)(bmp)->Scan0 + (y) * (bmp)->Width) #define Bitmap_GetRow(bmp, y) ((BitmapCol*)(bmp)->Scan0 + (y) * (bmp)->Width)
/* Gets the pixel at (x,y) in the given bitmap. */ /* Gets the pixel at (x,y) in the given bitmap. */

View File

@ -352,7 +352,7 @@ static float Block_GetSpriteBB_MinX(int size, int tileX, int tileY, const Bitmap
for (x = 0; x < size; x++) { for (x = 0; x < size; x++) {
for (y = 0; y < size; y++) { for (y = 0; y < size; y++) {
row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size); row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
if (row[x].A) { return (float)x / size; } if (BitmapCol_A(row[x])) { return (float)x / size; }
} }
} }
return 1.0f; return 1.0f;
@ -365,7 +365,7 @@ static float Block_GetSpriteBB_MinY(int size, int tileX, int tileY, const Bitmap
for (y = size - 1; y >= 0; y--) { for (y = size - 1; y >= 0; y--) {
row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size); row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
for (x = 0; x < size; x++) { for (x = 0; x < size; x++) {
if (row[x].A) { return 1.0f - (float)(y + 1) / size; } if (BitmapCol_A(row[x])) { return 1.0f - (float)(y + 1) / size; }
} }
} }
return 1.0f; return 1.0f;
@ -378,7 +378,7 @@ static float Block_GetSpriteBB_MaxX(int size, int tileX, int tileY, const Bitmap
for (x = size - 1; x >= 0; x--) { for (x = size - 1; x >= 0; x--) {
for (y = 0; y < size; y++) { for (y = 0; y < size; y++) {
row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size); row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
if (row[x].A) { return (float)(x + 1) / size; } if (BitmapCol_A(row[x])) { return (float)(x + 1) / size; }
} }
} }
return 0.0f; return 0.0f;
@ -391,7 +391,7 @@ static float Block_GetSpriteBB_MaxY(int size, int tileX, int tileY, const Bitmap
for (y = 0; y < size; y++) { for (y = 0; y < size; y++) {
row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size); row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
for (x = 0; x < size; x++) { for (x = 0; x < size; x++) {
if (row[x].A) { return 1.0f - (float)y / size; } if (BitmapCol_A(row[x])) { return 1.0f - (float)y / size; }
} }
} }
return 0.0f; return 0.0f;

View File

@ -30,8 +30,9 @@ typedef unsigned int cc_uintptr;
#define CC_HAS_TYPES #define CC_HAS_TYPES
#define CC_HAS_MISC #define CC_HAS_MISC
#elif __GNUC__ #elif __GNUC__
/* really old GCC/clang might not have these */ /* really old GCC/clang might not have these defined */
#ifdef __INT8_TYPE__ #ifdef __INT8_TYPE__
/* avoid including <stdint.h> because it breaks defining UNICODE in Platform.c with MinGW */
typedef __INT8_TYPE__ cc_int8; typedef __INT8_TYPE__ cc_int8;
typedef __INT16_TYPE__ cc_int16; typedef __INT16_TYPE__ cc_int16;
typedef __INT32_TYPE__ cc_int32; typedef __INT32_TYPE__ cc_int32;
@ -74,7 +75,7 @@ typedef unsigned __INTPTR_TYPE__ cc_uintptr;
#define CC_BIG_ENDIAN #define CC_BIG_ENDIAN
#endif #endif
/* Unrecognised compiler, so just go with sensisble defaults */ /* Unrecognised compiler, so just go with sensible defaults */
#ifndef CC_HAS_TYPES #ifndef CC_HAS_TYPES
#include <stdint.h> #include <stdint.h>
typedef int8_t cc_int8; typedef int8_t cc_int8;
@ -89,7 +90,7 @@ typedef uint64_t cc_uint64;
typedef uintptr_t cc_uintptr; typedef uintptr_t cc_uintptr;
#endif #endif
#ifndef CC_HAS_MISC #ifndef CC_HAS_MISC
#define CC_INLINE inline #define CC_INLINE
#define CC_NOINLINE #define CC_NOINLINE
#define CC_API #define CC_API
#define CC_VAR #define CC_VAR

View File

@ -115,7 +115,7 @@ static void Drawer2D_CalculateTextWidths(void) {
/* Iterate through each pixel of the given character, on the current scanline */ /* Iterate through each pixel of the given character, on the current scanline */
for (xx = tileSize - 1; xx >= 0; xx--) { for (xx = tileSize - 1; xx >= 0; xx--) {
if (!row[x + xx].A) continue; if (!BitmapCol_A(row[x + xx])) continue;
/* Check if this is the pixel furthest to the right, for the current character */ /* Check if this is the pixel furthest to the right, for the current character */
tileWidths[i] = max(tileWidths[i], xx + 1); tileWidths[i] = max(tileWidths[i], xx + 1);
@ -172,7 +172,7 @@ bool Drawer2D_Clamp(Bitmap* bmp, int* x, int* y, int* width, int* height) {
void Gradient_Noise(Bitmap* bmp, BitmapCol col, int variation, void Gradient_Noise(Bitmap* bmp, BitmapCol col, int variation,
int x, int y, int width, int height) { int x, int y, int width, int height) {
BitmapCol* dst; BitmapCol* dst;
int xx, yy, n; int R, G, B, xx, yy, n;
float noise; float noise;
if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return; if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return;
@ -184,14 +184,11 @@ void Gradient_Noise(Bitmap* bmp, BitmapCol col, int variation,
n = (n << 13) ^ n; n = (n << 13) ^ n;
noise = 1.0f - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f; noise = 1.0f - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f;
n = col.B + (int)(noise * variation); R = BitmapCol_R(col) + (int)(noise * variation); Drawer2D_ClampPixel(R);
dst->B = Drawer2D_ClampPixel(n); G = BitmapCol_G(col) + (int)(noise * variation); Drawer2D_ClampPixel(G);
n = col.G + (int)(noise * variation); B = BitmapCol_B(col) + (int)(noise * variation); Drawer2D_ClampPixel(B);
dst->G = Drawer2D_ClampPixel(n);
n = col.R + (int)(noise * variation);
dst->R = Drawer2D_ClampPixel(n);
dst->A = 255; *dst = BitmapCol_Make(R, G, B, 255);
} }
} }
} }
@ -202,15 +199,16 @@ void Gradient_Vertical(Bitmap* bmp, BitmapCol a, BitmapCol b,
int xx, yy; int xx, yy;
float t; float t;
if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return; if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return;
col.A = 255;
for (yy = 0; yy < height; yy++) { for (yy = 0; yy < height; yy++) {
row = Bitmap_GetRow(bmp, y + yy) + x; row = Bitmap_GetRow(bmp, y + yy) + x;
t = (float)yy / (height - 1); /* so last row has colour of b */ t = (float)yy / (height - 1); /* so last row has colour of b */
col.B = (cc_uint8)Math_Lerp(a.B, b.B, t); col = BitmapCol_Make(
col.G = (cc_uint8)Math_Lerp(a.G, b.G, t); Math_Lerp(BitmapCol_R(a), BitmapCol_R(b), t),
col.R = (cc_uint8)Math_Lerp(a.R, b.R, t); Math_Lerp(BitmapCol_G(a), BitmapCol_G(b), t),
Math_Lerp(BitmapCol_B(a), BitmapCol_B(b), t),
255);
for (xx = 0; xx < width; xx++) { row[xx] = col; } for (xx = 0; xx < width; xx++) { row[xx] = col; }
} }
@ -219,35 +217,35 @@ void Gradient_Vertical(Bitmap* bmp, BitmapCol a, BitmapCol b,
void Gradient_Blend(Bitmap* bmp, BitmapCol col, int blend, void Gradient_Blend(Bitmap* bmp, BitmapCol col, int blend,
int x, int y, int width, int height) { int x, int y, int width, int height) {
BitmapCol* dst; BitmapCol* dst;
int xx, yy, t; int R, G, B, xx, yy;
if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return; if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return;
/* Pre compute the alpha blended source colour */ /* Pre compute the alpha blended source colour */
col.R = (cc_uint8)(col.R * blend / 255); /* TODO: Avoid shift when multiplying */
col.G = (cc_uint8)(col.G * blend / 255); col = BitmapCol_Make(
col.B = (cc_uint8)(col.B * blend / 255); BitmapCol_R(col) * blend / 255,
BitmapCol_G(col) * blend / 255,
BitmapCol_B(col) * blend / 255,
0);
blend = 255 - blend; /* inverse for existing pixels */ blend = 255 - blend; /* inverse for existing pixels */
t = 0;
for (yy = 0; yy < height; yy++) { for (yy = 0; yy < height; yy++) {
dst = Bitmap_GetRow(bmp, y + yy) + x; dst = Bitmap_GetRow(bmp, y + yy) + x;
for (xx = 0; xx < width; xx++, dst++) { for (xx = 0; xx < width; xx++, dst++) {
t = col.B + (dst->B * blend) / 255; /* TODO: Not shift when multiplying */
dst->B = Drawer2D_ClampPixel(t); R = BitmapCol_R(col) + (BitmapCol_R(*dst) * blend) / 255;
t = col.G + (dst->G * blend) / 255; G = BitmapCol_G(col) + (BitmapCol_G(*dst) * blend) / 255;
dst->G = Drawer2D_ClampPixel(t); B = BitmapCol_B(col) + (BitmapCol_B(*dst) * blend) / 255;
t = col.R + (dst->R * blend) / 255;
dst->R = Drawer2D_ClampPixel(t);
dst->A = 255; *dst = BitmapCol_Make(R, G, B, 255);
} }
} }
} }
void Gradient_Tint(Bitmap* bmp, cc_uint8 tintA, cc_uint8 tintB, void Gradient_Tint(Bitmap* bmp, cc_uint8 tintA, cc_uint8 tintB,
int x, int y, int width, int height) { int x, int y, int width, int height) {
BitmapCol* row; BitmapCol* row, col;
cc_uint8 tint; cc_uint8 tint;
int xx, yy; int xx, yy;
if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return; if (!Drawer2D_Clamp(bmp, &x, &y, &width, &height)) return;
@ -257,9 +255,14 @@ void Gradient_Tint(Bitmap* bmp, cc_uint8 tintA, cc_uint8 tintB,
tint = (cc_uint8)Math_Lerp(tintA, tintB, (float)yy / height); tint = (cc_uint8)Math_Lerp(tintA, tintB, (float)yy / height);
for (xx = 0; xx < width; xx++) { for (xx = 0; xx < width; xx++) {
row[xx].B = (row[xx].B * tint) / 255; /* TODO: Not shift when multiplying */
row[xx].G = (row[xx].G * tint) / 255; col = BitmapCol_Make(
row[xx].R = (row[xx].R * tint) / 255; BitmapCol_R(row[xx]) * tint / 255,
BitmapCol_G(row[xx]) * tint / 255,
BitmapCol_B(row[xx]) * tint / 255,
0);
row[xx] = col | (row[xx] & BITMAPCOL_A_MASK);
} }
} }
} }
@ -278,7 +281,7 @@ void Drawer2D_BmpIndexed(Bitmap* bmp, int x, int y, int size,
for (xx = 0; xx < size; xx++) { for (xx = 0; xx < size; xx++) {
col = palette[*indices++]; col = palette[*indices++];
if (col._raw == 0) continue; /* transparent pixel */ if (col == 0) continue; /* transparent pixel */
if ((x + xx) < 0 || (x + xx) >= bmp->Width) continue; if ((x + xx) < 0 || (x + xx) >= bmp->Width) continue;
row[xx] = col; row[xx] = col;
} }
@ -343,7 +346,7 @@ void Drawer2D_Make2DTexture(struct Texture* tex, Bitmap* bmp, Size2D used) {
bool Drawer2D_ValidColCodeAt(const String* text, int i) { bool Drawer2D_ValidColCodeAt(const String* text, int i) {
if (i >= text->length) return false; if (i >= text->length) return false;
return Drawer2D_GetCol(text->buffer[i]).A > 0; return BitmapCol_A(Drawer2D_GetCol(text->buffer[i])) != 0;
} }
bool Drawer2D_IsEmptyText(const String* text) { bool Drawer2D_IsEmptyText(const String* text) {
@ -373,8 +376,13 @@ char Drawer2D_LastCol(const String* text, int start) {
bool Drawer2D_IsWhiteCol(char c) { return c == '\0' || c == 'f' || c == 'F'; } bool Drawer2D_IsWhiteCol(char c) { return c == '\0' || c == 'f' || c == 'F'; }
/* Divides R/G/B by 4 */ /* Divides R/G/B by 4 */
#define SHADOW_MASK ((0x3F << BITMAPCOL_R_SHIFT) | (0x3F << BITMAPCOL_G_SHIFT) | (0x3F << BITMAPCOL_B_SHIFT))
CC_NOINLINE static BitmapCol Drawer2D_ShadowCol(BitmapCol c) { CC_NOINLINE static BitmapCol Drawer2D_ShadowCol(BitmapCol c) {
c.R >>= 2; c.G >>= 2; c.B >>= 2; return c; /* Initial layout: aaaa_aaaa|rrrr_rrrr|gggg_gggg|bbbb_bbbb */
/* Shift right 2: 00aa_aaaa|aarr_rrrr|rrgg_gggg|ggbb_bbbb */
/* And by 3f3f3f: 0000_0000|00rr_rrrr|00gg_gggg|00bb_bbbb */
/* Or by alpha : aaaa_aaaa|00rr_rrrr|00gg_gggg|00bb_bbbb */
return (c & BITMAPCOL_A_MASK) | ((c >> 2) & SHADOW_MASK);
} }
/* TODO: Needs to account for DPI */ /* TODO: Needs to account for DPI */
@ -433,7 +441,6 @@ void Drawer2D_Underline(Bitmap* bmp, int x, int y, int width, int height, Bitmap
} }
static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int y, bool shadow) { static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int y, bool shadow) {
BitmapCol black = BITMAPCOL_CONST(0, 0, 0, 255);
BitmapCol col; BitmapCol col;
String text = args->text; String text = args->text;
int i, point = args->font->size, count = 0; int i, point = args->font->size, count = 0;
@ -454,7 +461,7 @@ static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int
col = Drawer2D_Cols['f']; col = Drawer2D_Cols['f'];
if (shadow) { if (shadow) {
col = Drawer2D_BlackTextShadows ? black : Drawer2D_ShadowCol(col); col = Drawer2D_BlackTextShadows ? BITMAPCOL_BLACK : Drawer2D_ShadowCol(col);
} }
for (i = 0; i < text.length; i++) { for (i = 0; i < text.length; i++) {
@ -462,7 +469,7 @@ static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int
if (c == '&' && Drawer2D_ValidColCodeAt(&text, i + 1)) { if (c == '&' && Drawer2D_ValidColCodeAt(&text, i + 1)) {
col = Drawer2D_GetCol(text.buffer[i + 1]); col = Drawer2D_GetCol(text.buffer[i + 1]);
if (shadow) { if (shadow) {
col = Drawer2D_BlackTextShadows ? black : Drawer2D_ShadowCol(col); col = Drawer2D_BlackTextShadows ? BITMAPCOL_BLACK : Drawer2D_ShadowCol(col);
} }
i++; continue; /* skip over the colour code */ i++; continue; /* skip over the colour code */
} }
@ -497,16 +504,19 @@ static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int
for (xx = 0; xx < dstWidth; xx++) { for (xx = 0; xx < dstWidth; xx++) {
fontX = srcX + xx * srcWidth / dstWidth; fontX = srcX + xx * srcWidth / dstWidth;
src = srcRow[fontX]; src = srcRow[fontX];
if (!src.A) continue; if (!BitmapCol_A(src)) continue;
dstX = x + xx; dstX = x + xx;
if ((unsigned)dstX >= (unsigned)bmp->Width) continue; if ((unsigned)dstX >= (unsigned)bmp->Width) continue;
dst.B = src.B * col.B / 255; /* TODO: Transparent text by multiplying by col.A */
dst.G = src.G * col.G / 255; /* TODO: Not shift when multiplying */
dst.R = src.R * col.R / 255; /* TODO: avoid BitmapCol_A shift */
dst.A = src.A; dstRow[dstX] = BitmapCol_Make(
dstRow[dstX] = dst; BitmapCol_R(src) * BitmapCol_R(col) / 255,
BitmapCol_G(src) * BitmapCol_G(col) / 255,
BitmapCol_B(src) * BitmapCol_B(col) / 255,
BitmapCol_A(src));
} }
x += dstWidth + xPadding; x += dstWidth + xPadding;
} }
@ -523,7 +533,7 @@ static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int
dstWidth = 0; dstWidth = 0;
col = cols[i]; col = cols[i];
for (; i < count && BitmapCol_Equals(col, cols[i]); i++) { for (; i < count && col == cols[i]; i++) {
dstWidth += dstWidths[i] + xPadding; dstWidth += dstWidths[i] + xPadding;
} }
Drawer2D_Underline(bmp, x, underlineY, dstWidth, underlineHeight, col); Drawer2D_Underline(bmp, x, underlineY, dstWidth, underlineHeight, col);
@ -567,7 +577,7 @@ static int Drawer2D_MeasureBitmapWidth(const struct DrawTextArgs* args) {
} }
void Drawer2D_DrawText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y) { void Drawer2D_DrawText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y) {
BitmapCol col, backCol, black = BITMAPCOL_CONST(0, 0, 0, 255); BitmapCol col, backCol;
String value = args->text; String value = args->text;
char colCode, nextCol = 'f'; char colCode, nextCol = 'f';
int i, partWidth; int i, partWidth;
@ -582,7 +592,7 @@ void Drawer2D_DrawText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y) {
col = Drawer2D_GetCol(colCode); col = Drawer2D_GetCol(colCode);
if (args->useShadow) { if (args->useShadow) {
backCol = Drawer2D_BlackTextShadows ? black : Drawer2D_ShadowCol(col); backCol = Drawer2D_BlackTextShadows ? BITMAPCOL_BLACK : Drawer2D_ShadowCol(col);
Font_SysTextDraw(args, bmp, x, y, backCol, true); Font_SysTextDraw(args, bmp, x, y, backCol, true);
} }
@ -672,18 +682,17 @@ void Drawer2D_DrawClippedText(Bitmap* bmp, struct DrawTextArgs* args, int x, int
*---------------------------------------------------Drawer2D component----------------------------------------------------* *---------------------------------------------------Drawer2D component----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static void Drawer2D_HexEncodedCol(int i, int hex, cc_uint8 lo, cc_uint8 hi) { static void Drawer2D_HexEncodedCol(int i, int hex, cc_uint8 lo, cc_uint8 hi) {
Drawer2D_Cols[i].R = (cc_uint8)(lo * ((hex >> 2) & 1) + hi * (hex >> 3)); Drawer2D_Cols[i] = BitmapCol_Make(
Drawer2D_Cols[i].G = (cc_uint8)(lo * ((hex >> 1) & 1) + hi * (hex >> 3)); lo * ((hex >> 2) & 1) + hi * (hex >> 3),
Drawer2D_Cols[i].B = (cc_uint8)(lo * ((hex >> 0) & 1) + hi * (hex >> 3)); lo * ((hex >> 1) & 1) + hi * (hex >> 3),
Drawer2D_Cols[i].A = 255; lo * ((hex >> 0) & 1) + hi * (hex >> 3),
255);
} }
static void Drawer2D_Reset(void) { static void Drawer2D_Reset(void) {
BitmapCol col = BITMAPCOL_CONST(0, 0, 0, 0); int i;
int i;
for (i = 0; i < DRAWER2D_MAX_COLS; i++) { for (i = 0; i < DRAWER2D_MAX_COLS; i++) {
Drawer2D_Cols[i] = col; Drawer2D_Cols[i] = 0;
} }
for (i = 0; i <= 9; i++) { for (i = 0; i <= 9; i++) {
@ -820,6 +829,9 @@ static ReturnCode SysFont_Init(const String* path, struct SysFont* font, FT_Open
FileHandle file; FileHandle file;
cc_uint32 size; cc_uint32 size;
ReturnCode res; ReturnCode res;
#ifdef CC_BUILD_OSX
String filename;
#endif
if ((res = File_Open(&file, path))) return res; if ((res = File_Open(&file, path))) return res;
if ((res = File_Length(file, &size))) { File_Close(file); return res; } if ((res = File_Length(file, &size))) { File_Close(file); return res; }
@ -845,7 +857,7 @@ static ReturnCode SysFont_Init(const String* path, struct SysFont* font, FT_Open
/* For OSX font suitcase files */ /* For OSX font suitcase files */
#ifdef CC_BUILD_OSX #ifdef CC_BUILD_OSX
String filename = String_NT_Array(font->filename); String_InitArray_NT(filename, font->filename);
String_Copy(&filename, path); String_Copy(&filename, path);
font->filename[filename.length] = '\0'; font->filename[filename.length] = '\0';
args->pathname = font->filename; args->pathname = font->filename;
@ -1069,7 +1081,7 @@ static int Font_SysTextWidth(struct DrawTextArgs* args) {
static void DrawGrayscaleGlyph(FT_Bitmap* img, Bitmap* bmp, int x, int y, BitmapCol col) { static void DrawGrayscaleGlyph(FT_Bitmap* img, Bitmap* bmp, int x, int y, BitmapCol col) {
cc_uint8* src; cc_uint8* src;
BitmapCol* dst; BitmapCol* dst;
cc_uint8 intensity, invIntensity; cc_uint8 I, invI; /* intensity */
int xx, yy; int xx, yy;
for (yy = 0; yy < img->rows; yy++) { for (yy = 0; yy < img->rows; yy++) {
@ -1079,13 +1091,17 @@ static void DrawGrayscaleGlyph(FT_Bitmap* img, Bitmap* bmp, int x, int y, Bitmap
for (xx = 0; xx < img->width; xx++, src++, dst++) { for (xx = 0; xx < img->width; xx++, src++, dst++) {
if ((unsigned)(x + xx) >= (unsigned)bmp->Width) continue; if ((unsigned)(x + xx) >= (unsigned)bmp->Width) continue;
intensity = *src; invIntensity = UInt8_MaxValue - intensity; I = *src; invI = UInt8_MaxValue - I;
dst->B = ((col.B * intensity) >> 8) + ((dst->B * invIntensity) >> 8); /* TODO: Support transparent text */
dst->G = ((col.G * intensity) >> 8) + ((dst->G * invIntensity) >> 8); /* dst->A = ((col.A * intensity) >> 8) + ((dst->A * invIntensity) >> 8);*/
dst->R = ((col.R * intensity) >> 8) + ((dst->R * invIntensity) >> 8); /* TODO: Not shift when multiplying */
/*dst->A = ((col.A * intensity) >> 8) + ((dst->A * invIntensity) >> 8);*/ *dst = BitmapCol_Make(
dst->A = intensity + ((dst->A * invIntensity) >> 8); ((BitmapCol_R(col) * I) >> 8) + ((BitmapCol_R(*dst) * invI) >> 8),
((BitmapCol_G(col) * I) >> 8) + ((BitmapCol_G(*dst) * invI) >> 8),
((BitmapCol_B(col) * I) >> 8) + ((BitmapCol_B(*dst) * invI) >> 8),
((BitmapCol_A(*dst) * invI) >> 8)
);
} }
} }
} }
@ -1105,15 +1121,15 @@ static void DrawBlackWhiteGlyph(FT_Bitmap* img, Bitmap* bmp, int x, int y, Bitma
if ((unsigned)(x + xx) >= (unsigned)bmp->Width) continue; if ((unsigned)(x + xx) >= (unsigned)bmp->Width) continue;
intensity = src[xx >> 3]; intensity = src[xx >> 3];
/* TODO: transparent text (don't set A to 255) */
if (intensity & (1 << (7 - (xx & 7)))) { if (intensity & (1 << (7 - (xx & 7)))) {
dst->B = col.B; dst->G = col.G; dst->R = col.R; *dst = col | BitmapCol_A_Bits(255);
/*dst->A = col.A*/
dst->A = 255;
} }
} }
} }
} }
static FT_Vector shadow_delta = { 83, -83 };
static int Font_SysTextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, BitmapCol col, bool shadow) { static int Font_SysTextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, BitmapCol col, bool shadow) {
struct SysFont* font = (struct SysFont*)args->font->handle; struct SysFont* font = (struct SysFont*)args->font->handle;
FT_BitmapGlyph* glyphs = font->glyphs; FT_BitmapGlyph* glyphs = font->glyphs;
@ -1131,8 +1147,7 @@ static int Font_SysTextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y
if (shadow) { if (shadow) {
glyphs = font->shadow_glyphs; glyphs = font->shadow_glyphs;
FT_Vector delta = { 83, -83 }; FT_Set_Transform(face, NULL, &shadow_delta);
FT_Set_Transform(face, NULL, &delta);
} }
height = args->font->height; height = args->font->height;

View File

@ -229,7 +229,7 @@ bool Entity_TouchesAnyWater(struct Entity* e) {
static void Entity_MakeNameTexture(struct Entity* e) { static void Entity_MakeNameTexture(struct Entity* e) {
String colorlessName; char colorlessBuffer[STRING_SIZE]; String colorlessName; char colorlessBuffer[STRING_SIZE];
BitmapCol shadowCol = BITMAPCOL_CONST(80, 80, 80, 255); BitmapCol shadowCol = BitmapCol_Make(80, 80, 80, 255);
BitmapCol origWhiteCol; BitmapCol origWhiteCol;
struct DrawTextArgs args; struct DrawTextArgs args;
@ -396,18 +396,16 @@ static void Entity_ClearHat(Bitmap* bmp, cc_uint8 skinType) {
for (y = 0; y < sizeY; y++) { for (y = 0; y < sizeY; y++) {
BitmapCol* row = Bitmap_GetRow(bmp, y) + sizeX; BitmapCol* row = Bitmap_GetRow(bmp, y) + sizeX;
for (x = 0; x < sizeX; x++) { for (x = 0; x < sizeX; x++) {
if (row[x].A != 255) return; if (BitmapCol_A(row[x]) != 255) return;
} }
} }
/* only perform filtering when the entire hat is opaque */ /* only perform filtering when the entire hat is opaque */
cc_uint32 white = PackedCol_ARGB(255, 255, 255, 255);
cc_uint32 black = PackedCol_ARGB(0, 0, 0, 255);
for (y = 0; y < sizeY; y++) { for (y = 0; y < sizeY; y++) {
cc_uint32* row = Bitmap_RawRow(bmp, y) + sizeX; BitmapCol* row = Bitmap_GetRow(bmp, y) + sizeX;
for (x = 0; x < sizeX; x++) { for (x = 0; x < sizeX; x++) {
cc_uint32 pixel = row[x]; BitmapCol c = row[x];
if (pixel == white || pixel == black) row[x] = 0; if (c == BITMAPCOL_WHITE || c == BITMAPCOL_BLACK) row[x] = 0;
} }
} }
} }

View File

@ -586,8 +586,7 @@ static bool ShadowComponent_GetBlocks(struct Entity* e, int x, int y, int z, str
#define sh_half (sh_size / 2) #define sh_half (sh_size / 2)
static void ShadowComponent_MakeTex(void) { static void ShadowComponent_MakeTex(void) {
cc_uint8 pixels[Bitmap_DataSize(sh_size, sh_size)]; cc_uint8 pixels[Bitmap_DataSize(sh_size, sh_size)];
BitmapCol inPix = BITMAPCOL_CONST(0, 0, 0, 200); BitmapCol col = BitmapCol_Make(0, 0, 0, 200);
BitmapCol outPix = BITMAPCOL_CONST(0, 0, 0, 0);
Bitmap bmp; Bitmap bmp;
cc_uint32 x, y; cc_uint32 x, y;
@ -599,7 +598,7 @@ static void ShadowComponent_MakeTex(void) {
double dist = double dist =
(sh_half - (x + 0.5)) * (sh_half - (x + 0.5)) + (sh_half - (x + 0.5)) * (sh_half - (x + 0.5)) +
(sh_half - (y + 0.5)) * (sh_half - (y + 0.5)); (sh_half - (y + 0.5)) * (sh_half - (y + 0.5));
row[x] = dist < sh_half * sh_half ? inPix : outPix; row[x] = dist < sh_half * sh_half ? col : 0;
} }
} }
ShadowComponent_ShadowTex = Gfx_CreateTexture(&bmp, false, false); ShadowComponent_ShadowTex = Gfx_CreateTexture(&bmp, false, false);

View File

@ -206,25 +206,25 @@ static BitmapCol AverageCol(BitmapCol p1, BitmapCol p2) {
cc_uint32 a1, a2, aSum; cc_uint32 a1, a2, aSum;
cc_uint32 b1, g1, r1; cc_uint32 b1, g1, r1;
cc_uint32 b2, g2, r2; cc_uint32 b2, g2, r2;
BitmapCol ave;
a1 = p1.A; a2 = p2.A; a1 = BitmapCol_A(p1); a2 = BitmapCol_A(p2);
aSum = (a1 + a2); aSum = (a1 + a2);
aSum = aSum > 0 ? aSum : 1; /* avoid divide by 0 below */ aSum = aSum > 0 ? aSum : 1; /* avoid divide by 0 below */
/* Convert RGB to pre-multiplied form */ /* Convert RGB to pre-multiplied form */
b1 = p1.B * a1; g1 = p1.G * a1; r1 = p1.R * a1; /* TODO: Don't shift when multiplying/averaging */
b2 = p2.B * a2; g2 = p2.G * a2; r2 = p2.R * a2; r1 = BitmapCol_R(p1) * a1; g1 = BitmapCol_G(p1) * a1; b1 = BitmapCol_B(p1) * a1;
r2 = BitmapCol_R(p2) * a2; g2 = BitmapCol_G(p2) * a2; b2 = BitmapCol_B(p2) * a2;
/* https://stackoverflow.com/a/347376 */ /* https://stackoverflow.com/a/347376 */
/* We need to convert RGB back from the pre-multiplied average into normal form */ /* We need to convert RGB back from the pre-multiplied average into normal form */
/* ((r1 + r2) / 2) / ((a1 + a2) / 2) */ /* ((r1 + r2) / 2) / ((a1 + a2) / 2) */
/* but we just cancel out the / 2 */ /* but we just cancel out the / 2 */
ave.B = (b1 + b2) / aSum; return BitmapCol_Make(
ave.G = (g1 + g2) / aSum; (r1 + r2) / aSum,
ave.R = (r1 + r2) / aSum; (g1 + g2) / aSum,
ave.A = aSum >> 1; (b1 + b2) / aSum,
return ave; aSum >> 1);
} }
/* Generates the next mipmaps level bitmap for the given bitmap. */ /* Generates the next mipmaps level bitmap for the given bitmap. */

View File

@ -330,15 +330,15 @@ CC_NOINLINE static void ColoursScreen_Update(struct ColoursScreen* s, int i, Bit
String tmp; char tmpBuffer[3]; String tmp; char tmpBuffer[3];
String_InitArray(tmp, tmpBuffer); String_InitArray(tmp, tmpBuffer);
String_AppendInt(&tmp, col.R); String_AppendInt(&tmp, BitmapCol_R(col));
LInput_SetText(&s->iptColours[i + 0], &tmp); LInput_SetText(&s->iptColours[i + 0], &tmp);
tmp.length = 0; tmp.length = 0;
String_AppendInt(&tmp, col.G); String_AppendInt(&tmp, BitmapCol_G(col));
LInput_SetText(&s->iptColours[i + 1], &tmp); LInput_SetText(&s->iptColours[i + 1], &tmp);
tmp.length = 0; tmp.length = 0;
String_AppendInt(&tmp, col.B); String_AppendInt(&tmp, BitmapCol_B(col));
LInput_SetText(&s->iptColours[i + 2], &tmp); LInput_SetText(&s->iptColours[i + 2], &tmp);
} }
@ -368,7 +368,7 @@ static void ColoursScreen_TextChanged(struct LInput* w) {
if (!Convert_ParseUInt8(&s->iptColours[index + 1].Text, &g)) return; if (!Convert_ParseUInt8(&s->iptColours[index + 1].Text, &g)) return;
if (!Convert_ParseUInt8(&s->iptColours[index + 2].Text, &b)) return; if (!Convert_ParseUInt8(&s->iptColours[index + 2].Text, &b)) return;
col->R = r; col->G = g; col->B = b; *col = BitmapCol_Make(r, g, b, 255);
Launcher_SaveSkin(); Launcher_SaveSkin();
Launcher_Redraw(); Launcher_Redraw();
} }
@ -952,7 +952,7 @@ static void ResourcesScreen_Next(void* w, int x, int y) {
static void ResourcesScreen_Init(struct LScreen* s_) { static void ResourcesScreen_Init(struct LScreen* s_) {
String str; char buffer[STRING_SIZE]; String str; char buffer[STRING_SIZE];
BitmapCol progressCol = BITMAPCOL_CONST(0, 220, 0, 255); BitmapCol progressCol = BitmapCol_Make(0, 220, 0, 255);
struct ResourcesScreen* s = (struct ResourcesScreen*)s_; struct ResourcesScreen* s = (struct ResourcesScreen*)s_;
float size; float size;
@ -1001,13 +1001,13 @@ static void ResourcesScreen_Layout(struct LScreen* s_) {
} }
CC_NOINLINE static void ResourcesScreen_ResetArea(int x, int y, int width, int height) { CC_NOINLINE static void ResourcesScreen_ResetArea(int x, int y, int width, int height) {
BitmapCol boxCol = BITMAPCOL_CONST(120, 85, 151, 255); BitmapCol boxCol = BitmapCol_Make(120, 85, 151, 255);
Gradient_Noise(&Launcher_Framebuffer, boxCol, 4, x, y, width, height); Gradient_Noise(&Launcher_Framebuffer, boxCol, 4, x, y, width, height);
Launcher_MarkDirty(x, y, width, height); Launcher_MarkDirty(x, y, width, height);
} }
static void ResourcesScreen_Draw(struct LScreen* s) { static void ResourcesScreen_Draw(struct LScreen* s) {
BitmapCol backCol = BITMAPCOL_CONST(12, 12, 12, 255); BitmapCol backCol = BitmapCol_Make(12, 12, 12, 255);
int x, y, width, height; int x, y, width, height;
Drawer2D_Clear(&Launcher_Framebuffer, backCol, Drawer2D_Clear(&Launcher_Framebuffer, backCol,

View File

@ -50,15 +50,15 @@ void LWidget_Redraw(void* widget) {
*#########################################################################################################################*/ *#########################################################################################################################*/
static BitmapCol LButton_Expand(BitmapCol a, int amount) { static BitmapCol LButton_Expand(BitmapCol a, int amount) {
int r, g, b; int r, g, b;
r = a.R + amount; Math_Clamp(r, 0, 255); a.R = r; r = BitmapCol_R(a) + amount; Math_Clamp(r, 0, 255);
g = a.G + amount; Math_Clamp(g, 0, 255); a.G = g; g = BitmapCol_G(a) + amount; Math_Clamp(g, 0, 255);
b = a.B + amount; Math_Clamp(b, 0, 255); a.B = b; b = BitmapCol_B(a) + amount; Math_Clamp(b, 0, 255);
return a; return BitmapCol_Make(r, g, b, 255);
} }
static void LButton_DrawBackground(struct LButton* w) { static void LButton_DrawBackground(struct LButton* w) {
BitmapCol activeCol = BITMAPCOL_CONST(126, 136, 191, 255); BitmapCol activeCol = BitmapCol_Make(126, 136, 191, 255);
BitmapCol inactiveCol = BITMAPCOL_CONST(111, 111, 111, 255); BitmapCol inactiveCol = BitmapCol_Make(111, 111, 111, 255);
BitmapCol col; BitmapCol col;
if (Launcher_ClassicBackground) { if (Launcher_ClassicBackground) {
@ -75,7 +75,7 @@ static void LButton_DrawBackground(struct LButton* w) {
} }
static void LButton_DrawBorder(struct LButton* w) { static void LButton_DrawBorder(struct LButton* w) {
BitmapCol black = BITMAPCOL_CONST(0, 0, 0, 255); BitmapCol black = BitmapCol_Make(0, 0, 0, 255);
BitmapCol backCol = Launcher_ClassicBackground ? black : Launcher_ButtonBorderCol; BitmapCol backCol = Launcher_ClassicBackground ? black : Launcher_ButtonBorderCol;
Drawer2D_Clear(&Launcher_Framebuffer, backCol, Drawer2D_Clear(&Launcher_Framebuffer, backCol,
@ -93,8 +93,8 @@ static void LButton_DrawBorder(struct LButton* w) {
} }
static void LButton_DrawHighlight(struct LButton* w) { static void LButton_DrawHighlight(struct LButton* w) {
BitmapCol activeCol = BITMAPCOL_CONST(189, 198, 255, 255); BitmapCol activeCol = BitmapCol_Make(189, 198, 255, 255);
BitmapCol inactiveCol = BITMAPCOL_CONST(168, 168, 168, 255); BitmapCol inactiveCol = BitmapCol_Make(168, 168, 168, 255);
BitmapCol highlightCol; BitmapCol highlightCol;
if (Launcher_ClassicBackground) { if (Launcher_ClassicBackground) {
@ -176,7 +176,7 @@ CC_NOINLINE static void LInput_GetText(struct LInput* w, String* text) {
} }
static void LInput_DrawOuterBorder(struct LInput* w) { static void LInput_DrawOuterBorder(struct LInput* w) {
BitmapCol col = BITMAPCOL_CONST(97, 81, 110, 255); BitmapCol col = BitmapCol_Make(97, 81, 110, 255);
if (w->Selected) { if (w->Selected) {
Drawer2D_Clear(&Launcher_Framebuffer, col, Drawer2D_Clear(&Launcher_Framebuffer, col,
@ -204,7 +204,7 @@ static void LInput_DrawOuterBorder(struct LInput* w) {
} }
static void LInput_DrawInnerBorder(struct LInput* w) { static void LInput_DrawInnerBorder(struct LInput* w) {
BitmapCol col = BITMAPCOL_CONST(165, 142, 168, 255); BitmapCol col = BitmapCol_Make(165, 142, 168, 255);
Drawer2D_Clear(&Launcher_Framebuffer, col, Drawer2D_Clear(&Launcher_Framebuffer, col,
w->X + BORDER, w->Y + BORDER, w->X + BORDER, w->Y + BORDER,
@ -221,7 +221,7 @@ static void LInput_DrawInnerBorder(struct LInput* w) {
} }
static void LInput_BlendBoxTop(struct LInput* w) { static void LInput_BlendBoxTop(struct LInput* w) {
BitmapCol col = BITMAPCOL_CONST(0, 0, 0, 255); BitmapCol col = BitmapCol_Make(0, 0, 0, 255);
Gradient_Blend(&Launcher_Framebuffer, col, 75, Gradient_Blend(&Launcher_Framebuffer, col, 75,
w->X + BORDER, w->Y + BORDER, w->X + BORDER, w->Y + BORDER,
@ -255,7 +255,6 @@ static void LInput_Draw(void* widget) {
String text; char textBuffer[STRING_SIZE]; String text; char textBuffer[STRING_SIZE];
struct DrawTextArgs args; struct DrawTextArgs args;
Size2D size; Size2D size;
BitmapCol white = BITMAPCOL_CONST(255, 255, 255, 255);
String_InitArray(text, textBuffer); String_InitArray(text, textBuffer);
LInput_GetText(w, &text); LInput_GetText(w, &text);
@ -267,7 +266,7 @@ static void LInput_Draw(void* widget) {
LInput_DrawOuterBorder(w); LInput_DrawOuterBorder(w);
LInput_DrawInnerBorder(w); LInput_DrawInnerBorder(w);
Drawer2D_Clear(&Launcher_Framebuffer, white, Drawer2D_Clear(&Launcher_Framebuffer, BITMAPCOL_WHITE,
w->X + BORDER2, w->Y + BORDER2, w->X + BORDER2, w->Y + BORDER2,
w->Width - BORDER4, w->Height - BORDER4); w->Width - BORDER4, w->Height - BORDER4);
LInput_BlendBoxTop(w); LInput_BlendBoxTop(w);
@ -309,7 +308,6 @@ static Rect2D lastCaretRec;
static void LInput_TickCaret(void* widget) { static void LInput_TickCaret(void* widget) {
struct LInput* w = (struct LInput*)widget; struct LInput* w = (struct LInput*)widget;
BitmapCol col = BITMAPCOL_CONST(0, 0, 0, 255);
int elapsed; int elapsed;
bool caretShow; bool caretShow;
Rect2D r; Rect2D r;
@ -325,7 +323,7 @@ static void LInput_TickCaret(void* widget) {
r = LInput_MeasureCaret(w); r = LInput_MeasureCaret(w);
if (caretShow) { if (caretShow) {
Drawer2D_Clear(&Launcher_Framebuffer, col, Drawer2D_Clear(&Launcher_Framebuffer, BITMAPCOL_BLACK,
r.X, r.Y, r.Width, r.Height); r.X, r.Y, r.Width, r.Height);
} }
@ -607,8 +605,8 @@ void LLine_Init(struct LScreen* s, struct LLine* w, int width) {
*------------------------------------------------------SliderWidget-------------------------------------------------------* *------------------------------------------------------SliderWidget-------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static void LSlider_DrawBoxBounds(struct LSlider* w) { static void LSlider_DrawBoxBounds(struct LSlider* w) {
BitmapCol boundsTop = BITMAPCOL_CONST(119, 100, 132, 255); BitmapCol boundsTop = BitmapCol_Make(119, 100, 132, 255);
BitmapCol boundsBottom = BITMAPCOL_CONST(150, 130, 165, 255); BitmapCol boundsBottom = BitmapCol_Make(150, 130, 165, 255);
/* TODO: Check these are actually right */ /* TODO: Check these are actually right */
Drawer2D_Clear(&Launcher_Framebuffer, boundsTop, Drawer2D_Clear(&Launcher_Framebuffer, boundsTop,
@ -627,8 +625,8 @@ static void LSlider_DrawBoxBounds(struct LSlider* w) {
} }
static void LSlider_DrawBox(struct LSlider* w) { static void LSlider_DrawBox(struct LSlider* w) {
BitmapCol progTop = BITMAPCOL_CONST(220, 204, 233, 255); BitmapCol progTop = BitmapCol_Make(220, 204, 233, 255);
BitmapCol progBottom = BITMAPCOL_CONST(207, 181, 216, 255); BitmapCol progBottom = BitmapCol_Make(207, 181, 216, 255);
int halfHeight = (w->Height - BORDER2) / 2; int halfHeight = (w->Height - BORDER2) / 2;
Gradient_Vertical(&Launcher_Framebuffer, progTop, progBottom, Gradient_Vertical(&Launcher_Framebuffer, progTop, progBottom,
@ -775,7 +773,7 @@ static void LTable_SetSelectedTo(struct LTable* w, int index) {
/* Draws background behind column headers */ /* Draws background behind column headers */
static void LTable_DrawHeaderBackground(struct LTable* w) { static void LTable_DrawHeaderBackground(struct LTable* w) {
BitmapCol gridCol = BITMAPCOL_CONST(20, 20, 10, 255); BitmapCol gridCol = BitmapCol_Make(20, 20, 10, 255);
if (!Launcher_ClassicBackground) { if (!Launcher_ClassicBackground) {
Drawer2D_Clear(&Launcher_Framebuffer, gridCol, Drawer2D_Clear(&Launcher_Framebuffer, gridCol,
@ -787,11 +785,10 @@ static void LTable_DrawHeaderBackground(struct LTable* w) {
/* Works out the background colour of the given row */ /* Works out the background colour of the given row */
static BitmapCol LTable_RowCol(struct LTable* w, struct ServerInfo* row) { static BitmapCol LTable_RowCol(struct LTable* w, struct ServerInfo* row) {
BitmapCol emptyCol = BITMAPCOL_CONST(0, 0, 0, 0); BitmapCol gridCol = BitmapCol_Make( 20, 20, 10, 255);
BitmapCol gridCol = BITMAPCOL_CONST(20, 20, 10, 255); BitmapCol featSelCol = BitmapCol_Make( 50, 53, 0, 255);
BitmapCol featSelCol = BITMAPCOL_CONST( 50, 53, 0, 255); BitmapCol featuredCol = BitmapCol_Make(101, 107, 0, 255);
BitmapCol featuredCol = BITMAPCOL_CONST(101, 107, 0, 255); BitmapCol selectedCol = BitmapCol_Make( 40, 40, 40, 255);
BitmapCol selectedCol = BITMAPCOL_CONST( 40, 40, 40, 255);
bool selected; bool selected;
if (row) { if (row) {
@ -802,7 +799,7 @@ static BitmapCol LTable_RowCol(struct LTable* w, struct ServerInfo* row) {
return selectedCol; return selectedCol;
} }
} }
return Launcher_ClassicBackground ? emptyCol : gridCol; return Launcher_ClassicBackground ? 0 : gridCol;
} }
/* Draws background behind each row in the table */ /* Draws background behind each row in the table */
@ -821,7 +818,7 @@ static void LTable_DrawRowsBackground(struct LTable* w) {
/* hit the end of the table */ /* hit the end of the table */
if (height < 0) break; if (height < 0) break;
if (col.A) { if (col) {
Drawer2D_Clear(&Launcher_Framebuffer, col, Drawer2D_Clear(&Launcher_Framebuffer, col,
w->X, y, w->Width, height); w->X, y, w->Width, height);
} else { } else {
@ -912,8 +909,8 @@ static void LTable_DrawRows(struct LTable* w) {
/* Draws scrollbar on the right edge of the table */ /* Draws scrollbar on the right edge of the table */
static void LTable_DrawScrollbar(struct LTable* w) { static void LTable_DrawScrollbar(struct LTable* w) {
BitmapCol classicBack = BITMAPCOL_CONST( 80, 80, 80, 255); BitmapCol classicBack = BitmapCol_Make( 80, 80, 80, 255);
BitmapCol classicScroll = BITMAPCOL_CONST(160, 160, 160, 255); BitmapCol classicScroll = BitmapCol_Make(160, 160, 160, 255);
BitmapCol backCol = Launcher_ClassicBackground ? classicBack : Launcher_ButtonBorderCol; BitmapCol backCol = Launcher_ClassicBackground ? classicBack : Launcher_ButtonBorderCol;
BitmapCol scrollCol = Launcher_ClassicBackground ? classicScroll : Launcher_ButtonForeActiveCol; BitmapCol scrollCol = Launcher_ClassicBackground ? classicScroll : Launcher_ButtonForeActiveCol;

View File

@ -161,8 +161,6 @@ static void Launcher_Display(void) {
} }
static void Launcher_Init(void) { static void Launcher_Init(void) {
BitmapCol col = BITMAPCOL_CONST(125, 125, 125, 255);
Event_RegisterVoid(&WindowEvents.Resized, NULL, Launcher_OnResize); Event_RegisterVoid(&WindowEvents.Resized, NULL, Launcher_OnResize);
Event_RegisterVoid(&WindowEvents.StateChanged, NULL, Launcher_OnResize); Event_RegisterVoid(&WindowEvents.StateChanged, NULL, Launcher_OnResize);
Event_RegisterVoid(&WindowEvents.Redraw, NULL, Launcher_ReqeustRedraw); Event_RegisterVoid(&WindowEvents.Redraw, NULL, Launcher_ReqeustRedraw);
@ -179,7 +177,7 @@ static void Launcher_Init(void) {
Drawer2D_MakeFont(&Launcher_TextFont, 14, FONT_STYLE_NORMAL); Drawer2D_MakeFont(&Launcher_TextFont, 14, FONT_STYLE_NORMAL);
Drawer2D_MakeFont(&Launcher_HintFont, 12, FONT_STYLE_ITALIC); Drawer2D_MakeFont(&Launcher_HintFont, 12, FONT_STYLE_ITALIC);
Drawer2D_Cols['g'] = col; Drawer2D_Cols['g'] = BitmapCol_Make(125, 125, 125, 255);
Utils_EnsureDirectory("texpacks"); Utils_EnsureDirectory("texpacks");
Utils_EnsureDirectory("audio"); Utils_EnsureDirectory("audio");
} }
@ -302,34 +300,33 @@ void Launcher_Run(void) {
/*########################################################################################################################* /*########################################################################################################################*
*---------------------------------------------------------Colours/Skin----------------------------------------------------* *---------------------------------------------------------Colours/Skin----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
BitmapCol Launcher_BackgroundCol = BITMAPCOL_CONST(153, 127, 172, 255); #define DEFAULT_BACKGROUND_COL BitmapCol_Make(153, 127, 172, 255);
BitmapCol Launcher_ButtonBorderCol = BITMAPCOL_CONST( 97, 81, 110, 255); #define DEFAULT_BUTTON_BORDER_COL BitmapCol_Make( 97, 81, 110, 255);
BitmapCol Launcher_ButtonForeActiveCol = BITMAPCOL_CONST(189, 168, 206, 255); #define DEFAULT_BUTTON_FORE_ACTIVE_COL BitmapCol_Make(189, 168, 206, 255);
BitmapCol Launcher_ButtonForeCol = BITMAPCOL_CONST(141, 114, 165, 255); #define DEFAULT_BUTTON_FORE_COL BitmapCol_Make(141, 114, 165, 255);
BitmapCol Launcher_ButtonHighlightCol = BITMAPCOL_CONST(162, 131, 186, 255); #define DEFAULT_BUTTON_HIGHLIGHT_COL BitmapCol_Make(162, 131, 186, 255);
BitmapCol Launcher_BackgroundCol = DEFAULT_BACKGROUND_COL;
BitmapCol Launcher_ButtonBorderCol = DEFAULT_BUTTON_BORDER_COL;
BitmapCol Launcher_ButtonForeActiveCol = DEFAULT_BUTTON_FORE_ACTIVE_COL;
BitmapCol Launcher_ButtonForeCol = DEFAULT_BUTTON_FORE_COL;
BitmapCol Launcher_ButtonHighlightCol = DEFAULT_BUTTON_HIGHLIGHT_COL;
void Launcher_ResetSkin(void) { void Launcher_ResetSkin(void) {
/* Have to duplicate it here, sigh */ Launcher_BackgroundCol = DEFAULT_BACKGROUND_COL;
BitmapCol defaultBackgroundCol = BITMAPCOL_CONST(153, 127, 172, 255); Launcher_ButtonBorderCol = DEFAULT_BUTTON_BORDER_COL;
BitmapCol defaultButtonBorderCol = BITMAPCOL_CONST( 97, 81, 110, 255); Launcher_ButtonForeActiveCol = DEFAULT_BUTTON_FORE_ACTIVE_COL;
BitmapCol defaultButtonForeActiveCol = BITMAPCOL_CONST(189, 168, 206, 255); Launcher_ButtonForeCol = DEFAULT_BUTTON_FORE_COL;
BitmapCol defaultButtonForeCol = BITMAPCOL_CONST(141, 114, 165, 255); Launcher_ButtonHighlightCol = DEFAULT_BUTTON_HIGHLIGHT_COL;
BitmapCol defaultButtonHighlightCol = BITMAPCOL_CONST(162, 131, 186, 255);
Launcher_BackgroundCol = defaultBackgroundCol;
Launcher_ButtonBorderCol = defaultButtonBorderCol;
Launcher_ButtonForeActiveCol = defaultButtonForeActiveCol;
Launcher_ButtonForeCol = defaultButtonForeCol;
Launcher_ButtonHighlightCol = defaultButtonHighlightCol;
} }
CC_NOINLINE static void Launcher_GetCol(const char* key, BitmapCol* col) { CC_NOINLINE static void Launcher_GetCol(const char* key, BitmapCol* col) {
cc_uint8 rgb[3]; cc_uint8 rgb[3];
String value; String value;
if (!Options_UNSAFE_Get(key, &value)) return; if (!Options_UNSAFE_Get(key, &value)) return;
if (!PackedCol_TryParseHex(&value, rgb)) return; if (!PackedCol_TryParseHex(&value, rgb)) return;
col->R = rgb[0]; col->G = rgb[1]; col->B = rgb[2]; *col = BitmapCol_Make(rgb[0], rgb[1], rgb[2], 255);
} }
void Launcher_LoadSkin(void) { void Launcher_LoadSkin(void) {
@ -343,7 +340,7 @@ void Launcher_LoadSkin(void) {
CC_NOINLINE static void Launcher_SetCol(const char* key, BitmapCol col) { CC_NOINLINE static void Launcher_SetCol(const char* key, BitmapCol col) {
String value; char valueBuffer[8]; String value; char valueBuffer[8];
/* Component order might be different to BitmapCol */ /* Component order might be different to BitmapCol */
PackedCol tmp = PackedCol_Make(col.R, col.G, col.B, 0); PackedCol tmp = PackedCol_Make(BitmapCol_R(col), BitmapCol_G(col), BitmapCol_B(col), 0);
String_InitArray(value, valueBuffer); String_InitArray(value, valueBuffer);
PackedCol_ToHex(&value, tmp); PackedCol_ToHex(&value, tmp);

View File

@ -19,6 +19,7 @@ PackedCol PackedCol_Tint(PackedCol a, PackedCol b) {
cc_uint32 R = PackedCol_R(a) * PackedCol_R(b) / 255; cc_uint32 R = PackedCol_R(a) * PackedCol_R(b) / 255;
cc_uint32 G = PackedCol_G(a) * PackedCol_G(b) / 255; cc_uint32 G = PackedCol_G(a) * PackedCol_G(b) / 255;
cc_uint32 B = PackedCol_B(a) * PackedCol_B(b) / 255; cc_uint32 B = PackedCol_B(a) * PackedCol_B(b) / 255;
/* TODO: don't shift when multiplying */
return (a & PACKEDCOL_A_MASK) | (R << PACKEDCOL_R_SHIFT) | (G << PACKEDCOL_G_SHIFT) | (B << PACKEDCOL_B_SHIFT); return (a & PACKEDCOL_A_MASK) | (R << PACKEDCOL_R_SHIFT) | (G << PACKEDCOL_G_SHIFT) | (B << PACKEDCOL_B_SHIFT);
} }

View File

@ -1161,15 +1161,12 @@ static void CPE_BulkBlockUpdate(cc_uint8* data) {
} }
static void CPE_SetTextColor(cc_uint8* data) { static void CPE_SetTextColor(cc_uint8* data) {
BitmapCol c; BitmapCol c = BitmapCol_Make(data[0], data[1], data[2], data[3]);
cc_uint8 code; cc_uint8 code = data[4];
c.R = *data++; c.G = *data++; c.B = *data++; c.A = *data++;
code = *data;
/* disallow space, null, and colour code specifiers */ /* disallow space, null, and colour code specifiers */
if (code == '\0' || code == ' ' || code == 0xFF) return; if (code == '\0' || code == ' ' || code == 0xFF) return;
if (code == '%' || code == '&') return; if (code == '%' || code == '&') return;
Drawer2D_Cols[code] = c; Drawer2D_Cols[code] = c;
Event_RaiseInt(&ChatEvents.ColCodeChanged, code); Event_RaiseInt(&ChatEvents.ColCodeChanged, code);

View File

@ -86,10 +86,11 @@ static void LavaAnimation_Tick(BitmapCol* ptr, int size) {
col = 2.0f * L_soupHeat[i]; col = 2.0f * L_soupHeat[i];
Math_Clamp(col, 0.0f, 1.0f); Math_Clamp(col, 0.0f, 1.0f);
ptr->R = (cc_uint8)(col * 100.0f + 155.0f); *ptr = BitmapCol_Make(
ptr->G = (cc_uint8)(col * col * 255.0f); col * 100.0f + 155.0f,
ptr->B = (cc_uint8)(col * col * col * col * 128.0f); col * col * 255.0f,
ptr->A = 255; col * col * col * col * 128.0f,
255);
ptr++; i++; ptr++; i++;
} }
@ -137,10 +138,11 @@ static void WaterAnimation_Tick(BitmapCol* ptr, int size) {
Math_Clamp(col, 0.0f, 1.0f); Math_Clamp(col, 0.0f, 1.0f);
col = col * col; col = col * col;
ptr->R = (cc_uint8)(32.0f + col * 32.0f); *ptr = BitmapCol_Make(
ptr->G = (cc_uint8)(50.0f + col * 64.0f); 32.0f + col * 32.0f,
ptr->A = (cc_uint8)(146.0f + col * 50.0f); 50.0f + col * 64.0f,
ptr->B = 255; 255,
146.0f + col * 50.0f);
ptr++; i++; ptr++; i++;
} }

View File

@ -61,26 +61,27 @@ int Utils_AccumulateWheelDelta(float* accumulator, float delta) {
/* Checks if an area is completely black, so Alex skins edited with Microsoft Paint are still treated as Alex */ /* Checks if an area is completely black, so Alex skins edited with Microsoft Paint are still treated as Alex */
static bool Utils_IsAllBlack(const Bitmap* bmp, int x1, int y1, int width, int height) { static bool Utils_IsAllBlack(const Bitmap* bmp, int x1, int y1, int width, int height) {
cc_uint32 black = PackedCol_ARGB(0, 0, 0, 255);
int x, y; int x, y;
for (y = y1; y < y1 + height; y++) { for (y = y1; y < y1 + height; y++) {
cc_uint32* row = Bitmap_RawRow(bmp, y); BitmapCol* row = Bitmap_GetRow(bmp, y);
for (x = x1; x < x1 + width; x++) { for (x = x1; x < x1 + width; x++) {
if (row[x] != black) return false; if (row[x] != BITMAPCOL_BLACK) return false;
} }
} }
return true; return true;
} }
cc_uint8 Utils_CalcSkinType(const Bitmap* bmp) { cc_uint8 Utils_CalcSkinType(const Bitmap* bmp) {
BitmapCol col;
int scale; int scale;
if (bmp->Width == bmp->Height * 2) return SKIN_64x32; if (bmp->Width == bmp->Height * 2) return SKIN_64x32;
if (bmp->Width != bmp->Height) return SKIN_INVALID; if (bmp->Width != bmp->Height) return SKIN_INVALID;
scale = bmp->Width / 64; scale = bmp->Width / 64;
/* Minecraft alex skins have this particular pixel with alpha of 0 */ /* Minecraft alex skins have this particular pixel with alpha of 0 */
if (Bitmap_GetPixel(bmp, 54 * scale, 20 * scale).A < 128) return SKIN_64x64_SLIM; col = Bitmap_GetPixel(bmp, 54 * scale, 20 * scale);
if (BitmapCol_A(col) < 128) return SKIN_64x64_SLIM;
return Utils_IsAllBlack(bmp, 54 * scale, 20 * scale, 2 * scale, 12 * scale) return Utils_IsAllBlack(bmp, 54 * scale, 20 * scale, 2 * scale, 12 * scale)
&& Utils_IsAllBlack(bmp, 50 * scale, 16 * scale, 2 * scale, 4 * scale) ? SKIN_64x64_SLIM : SKIN_64x64; && Utils_IsAllBlack(bmp, 50 * scale, 16 * scale, 2 * scale, 4 * scale) ? SKIN_64x64_SLIM : SKIN_64x64;

View File

@ -928,7 +928,9 @@ static void InputWidget_UpdateCaret(struct InputWidget* w) {
if (colCode) { if (colCode) {
col = Drawer2D_GetCol(colCode); col = Drawer2D_GetCol(colCode);
w->caretCol = PackedCol_Make(col.R, col.G, col.B, col.A); /* Component order might be different to BitmapCol */
w->caretCol = PackedCol_Make(BitmapCol_R(col), BitmapCol_G(col),
BitmapCol_B(col), BitmapCol_A(col));
} else { } else {
w->caretCol = PackedCol_Scale(PACKEDCOL_WHITE, 0.8f); w->caretCol = PackedCol_Scale(PACKEDCOL_WHITE, 0.8f);
} }
@ -1018,7 +1020,7 @@ static bool InputWidget_CheckCol(struct InputWidget* w, int index) {
code = w->text.buffer[index]; code = w->text.buffer[index];
col = w->text.buffer[index + 1]; col = w->text.buffer[index + 1];
return (code == '%' || code == '&') && Drawer2D_GetCol(col).A; return (code == '%' || code == '&') && BitmapCol_A(Drawer2D_GetCol(col));
} }
static void InputWidget_BackspaceKey(struct InputWidget* w) { static void InputWidget_BackspaceKey(struct InputWidget* w) {
@ -2468,8 +2470,8 @@ static void SpecialInputWidget_UpdateColString(struct SpecialInputWidget* w) {
String_InitArray(w->colString, w->_colBuffer); String_InitArray(w->colString, w->_colBuffer);
for (i = 0; i < DRAWER2D_MAX_COLS; i++) { for (i = 0; i < DRAWER2D_MAX_COLS; i++) {
if (i >= 'A' && i <= 'F') continue; if (i >= 'A' && i <= 'F') continue;
if (!Drawer2D_Cols[i].A) continue; if (!BitmapCol_A(Drawer2D_Cols[i])) continue;
String_Append(&w->colString, '&'); String_Append(&w->colString, (char)i); String_Append(&w->colString, '&'); String_Append(&w->colString, (char)i);
String_Append(&w->colString, '%'); String_Append(&w->colString, (char)i); String_Append(&w->colString, '%'); String_Append(&w->colString, (char)i);
@ -2557,8 +2559,8 @@ static Size2D SpecialInputWidget_MeasureTitles(struct SpecialInputWidget* w) {
} }
static void SpecialInputWidget_DrawTitles(struct SpecialInputWidget* w, Bitmap* bmp) { static void SpecialInputWidget_DrawTitles(struct SpecialInputWidget* w, Bitmap* bmp) {
BitmapCol col_selected = BITMAPCOL_CONST(30, 30, 30, 200); BitmapCol col_selected = BitmapCol_Make(30, 30, 30, 200);
BitmapCol col_inactive = BITMAPCOL_CONST( 0, 0, 0, 127); BitmapCol col_inactive = BitmapCol_Make( 0, 0, 0, 127);
BitmapCol col; BitmapCol col;
struct DrawTextArgs args; struct DrawTextArgs args;
int i, width, x = 0; int i, width, x = 0;
@ -2618,7 +2620,7 @@ static void SpecialInputWidget_DrawContent(struct SpecialInputWidget* w, struct
} }
static void SpecialInputWidget_Make(struct SpecialInputWidget* w, struct SpecialInputTab* tab) { static void SpecialInputWidget_Make(struct SpecialInputWidget* w, struct SpecialInputTab* tab) {
BitmapCol col = BITMAPCOL_CONST(30, 30, 30, 200); BitmapCol col = BitmapCol_Make(30, 30, 30, 200);
Size2D size, titles, content; Size2D size, titles, content;
Bitmap bmp; Bitmap bmp;