diff --git a/src/Block.c b/src/Block.c
index 25344b54e..42d0983ff 100644
--- a/src/Block.c
+++ b/src/Block.c
@@ -25,7 +25,7 @@ const char* const Sound_Names[SOUND_COUNT] = {
/* Brightness */
#define BRIT_NONE 0
-#define BRIT_FULL MODERN_LIGHTING_MAX_LEVEL
+#define BRIT_FULL FANCY_LIGHTING_MAX_LEVEL
#define BRIT_MAGM 10
struct SimpleBlockDef {
@@ -535,41 +535,41 @@ int Block_Parse(const cc_string* name) {
/* 0b_1000_0000 */
#define USE_MODERN_BRIGHTNESS_FLAG 1 << 7
/* 0b_0100_0000 */
-#define USE_SUN_COLOR 1 << 6
+#define USE_LAMP_COLOR 1 << 6
/* 0b_0000_1111 */
-#define BRIGHTNESS_MASK MODERN_LIGHTING_MAX_LEVEL
+#define BRIGHTNESS_MASK FANCY_LIGHTING_MAX_LEVEL
/* Reads network format 0b_US--_LLLL where U = uses fancy brightness, S = uses lamp brightness, and L = brightness */
/* Into CC's native format 0b_SSSS_BBBB where S = lamp brightness and B = lava brightness */
cc_uint8 Block_ReadBrightness(cc_uint8 fullBright) {
cc_bool useSun;
/* If the fullBright byte does not use the flag, we should interpret it as either completely dark or casting max block light */
- if ((fullBright & USE_MODERN_BRIGHTNESS_FLAG) == 0) { return fullBright > 0 ? MODERN_LIGHTING_MAX_LEVEL : 0; }
+ if ((fullBright & USE_MODERN_BRIGHTNESS_FLAG) == 0) { return fullBright > 0 ? FANCY_LIGHTING_MAX_LEVEL : 0; }
- useSun = fullBright & USE_SUN_COLOR;
+ useSun = fullBright & USE_LAMP_COLOR;
/* Preserve only the least significant four bits. This gives us our raw brightness level for sun or block light. */
fullBright &= BRIGHTNESS_MASK;
/* Sun light is stored in the upper four bits */
- if (useSun) { fullBright <<= MODERN_LIGHTING_SUN_SHIFT; }
+ if (useSun) { fullBright <<= FANCY_LIGHTING_LAMP_SHIFT; }
return fullBright;
}
/* Writes CC's native format 0b_SSSS_BBBB where S = lamp brightness and B = lava brightness */
/* into network format 0b_US--_LLLL where U = uses fancy brightness, S = uses lamp brightness, and L = brightness */
cc_uint8 Block_WriteFullBright(cc_uint8 brightness) {
- cc_uint8 blockBrightness, sunBrightness, fullBright;
- blockBrightness = brightness & BRIGHTNESS_MASK;
- sunBrightness = brightness >> MODERN_LIGHTING_SUN_SHIFT;
- fullBright = USE_MODERN_BRIGHTNESS_FLAG;
+ cc_uint8 lavaBrightness, lampBrightness, fullBright;
+ lavaBrightness = brightness & BRIGHTNESS_MASK;
+ lampBrightness = brightness >> FANCY_LIGHTING_LAMP_SHIFT;
+ fullBright = USE_MODERN_BRIGHTNESS_FLAG;
/* Modern brightness stored in a fullbright value is mutually exclusive between using block and using sun light */
- if (blockBrightness > 0) {
- fullBright |= blockBrightness;
- } else if (sunBrightness > 0) {
- fullBright |= USE_SUN_COLOR; /* Insert flag that tells us this fullbright value should be interpreted as sun brightness */
- fullBright |= sunBrightness;
+ if (lavaBrightness > 0) {
+ fullBright |= lavaBrightness;
+ } else if (lampBrightness > 0) {
+ fullBright |= USE_LAMP_COLOR; /* Insert flag that tells us this fullbright value should be interpreted as sun brightness */
+ fullBright |= lampBrightness;
} else {
return 0;
}
diff --git a/src/Builder.c b/src/Builder.c
index b9778657a..8d9f9fc8c 100644
--- a/src/Builder.c
+++ b/src/Builder.c
@@ -1317,9 +1317,9 @@ static PackedCol Modern_GetColorX(PackedCol orig, int x, int y, int z, int oY, i
cc_bool zOccluded = Modern_IsOccluded(x, y , z + oZ);
cc_bool xzOccluded = Modern_IsOccluded(x, y + oY, z + oZ);
- PackedCol CoX = xOccluded ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color_XSide_Fast(x, y + oY, z );
- PackedCol CoZ = zOccluded ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color_XSide_Fast(x, y , z + oZ);
- PackedCol CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color_XSide_Fast(x, y + oY, z + oZ);
+ PackedCol CoX = xOccluded ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_XSide_Fast(x, y + oY, z );
+ PackedCol CoZ = zOccluded ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_XSide_Fast(x, y , z + oZ);
+ PackedCol CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_XSide_Fast(x, y + oY, z + oZ);
PackedCol ab = AVERAGE(CoX, CoZ);
PackedCol cd = AVERAGE(CoXoZ, orig);
@@ -1396,9 +1396,9 @@ static PackedCol Modern_GetColorZ(PackedCol orig, int x, int y, int z, int oX, i
cc_bool zOccluded = Modern_IsOccluded(x, y + oY, z);
cc_bool xzOccluded = Modern_IsOccluded(x + oX, y + oY, z);
- PackedCol CoX = xOccluded ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color_ZSide_Fast(x + oX, y , z);
- PackedCol CoZ = zOccluded ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color_ZSide_Fast(x , y + oY, z);
- PackedCol CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color_ZSide_Fast(x + oX, y + oY, z);
+ PackedCol CoX = xOccluded ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_ZSide_Fast(x + oX, y , z);
+ PackedCol CoZ = zOccluded ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_ZSide_Fast(x , y + oY, z);
+ PackedCol CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_ZSide_Fast(x + oX, y + oY, z);
PackedCol ab = AVERAGE(CoX, CoZ);
PackedCol cd = AVERAGE(CoXoZ, orig);
@@ -1475,9 +1475,9 @@ static PackedCol Modern_GetColorYMin(PackedCol orig, int x, int y, int z, int oX
cc_bool zOccluded = Modern_IsOccluded(x, y, z + oZ);
cc_bool xzOccluded = Modern_IsOccluded(x + oX, y, z + oZ);
- PackedCol CoX = xOccluded ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color_YMin_Fast(x + oX, y, z );
- PackedCol CoZ = zOccluded ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color_YMin_Fast(x , y, z + oZ);
- PackedCol CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color_YMin_Fast(x + oX, y, z + oZ);
+ PackedCol CoX = xOccluded ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_YMin_Fast(x + oX, y, z );
+ PackedCol CoZ = zOccluded ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_YMin_Fast(x , y, z + oZ);
+ PackedCol CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_YMin_Fast(x + oX, y, z + oZ);
PackedCol ab = AVERAGE(CoX, CoZ);
PackedCol cd = AVERAGE(CoXoZ, orig);
@@ -1521,9 +1521,9 @@ static PackedCol Modern_GetColorYMax(PackedCol orig, int x, int y, int z, int oX
cc_bool zOccluded = Modern_IsOccluded(x, y, z + oZ);
cc_bool xzOccluded = Modern_IsOccluded(x + oX, y, z + oZ);
- PackedCol CoX = xOccluded ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color(x + oX, y, z );
- PackedCol CoZ = zOccluded ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color(x , y, z + oZ);
- PackedCol CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color(x + oX, y, z + oZ);
+ PackedCol CoX = xOccluded ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color(x + oX, y, z );
+ PackedCol CoZ = zOccluded ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color(x , y, z + oZ);
+ PackedCol CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color(x + oX, y, z + oZ);
PackedCol ab = AVERAGE(CoX, CoZ);
PackedCol cd = AVERAGE(CoXoZ, orig);
@@ -1621,7 +1621,7 @@ static void ModernBuilder_SetActive(void) {
cc_bool Builder_SmoothLighting;
void Builder_ApplyActive(void) {
if (Builder_SmoothLighting) {
- if (Lighting_Modern) {
+ if (Lighting_Mode != LIGHTING_MODE_CLASSIC) {
ModernBuilder_SetActive();
}
else {
diff --git a/src/ClassiCube.vcxproj b/src/ClassiCube.vcxproj
index 90dfcbcc4..8ae03e244 100644
--- a/src/ClassiCube.vcxproj
+++ b/src/ClassiCube.vcxproj
@@ -501,7 +501,7 @@
-
+
diff --git a/src/ClassiCube.vcxproj.filters b/src/ClassiCube.vcxproj.filters
index 05077b2c5..6c7084917 100644
--- a/src/ClassiCube.vcxproj.filters
+++ b/src/ClassiCube.vcxproj.filters
@@ -755,7 +755,7 @@
Source Files\Window
-
+
Source Files\Map
diff --git a/src/ModernLighting.c b/src/FancyLighting.c
similarity index 62%
rename from src/ModernLighting.c
rename to src/FancyLighting.c
index 27bd08ccc..fa2933ed8 100644
--- a/src/ModernLighting.c
+++ b/src/FancyLighting.c
@@ -13,25 +13,26 @@
#include "Options.h"
#include "Queue.h"
-struct LightNode {
- IVec3 coords;
- cc_uint8 brightness;
-};
-/*########################################################################################################################*
-*----------------------------------------------------Modern lighting------------------------------------------------------*
-*#########################################################################################################################*/
+struct LightNode {
+ IVec3 coords; /* 12 bytes */
+ cc_uint8 brightness; /* 1 byte */
+ /* char padding[3]; */
+};
static struct Queue lightQueue;
static struct Queue unlightQueue;
-
-
/* Top face, X face, Z face, bottomY face*/
#define PALETTE_SHADES 4
-/* One palette for sunlight, one palette for shadow */
-#define PALETTE_TYPES 2
-#define PALETTE_COUNT (PALETTE_SHADES * PALETTE_TYPES)
+/* One palette-group for sunlight, one palette-group for shadow */
+#define PALLETE_GROUP_COUNT 2
+#define PALETTE_COUNT (PALETTE_SHADES * PALLETE_GROUP_COUNT)
+
+#define PALETTE_YMAX_INDEX 0
+#define PALETTE_XSIDE_INDEX 1
+#define PALETTE_ZSIDE_INDEX 2
+#define PALETTE_YMIN_INDEX 3
/* Index into palettes of light colors. */
/* There are 8 different palettes: Four block-face shades for shadowed areas and four block-face shades for sunlit areas. */
@@ -39,12 +40,6 @@ static struct Queue unlightQueue;
/* E.G. myPalette[0b_0010_0001] will give us the color for lamp level 2 and lava level 1 (lowest level is 0) */
static PackedCol* palettes[PALETTE_COUNT];
-#define PALETTE_YMAX_INDEX 0
-#define PALETTE_XSIDE_INDEX 1
-#define PALETTE_ZSIDE_INDEX 2
-#define PALETTE_YMIN_INDEX 3
-
-
typedef cc_uint8* LightingChunk;
static cc_uint8* chunkLightingDataFlags;
#define CHUNK_UNCALCULATED 0
@@ -52,9 +47,6 @@ static cc_uint8* chunkLightingDataFlags;
#define CHUNK_ALL_CALCULATED 2
static LightingChunk* chunkLightingData;
-#define Modern_MakePaletteIndex(sun, block) ((sun << MODERN_LIGHTING_SUN_SHIFT) | block)
-
-
static PackedCol PackedCol_ScreenBlend(PackedCol a, PackedCol b) {
PackedCol finalColor, aInverted, bInverted;
cc_uint8 R, G, B;
@@ -75,66 +67,65 @@ static PackedCol PackedCol_ScreenBlend(PackedCol a, PackedCol b) {
B = 255 - PackedCol_B(finalColor);
return PackedCol_Make(R, G, B, 255);
}
-/* Fill in a palette with values based on the current environment colors */
-static void ModernLighting_InitPalette(PackedCol* palette, float shaded, PackedCol ambientColor) {
+
+#define MakePaletteIndex(lampLevel, lavaLevel) ((lampLevel << FANCY_LIGHTING_LAMP_SHIFT) | lavaLevel)
+/* Fill in a palette with values based on the current light colors, shaded by the given shade value and lightened by the given ambientColor */
+static void InitPalette(PackedCol* palette, float shaded, PackedCol ambientColor) {
PackedCol lavaColor, lampColor;
int lampLevel, lavaLevel;
- float blockLerp;
+ float curLerp;
- for (lampLevel = 0; lampLevel < MODERN_LIGHTING_LEVELS; lampLevel++) {
- for (lavaLevel = 0; lavaLevel < MODERN_LIGHTING_LEVELS; lavaLevel++) {
- if (lampLevel == MODERN_LIGHTING_LEVELS - 1) {
+ for (lampLevel = 0; lampLevel < FANCY_LIGHTING_LEVELS; lampLevel++) {
+ for (lavaLevel = 0; lavaLevel < FANCY_LIGHTING_LEVELS; lavaLevel++) {
+ if (lampLevel == FANCY_LIGHTING_LEVELS - 1) {
lampColor = Env.LampLightCol;
}
else {
- blockLerp = max(lampLevel, MODERN_LIGHTING_LEVELS - SUN_LEVELS) / (float)(MODERN_LIGHTING_LEVELS - 1);
- blockLerp *= (MATH_PI / 2);
- blockLerp = Math_Cos(blockLerp);
- lampColor = PackedCol_Lerp(0, Env.LampLightCol, 1 - blockLerp);
+ curLerp = lampLevel / (float)(FANCY_LIGHTING_LEVELS - 1);
+ curLerp *= (MATH_PI / 2);
+ curLerp = Math_Cos(curLerp);
+ lampColor = PackedCol_Lerp(0, Env.LampLightCol, 1 - curLerp);
}
- blockLerp = lavaLevel / (float)(MODERN_LIGHTING_LEVELS - 1);
- //blockLerp *= blockLerp;
- blockLerp *= (MATH_PI / 2);
- blockLerp = Math_Cos(blockLerp);
+ curLerp = lavaLevel / (float)(FANCY_LIGHTING_LEVELS - 1);
+ curLerp *= (MATH_PI / 2);
+ curLerp = Math_Cos(curLerp);
- lavaColor = PackedCol_Lerp(0, Env.LavaLightCol, 1 - blockLerp);
+ lavaColor = PackedCol_Lerp(0, Env.LavaLightCol, 1 - curLerp);
/* Blend the two light colors together, then blend that with the ambient color, then shade that by the face darkness */
- palette[Modern_MakePaletteIndex(lampLevel, lavaLevel)] =
+ palette[MakePaletteIndex(lampLevel, lavaLevel)] =
PackedCol_Scale(PackedCol_ScreenBlend(PackedCol_ScreenBlend(lampColor, lavaColor), ambientColor), shaded);
}
}
}
-static void ModernLighting_InitPalettes(void) {
+static void InitPalettes(void) {
int i;
for (i = 0; i < PALETTE_COUNT; i++) {
- palettes[i] = (PackedCol*)Mem_Alloc(MODERN_LIGHTING_LEVELS * MODERN_LIGHTING_LEVELS, sizeof(PackedCol), "light color palette");
+ palettes[i] = (PackedCol*)Mem_Alloc(FANCY_LIGHTING_LEVELS * FANCY_LIGHTING_LEVELS, sizeof(PackedCol), "light color palette");
}
-
i = 0;
- ModernLighting_InitPalette(palettes[i + PALETTE_YMAX_INDEX], 1, Env.ShadowCol);
- ModernLighting_InitPalette(palettes[i + PALETTE_XSIDE_INDEX], PACKEDCOL_SHADE_X, Env.ShadowCol);
- ModernLighting_InitPalette(palettes[i + PALETTE_ZSIDE_INDEX], PACKEDCOL_SHADE_Z, Env.ShadowCol);
- ModernLighting_InitPalette(palettes[i + PALETTE_YMIN_INDEX], PACKEDCOL_SHADE_YMIN, Env.ShadowCol);
+ InitPalette(palettes[i + PALETTE_YMAX_INDEX], 1, Env.ShadowCol);
+ InitPalette(palettes[i + PALETTE_XSIDE_INDEX], PACKEDCOL_SHADE_X, Env.ShadowCol);
+ InitPalette(palettes[i + PALETTE_ZSIDE_INDEX], PACKEDCOL_SHADE_Z, Env.ShadowCol);
+ InitPalette(palettes[i + PALETTE_YMIN_INDEX], PACKEDCOL_SHADE_YMIN, Env.ShadowCol);
i += PALETTE_SHADES;
- ModernLighting_InitPalette(palettes[i + PALETTE_YMAX_INDEX], 1, Env.SunCol);
- ModernLighting_InitPalette(palettes[i + PALETTE_XSIDE_INDEX], PACKEDCOL_SHADE_X, Env.SunCol);
- ModernLighting_InitPalette(palettes[i + PALETTE_ZSIDE_INDEX], PACKEDCOL_SHADE_Z, Env.SunCol);
- ModernLighting_InitPalette(palettes[i + PALETTE_YMIN_INDEX], PACKEDCOL_SHADE_YMIN, Env.SunCol);
+ InitPalette(palettes[i + PALETTE_YMAX_INDEX], 1, Env.SunCol);
+ InitPalette(palettes[i + PALETTE_XSIDE_INDEX], PACKEDCOL_SHADE_X, Env.SunCol);
+ InitPalette(palettes[i + PALETTE_ZSIDE_INDEX], PACKEDCOL_SHADE_Z, Env.SunCol);
+ InitPalette(palettes[i + PALETTE_YMIN_INDEX], PACKEDCOL_SHADE_YMIN, Env.SunCol);
}
-static void ModernLighting_FreePalettes(void) {
+static void FreePalettes(void) {
int i;
-
for (i = 0; i < PALETTE_COUNT; i++) {
Mem_Free(palettes[i]);
}
}
static int chunksCount;
-static void ModernLighting_AllocState(void) {
+static void AllocState(void) {
ClassicLighting_AllocState();
- ModernLighting_InitPalettes();
+ InitPalettes();
chunksCount = World.ChunksCount;
chunkLightingDataFlags = (cc_uint8*)Mem_AllocCleared(chunksCount, sizeof(cc_uint8), "light flags");
@@ -143,14 +134,14 @@ static void ModernLighting_AllocState(void) {
Queue_Init(&unlightQueue, sizeof(struct LightNode));
}
-static void ModernLighting_FreeState(void) {
+static void FreeState(void) {
int i;
ClassicLighting_FreeState();
- /* This function can be called multiple times without calling ModernLighting_AllocState, so... */
+ /* This function can be called multiple times without calling AllocState, so... */
if (!chunkLightingDataFlags) return;
- ModernLighting_FreePalettes();
+ FreePalettes();
for (i = 0; i < chunksCount; i++) {
Mem_Free(chunkLightingData[i]);
@@ -172,29 +163,26 @@ static void ModernLighting_FreeState(void) {
#define GlobalCoordsToChunkCoordsIndex(x, y, z) (LocalCoordsToIndex(x & CHUNK_MASK, y & CHUNK_MASK, z & CHUNK_MASK))
/* Sets the light level at this cell. Does NOT check that the cell is in bounds. */
-static void SetBlocklight(cc_uint8 blockLight, int x, int y, int z, cc_bool sun, cc_bool refreshChunk) {
- cc_uint8 clearMask;
- cc_uint8 shift = sun ? MODERN_LIGHTING_SUN_SHIFT : 0;
-
+static void SetBrightness(cc_uint8 brightness, int x, int y, int z, cc_bool isLamp, cc_bool refreshChunk) {
+ cc_uint8 clearMask, shift = isLamp ? FANCY_LIGHTING_LAMP_SHIFT : 0, prevValue;
int cx = x >> CHUNK_SHIFT, lx = x & CHUNK_MASK;
int cy = y >> CHUNK_SHIFT, ly = y & CHUNK_MASK;
int cz = z >> CHUNK_SHIFT, lz = z & CHUNK_MASK;
-
int chunkIndex = ChunkCoordsToIndex(cx, cy, cz);
+ int localIndex = LocalCoordsToIndex(lx, ly, lz);
+
if (chunkLightingData[chunkIndex] == NULL) {
chunkLightingData[chunkIndex] = (cc_uint8*)Mem_TryAllocCleared(CHUNK_SIZE_3, sizeof(cc_uint8));
}
- int localIndex = LocalCoordsToIndex(lx, ly, lz);
-
- /* 00001111 if sun, otherwise 11110000*/
- clearMask = ~(MODERN_LIGHTING_MAX_LEVEL << shift);
+ /* 00001111 if lamp, otherwise 11110000*/
+ clearMask = ~(FANCY_LIGHTING_MAX_LEVEL << shift);
if (refreshChunk) {
- cc_uint8 prevValue = chunkLightingData[chunkIndex][localIndex];
+ prevValue = chunkLightingData[chunkIndex][localIndex];
chunkLightingData[chunkIndex][localIndex] &= clearMask;
- chunkLightingData[chunkIndex][localIndex] |= blockLight << shift;
+ chunkLightingData[chunkIndex][localIndex] |= brightness << shift;
/* There is no reason to refresh current chunk as the builder does that automatically */
if (prevValue != chunkLightingData[chunkIndex][localIndex]) {
@@ -208,22 +196,22 @@ static void SetBlocklight(cc_uint8 blockLight, int x, int y, int z, cc_bool sun,
}
else {
chunkLightingData[chunkIndex][localIndex] &= clearMask;
- chunkLightingData[chunkIndex][localIndex] |= blockLight << shift;
+ chunkLightingData[chunkIndex][localIndex] |= brightness << shift;
}
}
/* Returns the light level at this cell. Does NOT check that the cell is in bounds. */
-static cc_uint8 GetBlocklight(int x, int y, int z, cc_bool sun) {
+static cc_uint8 GetBrightness(int x, int y, int z, cc_bool isLamp) {
int cx = x >> CHUNK_SHIFT, lx = x & CHUNK_MASK;
int cy = y >> CHUNK_SHIFT, ly = y & CHUNK_MASK;
int cz = z >> CHUNK_SHIFT, lz = z & CHUNK_MASK;
+ int chunkIndex = ChunkCoordsToIndex(cx, cy, cz), localIndex;
- int chunkIndex = ChunkCoordsToIndex(cx, cy, cz);
if (chunkLightingData[chunkIndex] == NULL) { return 0; }
- int localIndex = LocalCoordsToIndex(lx, ly, lz);
+ localIndex = LocalCoordsToIndex(lx, ly, lz);
- return sun ?
- chunkLightingData[chunkIndex][localIndex] >> MODERN_LIGHTING_SUN_SHIFT :
- chunkLightingData[chunkIndex][localIndex] & MODERN_LIGHTING_MAX_LEVEL;
+ return isLamp ?
+ chunkLightingData[chunkIndex][localIndex] >> FANCY_LIGHTING_LAMP_SHIFT :
+ chunkLightingData[chunkIndex][localIndex] & FANCY_LIGHTING_MAX_LEVEL;
}
@@ -248,56 +236,58 @@ static cc_bool CanLightPass(BlockID thisBlock, Face face) {
return !Block_IsFaceHidden(BLOCK_STONE, thisBlock, face);
}
-#define Light_TrySpreadInto(axis, AXIS, dir, limit, isSun, thisFace, thatFace) \
+#define Light_TrySpreadInto(axis, AXIS, dir, limit, isLamp, thisFace, thatFace) \
if (ln.coords.axis dir ## = limit && \
CanLightPass(thisBlock, FACE_ ## AXIS ## thisFace) && \
CanLightPass(World_GetBlock(ln.coords.x, ln.coords.y, ln.coords.z), FACE_ ## AXIS ## thatFace) && \
- GetBlocklight(ln.coords.x, ln.coords.y, ln.coords.z, isSun) < ln.brightness) { \
+ GetBrightness(ln.coords.x, ln.coords.y, ln.coords.z, isLamp) < ln.brightness) { \
Queue_Enqueue(&lightQueue, &ln); \
} \
-static void FlushLightQueue(cc_bool isSun, cc_bool refreshChunk) {
- int handled = 0;
- while (lightQueue.count > 0) {
- handled++;
- struct LightNode ln = *(struct LightNode*)(Queue_Dequeue(&lightQueue));
+static void FlushLightQueue(cc_bool isLamp, cc_bool refreshChunk) {
+ struct LightNode ln;
+ cc_uint8 brightnessHere;
+ BlockID thisBlock;
- cc_uint8 brightnessHere = GetBlocklight(ln.coords.x, ln.coords.y, ln.coords.z, isSun);
+ while (lightQueue.count > 0) {
+ ln = *(struct LightNode*)(Queue_Dequeue(&lightQueue));
+
+ brightnessHere = GetBrightness(ln.coords.x, ln.coords.y, ln.coords.z, isLamp);
/* If this cel is already more lit, we can assume this cel and its neighbors have been accounted for */
if (brightnessHere >= ln.brightness) { continue; }
if (ln.brightness == 0) { continue; }
//Platform_Log4("Placing %i at %i %i %i", &ln.brightness, &ln.coords.x, &ln.coords.y, &ln.coords.z);
- SetBlocklight(ln.brightness, ln.coords.x, ln.coords.y, ln.coords.z, isSun, refreshChunk);
+ SetBrightness(ln.brightness, ln.coords.x, ln.coords.y, ln.coords.z, isLamp, refreshChunk);
- BlockID thisBlock = World_GetBlock(ln.coords.x, ln.coords.y, ln.coords.z);
+ thisBlock = World_GetBlock(ln.coords.x, ln.coords.y, ln.coords.z);
ln.brightness--;
if (ln.brightness == 0) continue;
ln.coords.x--;
- Light_TrySpreadInto(x, X, > , 0, isSun, MAX, MIN)
+ Light_TrySpreadInto(x, X, > , 0, isLamp, MAX, MIN)
ln.coords.x += 2;
- Light_TrySpreadInto(x, X, < , World.MaxX, isSun, MIN, MAX)
+ Light_TrySpreadInto(x, X, < , World.MaxX, isLamp, MIN, MAX)
ln.coords.x--;
ln.coords.y--;
- Light_TrySpreadInto(y, Y, >, 0, isSun, MAX, MIN)
+ Light_TrySpreadInto(y, Y, >, 0, isLamp, MAX, MIN)
ln.coords.y += 2;
- Light_TrySpreadInto(y, Y, <, World.MaxY, isSun, MIN, MAX)
+ Light_TrySpreadInto(y, Y, <, World.MaxY, isLamp, MIN, MAX)
ln.coords.y--;
ln.coords.z--;
- Light_TrySpreadInto(z, Z, > , 0, isSun, MAX, MIN)
+ Light_TrySpreadInto(z, Z, > , 0, isLamp, MAX, MIN)
ln.coords.z += 2;
- Light_TrySpreadInto(z, Z, < , World.MaxZ, isSun, MIN, MAX)
+ Light_TrySpreadInto(z, Z, < , World.MaxZ, isLamp, MIN, MAX)
}
}
-cc_uint8 GetBlockBrightness(BlockID curBlock, cc_bool isSun) {
- if (isSun) return Blocks.Brightness[curBlock] >> MODERN_LIGHTING_SUN_SHIFT;
- return Blocks.Brightness[curBlock] & MODERN_LIGHTING_MAX_LEVEL;
+cc_uint8 GetBlockBrightness(BlockID curBlock, cc_bool isLamp) {
+ if (isLamp) return Blocks.Brightness[curBlock] >> FANCY_LIGHTING_LAMP_SHIFT;
+ return Blocks.Brightness[curBlock] & FANCY_LIGHTING_MAX_LEVEL;
}
static void CalculateChunkLightingSelf(int chunkIndex, int cx, int cy, int cz) {
@@ -312,7 +302,9 @@ static void CalculateChunkLightingSelf(int chunkIndex, int cx, int cy, int cz) {
chunkEndX = chunkStartX + CHUNK_SIZE;
chunkEndY = chunkStartY + CHUNK_SIZE;
chunkEndZ = chunkStartZ + CHUNK_SIZE;
- if (chunkEndX > World.Width) { chunkEndX = World.Width; }
+ struct LightNode entry;
+
+ if (chunkEndX > World.Width ) { chunkEndX = World.Width; }
if (chunkEndY > World.Height) { chunkEndY = World.Height; }
if (chunkEndZ > World.Length) { chunkEndZ = World.Length; }
@@ -327,14 +319,14 @@ static void CalculateChunkLightingSelf(int chunkIndex, int cx, int cy, int cz) {
brightness = GetBlockBrightness(curBlock, false);
if (brightness > 0) {
- struct LightNode entry = { x, y, z, brightness };
+ entry = (struct LightNode){ { x, y, z }, brightness };
Queue_Enqueue(&lightQueue, &entry);
FlushLightQueue(false, false);
}
else {
- /* If no block brightness, it must use sun brightness */
- brightness = Blocks.Brightness[curBlock] >> MODERN_LIGHTING_SUN_SHIFT;
- struct LightNode entry = { x, y, z, brightness };
+ /* If no lava brightness, it must use lamp brightness */
+ brightness = Blocks.Brightness[curBlock] >> FANCY_LIGHTING_LAMP_SHIFT;
+ entry = (struct LightNode){ { x, y, z }, brightness };
Queue_Enqueue(&lightQueue, &entry);
FlushLightQueue(true, false);
}
@@ -391,18 +383,18 @@ static void CalculateChunkLightingAll(int chunkIndex, int cx, int cy, int cz) {
CanLightPass(World_GetBlock(neighborCoords.x, neighborCoords.y, neighborCoords.z), FACE_ ## AXIS ## thatFace) \
) \
{ \
- neighborBrightness = GetBlocklight(neighborCoords.x, neighborCoords.y, neighborCoords.z, isSun); \
- neighborBlockBrightness = GetBlockBrightness(World_GetBlock(neighborCoords.x, neighborCoords.y, neighborCoords.z), isSun); \
+ neighborBrightness = GetBrightness(neighborCoords.x, neighborCoords.y, neighborCoords.z, isLamp); \
+ neighborBlockBrightness = GetBlockBrightness(World_GetBlock(neighborCoords.x, neighborCoords.y, neighborCoords.z), isLamp); \
/* This spot is a light caster, mark this spot as needing to be re-spread */ \
if (neighborBlockBrightness > 0) { \
- struct LightNode entry = { neighborCoords.x, neighborCoords.y, neighborCoords.z, neighborBlockBrightness }; \
+ entry = (struct LightNode){ { neighborCoords.x, neighborCoords.y, neighborCoords.z }, neighborBlockBrightness }; \
Queue_Enqueue(&lightQueue, &entry); \
} \
if (neighborBrightness > 0) { \
/* This neighbor is darker than cur spot, darken it*/ \
if (neighborBrightness < curNode.brightness) { \
- SetBlocklight(0, neighborCoords.x, neighborCoords.y, neighborCoords.z, isSun, true); \
- struct LightNode neighborNode = { { neighborCoords.x, neighborCoords.y, neighborCoords.z }, neighborBrightness }; \
+ SetBrightness(0, neighborCoords.x, neighborCoords.y, neighborCoords.z, isLamp, true); \
+ neighborNode = (struct LightNode){ { neighborCoords.x, neighborCoords.y, neighborCoords.z }, neighborBrightness }; \
Queue_Enqueue(&unlightQueue, &neighborNode); \
} \
/* This neighbor is brighter or same, mark this spot as needing to be re-spread */ \
@@ -413,7 +405,7 @@ static void CalculateChunkLightingAll(int chunkIndex, int cx, int cy, int cz) {
CanLightPass(World_GetBlock(neighborCoords.x, neighborCoords.y, neighborCoords.z), FACE_ ## AXIS ## thatFace) \
) \
{ \
- struct LightNode entry = curNode; \
+ entry = curNode; \
entry.brightness = neighborBrightness-1; \
Queue_Enqueue(&lightQueue, &entry); \
} \
@@ -422,22 +414,25 @@ static void CalculateChunkLightingAll(int chunkIndex, int cx, int cy, int cz) {
} \
/* Spreads darkness out from this point and relights any necessary areas afterward */
-static void CalcUnlight(int x, int y, int z, cc_uint8 brightness, cc_bool isSun) {
+static void CalcUnlight(int x, int y, int z, cc_uint8 brightness, cc_bool isLamp) {
int count = 0;
- SetBlocklight(0, x, y, z, isSun, true);
- struct LightNode sourceNode = { { x, y, z }, brightness };
+ struct LightNode sourceNode, curNode, entry, neighborNode;
+ cc_uint8 neighborBrightness, neighborBlockBrightness;
+ IVec3 neighborCoords;
+ BlockID thisBlockTrue, thisBlock;
+
+ SetBrightness(0, x, y, z, isLamp, true);
+ sourceNode = (struct LightNode){ { x, y, z }, brightness };
Queue_Enqueue(&unlightQueue, &sourceNode);
while (unlightQueue.count > 0) {
- struct LightNode curNode = *(struct LightNode*)(Queue_Dequeue(&unlightQueue));
- cc_uint8 neighborBrightness;
- cc_uint8 neighborBlockBrightness;
- IVec3 neighborCoords = curNode.coords;
+ curNode = *(struct LightNode*)(Queue_Dequeue(&unlightQueue));
+ neighborCoords = curNode.coords;
- BlockID thisBlockTrue = World_GetBlock(neighborCoords.x, neighborCoords.y, neighborCoords.z);
+ thisBlockTrue = World_GetBlock(neighborCoords.x, neighborCoords.y, neighborCoords.z);
/* For the original cell in the queue, assume this block is air
so that light can unspread "out" of it in the case of a solid blocks. */
- BlockID thisBlock = count == 0 ? BLOCK_AIR : thisBlockTrue;
+ thisBlock = count == 0 ? BLOCK_AIR : thisBlockTrue;
count++;
@@ -459,25 +454,24 @@ static void CalcUnlight(int x, int y, int z, cc_uint8 brightness, cc_bool isSun)
Light_TryUnSpreadInto(z, <, World.MaxZ, Z, MIN, MAX)
}
- FlushLightQueue(isSun, true);
+ FlushLightQueue(isLamp, true);
}
-static void CalcBlockChange(int x, int y, int z, BlockID oldBlock, BlockID newBlock, cc_bool isSun) {
- cc_uint8 oldBlockLightLevel = GetBlockBrightness(oldBlock, isSun);
- cc_uint8 newBlockLightLevel = GetBlockBrightness(newBlock, isSun);
-
- cc_uint8 oldLightLevelHere = GetBlocklight(x, y, z, isSun);
+static void CalcBlockChange(int x, int y, int z, BlockID oldBlock, BlockID newBlock, cc_bool isLamp) {
+ cc_uint8 oldBlockLightLevel = GetBlockBrightness(oldBlock, isLamp);
+ cc_uint8 newBlockLightLevel = GetBlockBrightness(newBlock, isLamp);
+ cc_uint8 oldLightLevelHere = GetBrightness(x, y, z, isLamp);
+ struct LightNode entry;
/* Cel has no lighting and new block doesn't cast light and blocks all light, no change */
if (!oldLightLevelHere && !newBlockLightLevel && IsFullOpaque(newBlock)) return;
-
/* Cel is darker than the new block, only brighter case */
if (oldLightLevelHere < newBlockLightLevel) {
/* brighten this spot, recalculate lighting */
//Platform_LogConst("Brightening");
- struct LightNode entry = { x, y, z, newBlockLightLevel };
+ entry = (struct LightNode){ { x, y, z }, newBlockLightLevel };
Queue_Enqueue(&lightQueue, &entry);
- FlushLightQueue(isSun, true);
+ FlushLightQueue(isLamp, true);
return;
}
@@ -487,10 +481,9 @@ static void CalcBlockChange(int x, int y, int z, BlockID oldBlock, BlockID newBl
return;
}
- CalcUnlight(x, y, z, oldLightLevelHere, isSun);
+ CalcUnlight(x, y, z, oldLightLevelHere, isLamp);
}
-static void ModernLighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock) {
-
+static void OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock) {
/* For some reason this is a possible case */
if (oldBlock == newBlock) { return; }
@@ -501,20 +494,20 @@ static void ModernLighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock,
}
/* Invalidates/Resets lighting state for all of the blocks in the world */
/* (e.g. because a block changed whether it is full bright or not) */
-static void ModernLighting_Refresh(void) {
+static void Refresh(void) {
ClassicLighting_Refresh();
- ModernLighting_FreeState();
- ModernLighting_AllocState();
+ FreeState();
+ AllocState();
}
-static cc_bool ModernLighting_IsLit(int x, int y, int z) { return true; }
-static cc_bool ModernLighting_IsLit_Fast(int x, int y, int z) { return true; }
+static cc_bool IsLit(int x, int y, int z) { return true; }
+static cc_bool IsLit_Fast(int x, int y, int z) { return true; }
#define CalcForChunkIfNeeded(cx, cy, cz, chunkIndex) \
if (chunkLightingDataFlags[chunkIndex] < CHUNK_ALL_CALCULATED) { \
CalculateChunkLightingAll(chunkIndex, cx, cy, cz); \
}
-static PackedCol ModernLighting_Color_Core(int x, int y, int z, int paletteFace, PackedCol outOfBoundsColor) {
+static PackedCol Color_Core(int x, int y, int z, int paletteFace, PackedCol outOfBoundsColor) {
cc_uint8 lightData;
int cx, cy, cz, chunkIndex;
int chunkCoordsIndex;
@@ -530,7 +523,7 @@ static PackedCol ModernLighting_Color_Core(int x, int y, int z, int paletteFace,
/* There might be no light data in this chunk even after it was calculated */
if (chunkLightingData[chunkIndex] == NULL) {
- /* 0, no sun or light (but it may appear as sun based on the 2D sun map) */
+ /* 0, no lava or lamp */
lightData = 0;
} else {
chunkCoordsIndex = GlobalCoordsToChunkCoordsIndex(x, y, z);
@@ -543,32 +536,26 @@ static PackedCol ModernLighting_Color_Core(int x, int y, int z, int paletteFace,
paletteFace += PALETTE_SHADES;
}
-
- ////palette test
- //cc_uint8 thing = y % MODERN_LIGHTING_LEVELS;
- //cc_uint8 thing2 = z % MODERN_LIGHTING_LEVELS;
- //return palettes[paletteFace][thing | (thing2 << 4)];
-
return palettes[paletteFace][lightData];
}
-static PackedCol ModernLighting_Color(int x, int y, int z) {
- return ModernLighting_Color_Core(x, y, z, PALETTE_YMAX_INDEX, Env.SunCol);
+static PackedCol Color(int x, int y, int z) {
+ return Color_Core(x, y, z, PALETTE_YMAX_INDEX, Env.SunCol);
}
-static PackedCol ModernLighting_Color_YMaxSide(int x, int y, int z) {
- return ModernLighting_Color_Core(x, y, z, PALETTE_YMAX_INDEX, Env.SunCol);
+static PackedCol Color_YMaxSide(int x, int y, int z) {
+ return Color_Core(x, y, z, PALETTE_YMAX_INDEX, Env.SunCol);
}
-static PackedCol ModernLighting_Color_YMinSide(int x, int y, int z) {
- return ModernLighting_Color_Core(x, y, z, PALETTE_YMIN_INDEX, Env.SunYMin);
+static PackedCol Color_YMinSide(int x, int y, int z) {
+ return Color_Core(x, y, z, PALETTE_YMIN_INDEX, Env.SunYMin);
}
-static PackedCol ModernLighting_Color_XSide(int x, int y, int z) {
- return ModernLighting_Color_Core(x, y, z, PALETTE_XSIDE_INDEX, Env.SunXSide);
+static PackedCol Color_XSide(int x, int y, int z) {
+ return Color_Core(x, y, z, PALETTE_XSIDE_INDEX, Env.SunXSide);
}
-static PackedCol ModernLighting_Color_ZSide(int x, int y, int z) {
- return ModernLighting_Color_Core(x, y, z, PALETTE_ZSIDE_INDEX, Env.SunZSide);
+static PackedCol Color_ZSide(int x, int y, int z) {
+ return Color_Core(x, y, z, PALETTE_ZSIDE_INDEX, Env.SunZSide);
}
-static void ModernLighting_LightHint(int startX, int startY, int startZ) {
+static void LightHint(int startX, int startY, int startZ) {
int cx, cy, cz, chunkIndex;
ClassicLighting_LightHint(startX, startY, startZ);
/* Add 1 to startX/Z, as coordinates are for the extended chunk (18x18x18) */
@@ -583,31 +570,35 @@ static void ModernLighting_LightHint(int startX, int startY, int startZ) {
CalcForChunkIfNeeded(cx, cy, cz, chunkIndex);
}
-void ModernLighting_SetActive(void) {
- Lighting.OnBlockChanged = ModernLighting_OnBlockChanged;
- Lighting.Refresh = ModernLighting_Refresh;
- Lighting.IsLit = ModernLighting_IsLit;
- Lighting.Color = ModernLighting_Color;
- Lighting.Color_XSide = ModernLighting_Color_XSide;
+void FancyLighting_SetActive(void) {
+ Lighting.OnBlockChanged = OnBlockChanged;
+ Lighting.Refresh = Refresh;
+ Lighting.IsLit = IsLit;
+ Lighting.Color = Color;
+ Lighting.Color_XSide = Color_XSide;
- Lighting.IsLit_Fast = ModernLighting_IsLit_Fast;
- Lighting.Color_Sprite_Fast = ModernLighting_Color;
- Lighting.Color_YMax_Fast = ModernLighting_Color;
- Lighting.Color_YMin_Fast = ModernLighting_Color_YMinSide;
- Lighting.Color_XSide_Fast = ModernLighting_Color_XSide;
- Lighting.Color_ZSide_Fast = ModernLighting_Color_ZSide;
+ Lighting.IsLit_Fast = IsLit_Fast;
+ Lighting.Color_Sprite_Fast = Color;
+ Lighting.Color_YMax_Fast = Color;
+ Lighting.Color_YMin_Fast = Color_YMinSide;
+ Lighting.Color_XSide_Fast = Color_XSide;
+ Lighting.Color_ZSide_Fast = Color_ZSide;
- Lighting.FreeState = ModernLighting_FreeState;
- Lighting.AllocState = ModernLighting_AllocState;
- Lighting.LightHint = ModernLighting_LightHint;
+ Lighting.FreeState = FreeState;
+ Lighting.AllocState = AllocState;
+ Lighting.LightHint = LightHint;
}
-void ModernLighting_OnEnvVariableChanged(void* obj, int envVar) {
- /* This is always called, but should only do anything if modern lighting is on */
- if (!Lighting_Modern) { return; }
+static void OnEnvVariableChanged(void* obj, int envVar) {
+ /* This is always called, but should only do anything if fancy lighting is on */
+ if (Lighting_Mode == LIGHTING_MODE_CLASSIC) { return; }
if (envVar == ENV_VAR_SUN_COLOR || envVar == ENV_VAR_SHADOW_COLOR || envVar == ENV_VAR_LAVALIGHT_COLOR || envVar == ENV_VAR_LAMPLIGHT_COLOR) {
- ModernLighting_InitPalettes();
+ InitPalettes();
}
if (envVar == ENV_VAR_LAVALIGHT_COLOR || envVar == ENV_VAR_LAMPLIGHT_COLOR) MapRenderer_Refresh();
+}
+
+void FancyLighting_OnInit(void) {
+ Event_Register_(&WorldEvents.EnvVarChanged, NULL, OnEnvVariableChanged);
}
\ No newline at end of file
diff --git a/src/Lighting.c b/src/Lighting.c
index adb800862..2e5a6fb13 100644
--- a/src/Lighting.c
+++ b/src/Lighting.c
@@ -11,7 +11,10 @@
#include "Chat.h"
#include "ExtMath.h"
#include "Options.h"
-cc_bool Lighting_Modern;
+
+const char* const LightingMode_Names[LIGHTING_MODE_COUNT] = { "Classic", "Fancy" };
+
+cc_uint8 Lighting_Mode;
struct _Lighting Lighting;
#define Lighting_Pack(x, z) ((x) + World.Width * (z))
@@ -58,11 +61,11 @@ int ClassicLighting_GetLightHeight(int x, int z) {
}
/* Outside color is same as sunlight color, so we reuse when possible */
-static cc_bool ClassicLighting_IsLit(int x, int y, int z) {
+cc_bool ClassicLighting_IsLit(int x, int y, int z) {
return y > ClassicLighting_GetLightHeight(x, z);
}
-static cc_bool ClassicLighting_IsLit_Fast(int x, int y, int z) {
+cc_bool ClassicLighting_IsLit_Fast(int x, int y, int z) {
return y > classic_heightmap[Lighting_Pack(x, z)];
}
@@ -412,8 +415,8 @@ static void ClassicLighting_SetActive(void) {
*---------------------------------------------------Lighting component----------------------------------------------------*
*#########################################################################################################################*/
void Lighting_ApplyActive(void) {
- if (Lighting_Modern) {
- ModernLighting_SetActive();
+ if (Lighting_Mode != LIGHTING_MODE_CLASSIC) {
+ FancyLighting_SetActive();
} else {
ClassicLighting_SetActive();
}
@@ -426,7 +429,10 @@ void Lighting_SwitchActive(void) {
}
static void OnInit(void) {
- Event_Register_(&WorldEvents.EnvVarChanged, NULL, ModernLighting_OnEnvVariableChanged);
+
+ Lighting_Mode = Options_GetEnum(OPT_LIGHTING_MODE, LIGHTING_MODE_CLASSIC, LightingMode_Names, LIGHTING_MODE_COUNT);
+
+ FancyLighting_OnInit();
Lighting_ApplyActive();
}
static void OnReset(void) { Lighting.FreeState(); }
diff --git a/src/Lighting.h b/src/Lighting.h
index 5cc55b517..73691a1af 100644
--- a/src/Lighting.h
+++ b/src/Lighting.h
@@ -10,18 +10,23 @@ Copyright 2014-2023 ClassiCube | Licensed under BSD-3
*/
struct IGameComponent;
extern struct IGameComponent Lighting_Component;
-/* Whether MC-style 16-level lighting should be used. */
-extern cc_bool Lighting_Modern;
-/* How much ambient occlusion to apply in modern lighting where 1.0f = none and 0.0f = maximum*/
-#define MODERN_AO 0.5F
-/* How many unique "levels" of light there are when modern lighting is used. */
-#define MODERN_LIGHTING_LEVELS 16
-#define MODERN_LIGHTING_MAX_LEVEL (MODERN_LIGHTING_LEVELS - 1)
-/* How many bits to shift sunlight level to the left when storing it in a byte along with blocklight level. */
-#define MODERN_LIGHTING_SUN_SHIFT 4
-#define SUN_LEVELS 16
-/* A byte that fills the sun level area with ones. Equivalent to 0b_1111_0000 */
-#define MODERN_LIGHTING_SUN_MASK 0xF0
+
+enum LightingMode {
+ LIGHTING_MODE_CLASSIC, LIGHTING_MODE_FANCY, LIGHTING_MODE_COUNT
+};
+extern const char* const LightingMode_Names[LIGHTING_MODE_COUNT];
+extern cc_uint8 Lighting_Mode;
+
+
+/* How much ambient occlusion to apply in fancy lighting where 1.0f = none and 0.0f = maximum*/
+#define FANCY_AO 0.5F
+/* How many unique "levels" of light there are when fancy lighting is used. */
+#define FANCY_LIGHTING_LEVELS 16
+#define FANCY_LIGHTING_MAX_LEVEL (FANCY_LIGHTING_LEVELS - 1)
+/* How many bits to shift lamplight level to the left when storing it in a byte along with lavalight level. */
+#define FANCY_LIGHTING_LAMP_SHIFT 4
+/* A byte that fills the lamp level area with ones. Equivalent to 0b_1111_0000 */
+#define FANCY_LIGHTING_LAMP_MASK 0xF0
CC_VAR extern struct _Lighting {
/* Releases/Frees the per-level lighting state */
@@ -62,13 +67,17 @@ CC_VAR extern struct _Lighting {
void Lighting_SwitchActive(void);
void Lighting_ApplyActive(void);
-void ModernLighting_SetActive(void);
-void ModernLighting_OnEnvVariableChanged(void* obj, int envVar);
+void FancyLighting_SetActive(void);
+void FancyLighting_OnInit(void);
+/* Expose ClassicLighting functions for reuse in Fancy lighting */
void ClassicLighting_Refresh(void);
void ClassicLighting_FreeState(void);
void ClassicLighting_AllocState(void);
int ClassicLighting_GetLightHeight(int x, int z);
void ClassicLighting_LightHint(int startX, int startY, int startZ);
+cc_bool ClassicLighting_IsLit(int x, int y, int z);
+cc_bool ClassicLighting_IsLit_Fast(int x, int y, int z);
void ClassicLighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock);
+
#endif
diff --git a/src/Menus.c b/src/Menus.c
index dbf64031f..3f27e8b45 100644
--- a/src/Menus.c
+++ b/src/Menus.c
@@ -2878,9 +2878,11 @@ static void GraphicsOptionsScreen_SetSmooth(const cc_string* v) {
Builder_ApplyActive();
MapRenderer_Refresh();
}
-static void GraphicsOptionsScreen_GetModernLighting(cc_string* v) { Menu_GetBool(v, Lighting_Modern); }
-static void GraphicsOptionsScreen_SetModernLighting(const cc_string* v) {
- Lighting_Modern = Menu_SetBool(v, OPT_MODERN_LIGHTING);
+static void GraphicsOptionsScreen_GetLighting(cc_string* v) { String_AppendConst(v, LightingMode_Names[Lighting_Mode]); }
+static void GraphicsOptionsScreen_SetLighting(const cc_string* v) {
+ Lighting_Mode = Utils_ParseEnum(v, 0, LightingMode_Names, LIGHTING_MODE_COUNT);
+ Options_Set(OPT_LIGHTING_MODE, v);
+
Lighting_SwitchActive();
Builder_ApplyActive();
MapRenderer_Refresh();
@@ -2923,8 +2925,8 @@ static void GraphicsOptionsScreen_InitWidgets(struct MenuOptionsScreen* s) {
GraphicsOptionsScreen_GetViewDist, GraphicsOptionsScreen_SetViewDist },
{ -1, 0, "Smooth lighting", MenuOptionsScreen_Bool,
GraphicsOptionsScreen_GetSmooth, GraphicsOptionsScreen_SetSmooth },
- { -1, 50, "Fancy lighting", MenuOptionsScreen_Bool,
- GraphicsOptionsScreen_GetModernLighting, GraphicsOptionsScreen_SetModernLighting },
+ { -1, 50, "Lighting mode", MenuOptionsScreen_Enum,
+ GraphicsOptionsScreen_GetLighting, GraphicsOptionsScreen_SetLighting },
{ 1, -150, "Smooth camera", MenuOptionsScreen_Bool,
GraphicsOptionsScreen_GetCamera, GraphicsOptionsScreen_SetCamera },
{ 1, -100, "Names", MenuOptionsScreen_Enum,
@@ -2953,8 +2955,9 @@ static void GraphicsOptionsScreen_InitWidgets(struct MenuOptionsScreen* s) {
"&eSmooth lighting smooths lighting and adds a minor glow to bright blocks.\n" \
"&cNote: &eThis setting may reduce performance.";
s->descriptions[4] = \
- "&eFancy lighting allows bright blocks to cast a much wider range of light.\n" \
- "&cNote: &eThis setting will reduce performance and increase memory usage.";
+ "&eClassic: &fTwo levels of light, sun and shadow. Good for performance.\n" \
+ "&eFancy: &fAllows bright blocks to cast a much wider range of light.\n" \
+ "&cNote: &eFancy will reduce performance and increase memory usage.";
s->descriptions[6] = \
"&eNone: &fNo names of players are drawn.\n" \
"&eHovered: &fName of the targeted player is drawn see-through.\n" \
@@ -2972,8 +2975,9 @@ void GraphicsOptionsScreen_Show(void) {
MenuInput_Float(menuOpts_descs[0], 1, 100, 20);
MenuInput_Enum(menuOpts_descs[1], FpsLimit_Names, FPS_LIMIT_COUNT);
MenuInput_Int(menuOpts_descs[2], 8, 4096, 512);
- MenuInput_Enum(menuOpts_descs[6], NameMode_Names, NAME_MODE_COUNT);
- MenuInput_Enum(menuOpts_descs[7], ShadowMode_Names, SHADOW_MODE_COUNT);
+ MenuInput_Enum(menuOpts_descs[4], LightingMode_Names, LIGHTING_MODE_COUNT)
+ MenuInput_Enum(menuOpts_descs[6], NameMode_Names, NAME_MODE_COUNT);
+ MenuInput_Enum(menuOpts_descs[7], ShadowMode_Names, SHADOW_MODE_COUNT);
MenuOptionsScreen_Show(GraphicsOptionsScreen_InitWidgets);
}
diff --git a/src/Options.h b/src/Options.h
index d52040566..3c5d5e7aa 100644
--- a/src/Options.h
+++ b/src/Options.h
@@ -23,7 +23,7 @@ Copyright 2014-2023 ClassiCube | Licensed under BSD-3
#define OPT_ENTITY_SHADOW "entityshadow"
#define OPT_RENDER_TYPE "normal"
#define OPT_SMOOTH_LIGHTING "gfx-smoothlighting"
-#define OPT_MODERN_LIGHTING "gfx-modernlighting"
+#define OPT_LIGHTING_MODE "gfx-lightingmode"
#define OPT_MIPMAPS "gfx-mipmaps"
#define OPT_CHAT_LOGGING "chat-logging"
#define OPT_WINDOW_WIDTH "window-width"
diff --git a/src/Protocol.c b/src/Protocol.c
index 7dbbac562..ea170e39a 100644
--- a/src/Protocol.c
+++ b/src/Protocol.c
@@ -1728,8 +1728,8 @@ static void BlockDefs_OnBlocksLightPropertyUpdated(BlockID block, cc_bool oldPro
static void BlockDefs_OnBrightnessPropertyUpdated(BlockID block, cc_uint8 oldProp) {
if (!World.Loaded) return;
- if (!Lighting_Modern) return;
- /* Need to refresh modern lighting when a block's brightness changes */
+ if (Lighting_Mode == LIGHTING_MODE_CLASSIC) return;
+ /* Need to refresh fancy lighting when a block's brightness changes */
if (Blocks.Brightness[block] != oldProp) Lighting.Refresh();
}