mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 10:35:11 -04:00
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:
parent
d18a8fe988
commit
883d93c6b8
30
src/Block.c
30
src/Block.c
@ -25,7 +25,7 @@ const char* const Sound_Names[SOUND_COUNT] = {
|
|||||||
|
|
||||||
/* Brightness */
|
/* Brightness */
|
||||||
#define BRIT_NONE 0
|
#define BRIT_NONE 0
|
||||||
#define BRIT_FULL MODERN_LIGHTING_MAX_LEVEL
|
#define BRIT_FULL FANCY_LIGHTING_MAX_LEVEL
|
||||||
#define BRIT_MAGM 10
|
#define BRIT_MAGM 10
|
||||||
|
|
||||||
struct SimpleBlockDef {
|
struct SimpleBlockDef {
|
||||||
@ -535,41 +535,41 @@ int Block_Parse(const cc_string* name) {
|
|||||||
/* 0b_1000_0000 */
|
/* 0b_1000_0000 */
|
||||||
#define USE_MODERN_BRIGHTNESS_FLAG 1 << 7
|
#define USE_MODERN_BRIGHTNESS_FLAG 1 << 7
|
||||||
/* 0b_0100_0000 */
|
/* 0b_0100_0000 */
|
||||||
#define USE_SUN_COLOR 1 << 6
|
#define USE_LAMP_COLOR 1 << 6
|
||||||
/* 0b_0000_1111 */
|
/* 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 */
|
/* 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 */
|
/* Into CC's native format 0b_SSSS_BBBB where S = lamp brightness and B = lava brightness */
|
||||||
cc_uint8 Block_ReadBrightness(cc_uint8 fullBright) {
|
cc_uint8 Block_ReadBrightness(cc_uint8 fullBright) {
|
||||||
cc_bool useSun;
|
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 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. */
|
/* Preserve only the least significant four bits. This gives us our raw brightness level for sun or block light. */
|
||||||
fullBright &= BRIGHTNESS_MASK;
|
fullBright &= BRIGHTNESS_MASK;
|
||||||
|
|
||||||
/* Sun light is stored in the upper four bits */
|
/* 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;
|
return fullBright;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Writes CC's native format 0b_SSSS_BBBB where S = lamp brightness and B = lava brightness */
|
/* 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 */
|
/* 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 Block_WriteFullBright(cc_uint8 brightness) {
|
||||||
cc_uint8 blockBrightness, sunBrightness, fullBright;
|
cc_uint8 lavaBrightness, lampBrightness, fullBright;
|
||||||
blockBrightness = brightness & BRIGHTNESS_MASK;
|
lavaBrightness = brightness & BRIGHTNESS_MASK;
|
||||||
sunBrightness = brightness >> MODERN_LIGHTING_SUN_SHIFT;
|
lampBrightness = brightness >> FANCY_LIGHTING_LAMP_SHIFT;
|
||||||
fullBright = USE_MODERN_BRIGHTNESS_FLAG;
|
fullBright = USE_MODERN_BRIGHTNESS_FLAG;
|
||||||
|
|
||||||
/* Modern brightness stored in a fullbright value is mutually exclusive between using block and using sun light */
|
/* Modern brightness stored in a fullbright value is mutually exclusive between using block and using sun light */
|
||||||
if (blockBrightness > 0) {
|
if (lavaBrightness > 0) {
|
||||||
fullBright |= blockBrightness;
|
fullBright |= lavaBrightness;
|
||||||
} else if (sunBrightness > 0) {
|
} else if (lampBrightness > 0) {
|
||||||
fullBright |= USE_SUN_COLOR; /* Insert flag that tells us this fullbright value should be interpreted as sun brightness */
|
fullBright |= USE_LAMP_COLOR; /* Insert flag that tells us this fullbright value should be interpreted as sun brightness */
|
||||||
fullBright |= sunBrightness;
|
fullBright |= lampBrightness;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -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 zOccluded = Modern_IsOccluded(x, y , z + oZ);
|
||||||
cc_bool xzOccluded = Modern_IsOccluded(x, y + oY, 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 CoX = xOccluded ? PackedCol_Scale(orig, FANCY_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 CoZ = zOccluded ? PackedCol_Scale(orig, FANCY_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 CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_XSide_Fast(x, y + oY, z + oZ);
|
||||||
|
|
||||||
PackedCol ab = AVERAGE(CoX, CoZ);
|
PackedCol ab = AVERAGE(CoX, CoZ);
|
||||||
PackedCol cd = AVERAGE(CoXoZ, orig);
|
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 zOccluded = Modern_IsOccluded(x, y + oY, z);
|
||||||
cc_bool xzOccluded = Modern_IsOccluded(x + oX, 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 CoX = xOccluded ? PackedCol_Scale(orig, FANCY_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 CoZ = zOccluded ? PackedCol_Scale(orig, FANCY_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 CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_ZSide_Fast(x + oX, y + oY, z);
|
||||||
|
|
||||||
PackedCol ab = AVERAGE(CoX, CoZ);
|
PackedCol ab = AVERAGE(CoX, CoZ);
|
||||||
PackedCol cd = AVERAGE(CoXoZ, orig);
|
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 zOccluded = Modern_IsOccluded(x, y, z + oZ);
|
||||||
cc_bool xzOccluded = Modern_IsOccluded(x + oX, 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 CoX = xOccluded ? PackedCol_Scale(orig, FANCY_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 CoZ = zOccluded ? PackedCol_Scale(orig, FANCY_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 CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color_YMin_Fast(x + oX, y, z + oZ);
|
||||||
|
|
||||||
PackedCol ab = AVERAGE(CoX, CoZ);
|
PackedCol ab = AVERAGE(CoX, CoZ);
|
||||||
PackedCol cd = AVERAGE(CoXoZ, orig);
|
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 zOccluded = Modern_IsOccluded(x, y, z + oZ);
|
||||||
cc_bool xzOccluded = Modern_IsOccluded(x + oX, 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 CoX = xOccluded ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color(x + oX, y, z );
|
||||||
PackedCol CoZ = zOccluded ? PackedCol_Scale(orig, MODERN_AO) : Lighting.Color(x , y, z + oZ);
|
PackedCol CoZ = zOccluded ? PackedCol_Scale(orig, FANCY_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 CoXoZ = (xzOccluded || (xOccluded && zOccluded)) ? PackedCol_Scale(orig, FANCY_AO) : Lighting.Color(x + oX, y, z + oZ);
|
||||||
|
|
||||||
PackedCol ab = AVERAGE(CoX, CoZ);
|
PackedCol ab = AVERAGE(CoX, CoZ);
|
||||||
PackedCol cd = AVERAGE(CoXoZ, orig);
|
PackedCol cd = AVERAGE(CoXoZ, orig);
|
||||||
@ -1621,7 +1621,7 @@ static void ModernBuilder_SetActive(void) {
|
|||||||
cc_bool Builder_SmoothLighting;
|
cc_bool Builder_SmoothLighting;
|
||||||
void Builder_ApplyActive(void) {
|
void Builder_ApplyActive(void) {
|
||||||
if (Builder_SmoothLighting) {
|
if (Builder_SmoothLighting) {
|
||||||
if (Lighting_Modern) {
|
if (Lighting_Mode != LIGHTING_MODE_CLASSIC) {
|
||||||
ModernBuilder_SetActive();
|
ModernBuilder_SetActive();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -501,7 +501,7 @@
|
|||||||
<ClCompile Include="Deflate.c" />
|
<ClCompile Include="Deflate.c" />
|
||||||
<ClCompile Include="Model.c" />
|
<ClCompile Include="Model.c" />
|
||||||
<ClCompile Include="Menus.c" />
|
<ClCompile Include="Menus.c" />
|
||||||
<ClCompile Include="ModernLighting.c" />
|
<ClCompile Include="FancyLighting.c" />
|
||||||
<ClCompile Include="Platform_3DS.c" />
|
<ClCompile Include="Platform_3DS.c" />
|
||||||
<ClCompile Include="Platform_Android.c" />
|
<ClCompile Include="Platform_Android.c" />
|
||||||
<ClCompile Include="Platform_Dreamcast.c" />
|
<ClCompile Include="Platform_Dreamcast.c" />
|
||||||
|
@ -755,7 +755,7 @@
|
|||||||
<ClCompile Include="Window_WiiU.cpp">
|
<ClCompile Include="Window_WiiU.cpp">
|
||||||
<Filter>Source Files\Window</Filter>
|
<Filter>Source Files\Window</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ModernLighting.c">
|
<ClCompile Include="FancyLighting.c">
|
||||||
<Filter>Source Files\Map</Filter>
|
<Filter>Source Files\Map</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Queue.c">
|
<ClCompile Include="Queue.c">
|
||||||
|
@ -13,25 +13,26 @@
|
|||||||
#include "Options.h"
|
#include "Options.h"
|
||||||
#include "Queue.h"
|
#include "Queue.h"
|
||||||
|
|
||||||
struct LightNode {
|
|
||||||
IVec3 coords;
|
|
||||||
cc_uint8 brightness;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*########################################################################################################################*
|
struct LightNode {
|
||||||
*----------------------------------------------------Modern lighting------------------------------------------------------*
|
IVec3 coords; /* 12 bytes */
|
||||||
*#########################################################################################################################*/
|
cc_uint8 brightness; /* 1 byte */
|
||||||
|
/* char padding[3]; */
|
||||||
|
};
|
||||||
|
|
||||||
static struct Queue lightQueue;
|
static struct Queue lightQueue;
|
||||||
static struct Queue unlightQueue;
|
static struct Queue unlightQueue;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Top face, X face, Z face, bottomY face*/
|
/* Top face, X face, Z face, bottomY face*/
|
||||||
#define PALETTE_SHADES 4
|
#define PALETTE_SHADES 4
|
||||||
/* One palette for sunlight, one palette for shadow */
|
/* One palette-group for sunlight, one palette-group for shadow */
|
||||||
#define PALETTE_TYPES 2
|
#define PALLETE_GROUP_COUNT 2
|
||||||
#define PALETTE_COUNT (PALETTE_SHADES * PALETTE_TYPES)
|
#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. */
|
/* 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. */
|
/* 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) */
|
/* 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];
|
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;
|
typedef cc_uint8* LightingChunk;
|
||||||
static cc_uint8* chunkLightingDataFlags;
|
static cc_uint8* chunkLightingDataFlags;
|
||||||
#define CHUNK_UNCALCULATED 0
|
#define CHUNK_UNCALCULATED 0
|
||||||
@ -52,9 +47,6 @@ static cc_uint8* chunkLightingDataFlags;
|
|||||||
#define CHUNK_ALL_CALCULATED 2
|
#define CHUNK_ALL_CALCULATED 2
|
||||||
static LightingChunk* chunkLightingData;
|
static LightingChunk* chunkLightingData;
|
||||||
|
|
||||||
#define Modern_MakePaletteIndex(sun, block) ((sun << MODERN_LIGHTING_SUN_SHIFT) | block)
|
|
||||||
|
|
||||||
|
|
||||||
static PackedCol PackedCol_ScreenBlend(PackedCol a, PackedCol b) {
|
static PackedCol PackedCol_ScreenBlend(PackedCol a, PackedCol b) {
|
||||||
PackedCol finalColor, aInverted, bInverted;
|
PackedCol finalColor, aInverted, bInverted;
|
||||||
cc_uint8 R, G, B;
|
cc_uint8 R, G, B;
|
||||||
@ -75,66 +67,65 @@ static PackedCol PackedCol_ScreenBlend(PackedCol a, PackedCol b) {
|
|||||||
B = 255 - PackedCol_B(finalColor);
|
B = 255 - PackedCol_B(finalColor);
|
||||||
return PackedCol_Make(R, G, B, 255);
|
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;
|
PackedCol lavaColor, lampColor;
|
||||||
int lampLevel, lavaLevel;
|
int lampLevel, lavaLevel;
|
||||||
float blockLerp;
|
float curLerp;
|
||||||
|
|
||||||
for (lampLevel = 0; lampLevel < MODERN_LIGHTING_LEVELS; lampLevel++) {
|
for (lampLevel = 0; lampLevel < FANCY_LIGHTING_LEVELS; lampLevel++) {
|
||||||
for (lavaLevel = 0; lavaLevel < MODERN_LIGHTING_LEVELS; lavaLevel++) {
|
for (lavaLevel = 0; lavaLevel < FANCY_LIGHTING_LEVELS; lavaLevel++) {
|
||||||
if (lampLevel == MODERN_LIGHTING_LEVELS - 1) {
|
if (lampLevel == FANCY_LIGHTING_LEVELS - 1) {
|
||||||
lampColor = Env.LampLightCol;
|
lampColor = Env.LampLightCol;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
blockLerp = max(lampLevel, MODERN_LIGHTING_LEVELS - SUN_LEVELS) / (float)(MODERN_LIGHTING_LEVELS - 1);
|
curLerp = lampLevel / (float)(FANCY_LIGHTING_LEVELS - 1);
|
||||||
blockLerp *= (MATH_PI / 2);
|
curLerp *= (MATH_PI / 2);
|
||||||
blockLerp = Math_Cos(blockLerp);
|
curLerp = Math_Cos(curLerp);
|
||||||
lampColor = PackedCol_Lerp(0, Env.LampLightCol, 1 - blockLerp);
|
lampColor = PackedCol_Lerp(0, Env.LampLightCol, 1 - curLerp);
|
||||||
}
|
}
|
||||||
|
|
||||||
blockLerp = lavaLevel / (float)(MODERN_LIGHTING_LEVELS - 1);
|
curLerp = lavaLevel / (float)(FANCY_LIGHTING_LEVELS - 1);
|
||||||
//blockLerp *= blockLerp;
|
curLerp *= (MATH_PI / 2);
|
||||||
blockLerp *= (MATH_PI / 2);
|
curLerp = Math_Cos(curLerp);
|
||||||
blockLerp = Math_Cos(blockLerp);
|
|
||||||
|
|
||||||
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 */
|
/* 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);
|
PackedCol_Scale(PackedCol_ScreenBlend(PackedCol_ScreenBlend(lampColor, lavaColor), ambientColor), shaded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void ModernLighting_InitPalettes(void) {
|
static void InitPalettes(void) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < PALETTE_COUNT; 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;
|
i = 0;
|
||||||
ModernLighting_InitPalette(palettes[i + PALETTE_YMAX_INDEX], 1, Env.ShadowCol);
|
InitPalette(palettes[i + PALETTE_YMAX_INDEX], 1, Env.ShadowCol);
|
||||||
ModernLighting_InitPalette(palettes[i + PALETTE_XSIDE_INDEX], PACKEDCOL_SHADE_X, Env.ShadowCol);
|
InitPalette(palettes[i + PALETTE_XSIDE_INDEX], PACKEDCOL_SHADE_X, Env.ShadowCol);
|
||||||
ModernLighting_InitPalette(palettes[i + PALETTE_ZSIDE_INDEX], PACKEDCOL_SHADE_Z, Env.ShadowCol);
|
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_YMIN_INDEX], PACKEDCOL_SHADE_YMIN, Env.ShadowCol);
|
||||||
i += PALETTE_SHADES;
|
i += PALETTE_SHADES;
|
||||||
ModernLighting_InitPalette(palettes[i + PALETTE_YMAX_INDEX], 1, Env.SunCol);
|
InitPalette(palettes[i + PALETTE_YMAX_INDEX], 1, Env.SunCol);
|
||||||
ModernLighting_InitPalette(palettes[i + PALETTE_XSIDE_INDEX], PACKEDCOL_SHADE_X, Env.SunCol);
|
InitPalette(palettes[i + PALETTE_XSIDE_INDEX], PACKEDCOL_SHADE_X, Env.SunCol);
|
||||||
ModernLighting_InitPalette(palettes[i + PALETTE_ZSIDE_INDEX], PACKEDCOL_SHADE_Z, Env.SunCol);
|
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_YMIN_INDEX], PACKEDCOL_SHADE_YMIN, Env.SunCol);
|
||||||
}
|
}
|
||||||
static void ModernLighting_FreePalettes(void) {
|
static void FreePalettes(void) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < PALETTE_COUNT; i++) {
|
for (i = 0; i < PALETTE_COUNT; i++) {
|
||||||
Mem_Free(palettes[i]);
|
Mem_Free(palettes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int chunksCount;
|
static int chunksCount;
|
||||||
static void ModernLighting_AllocState(void) {
|
static void AllocState(void) {
|
||||||
ClassicLighting_AllocState();
|
ClassicLighting_AllocState();
|
||||||
ModernLighting_InitPalettes();
|
InitPalettes();
|
||||||
chunksCount = World.ChunksCount;
|
chunksCount = World.ChunksCount;
|
||||||
|
|
||||||
chunkLightingDataFlags = (cc_uint8*)Mem_AllocCleared(chunksCount, sizeof(cc_uint8), "light flags");
|
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));
|
Queue_Init(&unlightQueue, sizeof(struct LightNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ModernLighting_FreeState(void) {
|
static void FreeState(void) {
|
||||||
int i;
|
int i;
|
||||||
ClassicLighting_FreeState();
|
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;
|
if (!chunkLightingDataFlags) return;
|
||||||
|
|
||||||
ModernLighting_FreePalettes();
|
FreePalettes();
|
||||||
|
|
||||||
for (i = 0; i < chunksCount; i++) {
|
for (i = 0; i < chunksCount; i++) {
|
||||||
Mem_Free(chunkLightingData[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))
|
#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. */
|
/* 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) {
|
static void SetBrightness(cc_uint8 brightness, int x, int y, int z, cc_bool isLamp, cc_bool refreshChunk) {
|
||||||
cc_uint8 clearMask;
|
cc_uint8 clearMask, shift = isLamp ? FANCY_LIGHTING_LAMP_SHIFT : 0, prevValue;
|
||||||
cc_uint8 shift = sun ? MODERN_LIGHTING_SUN_SHIFT : 0;
|
|
||||||
|
|
||||||
int cx = x >> CHUNK_SHIFT, lx = x & CHUNK_MASK;
|
int cx = x >> CHUNK_SHIFT, lx = x & CHUNK_MASK;
|
||||||
int cy = y >> CHUNK_SHIFT, ly = y & CHUNK_MASK;
|
int cy = y >> CHUNK_SHIFT, ly = y & CHUNK_MASK;
|
||||||
int cz = z >> CHUNK_SHIFT, lz = z & CHUNK_MASK;
|
int cz = z >> CHUNK_SHIFT, lz = z & CHUNK_MASK;
|
||||||
|
|
||||||
int chunkIndex = ChunkCoordsToIndex(cx, cy, cz);
|
int chunkIndex = ChunkCoordsToIndex(cx, cy, cz);
|
||||||
|
int localIndex = LocalCoordsToIndex(lx, ly, lz);
|
||||||
|
|
||||||
if (chunkLightingData[chunkIndex] == NULL) {
|
if (chunkLightingData[chunkIndex] == NULL) {
|
||||||
chunkLightingData[chunkIndex] = (cc_uint8*)Mem_TryAllocCleared(CHUNK_SIZE_3, sizeof(cc_uint8));
|
chunkLightingData[chunkIndex] = (cc_uint8*)Mem_TryAllocCleared(CHUNK_SIZE_3, sizeof(cc_uint8));
|
||||||
}
|
}
|
||||||
|
|
||||||
int localIndex = LocalCoordsToIndex(lx, ly, lz);
|
/* 00001111 if lamp, otherwise 11110000*/
|
||||||
|
clearMask = ~(FANCY_LIGHTING_MAX_LEVEL << shift);
|
||||||
/* 00001111 if sun, otherwise 11110000*/
|
|
||||||
clearMask = ~(MODERN_LIGHTING_MAX_LEVEL << shift);
|
|
||||||
|
|
||||||
if (refreshChunk) {
|
if (refreshChunk) {
|
||||||
cc_uint8 prevValue = chunkLightingData[chunkIndex][localIndex];
|
prevValue = chunkLightingData[chunkIndex][localIndex];
|
||||||
|
|
||||||
chunkLightingData[chunkIndex][localIndex] &= clearMask;
|
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 */
|
/* There is no reason to refresh current chunk as the builder does that automatically */
|
||||||
if (prevValue != chunkLightingData[chunkIndex][localIndex]) {
|
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 {
|
else {
|
||||||
chunkLightingData[chunkIndex][localIndex] &= clearMask;
|
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. */
|
/* 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 cx = x >> CHUNK_SHIFT, lx = x & CHUNK_MASK;
|
||||||
int cy = y >> CHUNK_SHIFT, ly = y & CHUNK_MASK;
|
int cy = y >> CHUNK_SHIFT, ly = y & CHUNK_MASK;
|
||||||
int cz = z >> CHUNK_SHIFT, lz = z & 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; }
|
if (chunkLightingData[chunkIndex] == NULL) { return 0; }
|
||||||
int localIndex = LocalCoordsToIndex(lx, ly, lz);
|
localIndex = LocalCoordsToIndex(lx, ly, lz);
|
||||||
|
|
||||||
return sun ?
|
return isLamp ?
|
||||||
chunkLightingData[chunkIndex][localIndex] >> MODERN_LIGHTING_SUN_SHIFT :
|
chunkLightingData[chunkIndex][localIndex] >> FANCY_LIGHTING_LAMP_SHIFT :
|
||||||
chunkLightingData[chunkIndex][localIndex] & MODERN_LIGHTING_MAX_LEVEL;
|
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);
|
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 && \
|
if (ln.coords.axis dir ## = limit && \
|
||||||
CanLightPass(thisBlock, FACE_ ## AXIS ## thisFace) && \
|
CanLightPass(thisBlock, FACE_ ## AXIS ## thisFace) && \
|
||||||
CanLightPass(World_GetBlock(ln.coords.x, ln.coords.y, ln.coords.z), FACE_ ## AXIS ## thatFace) && \
|
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); \
|
Queue_Enqueue(&lightQueue, &ln); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
static void FlushLightQueue(cc_bool isSun, cc_bool refreshChunk) {
|
static void FlushLightQueue(cc_bool isLamp, cc_bool refreshChunk) {
|
||||||
int handled = 0;
|
struct LightNode ln;
|
||||||
while (lightQueue.count > 0) {
|
cc_uint8 brightnessHere;
|
||||||
handled++;
|
BlockID thisBlock;
|
||||||
struct LightNode ln = *(struct LightNode*)(Queue_Dequeue(&lightQueue));
|
|
||||||
|
|
||||||
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 this cel is already more lit, we can assume this cel and its neighbors have been accounted for */
|
||||||
if (brightnessHere >= ln.brightness) { continue; }
|
if (brightnessHere >= ln.brightness) { continue; }
|
||||||
if (ln.brightness == 0) { 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);
|
//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--;
|
ln.brightness--;
|
||||||
if (ln.brightness == 0) continue;
|
if (ln.brightness == 0) continue;
|
||||||
|
|
||||||
ln.coords.x--;
|
ln.coords.x--;
|
||||||
Light_TrySpreadInto(x, X, > , 0, isSun, MAX, MIN)
|
Light_TrySpreadInto(x, X, > , 0, isLamp, MAX, MIN)
|
||||||
ln.coords.x += 2;
|
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.x--;
|
||||||
|
|
||||||
ln.coords.y--;
|
ln.coords.y--;
|
||||||
Light_TrySpreadInto(y, Y, >, 0, isSun, MAX, MIN)
|
Light_TrySpreadInto(y, Y, >, 0, isLamp, MAX, MIN)
|
||||||
ln.coords.y += 2;
|
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.y--;
|
||||||
|
|
||||||
ln.coords.z--;
|
ln.coords.z--;
|
||||||
Light_TrySpreadInto(z, Z, > , 0, isSun, MAX, MIN)
|
Light_TrySpreadInto(z, Z, > , 0, isLamp, MAX, MIN)
|
||||||
ln.coords.z += 2;
|
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) {
|
cc_uint8 GetBlockBrightness(BlockID curBlock, cc_bool isLamp) {
|
||||||
if (isSun) return Blocks.Brightness[curBlock] >> MODERN_LIGHTING_SUN_SHIFT;
|
if (isLamp) return Blocks.Brightness[curBlock] >> FANCY_LIGHTING_LAMP_SHIFT;
|
||||||
return Blocks.Brightness[curBlock] & MODERN_LIGHTING_MAX_LEVEL;
|
return Blocks.Brightness[curBlock] & FANCY_LIGHTING_MAX_LEVEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CalculateChunkLightingSelf(int chunkIndex, int cx, int cy, int cz) {
|
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;
|
chunkEndX = chunkStartX + CHUNK_SIZE;
|
||||||
chunkEndY = chunkStartY + CHUNK_SIZE;
|
chunkEndY = chunkStartY + CHUNK_SIZE;
|
||||||
chunkEndZ = chunkStartZ + 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 (chunkEndY > World.Height) { chunkEndY = World.Height; }
|
||||||
if (chunkEndZ > World.Length) { chunkEndZ = World.Length; }
|
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);
|
brightness = GetBlockBrightness(curBlock, false);
|
||||||
|
|
||||||
if (brightness > 0) {
|
if (brightness > 0) {
|
||||||
struct LightNode entry = { x, y, z, brightness };
|
entry = (struct LightNode){ { x, y, z }, brightness };
|
||||||
Queue_Enqueue(&lightQueue, &entry);
|
Queue_Enqueue(&lightQueue, &entry);
|
||||||
FlushLightQueue(false, false);
|
FlushLightQueue(false, false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* If no block brightness, it must use sun brightness */
|
/* If no lava brightness, it must use lamp brightness */
|
||||||
brightness = Blocks.Brightness[curBlock] >> MODERN_LIGHTING_SUN_SHIFT;
|
brightness = Blocks.Brightness[curBlock] >> FANCY_LIGHTING_LAMP_SHIFT;
|
||||||
struct LightNode entry = { x, y, z, brightness };
|
entry = (struct LightNode){ { x, y, z }, brightness };
|
||||||
Queue_Enqueue(&lightQueue, &entry);
|
Queue_Enqueue(&lightQueue, &entry);
|
||||||
FlushLightQueue(true, false);
|
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) \
|
CanLightPass(World_GetBlock(neighborCoords.x, neighborCoords.y, neighborCoords.z), FACE_ ## AXIS ## thatFace) \
|
||||||
) \
|
) \
|
||||||
{ \
|
{ \
|
||||||
neighborBrightness = GetBlocklight(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), isSun); \
|
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 */ \
|
/* This spot is a light caster, mark this spot as needing to be re-spread */ \
|
||||||
if (neighborBlockBrightness > 0) { \
|
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); \
|
Queue_Enqueue(&lightQueue, &entry); \
|
||||||
} \
|
} \
|
||||||
if (neighborBrightness > 0) { \
|
if (neighborBrightness > 0) { \
|
||||||
/* This neighbor is darker than cur spot, darken it*/ \
|
/* This neighbor is darker than cur spot, darken it*/ \
|
||||||
if (neighborBrightness < curNode.brightness) { \
|
if (neighborBrightness < curNode.brightness) { \
|
||||||
SetBlocklight(0, neighborCoords.x, neighborCoords.y, neighborCoords.z, isSun, true); \
|
SetBrightness(0, neighborCoords.x, neighborCoords.y, neighborCoords.z, isLamp, true); \
|
||||||
struct LightNode neighborNode = { { neighborCoords.x, neighborCoords.y, neighborCoords.z }, neighborBrightness }; \
|
neighborNode = (struct LightNode){ { neighborCoords.x, neighborCoords.y, neighborCoords.z }, neighborBrightness }; \
|
||||||
Queue_Enqueue(&unlightQueue, &neighborNode); \
|
Queue_Enqueue(&unlightQueue, &neighborNode); \
|
||||||
} \
|
} \
|
||||||
/* This neighbor is brighter or same, mark this spot as needing to be re-spread */ \
|
/* 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) \
|
CanLightPass(World_GetBlock(neighborCoords.x, neighborCoords.y, neighborCoords.z), FACE_ ## AXIS ## thatFace) \
|
||||||
) \
|
) \
|
||||||
{ \
|
{ \
|
||||||
struct LightNode entry = curNode; \
|
entry = curNode; \
|
||||||
entry.brightness = neighborBrightness-1; \
|
entry.brightness = neighborBrightness-1; \
|
||||||
Queue_Enqueue(&lightQueue, &entry); \
|
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 */
|
/* 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;
|
int count = 0;
|
||||||
SetBlocklight(0, x, y, z, isSun, true);
|
struct LightNode sourceNode, curNode, entry, neighborNode;
|
||||||
struct LightNode sourceNode = { { x, y, z }, brightness };
|
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);
|
Queue_Enqueue(&unlightQueue, &sourceNode);
|
||||||
|
|
||||||
while (unlightQueue.count > 0) {
|
while (unlightQueue.count > 0) {
|
||||||
struct LightNode curNode = *(struct LightNode*)(Queue_Dequeue(&unlightQueue));
|
curNode = *(struct LightNode*)(Queue_Dequeue(&unlightQueue));
|
||||||
cc_uint8 neighborBrightness;
|
neighborCoords = curNode.coords;
|
||||||
cc_uint8 neighborBlockBrightness;
|
|
||||||
IVec3 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
|
/* 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. */
|
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++;
|
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)
|
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) {
|
static void CalcBlockChange(int x, int y, int z, BlockID oldBlock, BlockID newBlock, cc_bool isLamp) {
|
||||||
cc_uint8 oldBlockLightLevel = GetBlockBrightness(oldBlock, isSun);
|
cc_uint8 oldBlockLightLevel = GetBlockBrightness(oldBlock, isLamp);
|
||||||
cc_uint8 newBlockLightLevel = GetBlockBrightness(newBlock, isSun);
|
cc_uint8 newBlockLightLevel = GetBlockBrightness(newBlock, isLamp);
|
||||||
|
cc_uint8 oldLightLevelHere = GetBrightness(x, y, z, isLamp);
|
||||||
cc_uint8 oldLightLevelHere = GetBlocklight(x, y, z, isSun);
|
struct LightNode entry;
|
||||||
|
|
||||||
/* Cel has no lighting and new block doesn't cast light and blocks all light, no change */
|
/* Cel has no lighting and new block doesn't cast light and blocks all light, no change */
|
||||||
if (!oldLightLevelHere && !newBlockLightLevel && IsFullOpaque(newBlock)) return;
|
if (!oldLightLevelHere && !newBlockLightLevel && IsFullOpaque(newBlock)) return;
|
||||||
|
|
||||||
|
|
||||||
/* Cel is darker than the new block, only brighter case */
|
/* Cel is darker than the new block, only brighter case */
|
||||||
if (oldLightLevelHere < newBlockLightLevel) {
|
if (oldLightLevelHere < newBlockLightLevel) {
|
||||||
/* brighten this spot, recalculate lighting */
|
/* brighten this spot, recalculate lighting */
|
||||||
//Platform_LogConst("Brightening");
|
//Platform_LogConst("Brightening");
|
||||||
struct LightNode entry = { x, y, z, newBlockLightLevel };
|
entry = (struct LightNode){ { x, y, z }, newBlockLightLevel };
|
||||||
Queue_Enqueue(&lightQueue, &entry);
|
Queue_Enqueue(&lightQueue, &entry);
|
||||||
FlushLightQueue(isSun, true);
|
FlushLightQueue(isLamp, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,10 +481,9 @@ static void CalcBlockChange(int x, int y, int z, BlockID oldBlock, BlockID newBl
|
|||||||
return;
|
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 */
|
/* For some reason this is a possible case */
|
||||||
if (oldBlock == newBlock) { return; }
|
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 */
|
/* 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) */
|
/* (e.g. because a block changed whether it is full bright or not) */
|
||||||
static void ModernLighting_Refresh(void) {
|
static void Refresh(void) {
|
||||||
ClassicLighting_Refresh();
|
ClassicLighting_Refresh();
|
||||||
ModernLighting_FreeState();
|
FreeState();
|
||||||
ModernLighting_AllocState();
|
AllocState();
|
||||||
}
|
}
|
||||||
static cc_bool ModernLighting_IsLit(int x, int y, int z) { return true; }
|
static cc_bool 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_Fast(int x, int y, int z) { return true; }
|
||||||
|
|
||||||
#define CalcForChunkIfNeeded(cx, cy, cz, chunkIndex) \
|
#define CalcForChunkIfNeeded(cx, cy, cz, chunkIndex) \
|
||||||
if (chunkLightingDataFlags[chunkIndex] < CHUNK_ALL_CALCULATED) { \
|
if (chunkLightingDataFlags[chunkIndex] < CHUNK_ALL_CALCULATED) { \
|
||||||
CalculateChunkLightingAll(chunkIndex, cx, cy, cz); \
|
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;
|
cc_uint8 lightData;
|
||||||
int cx, cy, cz, chunkIndex;
|
int cx, cy, cz, chunkIndex;
|
||||||
int chunkCoordsIndex;
|
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 */
|
/* There might be no light data in this chunk even after it was calculated */
|
||||||
if (chunkLightingData[chunkIndex] == NULL) {
|
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;
|
lightData = 0;
|
||||||
} else {
|
} else {
|
||||||
chunkCoordsIndex = GlobalCoordsToChunkCoordsIndex(x, y, z);
|
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;
|
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];
|
return palettes[paletteFace][lightData];
|
||||||
}
|
}
|
||||||
|
|
||||||
static PackedCol ModernLighting_Color(int x, int y, int z) {
|
static PackedCol Color(int x, int y, int z) {
|
||||||
return ModernLighting_Color_Core(x, y, z, PALETTE_YMAX_INDEX, Env.SunCol);
|
return Color_Core(x, y, z, PALETTE_YMAX_INDEX, Env.SunCol);
|
||||||
}
|
}
|
||||||
static PackedCol ModernLighting_Color_YMaxSide(int x, int y, int z) {
|
static PackedCol Color_YMaxSide(int x, int y, int z) {
|
||||||
return ModernLighting_Color_Core(x, y, z, PALETTE_YMAX_INDEX, Env.SunCol);
|
return Color_Core(x, y, z, PALETTE_YMAX_INDEX, Env.SunCol);
|
||||||
}
|
}
|
||||||
static PackedCol ModernLighting_Color_YMinSide(int x, int y, int z) {
|
static PackedCol Color_YMinSide(int x, int y, int z) {
|
||||||
return ModernLighting_Color_Core(x, y, z, PALETTE_YMIN_INDEX, Env.SunYMin);
|
return Color_Core(x, y, z, PALETTE_YMIN_INDEX, Env.SunYMin);
|
||||||
}
|
}
|
||||||
static PackedCol ModernLighting_Color_XSide(int x, int y, int z) {
|
static PackedCol Color_XSide(int x, int y, int z) {
|
||||||
return ModernLighting_Color_Core(x, y, z, PALETTE_XSIDE_INDEX, Env.SunXSide);
|
return Color_Core(x, y, z, PALETTE_XSIDE_INDEX, Env.SunXSide);
|
||||||
}
|
}
|
||||||
static PackedCol ModernLighting_Color_ZSide(int x, int y, int z) {
|
static PackedCol Color_ZSide(int x, int y, int z) {
|
||||||
return ModernLighting_Color_Core(x, y, z, PALETTE_ZSIDE_INDEX, Env.SunZSide);
|
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;
|
int cx, cy, cz, chunkIndex;
|
||||||
ClassicLighting_LightHint(startX, startY, startZ);
|
ClassicLighting_LightHint(startX, startY, startZ);
|
||||||
/* Add 1 to startX/Z, as coordinates are for the extended chunk (18x18x18) */
|
/* 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);
|
CalcForChunkIfNeeded(cx, cy, cz, chunkIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModernLighting_SetActive(void) {
|
void FancyLighting_SetActive(void) {
|
||||||
Lighting.OnBlockChanged = ModernLighting_OnBlockChanged;
|
Lighting.OnBlockChanged = OnBlockChanged;
|
||||||
Lighting.Refresh = ModernLighting_Refresh;
|
Lighting.Refresh = Refresh;
|
||||||
Lighting.IsLit = ModernLighting_IsLit;
|
Lighting.IsLit = IsLit;
|
||||||
Lighting.Color = ModernLighting_Color;
|
Lighting.Color = Color;
|
||||||
Lighting.Color_XSide = ModernLighting_Color_XSide;
|
Lighting.Color_XSide = Color_XSide;
|
||||||
|
|
||||||
Lighting.IsLit_Fast = ModernLighting_IsLit_Fast;
|
Lighting.IsLit_Fast = IsLit_Fast;
|
||||||
Lighting.Color_Sprite_Fast = ModernLighting_Color;
|
Lighting.Color_Sprite_Fast = Color;
|
||||||
Lighting.Color_YMax_Fast = ModernLighting_Color;
|
Lighting.Color_YMax_Fast = Color;
|
||||||
Lighting.Color_YMin_Fast = ModernLighting_Color_YMinSide;
|
Lighting.Color_YMin_Fast = Color_YMinSide;
|
||||||
Lighting.Color_XSide_Fast = ModernLighting_Color_XSide;
|
Lighting.Color_XSide_Fast = Color_XSide;
|
||||||
Lighting.Color_ZSide_Fast = ModernLighting_Color_ZSide;
|
Lighting.Color_ZSide_Fast = Color_ZSide;
|
||||||
|
|
||||||
Lighting.FreeState = ModernLighting_FreeState;
|
Lighting.FreeState = FreeState;
|
||||||
Lighting.AllocState = ModernLighting_AllocState;
|
Lighting.AllocState = AllocState;
|
||||||
Lighting.LightHint = ModernLighting_LightHint;
|
Lighting.LightHint = LightHint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModernLighting_OnEnvVariableChanged(void* obj, int envVar) {
|
static void OnEnvVariableChanged(void* obj, int envVar) {
|
||||||
/* This is always called, but should only do anything if modern lighting is on */
|
/* This is always called, but should only do anything if fancy lighting is on */
|
||||||
if (!Lighting_Modern) { return; }
|
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) {
|
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();
|
if (envVar == ENV_VAR_LAVALIGHT_COLOR || envVar == ENV_VAR_LAMPLIGHT_COLOR) MapRenderer_Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyLighting_OnInit(void) {
|
||||||
|
Event_Register_(&WorldEvents.EnvVarChanged, NULL, OnEnvVariableChanged);
|
||||||
}
|
}
|
@ -11,7 +11,10 @@
|
|||||||
#include "Chat.h"
|
#include "Chat.h"
|
||||||
#include "ExtMath.h"
|
#include "ExtMath.h"
|
||||||
#include "Options.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;
|
struct _Lighting Lighting;
|
||||||
#define Lighting_Pack(x, z) ((x) + World.Width * (z))
|
#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 */
|
/* 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);
|
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)];
|
return y > classic_heightmap[Lighting_Pack(x, z)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,8 +415,8 @@ static void ClassicLighting_SetActive(void) {
|
|||||||
*---------------------------------------------------Lighting component----------------------------------------------------*
|
*---------------------------------------------------Lighting component----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
void Lighting_ApplyActive(void) {
|
void Lighting_ApplyActive(void) {
|
||||||
if (Lighting_Modern) {
|
if (Lighting_Mode != LIGHTING_MODE_CLASSIC) {
|
||||||
ModernLighting_SetActive();
|
FancyLighting_SetActive();
|
||||||
} else {
|
} else {
|
||||||
ClassicLighting_SetActive();
|
ClassicLighting_SetActive();
|
||||||
}
|
}
|
||||||
@ -426,7 +429,10 @@ void Lighting_SwitchActive(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void OnInit(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();
|
Lighting_ApplyActive();
|
||||||
}
|
}
|
||||||
static void OnReset(void) { Lighting.FreeState(); }
|
static void OnReset(void) { Lighting.FreeState(); }
|
||||||
|
@ -10,18 +10,23 @@ Copyright 2014-2023 ClassiCube | Licensed under BSD-3
|
|||||||
*/
|
*/
|
||||||
struct IGameComponent;
|
struct IGameComponent;
|
||||||
extern struct IGameComponent Lighting_Component;
|
extern struct IGameComponent Lighting_Component;
|
||||||
/* Whether MC-style 16-level lighting should be used. */
|
|
||||||
extern cc_bool Lighting_Modern;
|
enum LightingMode {
|
||||||
/* How much ambient occlusion to apply in modern lighting where 1.0f = none and 0.0f = maximum*/
|
LIGHTING_MODE_CLASSIC, LIGHTING_MODE_FANCY, LIGHTING_MODE_COUNT
|
||||||
#define MODERN_AO 0.5F
|
};
|
||||||
/* How many unique "levels" of light there are when modern lighting is used. */
|
extern const char* const LightingMode_Names[LIGHTING_MODE_COUNT];
|
||||||
#define MODERN_LIGHTING_LEVELS 16
|
extern cc_uint8 Lighting_Mode;
|
||||||
#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
|
/* How much ambient occlusion to apply in fancy lighting where 1.0f = none and 0.0f = maximum*/
|
||||||
#define SUN_LEVELS 16
|
#define FANCY_AO 0.5F
|
||||||
/* A byte that fills the sun level area with ones. Equivalent to 0b_1111_0000 */
|
/* How many unique "levels" of light there are when fancy lighting is used. */
|
||||||
#define MODERN_LIGHTING_SUN_MASK 0xF0
|
#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 {
|
CC_VAR extern struct _Lighting {
|
||||||
/* Releases/Frees the per-level lighting state */
|
/* Releases/Frees the per-level lighting state */
|
||||||
@ -62,13 +67,17 @@ CC_VAR extern struct _Lighting {
|
|||||||
|
|
||||||
void Lighting_SwitchActive(void);
|
void Lighting_SwitchActive(void);
|
||||||
void Lighting_ApplyActive(void);
|
void Lighting_ApplyActive(void);
|
||||||
void ModernLighting_SetActive(void);
|
void FancyLighting_SetActive(void);
|
||||||
void ModernLighting_OnEnvVariableChanged(void* obj, int envVar);
|
void FancyLighting_OnInit(void);
|
||||||
|
|
||||||
|
/* Expose ClassicLighting functions for reuse in Fancy lighting */
|
||||||
void ClassicLighting_Refresh(void);
|
void ClassicLighting_Refresh(void);
|
||||||
void ClassicLighting_FreeState(void);
|
void ClassicLighting_FreeState(void);
|
||||||
void ClassicLighting_AllocState(void);
|
void ClassicLighting_AllocState(void);
|
||||||
int ClassicLighting_GetLightHeight(int x, int z);
|
int ClassicLighting_GetLightHeight(int x, int z);
|
||||||
void ClassicLighting_LightHint(int startX, int startY, int startZ);
|
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);
|
void ClassicLighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
22
src/Menus.c
22
src/Menus.c
@ -2878,9 +2878,11 @@ static void GraphicsOptionsScreen_SetSmooth(const cc_string* v) {
|
|||||||
Builder_ApplyActive();
|
Builder_ApplyActive();
|
||||||
MapRenderer_Refresh();
|
MapRenderer_Refresh();
|
||||||
}
|
}
|
||||||
static void GraphicsOptionsScreen_GetModernLighting(cc_string* v) { Menu_GetBool(v, Lighting_Modern); }
|
static void GraphicsOptionsScreen_GetLighting(cc_string* v) { String_AppendConst(v, LightingMode_Names[Lighting_Mode]); }
|
||||||
static void GraphicsOptionsScreen_SetModernLighting(const cc_string* v) {
|
static void GraphicsOptionsScreen_SetLighting(const cc_string* v) {
|
||||||
Lighting_Modern = Menu_SetBool(v, OPT_MODERN_LIGHTING);
|
Lighting_Mode = Utils_ParseEnum(v, 0, LightingMode_Names, LIGHTING_MODE_COUNT);
|
||||||
|
Options_Set(OPT_LIGHTING_MODE, v);
|
||||||
|
|
||||||
Lighting_SwitchActive();
|
Lighting_SwitchActive();
|
||||||
Builder_ApplyActive();
|
Builder_ApplyActive();
|
||||||
MapRenderer_Refresh();
|
MapRenderer_Refresh();
|
||||||
@ -2923,8 +2925,8 @@ static void GraphicsOptionsScreen_InitWidgets(struct MenuOptionsScreen* s) {
|
|||||||
GraphicsOptionsScreen_GetViewDist, GraphicsOptionsScreen_SetViewDist },
|
GraphicsOptionsScreen_GetViewDist, GraphicsOptionsScreen_SetViewDist },
|
||||||
{ -1, 0, "Smooth lighting", MenuOptionsScreen_Bool,
|
{ -1, 0, "Smooth lighting", MenuOptionsScreen_Bool,
|
||||||
GraphicsOptionsScreen_GetSmooth, GraphicsOptionsScreen_SetSmooth },
|
GraphicsOptionsScreen_GetSmooth, GraphicsOptionsScreen_SetSmooth },
|
||||||
{ -1, 50, "Fancy lighting", MenuOptionsScreen_Bool,
|
{ -1, 50, "Lighting mode", MenuOptionsScreen_Enum,
|
||||||
GraphicsOptionsScreen_GetModernLighting, GraphicsOptionsScreen_SetModernLighting },
|
GraphicsOptionsScreen_GetLighting, GraphicsOptionsScreen_SetLighting },
|
||||||
{ 1, -150, "Smooth camera", MenuOptionsScreen_Bool,
|
{ 1, -150, "Smooth camera", MenuOptionsScreen_Bool,
|
||||||
GraphicsOptionsScreen_GetCamera, GraphicsOptionsScreen_SetCamera },
|
GraphicsOptionsScreen_GetCamera, GraphicsOptionsScreen_SetCamera },
|
||||||
{ 1, -100, "Names", MenuOptionsScreen_Enum,
|
{ 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" \
|
"&eSmooth lighting smooths lighting and adds a minor glow to bright blocks.\n" \
|
||||||
"&cNote: &eThis setting may reduce performance.";
|
"&cNote: &eThis setting may reduce performance.";
|
||||||
s->descriptions[4] = \
|
s->descriptions[4] = \
|
||||||
"&eFancy lighting allows bright blocks to cast a much wider range of light.\n" \
|
"&eClassic: &fTwo levels of light, sun and shadow. Good for performance.\n" \
|
||||||
"&cNote: &eThis setting will reduce performance and increase memory usage.";
|
"&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] = \
|
s->descriptions[6] = \
|
||||||
"&eNone: &fNo names of players are drawn.\n" \
|
"&eNone: &fNo names of players are drawn.\n" \
|
||||||
"&eHovered: &fName of the targeted player is drawn see-through.\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_Float(menuOpts_descs[0], 1, 100, 20);
|
||||||
MenuInput_Enum(menuOpts_descs[1], FpsLimit_Names, FPS_LIMIT_COUNT);
|
MenuInput_Enum(menuOpts_descs[1], FpsLimit_Names, FPS_LIMIT_COUNT);
|
||||||
MenuInput_Int(menuOpts_descs[2], 8, 4096, 512);
|
MenuInput_Int(menuOpts_descs[2], 8, 4096, 512);
|
||||||
MenuInput_Enum(menuOpts_descs[6], NameMode_Names, NAME_MODE_COUNT);
|
MenuInput_Enum(menuOpts_descs[4], LightingMode_Names, LIGHTING_MODE_COUNT)
|
||||||
MenuInput_Enum(menuOpts_descs[7], ShadowMode_Names, SHADOW_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);
|
MenuOptionsScreen_Show(GraphicsOptionsScreen_InitWidgets);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ Copyright 2014-2023 ClassiCube | Licensed under BSD-3
|
|||||||
#define OPT_ENTITY_SHADOW "entityshadow"
|
#define OPT_ENTITY_SHADOW "entityshadow"
|
||||||
#define OPT_RENDER_TYPE "normal"
|
#define OPT_RENDER_TYPE "normal"
|
||||||
#define OPT_SMOOTH_LIGHTING "gfx-smoothlighting"
|
#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_MIPMAPS "gfx-mipmaps"
|
||||||
#define OPT_CHAT_LOGGING "chat-logging"
|
#define OPT_CHAT_LOGGING "chat-logging"
|
||||||
#define OPT_WINDOW_WIDTH "window-width"
|
#define OPT_WINDOW_WIDTH "window-width"
|
||||||
|
@ -1728,8 +1728,8 @@ static void BlockDefs_OnBlocksLightPropertyUpdated(BlockID block, cc_bool oldPro
|
|||||||
|
|
||||||
static void BlockDefs_OnBrightnessPropertyUpdated(BlockID block, cc_uint8 oldProp) {
|
static void BlockDefs_OnBrightnessPropertyUpdated(BlockID block, cc_uint8 oldProp) {
|
||||||
if (!World.Loaded) return;
|
if (!World.Loaded) return;
|
||||||
if (!Lighting_Modern) return;
|
if (Lighting_Mode == LIGHTING_MODE_CLASSIC) return;
|
||||||
/* Need to refresh modern lighting when a block's brightness changes */
|
/* Need to refresh fancy lighting when a block's brightness changes */
|
||||||
if (Blocks.Brightness[block] != oldProp) Lighting.Refresh();
|
if (Blocks.Brightness[block] != oldProp) Lighting.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user