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