Skip to content
Permalink
Browse files

Merge pull request #607 from UnknownShadow200/BitmapColRewrite

Bitmap col rewrite
  • Loading branch information...
UnknownShadow200 committed Oct 9, 2019
2 parents b62a787 + 657a967 commit 5513d49b85d9a4e572a2e0b0c20b9cb60e0a0265
Showing with 247 additions and 218 deletions.
  1. +25 −21 src/Bitmap.c
  2. +34 −19 src/Bitmap.h
  3. +4 −4 src/Block.c
  4. +4 −3 src/Core.h
  5. +82 −67 src/Drawer2D.c
  6. +5 −7 src/Entity.c
  7. +2 −3 src/EntityComponents.c
  8. +9 −9 src/Graphics.c
  9. +7 −7 src/LScreens.c
  10. +27 −30 src/LWidgets.c
  11. +20 −23 src/Launcher.c
  12. +1 −0 src/PackedCol.c
  13. +3 −6 src/Protocol.c
  14. +10 −8 src/TexturePack.c
  15. +5 −4 src/Utils.c
  16. +9 −7 src/Widgets.c
@@ -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_IHDR_SIZE 13
#define PNG_RGB_MASK 0xFFFFFFUL
#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)

@@ -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_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;
}

static void Png_ComputeTransparency(Bitmap* bmp, BitmapCol col) {
cc_uint32 trnsRGB = col.B | (col.G << 8) | (col.R << 16); /* TODO: Remove this!! */
/* Sets alpha to 0 for any pixels in the bitmap whose RGB is same as col */
static void ComputeTransparency(Bitmap* bmp, BitmapCol col) {
BitmapCol trnsRGB = col & BITMAPCOL_RGB_MASK;
int x, y, width = bmp->Width, height = bmp->Height;

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++) {
cc_uint32 rgb = row[x] & PNG_RGB_MASK;
BitmapCol rgb = row[x] & BITMAPCOL_RGB_MASK;
row[x] = (rgb == trnsRGB) ? trnsRGB : row[x];
}
}
@@ -337,8 +337,7 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
cc_uint32 scanlineSize, scanlineBytes;

/* palette data */
BitmapCol black = BITMAPCOL_CONST(0, 0, 0, 255);
BitmapCol transparentCol;
BitmapCol trnsCol;
BitmapCol palette[PNG_PALETTE];
cc_uint32 i;

@@ -360,8 +359,8 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
if (res) return res;
if (!Png_Detect(tmp, PNG_SIG_SIZE)) return PNG_ERR_INVALID_SIG;

transparentCol = black;
for (i = 0; i < PNG_PALETTE; i++) { palette[i] = black; }
trnsCol = BITMAPCOL_BLACK;
for (i = 0; i < PNG_PALETTE; i++) { palette[i] = BITMAPCOL_BLACK; }

Inflate_MakeStream(&compStream, &inflate, stream);
ZLibHeader_Init(&zlibHeader);
@@ -411,9 +410,10 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
if (res) return res;

for (i = 0; i < dataSize; i += 3) {
palette[i / 3].R = tmp[i];
palette[i / 3].G = tmp[i + 1];
palette[i / 3].B = tmp[i + 2];
palette[i / 3] &= BITMAPCOL_A_MASK; /* set RGB to 0 */
palette[i / 3] |= tmp[i ] << BITMAPCOL_R_SHIFT;
palette[i / 3] |= tmp[i + 1] << BITMAPCOL_G_SHIFT;
palette[i / 3] |= tmp[i + 2] << BITMAPCOL_B_SHIFT;
}
} break;

@@ -424,25 +424,24 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
if (res) return res;

/* RGB is 16 bits big endian, ignore least significant 8 bits */
transparentCol.R = tmp[0]; transparentCol.G = tmp[0];
transparentCol.B = tmp[0]; transparentCol.A = 0;
trnsCol = BitmapCol_Make(tmp[0], tmp[0], tmp[0], 0);
} else if (col == PNG_COL_INDEXED) {
if (dataSize > PNG_PALETTE) return PNG_ERR_TRANS_COUNT;
res = Stream_Read(stream, tmp, dataSize);
if (res) return res;

/* set alpha component of palette */
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) {
if (dataSize != 6) return PNG_ERR_TRANS_COUNT;
res = Stream_Read(stream, tmp, dataSize);
if (res) return res;

/* R,G,B is 16 bits big endian, ignore least significant 8 bits */
transparentCol.R = tmp[0]; transparentCol.G = tmp[2];
transparentCol.B = tmp[4]; transparentCol.A = 0;
trnsCol = BitmapCol_Make(tmp[0], tmp[2], tmp[4], 0);
} else {
return PNG_ERR_TRANS_INVALID;
}
@@ -499,7 +498,7 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {

case PNG_FourCC('I','E','N','D'): {
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;
} 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) {
cc_uint8* end = dst + lineLen;
BitmapCol col; /* if we use *src, register gets reloaded each time */

if (alpha) {
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 {
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);
}
}
}
@@ -6,37 +6,52 @@
*/
struct Stream;

/* Represents an ARGB colour, suitable for native graphics API texture pixels. */
typedef union BitmapCol_ {
/* Represents a packed 32 bit RGBA colour, suitable for native graphics API texture pixels. */
typedef cc_uint32 BitmapCol;
#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
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
cc_uint32 _raw;
} BitmapCol;

/* Whether components of two colours are all equal. */
#define BitmapCol_Equals(a,b) ((a)._raw == (b)._raw)
#define PackedCol_ARGB(r, g, b, a) (((cc_uint32)(r) << 16) | ((cc_uint32)(g) << 8) | ((cc_uint32)(b)) | ((cc_uint32)(a) << 24))
#define BITMAPCOL_R_MASK (0xFFU << BITMAPCOL_R_SHIFT)
#define BITMAPCOL_G_MASK (0xFFU << BITMAPCOL_G_SHIFT)
#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 */
typedef struct Bitmap_ { cc_uint8* Scan0; int Width, Height; } Bitmap;

#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. */
#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. */
#define Bitmap_GetRow(bmp, y) ((BitmapCol*)(bmp)->Scan0 + (y) * (bmp)->Width)
/* Gets the pixel at (x,y) in the given bitmap. */
@@ -352,7 +352,7 @@ static float Block_GetSpriteBB_MinX(int size, int tileX, int tileY, const Bitmap
for (x = 0; x < size; x++) {
for (y = 0; y < size; y++) {
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;
@@ -365,7 +365,7 @@ static float Block_GetSpriteBB_MinY(int size, int tileX, int tileY, const Bitmap
for (y = size - 1; y >= 0; y--) {
row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
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;
@@ -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 (y = 0; y < size; y++) {
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;
@@ -391,7 +391,7 @@ static float Block_GetSpriteBB_MaxY(int size, int tileX, int tileY, const Bitmap
for (y = 0; y < size; y++) {
row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
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;
@@ -30,8 +30,9 @@ typedef unsigned int cc_uintptr;
#define CC_HAS_TYPES
#define CC_HAS_MISC
#elif __GNUC__
/* really old GCC/clang might not have these */
/* really old GCC/clang might not have these defined */
#ifdef __INT8_TYPE__
/* avoid including <stdint.h> because it breaks defining UNICODE in Platform.c with MinGW */
typedef __INT8_TYPE__ cc_int8;
typedef __INT16_TYPE__ cc_int16;
typedef __INT32_TYPE__ cc_int32;
@@ -74,7 +75,7 @@ typedef unsigned __INTPTR_TYPE__ cc_uintptr;
#define CC_BIG_ENDIAN
#endif

/* Unrecognised compiler, so just go with sensisble defaults */
/* Unrecognised compiler, so just go with sensible defaults */
#ifndef CC_HAS_TYPES
#include <stdint.h>
typedef int8_t cc_int8;
@@ -89,7 +90,7 @@ typedef uint64_t cc_uint64;
typedef uintptr_t cc_uintptr;
#endif
#ifndef CC_HAS_MISC
#define CC_INLINE inline
#define CC_INLINE
#define CC_NOINLINE
#define CC_API
#define CC_VAR

0 comments on commit 5513d49

Please sign in to comment.
You can’t perform that action at this time.