Change "Fancy lighting" option bool to "Lighting mode" enum

Fully rename modern lighting to fancy lighting internally
Other misc code cleanup and rename "sun" light type to "lamp"
This commit is contained in:
Goodlyay 2024-05-16 20:21:38 -07:00
parent d18a8fe988
commit 883d93c6b8
10 changed files with 239 additions and 229 deletions

View File

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

View File

@ -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 {

View File

@ -501,7 +501,7 @@
<ClCompile Include="Deflate.c" />
<ClCompile Include="Model.c" />
<ClCompile Include="Menus.c" />
<ClCompile Include="ModernLighting.c" />
<ClCompile Include="FancyLighting.c" />
<ClCompile Include="Platform_3DS.c" />
<ClCompile Include="Platform_Android.c" />
<ClCompile Include="Platform_Dreamcast.c" />

View File

@ -755,7 +755,7 @@
<ClCompile Include="Window_WiiU.cpp">
<Filter>Source Files\Window</Filter>
</ClCompile>
<ClCompile Include="ModernLighting.c">
<ClCompile Include="FancyLighting.c">
<Filter>Source Files\Map</Filter>
</ClCompile>
<ClCompile Include="Queue.c">

View File

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

View File

@ -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(); }

View File

@ -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

View File

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

View File

@ -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"

View File

@ -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();
}