Adv builder shouldn't depend on Lighting_Heightmap

This commit is contained in:
UnknownShadow200 2021-06-19 08:02:34 +10:00
parent 480e6a9761
commit 621081f7ac
3 changed files with 36 additions and 30 deletions

View File

@ -772,7 +772,7 @@ enum ADV_MASK {
}; };
static int Adv_Lit(int x, int y, int z, int cIndex) { static int Adv_Lit(int x, int y, int z, int cIndex) {
int flags, offset, lightHeight, lightFlags; int flags, offset, lightFlags;
BlockID block; BlockID block;
if (y < 0 || y >= World.Height) return 7; /* all faces lit */ if (y < 0 || y >= World.Height) return 7; /* all faces lit */
@ -783,19 +783,18 @@ static int Adv_Lit(int x, int y, int z, int cIndex) {
flags = 0; flags = 0;
block = Builder_Chunk[cIndex]; block = Builder_Chunk[cIndex];
lightHeight = Lighting_Heightmap[Lighting_Pack(x, z)]; lightFlags = Blocks.LightOffset[block];
lightFlags = Blocks.LightOffset[block];
/* Use fact Light(Y.YMin) == Light((Y-1).YMax) */ /* Use fact Light(Y.YMin) == Light((Y-1).YMax) */
offset = (lightFlags >> FACE_YMIN) & 1; offset = (lightFlags >> FACE_YMIN) & 1;
flags |= ((y - offset) > lightHeight ? 1 : 0); flags |= Lighting_IsLit_Fast(x, y - offset, z) ? 1 : 0;
/* Light is same for all the horizontal faces */ /* Light is same for all the horizontal faces */
flags |= (y > lightHeight ? 2 : 0); flags |= Lighting_IsLit_Fast(x, y, z) ? 2 : 0;
/* Use fact Light((Y+1).YMin) == Light(Y.YMax) */ /* Use fact Light((Y+1).YMin) == Light(Y.YMax) */
offset = (lightFlags >> FACE_YMAX) & 1; offset = (lightFlags >> FACE_YMAX) & 1;
flags |= ((y - offset) >= lightHeight ? 4 : 0); flags |= Lighting_IsLit_Fast(x, (y + 1) - offset, z) ? 4 : 0;
/* Dynamic lighting */ /* Dynamic lighting */
if (Blocks.FullBright[block]) flags |= 5; if (Blocks.FullBright[block]) flags |= 5;

View File

@ -8,7 +8,7 @@
#include "Event.h" #include "Event.h"
#include "Game.h" #include "Game.h"
cc_int16* Lighting_Heightmap; static cc_int16* light_heightmap;
#define HEIGHT_UNCALCULATED Int16_MaxValue #define HEIGHT_UNCALCULATED Int16_MaxValue
#define Lighting_CalcBody(get_block)\ #define Lighting_CalcBody(get_block)\
@ -17,7 +17,7 @@ for (y = maxY; y >= 0; y--, i -= World.OneY) {\
\ \
if (Blocks.BlocksLight[block]) {\ if (Blocks.BlocksLight[block]) {\
offset = (Blocks.LightOffset[block] >> FACE_YMAX) & 1;\ offset = (Blocks.LightOffset[block] >> FACE_YMAX) & 1;\
Lighting_Heightmap[hIndex] = y - offset;\ light_heightmap[hIndex] = y - offset;\
return y - offset;\ return y - offset;\
}\ }\
} }
@ -37,13 +37,13 @@ static int Lighting_CalcHeightAt(int x, int maxY, int z, int hIndex) {
} }
#endif #endif
Lighting_Heightmap[hIndex] = -10; light_heightmap[hIndex] = -10;
return -10; return -10;
} }
static int Lighting_GetLightHeight(int x, int z) { static int Lighting_GetLightHeight(int x, int z) {
int hIndex = Lighting_Pack(x, z); int hIndex = Lighting_Pack(x, z);
int lightH = Lighting_Heightmap[hIndex]; int lightH = light_heightmap[hIndex];
return lightH == HEIGHT_UNCALCULATED ? Lighting_CalcHeightAt(x, World.Height - 1, z, hIndex) : lightH; return lightH == HEIGHT_UNCALCULATED ? Lighting_CalcHeightAt(x, World.Height - 1, z, hIndex) : lightH;
} }
@ -52,6 +52,10 @@ cc_bool Lighting_IsLit(int x, int y, int z) {
return y > Lighting_GetLightHeight(x, z); return y > Lighting_GetLightHeight(x, z);
} }
cc_bool Lighting_IsLit_Fast(int x, int y, int z) {
return y > light_heightmap[Lighting_Pack(x, z)];
}
PackedCol Lighting_Color(int x, int y, int z) { PackedCol Lighting_Color(int x, int y, int z) {
if (!World_Contains(x, y, z)) return Env.SunCol; if (!World_Contains(x, y, z)) return Env.SunCol;
return y > Lighting_GetLightHeight(x, z) ? Env.SunCol : Env.ShadowCol; return y > Lighting_GetLightHeight(x, z) ? Env.SunCol : Env.ShadowCol;
@ -63,29 +67,29 @@ PackedCol Lighting_Color_XSide(int x, int y, int z) {
} }
PackedCol Lighting_Color_Sprite_Fast(int x, int y, int z) { PackedCol Lighting_Color_Sprite_Fast(int x, int y, int z) {
return y > Lighting_Heightmap[Lighting_Pack(x, z)] ? Env.SunCol : Env.ShadowCol; return y > light_heightmap[Lighting_Pack(x, z)] ? Env.SunCol : Env.ShadowCol;
} }
PackedCol Lighting_Color_YMax_Fast(int x, int y, int z) { PackedCol Lighting_Color_YMax_Fast(int x, int y, int z) {
return y > Lighting_Heightmap[Lighting_Pack(x, z)] ? Env.SunCol : Env.ShadowCol; return y > light_heightmap[Lighting_Pack(x, z)] ? Env.SunCol : Env.ShadowCol;
} }
PackedCol Lighting_Color_YMin_Fast(int x, int y, int z) { PackedCol Lighting_Color_YMin_Fast(int x, int y, int z) {
return y > Lighting_Heightmap[Lighting_Pack(x, z)] ? Env.SunYMin : Env.ShadowYMin; return y > light_heightmap[Lighting_Pack(x, z)] ? Env.SunYMin : Env.ShadowYMin;
} }
PackedCol Lighting_Color_XSide_Fast(int x, int y, int z) { PackedCol Lighting_Color_XSide_Fast(int x, int y, int z) {
return y > Lighting_Heightmap[Lighting_Pack(x, z)] ? Env.SunXSide : Env.ShadowXSide; return y > light_heightmap[Lighting_Pack(x, z)] ? Env.SunXSide : Env.ShadowXSide;
} }
PackedCol Lighting_Color_ZSide_Fast(int x, int y, int z) { PackedCol Lighting_Color_ZSide_Fast(int x, int y, int z) {
return y > Lighting_Heightmap[Lighting_Pack(x, z)] ? Env.SunZSide : Env.ShadowZSide; return y > light_heightmap[Lighting_Pack(x, z)] ? Env.SunZSide : Env.ShadowZSide;
} }
void Lighting_Refresh(void) { void Lighting_Refresh(void) {
int i; int i;
for (i = 0; i < World.Width * World.Length; i++) { for (i = 0; i < World.Width * World.Length; i++) {
Lighting_Heightmap[i] = HEIGHT_UNCALCULATED; light_heightmap[i] = HEIGHT_UNCALCULATED;
} }
} }
@ -108,7 +112,7 @@ static void Lighting_UpdateLighting(int x, int y, int z, BlockID oldBlock, Block
if ((y - newOffset) >= lightH) { if ((y - newOffset) >= lightH) {
if (nowBlocks) { if (nowBlocks) {
Lighting_Heightmap[index] = y - newOffset; light_heightmap[index] = y - newOffset;
} else { } else {
/* Part of the column is now visible to light, we don't know how exactly how high it should be though. */ /* Part of the column is now visible to light, we don't know how exactly how high it should be though. */
/* However, we know that if the old block was above or equal to light height, then the new light height must be <= old block.y */ /* However, we know that if the old block was above or equal to light height, then the new light height must be <= old block.y */
@ -121,7 +125,7 @@ static void Lighting_UpdateLighting(int x, int y, int z, BlockID oldBlock, Block
if (Blocks.BlocksLight[above]) return; if (Blocks.BlocksLight[above]) return;
if (nowBlocks) { if (nowBlocks) {
Lighting_Heightmap[index] = y - newOffset; light_heightmap[index] = y - newOffset;
} else { } else {
Lighting_CalcHeightAt(x, y - 1, z, index); Lighting_CalcHeightAt(x, y - 1, z, index);
} }
@ -222,7 +226,7 @@ static void Lighting_RefreshAffected(int x, int y, int z, BlockID block, int old
void Lighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock) { void Lighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock) {
int hIndex = Lighting_Pack(x, z); int hIndex = Lighting_Pack(x, z);
int lightH = Lighting_Heightmap[hIndex]; int lightH = light_heightmap[hIndex];
int newHeight; int newHeight;
/* Since light wasn't checked to begin with, means column never had meshes for any of its chunks built. */ /* Since light wasn't checked to begin with, means column never had meshes for any of its chunks built. */
@ -230,7 +234,7 @@ void Lighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newB
if (lightH == HEIGHT_UNCALCULATED) return; if (lightH == HEIGHT_UNCALCULATED) return;
Lighting_UpdateLighting(x, y, z, oldBlock, newBlock, hIndex, lightH); Lighting_UpdateLighting(x, y, z, oldBlock, newBlock, hIndex, lightH);
newHeight = Lighting_Heightmap[hIndex] + 1; newHeight = light_heightmap[hIndex] + 1;
Lighting_RefreshAffected(x, y, z, newBlock, lightH + 1, newHeight); Lighting_RefreshAffected(x, y, z, newBlock, lightH + 1, newHeight);
} }
@ -245,7 +249,7 @@ static int Lighting_InitialHeightmapCoverage(int x1, int z1, int xCount, int zCo
for (z = 0; z < zCount; z++) { for (z = 0; z < zCount; z++) {
hIndex = Lighting_Pack(x1, z1 + z); hIndex = Lighting_Pack(x1, z1 + z);
for (x = 0; x < xCount; x++) { for (x = 0; x < xCount; x++) {
lightH = Lighting_Heightmap[hIndex++]; lightH = light_heightmap[hIndex++];
skip[index] = 0; skip[index] = 0;
if (lightH == HEIGHT_UNCALCULATED) { if (lightH == HEIGHT_UNCALCULATED) {
@ -277,7 +281,7 @@ for (y = World.Height - 1; y >= 0; y--) {\
\ \
if (x < xCount && Blocks.BlocksLight[get_block]) {\ if (x < xCount && Blocks.BlocksLight[get_block]) {\
lightOffset = (Blocks.LightOffset[get_block] >> FACE_YMAX) & 1;\ lightOffset = (Blocks.LightOffset[get_block] >> FACE_YMAX) & 1;\
Lighting_Heightmap[hIndex + x] = (cc_int16)(y - lightOffset);\ light_heightmap[hIndex + x] = (cc_int16)(y - lightOffset);\
elemsLeft--;\ elemsLeft--;\
skip[index] = 0;\ skip[index] = 0;\
\ \
@ -329,10 +333,10 @@ static void Lighting_FinishHeightmapCoverage(int x1, int z1, int xCount, int zCo
for (z = 0; z < zCount; z++) { for (z = 0; z < zCount; z++) {
hIndex = Lighting_Pack(x1, z1 + z); hIndex = Lighting_Pack(x1, z1 + z);
for (x = 0; x < xCount; x++, hIndex++) { for (x = 0; x < xCount; x++, hIndex++) {
lightH = Lighting_Heightmap[hIndex]; lightH = light_heightmap[hIndex];
if (lightH == HEIGHT_UNCALCULATED) { if (lightH == HEIGHT_UNCALCULATED) {
Lighting_Heightmap[hIndex] = -10; light_heightmap[hIndex] = -10;
} }
} }
} }
@ -355,13 +359,13 @@ void Lighting_LightHint(int startX, int startZ) {
*---------------------------------------------------Lighting component----------------------------------------------------* *---------------------------------------------------Lighting component----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static void OnReset(void) { static void OnReset(void) {
Mem_Free(Lighting_Heightmap); Mem_Free(light_heightmap);
Lighting_Heightmap = NULL; light_heightmap = NULL;
} }
static void OnNewMapLoaded(void) { static void OnNewMapLoaded(void) {
Lighting_Heightmap = (cc_int16*)Mem_TryAlloc(World.Width * World.Length, 2); light_heightmap = (cc_int16*)Mem_TryAlloc(World.Width * World.Length, 2);
if (Lighting_Heightmap) { if (light_heightmap) {
Lighting_Refresh(); Lighting_Refresh();
} else { } else {
World_OutOfMemory(); World_OutOfMemory();

View File

@ -9,8 +9,6 @@ struct IGameComponent;
extern struct IGameComponent Lighting_Component; extern struct IGameComponent Lighting_Component;
#define Lighting_Pack(x, z) ((x) + World.Width * (z)) #define Lighting_Pack(x, z) ((x) + World.Width * (z))
extern cc_int16* Lighting_Heightmap;
/* Equivalent to (but far more optimised form of) /* Equivalent to (but far more optimised form of)
* for x = startX; x < startX + 18; x++ * for x = startX; x < startX + 18; x++
* for z = startZ; z < startZ + 18; z++ * for z = startZ; z < startZ + 18; z++
@ -30,6 +28,11 @@ PackedCol Lighting_Color(int x, int y, int z);
/* Returns the light colour at the given coordinates. */ /* Returns the light colour at the given coordinates. */
PackedCol Lighting_Color_XSide(int x, int y, int z); PackedCol Lighting_Color_XSide(int x, int y, int z);
/* _Fast functions assume Lighting_LightHint has already been called */
/* and performed the necessary calculations for the given x/z coords */
/* _Fast functions also do NOT check coordinates are inside the map */
cc_bool Lighting_IsLit_Fast(int x, int y, int z);
PackedCol Lighting_Color_Sprite_Fast(int x, int y, int z); PackedCol Lighting_Color_Sprite_Fast(int x, int y, int z);
PackedCol Lighting_Color_YMax_Fast(int x, int y, int z); PackedCol Lighting_Color_YMax_Fast(int x, int y, int z);
PackedCol Lighting_Color_YMin_Fast(int x, int y, int z); PackedCol Lighting_Color_YMin_Fast(int x, int y, int z);