mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 02:25:32 -04:00
Fix 1/2/4 bit grayscale pngs being incorrectly decoded
This commit is contained in:
parent
e7738b50fa
commit
02c114db35
16
src/Bitmap.c
16
src/Bitmap.c
@ -125,9 +125,9 @@ static void Png_Reconstruct(uint8_t type, uint8_t bytesPerPixel, uint8_t* line,
|
||||
|
||||
#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_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_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]);
|
||||
|
||||
@ -326,6 +326,7 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
ReturnCode res;
|
||||
|
||||
/* header variables */
|
||||
static uint32_t samplesPerPixel[7] = { 1, 0, 3, 1, 2, 0, 4 };
|
||||
uint8_t col, bitsPerSample, bytesPerPixel;
|
||||
Png_RowExpander rowExpander;
|
||||
uint32_t scanlineSize, scanlineBytes;
|
||||
@ -384,7 +385,6 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
if (tmp[11] != 0) return PNG_ERR_FILTER;
|
||||
if (tmp[12] != 0) return PNG_ERR_INTERLACED;
|
||||
|
||||
static uint32_t samplesPerPixel[7] = { 1, 0, 3, 1, 2, 0, 4 };
|
||||
bytesPerPixel = ((samplesPerPixel[col] * bitsPerSample) + 7) >> 3;
|
||||
scanlineSize = ((samplesPerPixel[col] * bitsPerSample * bmp->Width) + 7) >> 3;
|
||||
scanlineBytes = scanlineSize + 1; /* Add 1 byte for filter byte of each scanline */
|
||||
@ -415,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 */
|
||||
transparentCol.B = tmp[0]; transparentCol.G = tmp[0];
|
||||
transparentCol.R = tmp[0]; transparentCol.A = 0;
|
||||
transparentCol.R = tmp[0]; transparentCol.G = tmp[0];
|
||||
transparentCol.B = 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);
|
||||
@ -432,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 */
|
||||
transparentCol.B = tmp[4]; transparentCol.G = tmp[2];
|
||||
transparentCol.R = tmp[0]; transparentCol.A = 0;
|
||||
transparentCol.R = tmp[0]; transparentCol.G = tmp[2];
|
||||
transparentCol.B = tmp[4]; transparentCol.A = 0;
|
||||
} else {
|
||||
return PNG_ERR_TRANS_INVALID;
|
||||
}
|
||||
|
36
src/Block.c
36
src/Block.c
@ -22,20 +22,20 @@ static uint32_t Block_DefinedCustomBlocks[BLOCK_COUNT >> 5];
|
||||
static char Block_NamesBuffer[STRING_SIZE * BLOCK_COUNT];
|
||||
#define Block_NamePtr(i) &Block_NamesBuffer[STRING_SIZE * i]
|
||||
|
||||
uint8_t Block_TopTex[BLOCK_CPE_COUNT] = { 0, 1, 0, 2, 16, 4, 15, 17, 14, 14,
|
||||
30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 24, 23, 6, 6, 7, 9, 4,
|
||||
36, 37, 16, 11, 25, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 26, 53, 52, };
|
||||
static uint8_t Block_TopTex[BLOCK_CPE_COUNT] = { 0, 1, 0, 2, 16, 4, 15,
|
||||
17, 14, 14, 30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69,
|
||||
70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 24, 23, 6, 6, 7, 9,
|
||||
4, 36, 37, 16, 11, 25, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 26, 53, 52 };
|
||||
|
||||
uint8_t Block_SideTex[BLOCK_CPE_COUNT] = { 0, 1, 3, 2, 16, 4, 15, 17, 14, 14,
|
||||
30, 30, 18, 19, 32, 33, 34, 20, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 40, 39, 5, 5, 7, 8, 35,
|
||||
36, 37, 16, 11, 41, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 42, 53, 52, };
|
||||
static uint8_t Block_SideTex[BLOCK_CPE_COUNT] = { 0, 1, 3, 2, 16, 4, 15,
|
||||
17, 14, 14, 30, 30, 18, 19, 32, 33, 34, 20, 22, 48, 49, 64, 65, 66, 67, 68, 69,
|
||||
70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 40, 39, 5, 5, 7, 8,
|
||||
35, 36, 37, 16, 11, 41, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 42, 53, 52 };
|
||||
|
||||
uint8_t Block_BottomTex[BLOCK_CPE_COUNT] = { 0, 1, 2, 2, 16, 4, 15, 17, 14, 14,
|
||||
30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 56, 55, 6, 6, 7, 10, 4,
|
||||
36, 37, 16, 11, 57, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 58, 53, 52 };
|
||||
static uint8_t Block_BottomTex[BLOCK_CPE_COUNT] = { 0, 1, 2, 2, 16, 4, 15,
|
||||
17, 14, 14, 30, 30, 18, 19, 32, 33, 34, 21, 22, 48, 49, 64, 65, 66, 67, 68, 69,
|
||||
70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 56, 55, 6, 6, 7, 10,
|
||||
4, 36, 37, 16, 11, 57, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 58, 53, 52 };
|
||||
|
||||
#ifdef EXTENDED_BLOCKS
|
||||
void Block_SetUsedCount(int count) {
|
||||
@ -589,11 +589,13 @@ float DefaultSet_FogDensity(BlockID b) {
|
||||
}
|
||||
|
||||
PackedCol DefaultSet_FogColour(BlockID b) {
|
||||
if (b == BLOCK_WATER || b == BLOCK_STILL_WATER)
|
||||
return PackedCol_Create3(5, 5, 51);
|
||||
if (b == BLOCK_LAVA || b == BLOCK_STILL_LAVA)
|
||||
return PackedCol_Create3(153, 25, 0);
|
||||
return PackedCol_Create4(0, 0, 0, 0);
|
||||
PackedCol colWater = PACKEDCOL_CONST( 5, 5, 51, 255);
|
||||
PackedCol colLava = PACKEDCOL_CONST(153, 25, 0, 255);
|
||||
PackedCol colZero = PACKEDCOL_CONST( 0, 0, 0, 0);
|
||||
|
||||
if (b == BLOCK_WATER || b == BLOCK_STILL_WATER) return colWater;
|
||||
if (b == BLOCK_LAVA || b == BLOCK_STILL_LAVA) return colLava;
|
||||
return colZero;
|
||||
}
|
||||
|
||||
CollideType DefaultSet_Collide(BlockID b) {
|
||||
|
@ -353,13 +353,17 @@ static void Drawer2D_DrawBitmapText(Bitmap* bmp, struct DrawTextArgs* args, int
|
||||
}
|
||||
|
||||
static Size2D Drawer2D_MeasureBitmapText(struct DrawTextArgs* args) {
|
||||
int point = args->Font.Size;
|
||||
/* adjust coords to make drawn text match GDI fonts */
|
||||
int i, offset;
|
||||
int xPadding = Drawer2D_XPadding(point);
|
||||
Size2D total = { 0, Drawer2D_AdjHeight(point) };
|
||||
int i, point = args->Font.Size;
|
||||
int offset, xPadding;
|
||||
Size2D total;
|
||||
String text;
|
||||
|
||||
String text = args->Text;
|
||||
/* adjust coords to make drawn text match GDI fonts */
|
||||
xPadding = Drawer2D_XPadding(point);
|
||||
total.Width = 0;
|
||||
total.Height = Drawer2D_AdjHeight(point);
|
||||
|
||||
text = args->Text;
|
||||
for (i = 0; i < text.length; i++) {
|
||||
char c = text.buffer[i];
|
||||
if (c == '&' && Drawer2D_ValidColCodeAt(&text, i + 1)) {
|
||||
|
36
src/Menus.c
36
src/Menus.c
@ -1628,16 +1628,20 @@ static void KeyBindingsScreen_OnBindingClick(void* screen, void* widget) {
|
||||
static int KeyBindingsScreen_MakeWidgets(struct KeyBindingsScreen* s, int y, int arrowsY, int leftLength, const char* title, int btnWidth) {
|
||||
static String lArrow = String_FromConst("<");
|
||||
static String rArrow = String_FromConst(">");
|
||||
String text; char textBuffer[STRING_SIZE];
|
||||
String titleText;
|
||||
Widget_LeftClick backClick;
|
||||
int origin, xOffset;
|
||||
int i, xDir;
|
||||
|
||||
int i, origin = y, xOffset = btnWidth / 2 + 5;
|
||||
origin = y;
|
||||
xOffset = btnWidth / 2 + 5;
|
||||
s->CurI = -1;
|
||||
|
||||
char textBuffer[STRING_SIZE];
|
||||
String text = String_FromArray(textBuffer);
|
||||
String_InitArray(text, textBuffer);
|
||||
|
||||
for (i = 0; i < s->BindsCount; i++) {
|
||||
if (i == leftLength) y = origin; /* reset y for next column */
|
||||
int xDir = leftLength == -1 ? 0 : (i < leftLength ? -1 : 1);
|
||||
xDir = leftLength == -1 ? 0 : (i < leftLength ? -1 : 1);
|
||||
|
||||
text.length = 0;
|
||||
KeyBindingsScreen_GetText(s, i, &text);
|
||||
@ -1647,11 +1651,11 @@ static int KeyBindingsScreen_MakeWidgets(struct KeyBindingsScreen* s, int y, int
|
||||
y += 50; /* distance between buttons */
|
||||
}
|
||||
|
||||
String titleText = String_FromReadonly(title);
|
||||
titleText = String_FromReadonly(title);
|
||||
Menu_Label(s, i, &s->Title, &titleText, &s->TitleFont,
|
||||
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -180); i++;
|
||||
|
||||
Widget_LeftClick backClick = Game_UseClassicOptions ? Menu_SwitchClassicOptions : Menu_SwitchOptions;
|
||||
backClick = Game_UseClassicOptions ? Menu_SwitchClassicOptions : Menu_SwitchOptions;
|
||||
Menu_Back(s, i, &s->Back, "Done", &s->TitleFont, backClick); i++;
|
||||
if (!s->LeftPage && !s->RightPage) return i;
|
||||
|
||||
@ -2997,11 +3001,14 @@ static void TexIdsOverlay_RenderTerrain(struct TexIdsOverlay* s) {
|
||||
}
|
||||
|
||||
static void TexIdsOverlay_RenderTextOverlay(struct TexIdsOverlay* s) {
|
||||
int x, y, size = s->TileSize;
|
||||
VertexP3fT2fC4b vertices[TEXID_OVERLAY_VERTICES_COUNT];
|
||||
VertexP3fT2fC4b* ptr = vertices;
|
||||
struct TextAtlas* idAtlas;
|
||||
int size, count;
|
||||
int x, y, id;
|
||||
|
||||
struct TextAtlas* idAtlas = &s->IdAtlas;
|
||||
size = s->TileSize;
|
||||
idAtlas = &s->IdAtlas;
|
||||
idAtlas->Tex.Y = s->YOffset + (size - idAtlas->Tex.Height);
|
||||
|
||||
for (y = 0; y < ATLAS2D_TILES_PER_ROW; y++) {
|
||||
@ -3010,11 +3017,12 @@ static void TexIdsOverlay_RenderTextOverlay(struct TexIdsOverlay* s) {
|
||||
int id = x + y * ATLAS2D_TILES_PER_ROW;
|
||||
TextAtlas_AddInt(idAtlas, id + s->BaseTexLoc, &ptr);
|
||||
}
|
||||
idAtlas->Tex.Y += size;
|
||||
|
||||
idAtlas->Tex.Y += size;
|
||||
if ((y % 4) != 3) continue;
|
||||
Gfx_BindTexture(idAtlas->Tex.ID);
|
||||
int count = (int)(ptr - vertices);
|
||||
|
||||
count = (int)(ptr - vertices);
|
||||
GfxCommon_UpdateDynamicVb_IndexedTris(s->DynamicVb, vertices, count);
|
||||
ptr = vertices;
|
||||
}
|
||||
@ -3035,16 +3043,14 @@ static void TexIdsOverlay_Render(void* screen, double delta) {
|
||||
Gfx_SetBatchFormat(VERTEX_FORMAT_P3FT2FC4B);
|
||||
Menu_Render(s, delta);
|
||||
|
||||
rows = Atlas2D_RowsCount;
|
||||
origXOffset = s->XOffset;
|
||||
s->BaseTexLoc = 0;
|
||||
|
||||
while (rows > 0) {
|
||||
for (rows = Atlas2D_RowsCount; rows > 0; rows -= ATLAS2D_TILES_PER_ROW) {
|
||||
TexIdsOverlay_RenderTerrain(s);
|
||||
TexIdsOverlay_RenderTextOverlay(s);
|
||||
rows -= ATLAS2D_TILES_PER_ROW;
|
||||
|
||||
s->XOffset += s->TileSize * ATLAS2D_TILES_PER_ROW;
|
||||
s->XOffset += s->TileSize * ATLAS2D_TILES_PER_ROW;
|
||||
s->BaseTexLoc += ATLAS2D_TILES_PER_ROW * ATLAS2D_TILES_PER_ROW;
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,6 @@
|
||||
#include "PackedCol.h"
|
||||
#include "ExtMath.h"
|
||||
|
||||
PackedCol PackedCol_Create4(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
||||
PackedCol c; c.R = r; c.G = g; c.B = b; c.A = a; return c;
|
||||
}
|
||||
|
||||
PackedCol PackedCol_Create3(uint8_t r, uint8_t g, uint8_t b) {
|
||||
PackedCol c; c.R = r; c.G = g; c.B = b; c.A = 255; return c;
|
||||
}
|
||||
|
||||
bool PackedCol_Equals(PackedCol a, PackedCol b) {
|
||||
return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
|
||||
}
|
||||
@ -54,9 +46,12 @@ void PackedCol_ToHex(String* str, PackedCol value) {
|
||||
}
|
||||
|
||||
bool PackedCol_TryParseHex(const String* str, PackedCol* value) {
|
||||
PackedCol colZero = PACKEDCOL_CONST(0, 0, 0, 0);
|
||||
int rH, rL, gH, gL, bH, bL;
|
||||
char* buffer = str->buffer;
|
||||
*value = PackedCol_Create4(0, 0, 0, 0);
|
||||
char* buffer;
|
||||
|
||||
buffer = str->buffer;
|
||||
*value = colZero;
|
||||
|
||||
/* accept XXYYZZ or #XXYYZZ forms */
|
||||
if (str->length < 6) return false;
|
||||
@ -67,6 +62,9 @@ bool PackedCol_TryParseHex(const String* str, PackedCol* value) {
|
||||
if (!PackedCol_Unhex(buffer[2], &gH) || !PackedCol_Unhex(buffer[3], &gL)) return false;
|
||||
if (!PackedCol_Unhex(buffer[4], &bH) || !PackedCol_Unhex(buffer[5], &bL)) return false;
|
||||
|
||||
*value = PackedCol_Create3((rH << 4) | rL, (gH << 4) | gL, (bH << 4) | bL);
|
||||
value->R = (uint8_t)((rH << 4) | rL);
|
||||
value->G = (uint8_t)((gH << 4) | gL);
|
||||
value->B = (uint8_t)((bH << 4) | bL);
|
||||
value->A = 255;
|
||||
return true;
|
||||
}
|
||||
|
@ -24,12 +24,9 @@ typedef union PackedColUnion_ { PackedCol C; uint32_t Raw; } PackedColUnion;
|
||||
#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))
|
||||
|
||||
bool PackedCol_Equals(PackedCol a, PackedCol b);
|
||||
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);
|
||||
|
@ -69,7 +69,9 @@ void PickedPosRenderer_Update(struct PickedPos* selected) {
|
||||
PickedPos_X(0) PickedPos_X(3) /* XMin, XMax */
|
||||
PickedPos_Z(0) PickedPos_Z(3) /* ZMin, ZMax */
|
||||
};
|
||||
|
||||
PackedCol col = PACKEDCOL_CONST(0, 0, 0, 102);
|
||||
VertexP3fC4b* ptr;
|
||||
int i;
|
||||
Vector3 delta;
|
||||
float dist, offset, size;
|
||||
Vector3 coords[4];
|
||||
@ -107,10 +109,7 @@ void PickedPosRenderer_Update(struct PickedPos* selected) {
|
||||
Vector3_Add1(&coords[3], &selected->Max, offset);
|
||||
Vector3_Add1(&coords[2], &coords[3], -size);
|
||||
|
||||
PackedCol col = PACKEDCOL_CONST(0, 0, 0, 102);
|
||||
VertexP3fC4b* ptr = pickedPos_vertices;
|
||||
int i;
|
||||
|
||||
ptr = pickedPos_vertices;
|
||||
for (i = 0; i < Array_Elems(indices); i += 3, ptr++) {
|
||||
ptr->X = coords[indices[i + 0]].X;
|
||||
ptr->Y = coords[indices[i + 1]].Y;
|
||||
|
Loading…
x
Reference in New Issue
Block a user