mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 02:25:32 -04:00
use more efficient bitmapcol
This commit is contained in:
parent
ad78ab8d0d
commit
e7738b50fa
@ -23,10 +23,9 @@ static float L_flameHeat[LIQUID_ANIM_MAX * LIQUID_ANIM_MAX];
|
||||
static RNGState L_rnd;
|
||||
static bool L_rndInitalised;
|
||||
|
||||
static void LavaAnimation_Tick(uint32_t* ptr, int size) {
|
||||
static void LavaAnimation_Tick(BitmapCol* ptr, int size) {
|
||||
int mask = size - 1, shift = Math_Log2(size);
|
||||
float soupHeat, potHeat, col;
|
||||
uint8_t r, g, b;
|
||||
int x, y, i = 0;
|
||||
|
||||
if (!L_rndInitalised) {
|
||||
@ -74,10 +73,10 @@ static void LavaAnimation_Tick(uint32_t* ptr, int size) {
|
||||
col = 2.0f * L_soupHeat[i];
|
||||
Math_Clamp(col, 0.0f, 1.0f);
|
||||
|
||||
r = (uint8_t)(col * 100.0f + 155.0f);
|
||||
g = (uint8_t)(col * col * 255.0f);
|
||||
b = (uint8_t)(col * col * col * col * 128.0f);
|
||||
*ptr = PackedCol_ARGB(r, g, b, 255);
|
||||
ptr->R = (uint8_t)(col * 100.0f + 155.0f);
|
||||
ptr->G = (uint8_t)(col * col * 255.0f);
|
||||
ptr->B = (uint8_t)(col * col * col * col * 128.0f);
|
||||
ptr->A = 255;
|
||||
|
||||
ptr++; i++;
|
||||
}
|
||||
@ -94,10 +93,9 @@ static float W_flameHeat[LIQUID_ANIM_MAX * LIQUID_ANIM_MAX];
|
||||
static RNGState W_rnd;
|
||||
static bool W_rndInitalised;
|
||||
|
||||
static void WaterAnimation_Tick(uint32_t* ptr, int size) {
|
||||
static void WaterAnimation_Tick(BitmapCol* ptr, int size) {
|
||||
int mask = size - 1, shift = Math_Log2(size);
|
||||
float soupHeat, col;
|
||||
uint8_t r, g, a;
|
||||
int x, y, i = 0;
|
||||
|
||||
if (!W_rndInitalised) {
|
||||
@ -126,10 +124,10 @@ static void WaterAnimation_Tick(uint32_t* ptr, int size) {
|
||||
Math_Clamp(col, 0.0f, 1.0f);
|
||||
col = col * col;
|
||||
|
||||
r = (uint8_t)(32.0f + col * 32.0f);
|
||||
g = (uint8_t)(50.0f + col * 64.0f);
|
||||
a = (uint8_t)(146.0f + col * 50.0f);
|
||||
*ptr = PackedCol_ARGB(r, g, 255, a);
|
||||
ptr->R = (uint8_t)(32.0f + col * 32.0f);
|
||||
ptr->G = (uint8_t)(50.0f + col * 64.0f);
|
||||
ptr->A = (uint8_t)(146.0f + col * 50.0f);
|
||||
ptr->B = 255;
|
||||
|
||||
ptr++; i++;
|
||||
}
|
||||
@ -230,9 +228,9 @@ static void Animations_Draw(struct AnimationData* data, TextureLoc texLoc, int s
|
||||
|
||||
if (!data) {
|
||||
if (texLoc == 30) {
|
||||
LavaAnimation_Tick((uint32_t*)frame.Scan0, size);
|
||||
LavaAnimation_Tick((BitmapCol*)frame.Scan0, size);
|
||||
} else if (texLoc == 14) {
|
||||
WaterAnimation_Tick((uint32_t*)frame.Scan0, size);
|
||||
WaterAnimation_Tick((BitmapCol*)frame.Scan0, size);
|
||||
}
|
||||
} else {
|
||||
srcX = data->FrameX + data->State * size;
|
||||
|
@ -37,7 +37,11 @@ void AxisLinesRenderer_Render(double delta) {
|
||||
1,2,2, 1,2,4, 3,2,4, 3,2,2, /* Z arrow */
|
||||
1,2,3, 1,4,3, 3,4,1, 3,2,1, /* Y arrow */
|
||||
};
|
||||
static PackedCol cols[3] = { PACKEDCOL_RED, PACKEDCOL_BLUE, PACKEDCOL_GREEN };
|
||||
static PackedCol cols[3] = {
|
||||
PACKEDCOL_CONST(255, 0, 0, 255), /* Red */
|
||||
PACKEDCOL_CONST( 0, 255, 0, 255), /* Green */
|
||||
PACKEDCOL_CONST( 0, 0, 255, 255), /* Blue */
|
||||
};
|
||||
|
||||
Vector3 coords[5], pos;
|
||||
VertexP3fC4b vertices[AXISLINES_NUM_VERTICES];
|
||||
|
200
src/Bitmap.c
200
src/Bitmap.c
@ -7,6 +7,13 @@
|
||||
#include "Stream.h"
|
||||
#include "Errors.h"
|
||||
|
||||
BitmapCol BitmapCol_Scale(BitmapCol value, float t) {
|
||||
value.R = (uint8_t)(value.R * t);
|
||||
value.G = (uint8_t)(value.G * t);
|
||||
value.B = (uint8_t)(value.B * t);
|
||||
return value;
|
||||
}
|
||||
|
||||
void Bitmap_Create(Bitmap* bmp, int width, int height, uint8_t* scan0) {
|
||||
bmp->Width = width; bmp->Height = height; bmp->Scan0 = scan0;
|
||||
}
|
||||
@ -14,11 +21,9 @@ void Bitmap_Create(Bitmap* bmp, int width, int height, uint8_t* scan0) {
|
||||
void Bitmap_CopyBlock(int srcX, int srcY, int dstX, int dstY, Bitmap* src, Bitmap* dst, int size) {
|
||||
int x, y;
|
||||
for (y = 0; y < size; y++) {
|
||||
uint32_t* srcRow = Bitmap_GetRow(src, srcY + y);
|
||||
uint32_t* dstRow = Bitmap_GetRow(dst, dstY + y);
|
||||
for (x = 0; x < size; x++) {
|
||||
dstRow[dstX + x] = srcRow[srcX + x];
|
||||
}
|
||||
BitmapCol* srcRow = Bitmap_GetRow(src, srcY + y) + srcX;
|
||||
BitmapCol* dstRow = Bitmap_GetRow(dst, dstY + y) + dstX;
|
||||
for (x = 0; x < size; x++) { dstRow[x] = srcRow[x]; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +59,7 @@ enum PngFilter {
|
||||
PNG_FILTER_NONE, PNG_FILTER_SUB, PNG_FILTER_UP, PNG_FILTER_AVERAGE, PNG_FILTER_PAETH
|
||||
};
|
||||
|
||||
typedef void (*Png_RowExpander)(int width, uint32_t* palette, uint8_t* src, uint32_t* dst);
|
||||
typedef void (*Png_RowExpander)(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst);
|
||||
static uint8_t png_sig[PNG_SIG_SIZE] = { 137, 80, 78, 71, 13, 10, 26, 10 };
|
||||
|
||||
bool Png_Detect(const uint8_t* data, uint32_t len) {
|
||||
@ -118,58 +123,60 @@ static void Png_Reconstruct(uint8_t type, uint8_t bytesPerPixel, uint8_t* line,
|
||||
}
|
||||
}
|
||||
|
||||
static void Png_Expand_GRAYSCALE_1(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i; /* NOTE: not optimised*/
|
||||
#define PNG_Do_Grayscale(tmp, dstI, srcI, scale) tmp = src[srcI] * scale; dst[dstI] = PackedCol_ARGB(tmp, tmp, tmp, 255);
|
||||
for (i = 0; i < width; i++) {
|
||||
int mask = (7 - (i & 7)); uint8_t rgb;
|
||||
PNG_Do_Grayscale(rgb, i, (src[i >> 3] >> mask) & 1, 255);
|
||||
}
|
||||
#define Bitmap_Set(dst, r,g,b,a) dst.B = b; dst.G = g; dst.R = r; dst.A = a;
|
||||
|
||||
#define PNG_Do_Grayscale(dstI, srcI, scale) rgb = src[srcI] * 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_A__8(dstI, srcI) rgb = src[srcI]; Bitmap_Set(dst[dstI], rgb, rgb, rgb, src[srcI + 1]);
|
||||
#define PNG_Do_RGB__8(dstI, srcI) Bitmap_Set(dst[dstI], src[srcI], src[srcI + 1], src[srcI + 2], 255);
|
||||
#define PNG_Do_RGB_A__8(dstI, srcI) Bitmap_Set(dst[dstI], src[srcI], src[srcI + 1], src[srcI + 2], src[srcI + 3]);
|
||||
|
||||
#define PNG_Mask_1(i) (7 - (i & 7))
|
||||
#define PNG_Mask_2(i) ((3 - (i & 3)) * 2)
|
||||
#define PNG_Mask_4(i) ((1 - (i & 1)) * 4)
|
||||
#define PNG_Get__1(i) ((src[i >> 3] >> PNG_Mask_1(i)) & 1)
|
||||
#define PNG_Get__2(i) ((src[i >> 2] >> PNG_Mask_2(i)) & 3)
|
||||
|
||||
static void Png_Expand_GRAYSCALE_1(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i; uint8_t rgb; /* NOTE: not optimised*/
|
||||
for (i = 0; i < width; i++) { PNG_Do_Grayscale(i, PNG_Get__1(i), 255); }
|
||||
}
|
||||
|
||||
static void Png_Expand_GRAYSCALE_2(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i; /* NOTE: not optimised */
|
||||
for (i = 0; i < width; i++) {
|
||||
int mask = (3 - (i & 3)) * 2; uint8_t rgb;
|
||||
PNG_Do_Grayscale(rgb, i, (src[i >> 3] >> mask) & 3, 85);
|
||||
}
|
||||
static void Png_Expand_GRAYSCALE_2(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i; uint8_t rgb; /* NOTE: not optimised */
|
||||
for (i = 0; i < width; i++) { PNG_Do_Grayscale(i, PNG_Get__2(i), 85); }
|
||||
}
|
||||
|
||||
static void Png_Expand_GRAYSCALE_4(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i, j, mask; uint8_t cur, rgb1, rgb2;
|
||||
static void Png_Expand_GRAYSCALE_4(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i, j; uint8_t rgb;
|
||||
|
||||
for (i = 0, j = 0; i < (width & ~0x1); i += 2, j++) {
|
||||
cur = src[j];
|
||||
PNG_Do_Grayscale(rgb1, i, cur >> 4, 17); PNG_Do_Grayscale(rgb2, i + 1, cur & 0x0F, 17);
|
||||
PNG_Do_Grayscale(i, src[j] >> 4, 17); PNG_Do_Grayscale(i + 1, src[j] & 0x0F, 17);
|
||||
}
|
||||
for (; i < width; i++) {
|
||||
mask = (1 - (i & 1)) * 4;
|
||||
PNG_Do_Grayscale(rgb1, i, (src[j] >> mask) & 15, 17);
|
||||
PNG_Do_Grayscale(i, (src[j] >> PNG_Mask_4(i)) & 15, 17);
|
||||
}
|
||||
}
|
||||
|
||||
static void Png_Expand_GRAYSCALE_8(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i; uint8_t rgb1, rgb2, rgb3, rgb4;
|
||||
#define PNG_Do_Grayscale_8(tmp, dstI, srcI) tmp = src[srcI]; dst[dstI] = PackedCol_ARGB(tmp, tmp, tmp, 255);
|
||||
static void Png_Expand_GRAYSCALE_8(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i; uint8_t rgb;
|
||||
|
||||
for (i = 0; i < (width & ~0x3); i += 4) {
|
||||
PNG_Do_Grayscale_8(rgb1, i , i ); PNG_Do_Grayscale_8(rgb2, i + 1, i + 1);
|
||||
PNG_Do_Grayscale_8(rgb3, i + 2, i + 2); PNG_Do_Grayscale_8(rgb4, i + 3, i + 3);
|
||||
PNG_Do_Grayscale_8(i , i ); PNG_Do_Grayscale_8(i + 1, i + 1);
|
||||
PNG_Do_Grayscale_8(i + 2, i + 2); PNG_Do_Grayscale_8(i + 3, i + 3);
|
||||
}
|
||||
for (; i < width; i++) { PNG_Do_Grayscale_8(rgb1, i, i); }
|
||||
for (; i < width; i++) { PNG_Do_Grayscale_8(i, i); }
|
||||
}
|
||||
|
||||
static void Png_Expand_GRAYSCALE_16(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i;
|
||||
static void Png_Expand_GRAYSCALE_16(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i; uint8_t rgb; /* NOTE: not optimised */
|
||||
for (i = 0; i < width; i++) {
|
||||
uint8_t rgb = src[i * 2];
|
||||
dst[i] = PackedCol_ARGB(rgb, rgb, rgb, 255);
|
||||
rgb = src[i * 2]; Bitmap_Set(dst[i], rgb, rgb, rgb, 255);
|
||||
}
|
||||
}
|
||||
|
||||
static void Png_Expand_RGB_8(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
static void Png_Expand_RGB_8(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i, j;
|
||||
#define PNG_Do_RGB__8(dstI, srcI) dst[dstI] = PackedCol_ARGB(src[srcI], src[srcI + 1], src[srcI + 2], 255);
|
||||
|
||||
for (i = 0, j = 0; i < (width & ~0x03); i += 4, j += 12) {
|
||||
PNG_Do_RGB__8(i , j ); PNG_Do_RGB__8(i + 1, j + 3);
|
||||
@ -178,75 +185,64 @@ static void Png_Expand_RGB_8(int width, uint32_t* palette, uint8_t* src, uint32_
|
||||
for (; i < width; i++, j += 3) { PNG_Do_RGB__8(i, j); }
|
||||
}
|
||||
|
||||
static void Png_Expand_RGB_16(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i, j;
|
||||
static void Png_Expand_RGB_16(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i, j; /* NOTE: not optimised */
|
||||
for (i = 0, j = 0; i < width; i++, j += 6) {
|
||||
dst[i] = PackedCol_ARGB(src[j], src[j + 2], src[j + 4], 255);
|
||||
Bitmap_Set(dst[i], src[j], src[j + 2], src[j + 4], 255);
|
||||
}
|
||||
}
|
||||
|
||||
static void Png_Expand_INDEXED_1(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i; /* NOTE: not optimised*/
|
||||
for (i = 0; i < width; i++) {
|
||||
int mask = (7 - (i & 7));
|
||||
dst[i] = palette[(src[i >> 3] >> mask) & 1];
|
||||
}
|
||||
static void Png_Expand_INDEXED_1(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i; /* NOTE: not optimised */
|
||||
for (i = 0; i < width; i++) { dst[i] = palette[PNG_Get__1(i)]; }
|
||||
}
|
||||
|
||||
static void Png_Expand_INDEXED_2(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i; /* NOTE: not optimised*/
|
||||
for (i = 0; i < width; i++) {
|
||||
int mask = (3 - (i & 3)) * 2;
|
||||
dst[i] = palette[(src[i >> 3] >> mask) & 3];
|
||||
}
|
||||
static void Png_Expand_INDEXED_2(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i; /* NOTE: not optimised */
|
||||
for (i = 0; i < width; i++) { dst[i] = palette[PNG_Get__2(i)]; }
|
||||
}
|
||||
|
||||
static void Png_Expand_INDEXED_4(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i, j, mask; uint8_t cur;
|
||||
#define PNG_Do_Indexed(dstI, srcI) dst[dstI] = palette[srcI];
|
||||
static void Png_Expand_INDEXED_4(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i, j; uint8_t cur;
|
||||
|
||||
for (i = 0, j = 0; i < (width & ~0x1); i += 2, j++) {
|
||||
cur = src[j];
|
||||
PNG_Do_Indexed(i, cur >> 4); PNG_Do_Indexed(i + 1, cur & 0x0F);
|
||||
dst[i] = palette[cur >> 4]; dst[i + 1] = palette[cur & 0x0F];
|
||||
}
|
||||
for (; i < width; i++) {
|
||||
mask = (1 - (i & 1)) * 4;
|
||||
PNG_Do_Indexed(i, (src[j] >> mask) & 15);
|
||||
dst[i] = palette[(src[j] >> PNG_Mask_4(i)) & 15];
|
||||
}
|
||||
}
|
||||
|
||||
static void Png_Expand_INDEXED_8(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
static void Png_Expand_INDEXED_8(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (width & ~0x3); i += 4) {
|
||||
PNG_Do_Indexed(i , src[i] ); PNG_Do_Indexed(i + 1, src[i + 1]);
|
||||
PNG_Do_Indexed(i + 2, src[i + 2]); PNG_Do_Indexed(i + 3, src[i + 3]);
|
||||
dst[i] = palette[src[i]]; dst[i + 1] = palette[src[i + 1]];
|
||||
dst[i + 2] = palette[src[i + 2]]; dst[i + 3] = palette[src[i + 3]];
|
||||
}
|
||||
for (; i < width; i++) { PNG_Do_Indexed(i, src[i]); }
|
||||
for (; i < width; i++) { dst[i] = palette[src[i]]; }
|
||||
}
|
||||
|
||||
static void Png_Expand_GRAYSCALE_A_8(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i, j; uint8_t rgb1, rgb2, rgb3, rgb4;
|
||||
#define PNG_Do_Grayscale_A__8(tmp, dstI, srcI) tmp = src[srcI]; dst[dstI] = PackedCol_ARGB(tmp, tmp, tmp, src[srcI + 1]);
|
||||
static void Png_Expand_GRAYSCALE_A_8(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i, j; uint8_t rgb;
|
||||
|
||||
for (i = 0, j = 0; i < (width & ~0x3); i += 4, j += 8) {
|
||||
PNG_Do_Grayscale_A__8(rgb1, i , j ); PNG_Do_Grayscale_A__8(rgb2, i + 1, j + 2);
|
||||
PNG_Do_Grayscale_A__8(rgb3, i + 2, j + 4); PNG_Do_Grayscale_A__8(rgb4, i + 3, j + 6);
|
||||
PNG_Do_Grayscale_A__8(i , j ); PNG_Do_Grayscale_A__8(i + 1, j + 2);
|
||||
PNG_Do_Grayscale_A__8(i + 2, j + 4); PNG_Do_Grayscale_A__8(i + 3, j + 6);
|
||||
}
|
||||
for (; i < width; i++, j += 2) { PNG_Do_Grayscale_A__8(rgb1, i, j); }
|
||||
for (; i < width; i++, j += 2) { PNG_Do_Grayscale_A__8(i, j); }
|
||||
}
|
||||
|
||||
static void Png_Expand_GRAYSCALE_A_16(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
int i, j; /* NOTE: not optimised*/
|
||||
for (i = 0, j = 0; i < width; i++, j += 4) {
|
||||
uint8_t rgb = src[j];
|
||||
dst[i] = PackedCol_ARGB(rgb, rgb, rgb, src[j + 2]);
|
||||
static void Png_Expand_GRAYSCALE_A_16(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i; uint8_t rgb; /* NOTE: not optimised*/
|
||||
for (i = 0; i < width; i++) {
|
||||
rgb = src[i * 4]; Bitmap_Set(dst[i], rgb, rgb, rgb, src[i * 4 + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
static void Png_Expand_RGB_A_8(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
static void Png_Expand_RGB_A_8(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i, j;
|
||||
#define PNG_Do_RGB_A__8(dstI, srcI) dst[dstI] = PackedCol_ARGB(src[srcI], src[srcI + 1], src[srcI + 2], src[srcI + 3]);
|
||||
|
||||
for (i = 0, j = 0; i < (width & ~0x3); i += 4, j += 16) {
|
||||
PNG_Do_RGB_A__8(i , j ); PNG_Do_RGB_A__8(i + 1, j + 4 );
|
||||
@ -255,10 +251,10 @@ static void Png_Expand_RGB_A_8(int width, uint32_t* palette, uint8_t* src, uint3
|
||||
for (; i < width; i++, j += 4) { PNG_Do_RGB_A__8(i, j); }
|
||||
}
|
||||
|
||||
static void Png_Expand_RGB_A_16(int width, uint32_t* palette, uint8_t* src, uint32_t* dst) {
|
||||
static void Png_Expand_RGB_A_16(int width, BitmapCol* palette, uint8_t* src, BitmapCol* dst) {
|
||||
int i, j; /* NOTE: not optimised*/
|
||||
for (i = 0, j = 0; i < width; i++, j += 8) {
|
||||
dst[i] = PackedCol_ARGB(src[j], src[j + 2], src[j + 4], src[j + 6]);
|
||||
Bitmap_Set(dst[i], src[j], src[j + 2], src[j + 4], src[j + 6]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,12 +303,12 @@ Png_RowExpander Png_GetExpander(uint8_t col, uint8_t bitsPerSample) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void Png_ComputeTransparency(Bitmap* bmp, uint32_t transparentCol) {
|
||||
uint32_t trnsRGB = transparentCol & PNG_RGB_MASK;
|
||||
static void Png_ComputeTransparency(Bitmap* bmp, BitmapCol col) {
|
||||
uint32_t trnsRGB = col.B | (col.G << 8) | (col.R << 16); /* TODO: Remove this!! */
|
||||
int x, y, width = bmp->Width, height = bmp->Height;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
uint32_t* row = Bitmap_GetRow(bmp, y);
|
||||
uint32_t* row = Bitmap_RawRow(bmp, y);
|
||||
for (x = 0; x < width; x++) {
|
||||
uint32_t rgb = row[x] & PNG_RGB_MASK;
|
||||
row[x] = (rgb == trnsRGB) ? trnsRGB : row[x];
|
||||
@ -335,8 +331,9 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
uint32_t scanlineSize, scanlineBytes;
|
||||
|
||||
/* palette data */
|
||||
uint32_t transparentCol = PackedCol_ARGB(0, 0, 0, 255);
|
||||
uint32_t palette[PNG_PALETTE];
|
||||
BitmapCol black = BITMAPCOL_CONST(0, 0, 0, 255);
|
||||
BitmapCol transparentCol;
|
||||
BitmapCol palette[PNG_PALETTE];
|
||||
uint32_t i;
|
||||
|
||||
/* idat state */
|
||||
@ -355,15 +352,13 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
if (res) return res;
|
||||
if (!Png_Detect(tmp, PNG_SIG_SIZE)) return PNG_ERR_INVALID_SIG;
|
||||
|
||||
for (i = 0; i < PNG_PALETTE; i++) {
|
||||
palette[i] = PackedCol_ARGB(0, 0, 0, 255);
|
||||
}
|
||||
bool readingChunks = true;
|
||||
transparentCol = black;
|
||||
for (i = 0; i < PNG_PALETTE; i++) { palette[i] = black; }
|
||||
|
||||
Inflate_MakeStream(&compStream, &inflate, stream);
|
||||
ZLibHeader_Init(&zlibHeader);
|
||||
|
||||
while (readingChunks) {
|
||||
for (;;) {
|
||||
res = Stream_Read(stream, tmp, 8);
|
||||
if (res) return res;
|
||||
dataSize = Stream_GetU32_BE(&tmp[0]);
|
||||
@ -407,7 +402,9 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
if (res) return res;
|
||||
|
||||
for (i = 0; i < dataSize; i += 3) {
|
||||
palette[i / 3] = PackedCol_ARGB(tmp[i], tmp[i + 1], tmp[i + 2], 255);
|
||||
palette[i / 3].R = tmp[i];
|
||||
palette[i / 3].G = tmp[i + 1];
|
||||
palette[i / 3].B = tmp[i + 2];
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -418,8 +415,8 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
if (res) return res;
|
||||
|
||||
/* RGB is 16 bits big endian, ignore least significant 8 bits */
|
||||
uint8_t palRGB = tmp[0];
|
||||
transparentCol = PackedCol_ARGB(palRGB, palRGB, palRGB, 0);
|
||||
transparentCol.B = tmp[0]; transparentCol.G = tmp[0];
|
||||
transparentCol.R = tmp[0]; transparentCol.A = 0;
|
||||
} else if (col == PNG_COL_INDEXED) {
|
||||
if (dataSize > PNG_PALETTE) return PNG_ERR_TRANS_COUNT;
|
||||
res = Stream_Read(stream, tmp, dataSize);
|
||||
@ -427,8 +424,7 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
|
||||
/* set alpha component of palette*/
|
||||
for (i = 0; i < dataSize; i++) {
|
||||
palette[i] &= PNG_RGB_MASK;
|
||||
palette[i] |= (uint32_t)tmp[i] << 24;
|
||||
palette[i].A = tmp[i];
|
||||
}
|
||||
} else if (col == PNG_COL_RGB) {
|
||||
if (dataSize != 6) return PNG_ERR_TRANS_COUNT;
|
||||
@ -436,8 +432,8 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
if (res) return res;
|
||||
|
||||
/* R,G,B is 16 bits big endian, ignore least significant 8 bits */
|
||||
uint8_t palR = tmp[0], palG = tmp[2], palB = tmp[4];
|
||||
transparentCol = PackedCol_ARGB(palR, palG, palB, 0);
|
||||
transparentCol.B = tmp[4]; transparentCol.G = tmp[2];
|
||||
transparentCol.R = tmp[0]; transparentCol.A = 0;
|
||||
} else {
|
||||
return PNG_ERR_TRANS_INVALID;
|
||||
}
|
||||
@ -491,8 +487,9 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
} break;
|
||||
|
||||
case PNG_FourCC('I','E','N','D'): {
|
||||
readingChunks = false;
|
||||
if (dataSize) return PNG_ERR_INVALID_END_SIZE;
|
||||
if (!transparentCol.A) Png_ComputeTransparency(bmp, transparentCol);
|
||||
return bmp->Scan0 ? 0 : PNG_ERR_NO_DATA;
|
||||
} break;
|
||||
|
||||
default:
|
||||
@ -502,11 +499,6 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
|
||||
if ((res = stream->Skip(stream, 4))) return res; /* Skip CRC32 */
|
||||
}
|
||||
|
||||
if (transparentCol <= PNG_RGB_MASK) {
|
||||
Png_ComputeTransparency(bmp, transparentCol);
|
||||
}
|
||||
return bmp->Scan0 ? 0 : PNG_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
|
||||
@ -589,14 +581,14 @@ static void Png_Filter(uint8_t filter, uint8_t* cur, uint8_t* prior, uint8_t* be
|
||||
}
|
||||
}
|
||||
|
||||
static void Png_EncodeRow(const uint8_t* src, uint8_t* cur, uint8_t* prior, uint8_t* best, int lineLen) {
|
||||
static void Png_EncodeRow(const BitmapCol* src, uint8_t* cur, uint8_t* prior, uint8_t* best, int lineLen) {
|
||||
uint8_t* dst = cur;
|
||||
int bestFilter, bestEstimate = Int32_MaxValue;
|
||||
int x, filter, estimate;
|
||||
|
||||
for (x = 0; x < lineLen; x += 3) {
|
||||
dst[0] = src[2]; dst[1] = src[1]; dst[2] = src[0];
|
||||
src += 4; dst += 3;
|
||||
dst[0] = src->R; dst[1] = src->G; dst[2] = src->B;
|
||||
src++; dst += 3;
|
||||
}
|
||||
|
||||
dst = best + 1;
|
||||
@ -665,7 +657,7 @@ ReturnCode Png_Encode(Bitmap* bmp, struct Stream* stream, Png_RowSelector select
|
||||
|
||||
for (y = 0; y < bmp->Height; y++) {
|
||||
int row = selectRow(bmp, y);
|
||||
uint8_t* src = (uint8_t*)Bitmap_GetRow(bmp, row);
|
||||
BitmapCol* src = Bitmap_GetRow(bmp, row);
|
||||
uint8_t* prev = (y & 1) == 0 ? prevLine : curLine;
|
||||
uint8_t* cur = (y & 1) == 0 ? curLine : prevLine;
|
||||
|
||||
|
16
src/Bitmap.h
16
src/Bitmap.h
@ -6,12 +6,26 @@
|
||||
*/
|
||||
struct Stream;
|
||||
|
||||
/* Represents an ARGB colour, suitable for native graphics API texture pixels. */
|
||||
typedef CC_ALIGN_HINT(4) struct BitmapCol_ {
|
||||
uint8_t B, G, R, A;
|
||||
} BitmapCol;
|
||||
/* Represents an ARGB colour, suitable for native graphics API texture pixels. */
|
||||
/* Unioned with Packed member for efficient equality comparison */
|
||||
typedef union BitmapColUnion_ { BitmapCol C; uint32_t Raw; } BitmapColUnion;
|
||||
|
||||
typedef struct Bitmap_ { uint8_t* Scan0; int Width, Height; } Bitmap;
|
||||
|
||||
#define PNG_MAX_DIMS 0x8000
|
||||
#define BITMAPCOL_CONST(r, g, b, a) { b, g, r, a }
|
||||
#define BITMAP_SIZEOF_PIXEL 4 /* 32 bit ARGB */
|
||||
|
||||
#define Bitmap_DataSize(width, height) ((uint32_t)(width) * (uint32_t)(height) * (uint32_t)BITMAP_SIZEOF_PIXEL)
|
||||
#define Bitmap_GetRow(bmp, y) ((uint32_t*)((bmp)->Scan0 + ((y) * ((bmp)->Width << 2))))
|
||||
#define Bitmap_RawRow(bmp, y) ((uint32_t*)((bmp)->Scan0 + ((y) * ((bmp)->Width << 2))))
|
||||
#define Bitmap_GetRow(bmp, y) ((BitmapCol*)((bmp)->Scan0 + ((y) * ((bmp)->Width << 2))))
|
||||
#define Bitmap_GetPixel(bmp, x, y) (Bitmap_GetRow(bmp, y)[x])
|
||||
|
||||
BitmapCol BitmapCol_Scale(BitmapCol value, float t);
|
||||
void Bitmap_Create(Bitmap* bmp, int width, int height, uint8_t* scan0);
|
||||
void Bitmap_CopyBlock(int srcX, int srcY, int dstX, int dstY, Bitmap* src, Bitmap* dst, int size);
|
||||
/* Allocates a new bitmap of the given dimensions. You are responsible for freeing its memory! */
|
||||
|
34
src/Block.c
34
src/Block.c
@ -89,7 +89,7 @@ void Block_SetCustomDefined(BlockID block, bool defined) {
|
||||
}
|
||||
|
||||
void Block_DefineCustom(BlockID block) {
|
||||
PackedCol black = PACKEDCOL_BLACK;
|
||||
PackedCol black = PACKEDCOL_CONST(0, 0, 0, 255);
|
||||
String name = Block_UNSAFE_GetName(block);
|
||||
Block_Tinted[block] = !PackedCol_Equals(Block_FogCol[block], black) && String_IndexOf(&name, '#', 0) >= 0;
|
||||
|
||||
@ -283,60 +283,52 @@ void Block_RecalculateSpriteBB(void) {
|
||||
}
|
||||
|
||||
static float Block_GetSpriteBB_MinX(int size, int tileX, int tileY, Bitmap* bmp) {
|
||||
uint32_t* row;
|
||||
BitmapCol* row;
|
||||
int x, y;
|
||||
|
||||
for (x = 0; x < size; x++) {
|
||||
for (y = 0; y < size; y++) {
|
||||
row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
|
||||
|
||||
if (PackedCol_ARGB_A(row[x]) != 0) {
|
||||
return (float)x / size;
|
||||
}
|
||||
if (row[x].A) { return (float)x / size; }
|
||||
}
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
static float Block_GetSpriteBB_MinY(int size, int tileX, int tileY, Bitmap* bmp) {
|
||||
uint32_t* row;
|
||||
BitmapCol* row;
|
||||
int x, y;
|
||||
|
||||
for (y = size - 1; y >= 0; y--) {
|
||||
row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
|
||||
|
||||
for (x = 0; x < size; x++) {
|
||||
if (PackedCol_ARGB_A(row[x]) != 0) {
|
||||
return 1.0f - (float)(y + 1) / size;
|
||||
}
|
||||
if (row[x].A) { return 1.0f - (float)(y + 1) / size; }
|
||||
}
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
static float Block_GetSpriteBB_MaxX(int size, int tileX, int tileY, Bitmap* bmp) {
|
||||
uint32_t* row;
|
||||
BitmapCol* row;
|
||||
int x, y;
|
||||
|
||||
for (x = size - 1; x >= 0; x--) {
|
||||
for (y = 0; y < size; y++) {
|
||||
row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
|
||||
|
||||
if (PackedCol_ARGB_A(row[x]) != 0) {
|
||||
return (float)(x + 1) / size;
|
||||
}
|
||||
if (row[x].A) { return (float)(x + 1) / size; }
|
||||
}
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
static float Block_GetSpriteBB_MaxY(int size, int tileX, int tileY, Bitmap* bmp) {
|
||||
uint32_t* row;
|
||||
BitmapCol* row;
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < size; y++) {
|
||||
row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
|
||||
|
||||
for (x = 0; x < size; x++) {
|
||||
if (PackedCol_ARGB_A(row[x]) != 0) {
|
||||
return 1.0f - (float)y / size;
|
||||
}
|
||||
if (row[x].A) { return 1.0f - (float)y / size; }
|
||||
}
|
||||
}
|
||||
return 0.0f;
|
||||
|
@ -508,7 +508,7 @@ static PackedCol Normal_LightCol(int x, int y, int z, Face face, BlockID block)
|
||||
return y >= World_MaxY ? Env_SunCol : Lighting_Col_YMax_Fast(x, (y + 1) - offset, z);
|
||||
}
|
||||
|
||||
PackedCol black = PACKEDCOL_BLACK; return black;
|
||||
PackedCol invalid = PACKEDCOL_CONST(0, 0, 0, 0); return invalid;
|
||||
}
|
||||
|
||||
static bool Normal_CanStretch(BlockID initial, int chunkIndex, int x, int y, int z, Face face) {
|
||||
|
@ -270,25 +270,28 @@ static int ChunkUpdater_UpdateChunksStill(int* chunkUpdates) {
|
||||
return j;
|
||||
}
|
||||
|
||||
void ChunkUpdater_UpdateChunks(double delta) {
|
||||
static void ChunkUpdater_UpdateChunks(double delta) {
|
||||
struct LocalPlayer* p;
|
||||
bool samePos;
|
||||
int chunkUpdates = 0;
|
||||
cu_chunksTarget += delta < cu_targetTime ? 1 : -1; /* build more chunks if 30 FPS or over, otherwise slowdown. */
|
||||
|
||||
/* Build more chunks if 30 FPS or over, otherwise slowdown */
|
||||
cu_chunksTarget += delta < cu_targetTime ? 1 : -1;
|
||||
Math_Clamp(cu_chunksTarget, 4, Game_MaxChunkUpdates);
|
||||
|
||||
struct LocalPlayer* p = &LocalPlayer_Instance;
|
||||
Vector3 pos = Camera_CurrentPos;
|
||||
float headX = p->Base.HeadX;
|
||||
float headY = p->Base.HeadY;
|
||||
p = &LocalPlayer_Instance;
|
||||
samePos = Vector3_Equals(&Camera_CurrentPos, &cu_lastCamPos)
|
||||
&& p->Base.HeadX == cu_lastHeadX && p->Base.HeadY == cu_lastHeadY;
|
||||
|
||||
bool samePos = Vector3_Equals(&pos, &cu_lastCamPos) && headX == cu_lastHeadX && headY == cu_lastHeadY;
|
||||
MapRenderer_RenderChunksCount = samePos ?
|
||||
ChunkUpdater_UpdateChunksStill(&chunkUpdates) :
|
||||
ChunkUpdater_UpdateChunksAndVisibility(&chunkUpdates);
|
||||
|
||||
cu_lastCamPos = pos;
|
||||
cu_lastHeadX = headX; cu_lastHeadY = headY;
|
||||
cu_lastCamPos = Camera_CurrentPos;
|
||||
cu_lastHeadX = p->Base.HeadX;
|
||||
cu_lastHeadY = p->Base.HeadY;
|
||||
|
||||
if (!samePos || chunkUpdates != 0) {
|
||||
if (!samePos || chunkUpdates) {
|
||||
ChunkUpdater_ResetPartFlags();
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,6 @@ typedef struct Point2D_ { int X, Y; } Point2D;
|
||||
typedef struct Size2D_ { int Width, Height; } Size2D;
|
||||
typedef struct FontDesc_ { void* Handle; uint16_t Size, Style; } FontDesc;
|
||||
typedef struct TextureRec_ { float U1, V1, U2, V2; } TextureRec;
|
||||
typedef struct Bitmap_ { uint8_t* Scan0; int Width, Height; } Bitmap;
|
||||
|
||||
/*#define CC_BUILD_GL11*/
|
||||
/*#define CC_BUILD_SOLARIS*/
|
||||
|
@ -38,7 +38,7 @@ static int Drawer2D_Widths[256];
|
||||
|
||||
static void Drawer2D_CalculateTextWidths(void) {
|
||||
int width = Drawer2D_FontBitmap.Width, height = Drawer2D_FontBitmap.Height;
|
||||
uint32_t* row;
|
||||
BitmapCol* row;
|
||||
int i, x, y, xx, tileX, tileY;
|
||||
|
||||
for (i = 0; i < Array_Elems(Drawer2D_Widths); i++) {
|
||||
@ -55,9 +55,7 @@ static void Drawer2D_CalculateTextWidths(void) {
|
||||
|
||||
/* Iterate through each pixel of the given character, on the current scanline */
|
||||
for (xx = Drawer2D_TileSize - 1; xx >= 0; xx--) {
|
||||
uint32_t pixel = row[x + xx];
|
||||
uint8_t a = PackedCol_ARGB_A(pixel);
|
||||
if (a < 127) continue;
|
||||
if (row[x + xx].A < 127) continue;
|
||||
|
||||
/* Check if this is the pixel furthest to the right, for the current character */
|
||||
Drawer2D_Widths[i] = max(Drawer2D_Widths[i], xx + 1);
|
||||
@ -82,15 +80,14 @@ void Drawer2D_SetFontBitmap(Bitmap* bmp) {
|
||||
|
||||
|
||||
void Drawer2D_HexEncodedCol(int i, int hex, uint8_t lo, uint8_t hi) {
|
||||
PackedCol* col = &Drawer2D_Cols[i];
|
||||
col->R = (uint8_t)(lo * ((hex >> 2) & 1) + hi * (hex >> 3));
|
||||
col->G = (uint8_t)(lo * ((hex >> 1) & 1) + hi * (hex >> 3));
|
||||
col->B = (uint8_t)(lo * ((hex >> 0) & 1) + hi * (hex >> 3));
|
||||
col->A = UInt8_MaxValue;
|
||||
Drawer2D_Cols[i].R = (uint8_t)(lo * ((hex >> 2) & 1) + hi * (hex >> 3));
|
||||
Drawer2D_Cols[i].G = (uint8_t)(lo * ((hex >> 1) & 1) + hi * (hex >> 3));
|
||||
Drawer2D_Cols[i].B = (uint8_t)(lo * ((hex >> 0) & 1) + hi * (hex >> 3));
|
||||
Drawer2D_Cols[i].A = 255;
|
||||
}
|
||||
|
||||
void Drawer2D_Init(void) {
|
||||
PackedCol col = PACKEDCOL_CONST(0, 0, 0, 0);
|
||||
BitmapCol col = BITMAPCOL_CONST(0, 0, 0, 0);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DRAWER2D_MAX_COLS; i++) {
|
||||
@ -109,11 +106,10 @@ void Drawer2D_Init(void) {
|
||||
void Drawer2D_Free(void) { Drawer2D_FreeFontBitmap(); }
|
||||
|
||||
/* Draws a 2D flat rectangle. */
|
||||
void Drawer2D_Rect(Bitmap* bmp, PackedCol col, int x, int y, int width, int height);
|
||||
void Drawer2D_Rect(Bitmap* bmp, BitmapCol col, int x, int y, int width, int height);
|
||||
|
||||
void Drawer2D_Clear(Bitmap* bmp, PackedCol col, int x, int y, int width, int height) {
|
||||
uint32_t argb = PackedCol_ToARGB(col);
|
||||
uint32_t* row;
|
||||
void Drawer2D_Clear(Bitmap* bmp, BitmapCol col, int x, int y, int width, int height) {
|
||||
BitmapCol* row;
|
||||
int xx, yy;
|
||||
|
||||
if (x < 0 || y < 0 || (x + width) > bmp->Width || (y + height) > bmp->Height) {
|
||||
@ -122,7 +118,7 @@ void Drawer2D_Clear(Bitmap* bmp, PackedCol col, int x, int y, int width, int hei
|
||||
|
||||
for (yy = 0; yy < height; yy++) {
|
||||
row = Bitmap_GetRow(bmp, y + yy) + x;
|
||||
for (xx = 0; xx < width; xx++) { row[xx] = argb; }
|
||||
for (xx = 0; xx < width; xx++) { row[xx] = col; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,9 +229,8 @@ static int Drawer2D_NextPart(int i, STRING_REF String* value, String* part, char
|
||||
return i;
|
||||
}
|
||||
|
||||
void Drawer2D_Underline(Bitmap* bmp, int x, int y, int width, int height, PackedCol col) {
|
||||
uint32_t argb = PackedCol_ToARGB(col);
|
||||
uint32_t* row;
|
||||
void Drawer2D_Underline(Bitmap* bmp, int x, int y, int width, int height, BitmapCol col) {
|
||||
BitmapCol* row;
|
||||
int xx, yy;
|
||||
|
||||
for (yy = y; yy < y + height; yy++) {
|
||||
@ -244,14 +239,14 @@ void Drawer2D_Underline(Bitmap* bmp, int x, int y, int width, int height, Packed
|
||||
|
||||
for (xx = x; xx < x + width; xx++) {
|
||||
if (xx >= bmp->Width) break;
|
||||
row[xx] = argb;
|
||||
row[xx] = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int y, bool shadow) {
|
||||
PackedCol black = PACKEDCOL_BLACK;
|
||||
PackedColUnion col;
|
||||
BitmapCol black = BITMAPCOL_CONST(0, 0, 0, 255);
|
||||
BitmapColUnion col;
|
||||
String text = args->Text;
|
||||
int i, point = args->Font.Size, count = 0;
|
||||
|
||||
@ -262,13 +257,16 @@ static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int
|
||||
int dstHeight, begX, xx, yy;
|
||||
int cellY, underlineY, underlineHeight;
|
||||
|
||||
BitmapCol* srcRow, src;
|
||||
BitmapCol* dstRow, dst;
|
||||
|
||||
uint8_t coords[256];
|
||||
PackedColUnion cols[256];
|
||||
BitmapColUnion cols[256];
|
||||
uint16_t dstWidths[256];
|
||||
|
||||
col.C = Drawer2D_Cols['f'];
|
||||
if (shadow) {
|
||||
col.C = Drawer2D_BlackTextShadows ? black : PackedCol_Scale(col.C, 0.25f);
|
||||
col.C = Drawer2D_BlackTextShadows ? black : BitmapCol_Scale(col.C, 0.25f);
|
||||
}
|
||||
|
||||
for (i = 0; i < text.length; i++) {
|
||||
@ -276,7 +274,7 @@ static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int
|
||||
if (c == '&' && Drawer2D_ValidColCodeAt(&text, i + 1)) {
|
||||
col.C = Drawer2D_GetCol(text.buffer[i + 1]);
|
||||
if (shadow) {
|
||||
col.C = Drawer2D_BlackTextShadows ? black : PackedCol_Scale(col.C, 0.25f);
|
||||
col.C = Drawer2D_BlackTextShadows ? black : BitmapCol_Scale(col.C, 0.25f);
|
||||
}
|
||||
i++; continue; /* skip over the colour code */
|
||||
}
|
||||
@ -297,12 +295,12 @@ static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int
|
||||
if (dstY >= bmp->Height) break;
|
||||
|
||||
fontY = 0 + yy * Drawer2D_TileSize / dstHeight;
|
||||
uint32_t* dstRow = Bitmap_GetRow(bmp, dstY);
|
||||
dstRow = Bitmap_GetRow(bmp, dstY);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
srcX = (coords[i] & 0x0F) * Drawer2D_TileSize;
|
||||
srcY = (coords[i] >> 4) * Drawer2D_TileSize;
|
||||
uint32_t* fontRow = Bitmap_GetRow(&Drawer2D_FontBitmap, fontY + srcY);
|
||||
srcRow = Bitmap_GetRow(&Drawer2D_FontBitmap, fontY + srcY);
|
||||
|
||||
srcWidth = Drawer2D_Widths[coords[i]];
|
||||
dstWidth = dstWidths[i];
|
||||
@ -310,17 +308,17 @@ static void Drawer2D_DrawCore(Bitmap* bmp, struct DrawTextArgs* args, int x, int
|
||||
|
||||
for (xx = 0; xx < dstWidth; xx++) {
|
||||
fontX = srcX + xx * srcWidth / dstWidth;
|
||||
uint32_t src = fontRow[fontX];
|
||||
if (PackedCol_ARGB_A(src) == 0) continue;
|
||||
src = srcRow[fontX];
|
||||
if (!src.A) continue;
|
||||
|
||||
dstX = x + xx;
|
||||
if (dstX >= bmp->Width) break;
|
||||
|
||||
uint32_t pixel = src & ~0xFFFFFF;
|
||||
pixel |= ((src & 0xFF) * col.C.B / 255);
|
||||
pixel |= (((src >> 8) & 0xFF) * col.C.G / 255) << 8;
|
||||
pixel |= (((src >> 16) & 0xFF) * col.C.R / 255) << 16;
|
||||
dstRow[dstX] = pixel;
|
||||
dst.B = src.B * col.C.B / 255;
|
||||
dst.G = src.G * col.C.G / 255;
|
||||
dst.R = src.R * col.C.R / 255;
|
||||
dst.A = src.A;
|
||||
dstRow[dstX] = dst;
|
||||
}
|
||||
x += dstWidth + xPadding;
|
||||
}
|
||||
@ -382,7 +380,7 @@ static Size2D Drawer2D_MeasureBitmapText(struct DrawTextArgs* args) {
|
||||
}
|
||||
|
||||
void Drawer2D_DrawText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y) {
|
||||
PackedCol col, backCol, black = PACKEDCOL_BLACK;
|
||||
BitmapCol col, backCol, black = BITMAPCOL_CONST(0, 0, 0, 255);
|
||||
Size2D partSize;
|
||||
String value = args->Text;
|
||||
char colCode, nextCol = 'f';
|
||||
@ -398,7 +396,7 @@ void Drawer2D_DrawText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y) {
|
||||
|
||||
col = Drawer2D_GetCol(colCode);
|
||||
if (args->UseShadow) {
|
||||
backCol = Drawer2D_BlackTextShadows ? black : PackedCol_Scale(col, 0.25f);
|
||||
backCol = Drawer2D_BlackTextShadows ? black : BitmapCol_Scale(col, 0.25f);
|
||||
Platform_TextDraw(args, bmp, x + DRAWER2D_OFFSET, y + DRAWER2D_OFFSET, backCol);
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define CC_DRAWER2D_H
|
||||
#include "PackedCol.h"
|
||||
#include "Constants.h"
|
||||
#include "Bitmap.h"
|
||||
/* Responsible for performing drawing operations on bitmaps, and for converting bitmaps into textures.
|
||||
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
@ -18,7 +19,7 @@ CC_NOINLINE void Drawer2D_MakeFont(FontDesc* desc, int size, int style);
|
||||
bool Drawer2D_BitmappedText;
|
||||
/* Whether the shadows behind text (that uses shadows) is fully black. */
|
||||
bool Drawer2D_BlackTextShadows;
|
||||
PackedCol Drawer2D_Cols[DRAWER2D_MAX_COLS];
|
||||
BitmapCol Drawer2D_Cols[DRAWER2D_MAX_COLS];
|
||||
#define DRAWER2D_OFFSET 1
|
||||
#define Drawer2D_GetCol(c) Drawer2D_Cols[(uint8_t)c]
|
||||
|
||||
@ -26,11 +27,11 @@ void Drawer2D_Init(void);
|
||||
void Drawer2D_Free(void);
|
||||
|
||||
/* Draws a 2D flat rectangle. */
|
||||
void Drawer2D_Rect(Bitmap* bmp, PackedCol col, int x, int y, int width, int height);
|
||||
void Drawer2D_Rect(Bitmap* bmp, BitmapCol col, int x, int y, int width, int height);
|
||||
/* Clears the entire given area to the specified colour. */
|
||||
void Drawer2D_Clear(Bitmap* bmp, PackedCol col, int x, int y, int width, int height);
|
||||
void Drawer2D_Clear(Bitmap* bmp, BitmapCol col, int x, int y, int width, int height);
|
||||
|
||||
void Drawer2D_Underline(Bitmap* bmp, int x, int y, int width, int height, PackedCol col);
|
||||
void Drawer2D_Underline(Bitmap* bmp, int x, int y, int width, int height, BitmapCol col);
|
||||
void Drawer2D_DrawText(Bitmap* bmp, struct DrawTextArgs* args, int x, int y);
|
||||
Size2D Drawer2D_MeasureText(struct DrawTextArgs* args);
|
||||
int Drawer2D_FontHeight(const FontDesc* font, bool useShadow);
|
||||
|
20
src/Entity.c
20
src/Entity.c
@ -477,6 +477,9 @@ void TabList_MakeComponent(struct IGameComponent* comp) {
|
||||
|
||||
static void Player_MakeNameTexture(struct Player* player) {
|
||||
String colorlessName; char colorlessBuffer[STRING_SIZE];
|
||||
BitmapCol shadowCol = BITMAPCOL_CONST(80, 80, 80, 255);
|
||||
BitmapCol origWhiteCol;
|
||||
|
||||
struct DrawTextArgs args;
|
||||
bool bitmapped;
|
||||
String name;
|
||||
@ -501,9 +504,9 @@ static void Player_MakeNameTexture(struct Player* player) {
|
||||
|
||||
Bitmap_AllocateClearedPow2(&bmp, size.Width, size.Height);
|
||||
{
|
||||
PackedCol origWhiteCol = Drawer2D_Cols['f'];
|
||||
origWhiteCol = Drawer2D_Cols['f'];
|
||||
|
||||
Drawer2D_Cols['f'] = PackedCol_Create3(80, 80, 80);
|
||||
Drawer2D_Cols['f'] = shadowCol;
|
||||
String_AppendColorless(&colorlessName, &name);
|
||||
args.Text = colorlessName;
|
||||
Drawer2D_DrawText(&bmp, &args, NAME_OFFSET, NAME_OFFSET);
|
||||
@ -653,11 +656,9 @@ static void Player_ClearHat(Bitmap* bmp, uint8_t skinType) {
|
||||
|
||||
/* determine if we actually need filtering */
|
||||
for (y = 0; y < sizeY; y++) {
|
||||
uint32_t* row = Bitmap_GetRow(bmp, y);
|
||||
row += sizeX;
|
||||
BitmapCol* row = Bitmap_GetRow(bmp, y) + sizeX;
|
||||
for (x = 0; x < sizeX; x++) {
|
||||
uint8_t alpha = PackedCol_ARGB_A(row[x]);
|
||||
if (alpha != 255) return;
|
||||
if (row[x].A != 255) return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -665,8 +666,7 @@ static void Player_ClearHat(Bitmap* bmp, uint8_t skinType) {
|
||||
uint32_t fullWhite = PackedCol_ARGB(255, 255, 255, 255);
|
||||
uint32_t fullBlack = PackedCol_ARGB(0, 0, 0, 255);
|
||||
for (y = 0; y < sizeY; y++) {
|
||||
uint32_t* row = Bitmap_GetRow(bmp, y);
|
||||
row += sizeX;
|
||||
uint32_t* row = Bitmap_RawRow(bmp, y) + sizeX;
|
||||
for (x = 0; x < sizeX; x++) {
|
||||
uint32_t pixel = row[x];
|
||||
if (pixel == fullWhite || pixel == fullBlack) row[x] = 0;
|
||||
@ -690,8 +690,8 @@ static void Player_EnsurePow2(struct Player* p, Bitmap* bmp) {
|
||||
stride = bmp->Width * BITMAP_SIZEOF_PIXEL;
|
||||
|
||||
for (y = 0; y < bmp->Height; y++) {
|
||||
uint32_t* src = Bitmap_GetRow(bmp, y);
|
||||
uint32_t* dst = Bitmap_GetRow(&scaled, y);
|
||||
BitmapCol* src = Bitmap_GetRow(bmp, y);
|
||||
BitmapCol* dst = Bitmap_GetRow(&scaled, y);
|
||||
Mem_Copy(dst, src, stride);
|
||||
}
|
||||
|
||||
|
@ -602,14 +602,14 @@ static bool ShadowComponent_GetBlocks(struct Entity* e, int x, int y, int z, str
|
||||
#define sh_half (sh_size / 2)
|
||||
static void ShadowComponent_MakeTex(void) {
|
||||
uint8_t pixels[Bitmap_DataSize(sh_size, sh_size)];
|
||||
Bitmap bmp; Bitmap_Create(&bmp, sh_size, sh_size, pixels);
|
||||
|
||||
uint32_t inPix = PackedCol_ARGB(0, 0, 0, 200);
|
||||
uint32_t outPix = PackedCol_ARGB(0, 0, 0, 0);
|
||||
|
||||
BitmapCol inPix = BITMAPCOL_CONST(0, 0, 0, 200);
|
||||
BitmapCol outPix = BITMAPCOL_CONST(0, 0, 0, 0);
|
||||
Bitmap bmp;
|
||||
uint32_t x, y;
|
||||
Bitmap_Create(&bmp, sh_size, sh_size, pixels);
|
||||
|
||||
for (y = 0; y < sh_size; y++) {
|
||||
uint32_t* row = Bitmap_GetRow(&bmp, y);
|
||||
BitmapCol* row = Bitmap_GetRow(&bmp, y);
|
||||
for (x = 0; x < sh_size; x++) {
|
||||
double dist =
|
||||
(sh_half - (x + 0.5)) * (sh_half - (x + 0.5)) +
|
||||
|
@ -215,18 +215,21 @@ static GfxResourceID sky_vb;
|
||||
static int sky_vertices;
|
||||
|
||||
void EnvRenderer_RenderSky(double deltaTime) {
|
||||
struct Matrix m;
|
||||
float skyY, normY, dy;
|
||||
if (!sky_vb || EnvRenderer_ShouldRenderSkybox()) return;
|
||||
Vector3 pos = Camera_CurrentPos;
|
||||
float normalY = (float)World_Height + 8.0f;
|
||||
float skyY = max(pos.Y + 8.0f, normalY);
|
||||
|
||||
normY = (float)World_Height + 8.0f;
|
||||
skyY = max(Camera_CurrentPos.Y + 8.0f, normY);
|
||||
Gfx_SetBatchFormat(VERTEX_FORMAT_P3FC4B);
|
||||
Gfx_BindVb(sky_vb);
|
||||
|
||||
if (skyY == normalY) {
|
||||
if (skyY == normY) {
|
||||
Gfx_DrawVb_IndexedTris(sky_vertices);
|
||||
} else {
|
||||
struct Matrix m = Gfx_View;
|
||||
float dy = skyY - normalY; /* inlined Y translation matrix multiply */
|
||||
m = Gfx_View;
|
||||
dy = skyY - normY;
|
||||
/* inlined Y translation matrix multiply */
|
||||
m.Row3.X += dy * m.Row1.X; m.Row3.Y += dy * m.Row1.Y;
|
||||
m.Row3.Z += dy * m.Row1.Z; m.Row3.W += dy * m.Row1.W;
|
||||
|
||||
@ -445,12 +448,19 @@ static float EnvRenderer_RainAlphaAt(float x) {
|
||||
}
|
||||
|
||||
void EnvRenderer_RenderWeather(double deltaTime) {
|
||||
int weather = Env_Weather;
|
||||
VertexP3fT2fC4b vertices[WEATHER_VERTS_COUNT];
|
||||
VertexP3fT2fC4b* ptr, v;
|
||||
int weather, vCount;
|
||||
Vector3I pos;
|
||||
bool moved, particles;
|
||||
float speed, vOffset;
|
||||
float dist, alpha;
|
||||
|
||||
int dist, dx, dz, x, z;
|
||||
float alpha, y, height;
|
||||
float worldV, v1, v2;
|
||||
float x1,y1,z1, x2,y2,z2;
|
||||
|
||||
weather = Env_Weather;
|
||||
if (weather == WEATHER_SUNNY) return;
|
||||
if (!Weather_Heightmap) EnvRenderer_InitWeatherHeightmap();
|
||||
Gfx_BindTexture(weather == WEATHER_RAINY ? rain_tex : snow_tex);
|
||||
@ -468,16 +478,15 @@ void EnvRenderer_RenderWeather(double deltaTime) {
|
||||
particles = weather == WEATHER_RAINY;
|
||||
weather_accumulator += deltaTime;
|
||||
|
||||
VertexP3fT2fC4b v; v.Col = Env_SunCol;
|
||||
VertexP3fT2fC4b vertices[WEATHER_VERTS_COUNT];
|
||||
VertexP3fT2fC4b* ptr = vertices;
|
||||
ptr = vertices;
|
||||
v.Col = Env_SunCol;
|
||||
|
||||
int dx, dz;
|
||||
for (dx = -WEATHER_EXTENT; dx <= WEATHER_EXTENT; dx++) {
|
||||
for (dz = -WEATHER_EXTENT; dz <= WEATHER_EXTENT; dz++) {
|
||||
int x = pos.X + dx, z = pos.Z + dz;
|
||||
float y = EnvRenderer_RainHeight(x, z);
|
||||
float height = pos.Y - y;
|
||||
x = pos.X + dx; z = pos.Z + dz;
|
||||
|
||||
y = EnvRenderer_RainHeight(x, z);
|
||||
height = pos.Y - y;
|
||||
if (height <= 0) continue;
|
||||
|
||||
if (particles && (weather_accumulator >= 0.25 || moved)) {
|
||||
@ -485,16 +494,17 @@ void EnvRenderer_RenderWeather(double deltaTime) {
|
||||
Particles_RainSnowEffect(particlePos);
|
||||
}
|
||||
|
||||
dist = (float)dx * (float)dx + (float)dz * (float)dz;
|
||||
alpha = EnvRenderer_RainAlphaAt(dist);
|
||||
dist = dx * dx + dz * dz;
|
||||
alpha = EnvRenderer_RainAlphaAt((float)dist);
|
||||
Math_Clamp(alpha, 0.0f, 255.0f);
|
||||
v.Col.A = (uint8_t)alpha;
|
||||
|
||||
/* NOTE: Making vertex is inlined since this is called millions of times. */
|
||||
float worldV = vOffset + (z & 1) / 2.0f - (x & 0x0F) / 16.0f;
|
||||
float v1 = y / 6.0f + worldV, v2 = (y + height) / 6.0f + worldV;
|
||||
float x1 = (float)x, y1 = (float)y, z1 = (float)z;
|
||||
float x2 = (float)(x + 1), y2 = (float)(y + height), z2 = (float)(z + 1);
|
||||
worldV = vOffset + (z & 1) / 2.0f - (x & 0x0F) / 16.0f;
|
||||
v1 = y / 6.0f + worldV;
|
||||
v2 = (y + height) / 6.0f + worldV;
|
||||
x1 = (float)x; y1 = (float)y; z1 = (float)z;
|
||||
x2 = (float)(x + 1); y2 = (float)(y + height); z2 = (float)(z + 1);
|
||||
|
||||
v.X = x1; v.Y = y1; v.Z = z1; v.U = 0.0f; v.V = v1; *ptr++ = v;
|
||||
v.Y = y2; v.V = v2; *ptr++ = v;
|
||||
@ -518,7 +528,7 @@ void EnvRenderer_RenderWeather(double deltaTime) {
|
||||
Gfx_SetAlphaArgBlend(true);
|
||||
|
||||
Gfx_SetBatchFormat(VERTEX_FORMAT_P3FT2FC4B);
|
||||
int vCount = (int)(ptr - vertices);
|
||||
vCount = (int)(ptr - vertices);
|
||||
GfxCommon_UpdateDynamicVb_IndexedTris(weather_vb, vertices, vCount);
|
||||
|
||||
Gfx_SetAlphaArgBlend(false);
|
||||
|
@ -445,13 +445,16 @@ typedef struct {
|
||||
} X11Button;
|
||||
|
||||
static void X11Button_Draw(X11Button* b, X11Window* w) {
|
||||
X11Textbox* t;
|
||||
int begX, endX, begY, endY;
|
||||
|
||||
XSetForeground(dpy, w->gc, w->btnBorder);
|
||||
XDrawRectangle(dpy, w->win, w->gc, b->X, b->Y,
|
||||
b->Width, b->Height);
|
||||
|
||||
X11Textbox* t = &b->Text;
|
||||
int begX = b->X + 1, endX = b->X + b->Width - 1;
|
||||
int begY = b->Y + 1, endY = b->Y + b->Height - 1;
|
||||
t = &b->Text;
|
||||
begX = b->X + 1; endX = b->X + b->Width - 1;
|
||||
begY = b->Y + 1; endY = b->Y + b->Height - 1;
|
||||
|
||||
if (b->Clicked) {
|
||||
XSetForeground(dpy, w->gc, w->highlight);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define CC_GAME_H
|
||||
#include "Picking.h"
|
||||
#include "Options.h"
|
||||
#include "Bitmap.h"
|
||||
/* Represents the game.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "PackedCol.h"
|
||||
#include "Vectors.h"
|
||||
#include "GameStructs.h"
|
||||
#include "Bitmap.h"
|
||||
|
||||
/* Abstracts a 3D graphics rendering API.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
|
@ -167,52 +167,54 @@ void GfxCommon_RestoreAlphaState(uint8_t draw) {
|
||||
}
|
||||
|
||||
|
||||
#define alphaMask ((uint32_t)0xFF000000UL)
|
||||
/* Quoted from http://www.realtimerendering.com/blog/gpus-prefer-premultiplication/
|
||||
The short version: if you want your renderer to properly handle textures with alphas when using
|
||||
bilinear interpolation or mipmapping, you need to premultiply your PNG color data by their (unassociated) alphas. */
|
||||
static uint32_t GfxCommon_Average(uint32_t p1, uint32_t p2) {
|
||||
uint32_t a1 = ((p1 & alphaMask) >> 24) & 0xFF;
|
||||
uint32_t a2 = ((p2 & alphaMask) >> 24) & 0xFF;
|
||||
uint32_t aSum = (a1 + a2);
|
||||
static BitmapCol GfxCommon_Average(BitmapCol p1, BitmapCol p2) {
|
||||
uint32_t a1, a2, aSum;
|
||||
uint32_t b1, g1, r1;
|
||||
uint32_t b2, g2, r2;
|
||||
BitmapCol ave;
|
||||
|
||||
a1 = p1.A; a2 = p2.A;
|
||||
aSum = (a1 + a2);
|
||||
aSum = aSum > 0 ? aSum : 1; /* avoid divide by 0 below */
|
||||
|
||||
/* Convert RGB to pre-multiplied form */
|
||||
uint32_t r1 = ((p1 >> 16) & 0xFF) * a1, g1 = ((p1 >> 8) & 0xFF) * a1, b1 = (p1 & 0xFF) * a1;
|
||||
uint32_t r2 = ((p2 >> 16) & 0xFF) * a2, g2 = ((p2 >> 8) & 0xFF) * a2, b2 = (p2 & 0xFF) * a2;
|
||||
b1 = p1.B * a1; g1 = p1.G * a1; r1 = p1.R * a1;
|
||||
b2 = p1.B * a2; g2 = p2.G * a2; r2 = p2.R * a2;
|
||||
|
||||
/* https://stackoverflow.com/a/347376
|
||||
We need to convert RGB back from the pre-multiplied average into normal form
|
||||
((r1 + r2) / 2) / ((a1 + a2) / 2)
|
||||
but we just cancel out the / 2*/
|
||||
uint32_t aAve = aSum >> 1;
|
||||
uint32_t rAve = (r1 + r2) / aSum;
|
||||
uint32_t gAve = (g1 + g2) / aSum;
|
||||
uint32_t bAve = (b1 + b2) / aSum;
|
||||
|
||||
return (aAve << 24) | (rAve << 16) | (gAve << 8) | bAve;
|
||||
ave.B = (b1 + b2) / aSum;
|
||||
ave.G = (g1 + g2) / aSum;
|
||||
ave.R = (r1 + r2) / aSum;
|
||||
ave.A = aSum >> 1;
|
||||
return ave;
|
||||
}
|
||||
|
||||
void GfxCommon_GenMipmaps(int width, int height, uint8_t* lvlScan0, uint8_t* scan0) {
|
||||
uint32_t* baseSrc = (uint32_t*)scan0;
|
||||
uint32_t* baseDst = (uint32_t*)lvlScan0;
|
||||
BitmapCol* baseSrc = (BitmapCol*)scan0;
|
||||
BitmapCol* baseDst = (BitmapCol*)lvlScan0;
|
||||
int srcWidth = width << 1;
|
||||
|
||||
int x, y;
|
||||
for (y = 0; y < height; y++) {
|
||||
int srcY = (y << 1);
|
||||
uint32_t* src0 = baseSrc + srcY * srcWidth;
|
||||
uint32_t* src1 = src0 + srcWidth;
|
||||
uint32_t* dst = baseDst + y * width;
|
||||
BitmapCol* src0 = baseSrc + srcY * srcWidth;
|
||||
BitmapCol* src1 = src0 + srcWidth;
|
||||
BitmapCol* dst = baseDst + y * width;
|
||||
|
||||
for (x = 0; x < width; x++) {
|
||||
int srcX = (x << 1);
|
||||
uint32_t src00 = src0[srcX], src01 = src0[srcX + 1];
|
||||
uint32_t src10 = src1[srcX], src11 = src1[srcX + 1];
|
||||
BitmapCol src00 = src0[srcX], src01 = src0[srcX + 1];
|
||||
BitmapCol src10 = src1[srcX], src11 = src1[srcX + 1];
|
||||
|
||||
/* bilinear filter this mipmap */
|
||||
uint32_t ave0 = GfxCommon_Average(src00, src01);
|
||||
uint32_t ave1 = GfxCommon_Average(src10, src11);
|
||||
BitmapCol ave0 = GfxCommon_Average(src00, src01);
|
||||
BitmapCol ave1 = GfxCommon_Average(src10, src11);
|
||||
dst[x] = GfxCommon_Average(ave0, ave1);
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,6 @@ bool PackedCol_Equals(PackedCol a, PackedCol b) {
|
||||
return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
|
||||
}
|
||||
|
||||
uint32_t PackedCol_ToARGB(PackedCol col) {
|
||||
return PackedCol_ARGB(col.R, col.G, col.B, col.A);
|
||||
}
|
||||
|
||||
PackedCol PackedCol_Scale(PackedCol value, float t) {
|
||||
value.R = (uint8_t)(value.R * t);
|
||||
value.G = (uint8_t)(value.G * t);
|
||||
|
@ -1,11 +1,11 @@
|
||||
#ifndef CC_PACKEDCOL_H
|
||||
#define CC_PACKEDCOL_H
|
||||
#include "String.h"
|
||||
/* Manipulates an ARGB colour, in a format suitable for the native 3d graphics api.
|
||||
/* Manipulates an ARGB colour, in a format suitable for the native 3D graphics API.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
/* Represents an ARGB colour, in a format suitable for the native graphics api. */
|
||||
/* Represents an ARGB colour, suitable for native graphics API colours. */
|
||||
typedef CC_ALIGN_HINT(4) struct PackedCol_ {
|
||||
#ifdef CC_BUILD_D3D9
|
||||
uint8_t B, G, R, A;
|
||||
@ -14,25 +14,22 @@
|
||||
#endif
|
||||
} PackedCol;
|
||||
|
||||
/* Represents an ARGB colour, in a format suitable for the native graphics api. */
|
||||
/* Represents an ARGB colour, suitable for native graphics API colours. */
|
||||
/* Unioned with Packed member for efficient equality comparison */
|
||||
typedef union PackedColUnion_ { PackedCol C; uint32_t Raw; } PackedColUnion;
|
||||
/* NOTE: can't just use "struct { uint8_t B, G, R, A; };" here,
|
||||
because unnamed members aren't supported on all compilers) */
|
||||
|
||||
#ifdef CC_BUILD_D3D9
|
||||
#define PACKEDCOL_CONST(r, g, b, a) { b, g, r, a }
|
||||
#else
|
||||
#define PACKEDCOL_CONST(r, g, b, a) { r, g, b, a }
|
||||
#endif
|
||||
#define PACKEDCOL_WHITE PACKEDCOL_CONST(255, 255, 255, 255)
|
||||
|
||||
PackedCol PackedCol_Create4(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||
PackedCol PackedCol_Create3(uint8_t r, uint8_t g, uint8_t b);
|
||||
bool PackedCol_Equals(PackedCol a, PackedCol b);
|
||||
|
||||
#define PackedCol_ARGB(r, g, b, a) (((uint32_t)(r) << 16) | ((uint32_t)(g) << 8) | ((uint32_t)(b)) | ((uint32_t)(a) << 24))
|
||||
#define PackedCol_ARGB_A(col) ((uint8_t)((col) >> 24))
|
||||
uint32_t PackedCol_ToARGB(PackedCol col);
|
||||
PackedCol PackedCol_Scale(PackedCol value, float t);
|
||||
PackedCol PackedCol_Lerp(PackedCol a, PackedCol b, float t);
|
||||
CC_NOINLINE bool PackedCol_Unhex(char hex, int* value);
|
||||
@ -44,13 +41,4 @@ CC_NOINLINE bool PackedCol_TryParseHex(const String* str, PackedCol* value);
|
||||
#define PACKEDCOL_SHADE_YMIN 0.5f
|
||||
/* Retrieves shaded colours for ambient block face lighting */
|
||||
void PackedCol_GetShaded(PackedCol normal, PackedCol* xSide, PackedCol* zSide, PackedCol* yMin);
|
||||
|
||||
#define PACKEDCOL_WHITE PACKEDCOL_CONST(255, 255, 255, 255)
|
||||
#define PACKEDCOL_BLACK PACKEDCOL_CONST( 0, 0, 0, 255)
|
||||
#define PACKEDCOL_RED PACKEDCOL_CONST(255, 0, 0, 255)
|
||||
#define PACKEDCOL_GREEN PACKEDCOL_CONST( 0, 255, 0, 255)
|
||||
#define PACKEDCOL_BLUE PACKEDCOL_CONST( 0, 0, 255, 255)
|
||||
#define PACKEDCOL_YELLOW PACKEDCOL_CONST(255, 255, 0, 255)
|
||||
#define PACKEDCOL_MAGENTA PACKEDCOL_CONST(255, 0, 255, 255)
|
||||
#define PACKEDCOL_CYAN PACKEDCOL_CONST( 0, 255, 255, 255)
|
||||
#endif
|
||||
|
@ -1212,7 +1212,7 @@ static void CPE_BulkBlockUpdate(uint8_t* data) {
|
||||
}
|
||||
|
||||
static void CPE_SetTextColor(uint8_t* data) {
|
||||
PackedCol c;
|
||||
BitmapCol c;
|
||||
uint8_t code;
|
||||
|
||||
c.R = *data++; c.G = *data++; c.B = *data++; c.A = *data++;
|
||||
|
@ -1007,7 +1007,7 @@ Size2D Platform_TextMeasure(struct DrawTextArgs* args) {
|
||||
return s;
|
||||
}
|
||||
|
||||
Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, PackedCol col) {
|
||||
Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, BitmapCol col) {
|
||||
FT_Face face = args->Font.Handle;
|
||||
String text = args->Text;
|
||||
Size2D s = { x, TEXT_CEIL(face->size->metrics.height) };
|
||||
@ -1024,18 +1024,18 @@ Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, P
|
||||
for (yy = 0; yy < img->rows; yy++) {
|
||||
if ((y + yy) < 0 || (y + yy) >= bmp->Height) continue;
|
||||
uint8_t* src = img->buffer + (yy * img->width);
|
||||
uint8_t* dst = (uint8_t*)Bitmap_GetRow(bmp, y + yy) + (x * BITMAP_SIZEOF_PIXEL);
|
||||
BitmapCol* dst = Bitmap_GetRow(bmp, y + yy) + x;
|
||||
|
||||
for (xx = 0; xx < img->width; xx++) {
|
||||
if ((x + xx) < 0 || (x + xx) >= bmp->Width) continue;
|
||||
|
||||
uint8_t intensity = *src, invIntensity = UInt8_MaxValue - intensity;
|
||||
dst[0] = ((col.B * intensity) >> 8) + ((dst[0] * invIntensity) >> 8);
|
||||
dst[1] = ((col.G * intensity) >> 8) + ((dst[1] * invIntensity) >> 8);
|
||||
dst[2] = ((col.R * intensity) >> 8) + ((dst[2] * invIntensity) >> 8);
|
||||
//dst[3] = ((col.A * intensity) >> 8) + ((dst[3] * invIntensity) >> 8);
|
||||
dst[3] = intensity + ((dst[3] * invIntensity) >> 8);
|
||||
src++; dst += BITMAP_SIZEOF_PIXEL;
|
||||
dst->B = ((col.B * intensity) >> 8) + ((dst->B * invIntensity) >> 8);
|
||||
dst->G = ((col.G * intensity) >> 8) + ((dst->G * invIntensity) >> 8);
|
||||
dst->R = ((col.R * intensity) >> 8) + ((dst->R * invIntensity) >> 8);
|
||||
//dst[3] = ((col.A * intensity) >> 8) + ((dst->A * invIntensity) >> 8);
|
||||
dst->A = intensity + ((dst->A * invIntensity) >> 8);
|
||||
src++; dst++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define CC_PLATFORM_H
|
||||
#include "Utils.h"
|
||||
#include "PackedCol.h"
|
||||
#include "Bitmap.h"
|
||||
/* Abstracts platform specific memory management, I/O, etc.
|
||||
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
@ -176,7 +177,7 @@ CC_EXPORT void Font_Free(FontDesc* desc);
|
||||
/* Measures dimensions of the given text, if it was drawn with the given font. */
|
||||
CC_EXPORT Size2D Platform_TextMeasure(struct DrawTextArgs* args);
|
||||
/* Draws the given text with the given font onto the given bitmap. */
|
||||
CC_EXPORT Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, PackedCol col);
|
||||
CC_EXPORT Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, int x, int y, BitmapCol col);
|
||||
|
||||
/* Allocates a new socket. */
|
||||
void Socket_Create(SocketPtr* socket);
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "TerrainAtlas.h"
|
||||
#include "Bitmap.h"
|
||||
#include "Block.h"
|
||||
#include "ExtMath.h"
|
||||
#include "Funcs.h"
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef CC_TERRAINATLAS_H
|
||||
#define CC_TERRAINATLAS_H
|
||||
#include "Core.h"
|
||||
#include "Bitmap.h"
|
||||
/* Represents the 2D texture atlas of terrain.png, and converted into an array of 1D textures.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
@ -154,14 +154,13 @@ int Utils_AccumulateWheelDelta(float* accumulator, float delta) {
|
||||
}
|
||||
|
||||
uint8_t Utils_GetSkinType(const Bitmap* bmp) {
|
||||
int scale;
|
||||
if (bmp->Width == bmp->Height * 2) return SKIN_64x32;
|
||||
if (bmp->Width != bmp->Height) return SKIN_INVALID;
|
||||
|
||||
/* Minecraft alex skins have this particular pixel with alpha of 0 */
|
||||
int scale = bmp->Width / 64;
|
||||
uint32_t pixel = Bitmap_GetPixel(bmp, 54 * scale, 20 * scale);
|
||||
uint8_t alpha = PackedCol_ARGB_A(pixel);
|
||||
return alpha >= 127 ? SKIN_64x64 : SKIN_64x64_SLIM;
|
||||
scale = bmp->Width / 64;
|
||||
return Bitmap_GetPixel(bmp, 54 * scale, 20 * scale).A >= 127 ? SKIN_64x64 : SKIN_64x64_SLIM;
|
||||
}
|
||||
|
||||
uint32_t Utils_CRC32(const uint8_t* data, uint32_t length) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef CC_UTILS_H
|
||||
#define CC_UTILS_H
|
||||
#include "String.h"
|
||||
#include "Bitmap.h"
|
||||
/* Implements various utility functions.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
@ -925,6 +925,7 @@ static char InputWidget_GetLastCol(struct InputWidget* w, int x, int y) {
|
||||
}
|
||||
|
||||
static void InputWidget_UpdateCaret(struct InputWidget* w) {
|
||||
BitmapCol col;
|
||||
String line; char lineBuffer[STRING_SIZE];
|
||||
struct DrawTextArgs args;
|
||||
int maxChars, lineWidth;
|
||||
@ -961,7 +962,9 @@ static void InputWidget_UpdateCaret(struct InputWidget* w) {
|
||||
colCode = InputWidget_GetLastCol(w, w->CaretX, w->CaretY);
|
||||
|
||||
if (colCode) {
|
||||
w->CaretCol = Drawer2D_GetCol(colCode);
|
||||
col = Drawer2D_GetCol(colCode);
|
||||
w->CaretCol.B = col.B; w->CaretCol.G = col.G;
|
||||
w->CaretCol.R = col.R; w->CaretCol.A = col.A;
|
||||
} else {
|
||||
PackedCol white = PACKEDCOL_WHITE;
|
||||
w->CaretCol = PackedCol_Scale(white, 0.8f);
|
||||
@ -2725,9 +2728,9 @@ static Size2D SpecialInputWidget_MeasureTitles(struct SpecialInputWidget* w) {
|
||||
}
|
||||
|
||||
static void SpecialInputWidget_DrawTitles(struct SpecialInputWidget* w, Bitmap* bmp) {
|
||||
PackedCol col_selected = PACKEDCOL_CONST(30, 30, 30, 200);
|
||||
PackedCol col_inactive = PACKEDCOL_CONST( 0, 0, 0, 127);
|
||||
PackedCol col;
|
||||
BitmapCol col_selected = BITMAPCOL_CONST(30, 30, 30, 200);
|
||||
BitmapCol col_inactive = BITMAPCOL_CONST( 0, 0, 0, 127);
|
||||
BitmapCol col;
|
||||
|
||||
struct DrawTextArgs args;
|
||||
Size2D size;
|
||||
@ -2788,7 +2791,7 @@ static void SpecialInputWidget_DrawContent(struct SpecialInputWidget* w, struct
|
||||
}
|
||||
|
||||
static void SpecialInputWidget_Make(struct SpecialInputWidget* w, struct SpecialInputTab* tab) {
|
||||
PackedCol col = PACKEDCOL_CONST(30, 30, 30, 200);
|
||||
BitmapCol col = PACKEDCOL_CONST(30, 30, 30, 200);
|
||||
Size2D size, titles, content;
|
||||
Bitmap bmp;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user